Windows x64内核学习笔记(三)—— SMEP SMAP
Windows x64內核學習筆記(三)—— SMEP & SMAP
- SMEP & SMAP
- 實驗:構造IDT后門
- 第一步:編譯以下代碼
- 第二步:構造IDT后門
- 第三步:運行程序
- 第四步:驗證SMEP
- 第五步:修改代碼,再次運行
- 第六步:驗證SMAP
- 第七步:使用STAC指令
- 結語
- 參考資料
SMEP & SMAP
SMEP:位于Cr4的第20位,作用是讓處于內核權限的CPU無法執行用戶代碼。
SMAP:位于Cr4的第21位,作用是讓處于內核權限的CPU無法讀寫用戶代碼。
關于控制寄存器各個標志位的具體含義可參考Intel開發手冊卷3第2.5節。
實驗:構造IDT后門
描述:嘗試在x64系統中構造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屬性:
項目屬性:
第二步:構造IDT后門
IntEntry函數表示手動構造IDT后門的入口地址,筆者環境下的地址為0x100001002
這里選擇將后門寫到IDT[0x21]的位置,Win10系統沒有占用這個位置,里面保存的是IDT的基地址,可以看一下。
那么,只要構造好中斷門描述符,并寫到IDT[0x21]就可以了。
構造好的中斷門描述符(可以從IDT[3]的位置拷貝一份進行修改):
低四字節:0000ee00`00101000 高四字節:00000000`00000001
將構造好中斷門描述符寫入IDT[0x21]
查看寫入的IDT后門解析情況,目標地址已經成功指向后門函數的地址。
第三步:運行程序
注意:運行程序前可以先給虛擬機打個快照。
運行結果:系統卡死,且WinDbg無法中斷。
其實這個時候產生了三重錯誤(三重錯誤的概念在VT系列筆記中提到過),因此WinDbg也無法接管。
正常來說,在x86系統中構造IDT后門,只要權限和地址正確,就能夠正常調用。
而從Windows 8的某一版本開始,開始引入了一些保護機制,即在Cr4中加入SMEP和SMAP這兩個標志位,用于防止內核權限的CPU讀寫或執行用戶代碼。
回滾快照,看一下程序運行前Cr4的值:
可以看到,此時SMEP和SMAP兩個標志位都為1。
第四步:驗證SMEP
在WinDbg中將SMEP位改為0。
然后再次運行程序,運行結果:
可以看到,此時已經可以正常運行了,程序成功走到了后門函數并返回。
由于我們目前還未加入修改變量x的代碼,因此讀出來的值是0,是正常的。
第五步:修改代碼,再次運行
將后門函數的代碼修改為如下,重新編譯
IntEntry PROCmov rax, qword ptr [0fffff8034b290fd0h] // gdt[4]mov x, raxiretq IntEntry ENDP0fffff8034b290fd0h這個值是通過windbg讀取的,指向gdt表的第4項
目的是嘗試讓程序通過后門函數讀取0環的內存。
運行結果:
系統再次卡死,這次是由于觸發了SMAP保護。
第六步:驗證SMAP
回滾快照,下面來驗證下SMAP位,記得先將IDT設置好。
然后把SMAP和SMEP都置為0:
再次運行程序,運行結果:
此時,由于又解除了SMAP保護,程序已經能成功從0環讀取數據了。
第七步:使用STAC指令
描述:STAC指令相當于Set AC,用于設置AC標志位,能暫時解除系統的一些保護,包括SMAP保護。
再次回滾快照,這次我們只清除Cr4的SMEP位,保留SMAP位,注意構造IDT后門。
將后門函數的代碼修改為如下,重新編譯:
運行結果:
可以看到,在不解除SMAP位的情況下,使用STAC指令后依然能夠讀到0環內存。
結語
那么通過以上內容,我們了解并驗證了SMEP/SMAP這兩個標志位的作用。
事實上,就算解除了SMEP和SMAP保護,目前也只能訪問和執行一部分0環內存,這是因為還存在「內核頁表隔離」機制,這是后話了。
關于SMAP保護的具體實現可參考Intel開發手冊卷3第4.6節。
參考資料
- bilibili周壑:x64內核研究系列教程
總結
以上是生活随笔為你收集整理的Windows x64内核学习笔记(三)—— SMEP SMAP的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows x64内核学习笔记(一)
- 下一篇: Windows x64内核学习笔记(四)