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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

3.API的调用过程(保存现场)

發(fā)布時(shí)間:2025/3/20 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 3.API的调用过程(保存现场) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

_KTrap_Frame 結(jié)構(gòu)

kd> dt _KTrap_Frame ntdll!_KTRAP_FRAME//調(diào)試系統(tǒng)服務(wù)+0x000 DbgEbp : Uint4B+0x004 DbgEip : Uint4B+0x008 DbgArgMark : Uint4B+0x00c DbgArgPointer : Uint4B//當(dāng)需要調(diào)整棧時(shí)以下作為臨時(shí)變量+0x010 TempSegCs : Uint4B+0x014 TempEsp : Uint4B//調(diào)試寄存器+0x018 Dr0 : Uint4B+0x01c Dr1 : Uint4B+0x020 Dr2 : Uint4B+0x024 Dr3 : Uint4B+0x028 Dr6 : Uint4B+0x02c Dr7 : Uint4B//段寄存器+0x030 SegGs : Uint4B+0x034 SegEs : Uint4B+0x038 SegDs : Uint4B//易失寄存器+0x03c Edx : Uint4B+0x040 Ecx : Uint4B+0x044 Eax : Uint4B//非易失性寄存器需要在中斷例程中先保存+0x048 PreviousPreviousMode : Uint4B+0x04c ExceptionList : Ptr32 _EXCEPTION_REGISTRATION_RECORD+0x050 SegFs : Uint4B//非易失寄存器+0x054 Edi : Uint4B+0x058 Esi : Uint4B+0x05c Ebx : Uint4B+0x060 Ebp : Uint4B+0x064 ErrCode : Uint4B//硬件填充 (通過(guò)中斷門(mén)進(jìn)入的,這個(gè)值為NULL)//中斷發(fā)生時(shí)保存被中斷的代碼段和地址,iret返回到此地址+0x068 Eip : Uint4B//硬件填充+0x06c SegCs : Uint4B//硬件填充+0x070 EFlags : Uint4B//硬件填充//中斷發(fā)生時(shí),若發(fā)生權(quán)限變換,則要保存舊堆棧+0x074 HardwareEsp : Uint4B//硬件填充,僅當(dāng)有模式切換時(shí)才會(huì)使用+0x078 HardwareSegSs : Uint4B//硬件填充,僅當(dāng)有模式切換時(shí)才會(huì)使用//這4個(gè)在保護(hù)模式下沒(méi)有使用+0x07c V86Es : Uint4B//硬件填充+0x080 V86Ds : Uint4B//硬件填充+0x084 V86Fs : Uint4B//硬件填充+0x088 V86Gs : Uint4B//硬件填充

無(wú)論是通過(guò)中斷門(mén)進(jìn)入的0環(huán),還是快速調(diào)用,3環(huán)所有的寄存器都會(huì)保存在這個(gè)結(jié)構(gòu)體里。
通過(guò)快速調(diào)用68~78是沒(méi)有的




權(quán)限發(fā)生切換時(shí)堆棧也會(huì)改變,這里聽(tīng)不懂的話去學(xué)習(xí)保護(hù)模式

內(nèi)核層的ESP = TSS+4
Windows操作系統(tǒng)在每個(gè)處理器初始化時(shí),會(huì)在GDT中為它構(gòu)造一個(gè)TSS段,然后利用ltr指令設(shè)置處理器的任務(wù)環(huán)境段。(參考_KiSystemStartup函數(shù))
另外,Windows每次切換線程時(shí),總是會(huì)設(shè)置好TSS中Ring0的esp,使指向當(dāng)前線程的內(nèi)核棧。(參考SwapContext函數(shù))

保存3環(huán)寄存器值到_KTrap_Frame的0x50~0x64
fs :0030 拆分 0000 0000 0011 0 0 00,RPL為0 ,查gdt,第六組
ffc093df`f0000001
ffdff000這個(gè)地址剛好指向的就是CUP的KPCR結(jié)構(gòu),fs在3環(huán)指向的是PEB結(jié)構(gòu),0環(huán)就是kpcr。

繼續(xù)上面

Exceptionlist是異常鏈表。
把老的Exceptionlist保存到_KTRAP_FRAME的+0x4c位置,然后把它置為空白。
將kpcr+0x124放到esi中,也就是CurrentThread。

將[esi+140]保存先前模式到_KTRAP_FRAME的+048位置,_KTHREAD.PreviousMode 。
提升堆棧0x48
取出3環(huán)的CS放到ebx,然后and 上1結(jié)果放到esi+0x140,也就是新的先前模式。

先前模式:當(dāng)你調(diào)用這段代碼的時(shí)候,如果是0環(huán)的程序先前模式就存0,3環(huán)就存1。操作系統(tǒng)想知道是哪一環(huán)的程序調(diào)用我只需要查看調(diào)用者的先前模式即可

提升棧底ebp與esp指向同一個(gè)位置_KTRAP_FRAME最開(kāi)始的位置
取出esi+0x134的位置_KTHREAD.TrapFrame (+0x134 當(dāng)前線程的信息),放到ebp+3c_KTHREAD.Edx 。


_KTRAP_FRAME放到_KTHREAD.TrapFrame
把3環(huán)的ebp放到ebx
把3環(huán)的eip放到edi
把3環(huán)的參數(shù)指針?lè)诺絖KTRAP_FRAME.DbgArgPointer


0x0dadb0d0(操作系統(tǒng)用到的一個(gè)標(biāo)志)放到_KTRAP_FRAME.DbgArgMark
ebp+0 = _KTRAP_FRAME.DbgEbp
ebp+04 = _KTRAP_FRAME.DbgEip
比較_KTHREAD.DebugActive(當(dāng)前線程是否處于調(diào)試狀態(tài)如果處于調(diào)試狀態(tài)這個(gè)值就不是0ff),如果你處于調(diào)試狀態(tài)他就會(huì)跳轉(zhuǎn)到下面的代碼。
就是將dr0~dr7存到_KTRAP_FRAME的+0x18到+0x2c。

如果不處于調(diào)試狀態(tài)跳轉(zhuǎn)到以下代碼
無(wú)論是從KiFastCallEntry還是kisystenService都會(huì)最終都會(huì)調(diào)用一下的代碼

兩空進(jìn)來(lái)最中執(zhí)行的代碼是一樣的,中斷進(jìn)來(lái)和快速調(diào)用的他們填表(_KTrap_Frame)的方式不一樣但是最終調(diào)用的代碼都是一樣的

  • kiSystenService:
    進(jìn)入0環(huán)后原來(lái)3環(huán)的寄存器保存在_KTrap_Frame的0x50~0x64
    把3環(huán)的參數(shù)指針?lè)诺絖KTRAP_FRAME.DbgArgPointer

以上都kiSystenService從0環(huán)進(jìn)入3環(huán)的填表過(guò)程

KiFastCallEntry的填表過(guò)程


KPCR+40就是TSS,TSS+4就是esp0

push 到_KTrap_Frame
+0x078 HardwareSegSs : Uint4B
+0x074 HardwareEsp : Uint4B
+0x070 EFlags : Uint4B

直接貼ida分析代碼了

mov ecx, 23hpush 30hpop fs ; 修改fs寄存器為30mov ds, ecxmov es, ecxmov ecx, ds:0FFDFF040h ; 獲取當(dāng)前TSSmov esp, [ecx+4] ; TSS中得到ESPpush 23h ; 原ss壓棧push edx ; 原esp壓棧pushf ; EFLAGS壓棧loc_40770A: ; CODE XREF: _KiFastCallEntry2+22jpush 2add edx, 8 ; 當(dāng)前保存著sysentet進(jìn)入前的ESP的值; +8 = 參數(shù)指針popfor [esp+0Ch+var_B], 2 ; KtrapFrame->Eflags.if = 1push 1Bh ; KtrapFrame->CS=0x1b 保存r3的cspush dword ptr ds:0FFDF0304h ; KtrapFrame->EIP =返回地址push 0 ; KtrapFrame->Error = 0push ebp ; KtrapFrame->ebp = ebppush ebx ; KtrapFrame->ebx = ebxpush esi ; KtrapFrame->esi = esipush edi ; KtrapFrame->edi = edimov ebx, ds:0FFDFF01Chpush 3Bh ; KtrapFrame->SegFs = 0x3b 保存r3的fsmov esi, [ebx+124h] ; 得到當(dāng)前線程結(jié)構(gòu)push dword ptr [ebx] ; KtrapFrame->0x4c 保存原異常鏈mov dword ptr [ebx], 0FFFFFFFFh ; 設(shè)置為空的異常鏈mov ebp, [esi+18h] ; 得到初始堆棧KtrapFrame->0x48push 1 ; KtrapFrame->PreviousPreviousMode = 1sub esp, 48h ; 提升棧頂指針到_Ktrap_Framesub ebp, 29Ch ; Ktrap_Framemov byte ptr [esi+140h], 1 ; 先前模式cmp ebp, espjnz loc_4076C8and dword ptr [ebp+2Ch], 0 ; 清零dr7test byte ptr [esi+2Ch], 0FFh ; 檢查是否處于調(diào)試狀態(tài)mov [esi+134h], ebp ; ;jnz Dr_FastCallDrSaveloc_40776A: ; CODE XREF: Dr_FastCallDrSave+10j; Dr_FastCallDrSave+7Cjmov ebx, [ebp+60h] ; ebp = KtrapFrame->ebpmov edi, [ebp+68h] ; edi = KtrapFrame->eipmov [ebp+0Ch], edx ; KtrapFrame->DbgArgPointer = 參數(shù)指針mov dword ptr [ebp+8], 0BADB0D00hmov [ebp+0], ebx ; KtrapFrame->DbgEbp = ebxmov [ebp+4], edi ; KtrapFrame->DbgEip = edisti

總結(jié)

以上是生活随笔為你收集整理的3.API的调用过程(保存现场)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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