Windows x64内核学习笔记(五)—— KPTI(未完待续)
Windows x64內核學習筆記(五)—— KPTI(未完待續)
- KPTI
- 實驗一:構造IDT后門并讀取Cr3
- 參考資料
KPTI
描述:KPTI(Kernel page-table isolation)即內核頁表隔離機制。
在學習SMEP&SMAP兩個標志位時,我們成功通過將這兩個標志位的值置0以達到讓處于內核權限的CPU擁有讀寫和執行用戶代碼的權限,但實際上,只有內核模塊的KVASCODE區段范圍的地址是可讀的,正是因為x64模式擁有內核頁表隔離機制。
實驗一:構造IDT后門并讀取Cr3
第一步:編譯以下代碼,項目配置可參考這篇筆記。
//x64asm.asm option casemap:noneEXTERN x:qword.DATA.CODEIntEntry PROCmov rax, Cr3mov x, raxiretq IntEntry ENDPgo PROCint 21hret go ENDPEND //test.cpp #include <windows.h> #include <stdio.h>extern "C" void IntEntry(); extern "C" void go(); extern "C" ULONG64 x;ULONG64 x;void main() {// eq idtr+210 0000ee00`00101000// eq idtr+218 00000000`00000001if ((ULONG64)IntEntry != 0x0000000100001000){printf("wrong IntEntry at %p \n", IntEntry);system("pause");exit(-1);}go();printf("%p \n", x);system("pause"); }第二步:將Cr4中的SMEP和SMAP位置0
第三步:構造IDT后門(地址使用IDA得到):
構造好的中斷門描述符
低四字節:0000ee00`00101000 高四字節:00000000`00000001
第五步:將構造好的IDT后門寫入IDT[0x21]
kd> r idtr
idtr=fffff8034b28e000
第六步:運行程序,運行結果如下。
好了,本次學習到此為止(無奈),為什么呢,因為筆者發現從0環讀出的Cr3居然和3環讀取的Cr3居然是同一個。
一開始以為是測試機沒開KPTI,然后各種谷歌、百度如何打開KPTI,嘗試過在「Windows安全中心」-「設備安全性」-「內核隔離」中打開「內存完整性」,發現每次重啟后都會自動關閉(并且如果開啟內存完整性,并為虛擬機開啟VT支持還會導致開機卡死),也嘗試過修改注冊表,組策略,切換低權限用戶,全部無效,耗費了近兩天時間,因此暫時沒法繼續往下做實驗了,希望有大神知道怎么回事的話能在評論區指點一下,萬分感謝。
那么正常的實驗結果應該是怎么樣的呢?下面簡單說一下。
如果開啟KPTI的話,首先0環和3環的Cr3不會是同一個,兩個Cr3分別擁有一套自己的頁表。0環的Cr3能夠訪問內核所有的物理頁,而三環的Cr3只映射了內核的KVASCODE區段的物理頁,而沒有映射其他區段的,因此通過3環的Cr3尋找內核TEXT段的物理頁,最多只能找到PPE,而從PDE開始就沒有映射了。
參考資料
- bilibili周壑:x64內核研究系列教程
總結
以上是生活随笔為你收集整理的Windows x64内核学习笔记(五)—— KPTI(未完待续)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows x64内核学习笔记(四)
- 下一篇: windows编写第一个MFC程序