日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows x64内核学习笔记(三)—— SMEP SMAP

發(fā)布時間:2025/3/21 windows 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows x64内核学习笔记(三)—— SMEP SMAP 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Windows x64內(nèi)核學(xué)習(xí)筆記(三)—— SMEP & SMAP

  • SMEP & SMAP
  • 實驗:構(gòu)造IDT后門
    • 第一步:編譯以下代碼
    • 第二步:構(gòu)造IDT后門
    • 第三步:運行程序
    • 第四步:驗證SMEP
    • 第五步:修改代碼,再次運行
    • 第六步:驗證SMAP
    • 第七步:使用STAC指令
  • 結(jié)語
  • 參考資料

SMEP & SMAP

SMEP:位于Cr4的第20位,作用是讓處于內(nèi)核權(quán)限的CPU無法執(zhí)行用戶代碼。
SMAP:位于Cr4的第21位,作用是讓處于內(nèi)核權(quán)限的CPU無法讀寫用戶代碼。

關(guān)于控制寄存器各個標(biāo)志位的具體含義可參考Intel開發(fā)手冊卷3第2.5節(jié)。

實驗:構(gòu)造IDT后門

描述:嘗試在x64系統(tǒng)中構(gòu)造IDT后門

第一步:編譯以下代碼

//x64asm.asm option casemap:noneEXTERN x:qword.DATA.CODEIntEntry PROCiretq IntEntry ENDPgo PROCint 21hret go ENDPEND //test.c #include <windows.h> #include <stdio.h>extern "C" void IntEntry(); extern "C" void go(); extern "C" ULONG64 x;ULONG64 x;void main() {if ((ULONG64)IntEntry != 0x0000000100001000){printf("wrong IntEntry at %p \n", IntEntry);system("pause");exit(-1);}go();printf("%p \n", x);system("pause"); }

x64asm.asm屬性


項目屬性

第二步:構(gòu)造IDT后門

IntEntry函數(shù)表示手動構(gòu)造IDT后門的入口地址,筆者環(huán)境下的地址為0x100001002

這里選擇將后門寫到IDT[0x21]的位置,Win10系統(tǒng)沒有占用這個位置,里面保存的是IDT的基地址,可以看一下。

那么,只要構(gòu)造好中斷門描述符,并寫到IDT[0x21]就可以了。

構(gòu)造好的中斷門描述符(可以從IDT[3]的位置拷貝一份進行修改):

低四字節(jié):0000ee00`00101000 高四字節(jié):00000000`00000001

將構(gòu)造好中斷門描述符寫入IDT[0x21]

查看寫入的IDT后門解析情況,目標(biāo)地址已經(jīng)成功指向后門函數(shù)的地址。

第三步:運行程序

注意:運行程序前可以先給虛擬機打個快照。

運行結(jié)果:系統(tǒng)卡死,且WinDbg無法中斷。

其實這個時候產(chǎn)生了三重錯誤(三重錯誤的概念在VT系列筆記中提到過),因此WinDbg也無法接管。

正常來說,在x86系統(tǒng)中構(gòu)造IDT后門,只要權(quán)限和地址正確,就能夠正常調(diào)用。

而從Windows 8的某一版本開始,開始引入了一些保護機制,即在Cr4中加入SMEP和SMAP這兩個標(biāo)志位,用于防止內(nèi)核權(quán)限的CPU讀寫或執(zhí)行用戶代碼。

回滾快照,看一下程序運行前Cr4的值:

可以看到,此時SMEP和SMAP兩個標(biāo)志位都為1。

第四步:驗證SMEP

在WinDbg中將SMEP位改為0。

然后再次運行程序,運行結(jié)果:

可以看到,此時已經(jīng)可以正常運行了,程序成功走到了后門函數(shù)并返回。

由于我們目前還未加入修改變量x的代碼,因此讀出來的值是0,是正常的。

第五步:修改代碼,再次運行

將后門函數(shù)的代碼修改為如下,重新編譯

IntEntry PROCmov rax, qword ptr [0fffff8034b290fd0h] // gdt[4]mov x, raxiretq IntEntry ENDP

0fffff8034b290fd0h這個值是通過windbg讀取的,指向gdt表的第4項

目的是嘗試讓程序通過后門函數(shù)讀取0環(huán)的內(nèi)存。

運行結(jié)果

系統(tǒng)再次卡死,這次是由于觸發(fā)了SMAP保護。

第六步:驗證SMAP

回滾快照,下面來驗證下SMAP位,記得先將IDT設(shè)置好。

然后把SMAP和SMEP都置為0:

再次運行程序,運行結(jié)果:

此時,由于又解除了SMAP保護,程序已經(jīng)能成功從0環(huán)讀取數(shù)據(jù)了。

第七步:使用STAC指令

描述:STAC指令相當(dāng)于Set AC,用于設(shè)置AC標(biāo)志位,能暫時解除系統(tǒng)的一些保護,包括SMAP保護。

再次回滾快照,這次我們只清除Cr4的SMEP位,保留SMAP位,注意構(gòu)造IDT后門。

將后門函數(shù)的代碼修改為如下,重新編譯:

IntEntry PROCmov rax, qword ptr [0fffff8034b290fd0h]stac ;如果找不到這條指令,可以emit對應(yīng)的字節(jié)碼mov x, raxiretq IntEntry ENDP

運行結(jié)果:

可以看到,在不解除SMAP位的情況下,使用STAC指令后依然能夠讀到0環(huán)內(nèi)存。

結(jié)語

那么通過以上內(nèi)容,我們了解并驗證了SMEP/SMAP這兩個標(biāo)志位的作用。

事實上,就算解除了SMEP和SMAP保護,目前也只能訪問和執(zhí)行一部分0環(huán)內(nèi)存,這是因為還存在「內(nèi)核頁表隔離」機制,這是后話了。

關(guān)于SMAP保護的具體實現(xiàn)可參考Intel開發(fā)手冊卷3第4.6節(jié)。

參考資料

  • bilibili周壑:x64內(nèi)核研究系列教程

總結(jié)

以上是生活随笔為你收集整理的Windows x64内核学习笔记(三)—— SMEP SMAP的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。