(48)逆向分析 KiFastCallEntry 函式填充 _KTRAP_FRAME 部分

hambaga發表於2020-11-02

一、回顧

上一篇部落格我逆向了 KiSystemService 函式填充 _KTRAP_FRAME 部分。

逆向分析 KiSystemService 函式填充 _KTRAP_FRAME 部分

裡面涉及了6個結構體,分別是 _KTRAP_FRAME,_ETHREAD,_KTHREAD,_KPCR,_NT_TIB 和 _KPRCB。這些結構體待會逆向 _KiFastCallEntry 時也要用到,我在本文就不貼出來了,有需要可以去上篇部落格檢視或者在windbg裡 dt 檢視。

這裡貼一張 _KTRAP_FRAME 的示意圖:

在這裡插入圖片描述

KiSystemService 通過中斷門進0環,進0環後,3環的 esp,ss,eip,cs,eflags 都儲存到0環棧裡了,進0環後應該先把當前的暫存器的值按照_KTRAP_FRAME的約定壓到棧裡。

KiFastCallEntry 做的事情是類似的,下面我貼出我逆向的結果。

二、逆向分析 KiFastCallEntry 函式

.text:00466540 _KiFastCallEntry:                       ; DATA XREF: KiLoadFastSyscallMachineSpecificRegisters(x)+24o
.text:00466540                                         ; _KiTrap01+72o
.text:00466540                 mov     ecx, 23h
.text:00466545                 push    30h
.text:00466547                 pop     fs              ; fs = 0x30, ffc093df`f0000001, 0環資料段
.text:00466549                 mov     ds, ecx         ; ds = 0x23, 00cff300`0000ffff, 3環資料段
.text:0046654B                 mov     es, ecx         ; es = 0x23
.text:0046654D                 mov     ecx, ds:0FFDFF040h
.text:00466553                 mov     esp, [ecx+4]    ; esp = _KPCR.TSS.Esp0,切換到0環堆疊
.text:00466556                 push    23h             ; _KTRAP_FRAME.HardwareSegSs = 0x23
.text:00466558                 push    edx             ; _KTRAP_FRAME.HardwareEsp = edx, edx是3環棧頂.
.text:00466559                 pushf                   ; _KTRAP_FRAME.EFlags = EFlags
.text:0046655A
.text:0046655A loc_46655A:                             ; CODE XREF: _KiSystemService+96j
.text:0046655A                 push    2
.text:0046655C                 add     edx, 8          ; edx 指向3環API引數
.text:0046655F                 popf                    ; EFlags = 0x02,即清空0環所有標誌位
.text:0046655F                                         ; 此時 esp 指向 EFlags
.text:00466560                 or      [esp+0A4h+var_A3], 2 ; _KTRAP_FRAME.EFlags 即3環 EFlags 的 IF = 1
.text:00466565                 push    1Bh             ; _KTRAP_FRAME.SegCs = 0x1B, 3環程式碼段
.text:00466567                 push    dword ptr ds:0FFDF0304h ; _KTRAP_FRAME.Eip = _KUSER_SHARED_DATA.SystemCallReturn
.text:0046656D                 push    0               ; _KTRAP_FRAME.ErrCode = 0
.text:0046656F                 push    ebp             ; _KTRAP_FRAME.Ebp = ebp
.text:00466570                 push    ebx             ; _KTRAP_FRAME.Ebx = ebx
.text:00466571                 push    esi             ; _KTRAP_FRAME.Esi = esi
.text:00466572                 push    edi             ; _KTRAP_FRAME.Edi = edi
.text:00466573                 mov     ebx, ds:0FFDFF01Ch ; ebx = _KPCR.SelfPcr,即 ebx 指向 _KPCR
.text:00466579                 push    3Bh             ; _KTRAP_FRAME.SegFs = 0x3B
.text:0046657B                 mov     esi, [ebx+124h] ; esi = _KPCR._KPRCB.CurrentThread
.text:00466581                 push    dword ptr [ebx] ; _KTRAP_FRAME.ExceptionList = _KPCR.NtTib.ExceptionList
.text:00466583                 mov     dword ptr [ebx], 0FFFFFFFFh ; _KPCR.NtTib.ExceptionList = -1
.text:00466589                 mov     ebp, [esi+18h]  ; ebp = _KPCR._KPRCB.CurrentThread.InitialStack
.text:0046658C                 push    1               ; _KTRAP_FRAME.PreviousPreviousMode = 1,表示從3環來
.text:0046658E                 sub     esp, 48h        ; esp 指向 _KTRAP_FRAME

三、總結

和 KiSystemService 大同小異,按照 _KTRAP_FRAME 的約定一個一個填值而已。但是有一行我看不懂:

.text:00466560                 or      [esp+0A4h+var_A3], 2

這行實際上是:

.text:00466560                 or      [esp+1], 2

分析後可以發現,這行指令的作用是將3環的EFlags的IF位置1,即啟用中斷。

附 eflags 暫存器

在這裡插入圖片描述

相關文章