2.API的调用过程(3环进0环)
User層地址為: 0x7ffe0000
Kernnel層地址為: 0xffdf0000
他們兩個線性地址對應的物理頁是一樣的,只不過映射了兩份
特別說明:
雖然指向的是同一個物理頁,但在User層是只讀的,在Kernnel層是可讀可寫的.
我們來看看這個結構
回顧之前的
也就是說我們用了SystemCall的方式進入0環,下面我們來看看0x7FFE0300儲存的是什么
當通過eax=1來執行cpuid指令時,處理器的特征信息被放在ecx和edx寄存器中, 其中edx包含了一個SEP位(11位) ,該位指明了當前CPU知否支持-sysenter/sysexit指令(快速調用)
SEP位=1:支持快速調用
SEP位=0:不支持快速調用
支持:ntdll.dl!KiFastSystemCall()
不支持:ntdll.dl!lkilntSystemCall()
我的是支持的,當操作系統啟動的時候就會提供cpuid指令來查看你支不支持sysenter/sysexit指令,當你支持的時后它會把ntdll.dl!KiFastSystemCall()這個函數的地址寫到_KUSER_SHARED_DATA結構+300的處,如果不支持就寫ntdll.dl! lkilntSystemCal()
進入0環需要修改的寄存器
ntdll.dl!KiFastSystemCall()與ntall.dl!lkilntSystemCall()就是提供了兩種不同的找法
API通過中斷門進0環
當你的CPU不支持快速調用是用以下方法進入0環的
eax里的值是內核操作碼,edx存的是參數的指針,api統一中斷號0x2e(idt 表2e位置)
int 0x2e進ring0
0008 就是CS,高4字節+低4字節就是EIP:8053e481,ss與esp是從Tss(任務段)提供的
EIP:KiSystemService();,這個函數是內核模塊里的
sysenter進0環
eax是操作碼,edx是返回地址以及參數的指針
為什么叫快速調用?
中斷門進0環,需要的CS, EIP在IDT表中,需要查內存(SS與ESP由TSS提供)
而CPU如果支持sysenter指令時,操作系統會提前將CS/SS/ESP/EIP的值存儲在 MSR寄存器中, sysenter指令執行時, CPU會將MSR寄存器中的值直接寫入相關,寄存器,沒有讀內存的討程,所以叫快速調用,本質是一樣的!
在執行sysenter指令之前,操作系統必須指定0環的CS段、SS段、EIP以及ESP.
MSR寄存器是非常大的,0x174位置存放新的CS,0x175存放新的ESP,0x176存放新的EIP。SS并沒有存放在MSR寄存器中,執行sysenter后cs+8就是ss了
可以通過RDMSR/WRMST來進行讀寫(操作系統使用WRMST寫該寄存器) :
windbg 查看這這幾個值
rdmsr 174 //查看CSrdmsr 175 //查看ESPrdmsr 176 //查看EIP
EIP:KiFastCallEntry();
用戶代碼調用sysenter指令以前,必須將要返回的指令地址和棧指針值保存到edx和ecx寄存器中,否則,內核模式代碼將來無法設置正確的值,以使sysexit還能返回到用戶模式代碼原來的位置。
API通過sysenter指令進0環:
sysexit:
將IA_32_SYSENTER_CS+16裝載到CS寄存器;將edx寄存器中的指針裝載到eip寄存器中;(指定用戶模式代碼段)
將IA_32_SYSENTER_CS+24裝載到SS寄存器;將ecx寄存器中的指針裝載到esp寄存器中;(指定用戶模式棧段)
切換到特權級3,執行eip寄存器中指定的用戶代碼。
C:\Windows\System32
內核模塊: ntoskrnl.exe/ntkrnlpa.exe
2-9-9-12分頁用:ntkrnlpa.exe
10-10-12用:ntoskrnl.exe
總結
以上是生活随笔為你收集整理的2.API的调用过程(3环进0环)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1.API的调用过程(3环部分)
- 下一篇: 3.API的调用过程(保存现场)