Sysenter/Kifastcallentry hook 檢測與恢復


關於Sysenter、Kifastcallentry、中斷之類的內核入口hook技術早就爛大街了,可是對hook的檢測與恢復代碼卻是寥寥無幾,一切拋開代碼將原理的行為都是耍流氓。  

下面以Sysenter hook技術為例子,重點分析下這類鈎子的檢測與恢復技術。

 

Sysenter簡述 :

  Windows2000以前用int 2e作為中斷指令進入內核發起系統調用。從Windows2000以后,准確的說是Pentium II處理器開始,為了避免int 2e指令對模式切換的巨大開銷,Intel引入了一對新的指令,sysenter/sysexit,實現快速的模式切換,所以也叫快速系統調用。 關於兩者之間的具體異同請參考潘愛民老師《Windows內核原理與實現》第8章Windows系統服務,再次不是分析重點,不在累贅。

 

  sysenter使用三個MSR(Model Specific Register)寄存器來指定跳轉目標地址和棧位置。操作系統在內核模式下通過rdmsr/wrmsr特權指令來設置這三個寄存器,當然必須在系統初始化時(第一次系統調用發生以前)完成。

 

MSR寄存器                                MSR地址        含義

IA32_SYSENTRY_CS                  174h           低16位值制訂了特權級0的代碼段和棧段的段選擇符

IA32_SYSENTRY_ESP       175h           內核棧指針的32位偏移  

IA32_SYSENTRY_EIP       176h              目標例程的32位偏移(Kifastcallentry地址)

 

根據這三個MSR寄存器的屬性我們看一段代碼

    _asm
    {
        mov ecx,0x176
        rdmsr
        mov KifastcalllAddress,eax
    }

 

獲取Kifastcallentry地址其實只需要三行匯編就可以搞定,但是有很多人說看不懂。  

RDMSR將64位由ECX寄存器指定的MSR(model specific register,模式指定寄存器)的內容讀出至寄存器EDX:EAX中(在支持intel64架構的處理器中RCX的高32位忽略)。MSR的高32位內容存放在EDX寄存器中,MSR的低32位內容存放在EAX寄存器(在支持intel64架構的處理器中RDX和RAX的高32位忽略)。

說這么多其實就是把MSR寄存器地址放進ECX,然后通過RDMSR特權指令就能把相應MSR寄存器的值讀進EAX中。而IA32_SYSENTRY_EIP寄存器中保存的就是Kifastcallentry地址。

 

Sysenter hook:

下面看一個替換IA32_SYSENTRY_EIP值進行sysentry hook小Demo。

 

#include "HookSysenter.h"


ULONG  OriginalAddress = 0;
ULONG  i = 0;

__declspec(naked)FakeAddress()
{

    _asm
    {
        mov i,eax
    }

    __asm
    {
        pushad
        push fs
        push 0x30
        pop fs
    }

    if (i==0x101)
    {
        DbgPrint("Terminate\r\n");
    }


    _asm
    { 
        pop fs   
        popad
        jmp [OriginalAddress]    
    }
}


NTSTATUS
DriverEntry(PDRIVER_OBJECT  DriverObject,
            PUNICODE_STRING RegisterPath)
{

    DriverObject->DriverUnload = UnloadDriver;



    DbgPrint("Hello\r\n");


    Hook();
    return STATUS_SUCCESS;
}

VOID
UnloadDriver(PDRIVER_OBJECT  DriverObject)
{
    UnHook();
}

VOID
Hook()
{
    _asm
    {
        mov ecx,0x176
        rdmsr
        mov OriginalAddress,eax
        mov eax, FakeAddress
        wrmsr
    }
}

VOID
UnHook()
{
    KIRQL oldIrql;
    oldIrql=KeRaiseIrqlToDpcLevel();
    _asm
    {
        mov ecx,0x176
        mov eax,OriginalAddress
        wrmsr
    }
    KeLowerIrql(oldIrql);
}

 

只是替換Kifastcallentry地址,然后簡單判斷了下是否發起對NTterminateProcess的系統調用,很簡單。

 

那么問題來了,我們如何通過內核文件去尋找原始的Kifastcallentry呢?

 

內核Ntoskrnl.exe的OEP入口函數可以理解是kisystemstartup,然后我們用WinDbg來看一看這個函數。

kd> u kisystemstartup 
nt!KiSystemStartup:
806907e0 0000            add     byte ptr [eax],al
806907e2 0000            add     byte ptr [eax],al
806907e4 0000            add     byte ptr [eax],al
806907e6 0000            add     byte ptr [eax],al
806907e8 0000            add     byte ptr [eax],al
806907ea 0000            add     byte ptr [eax],al
806907ec 0000            add     byte ptr [eax],al
806907ee 0000            add     byte ptr [eax],al

竟然什么都沒有!  原來操作系統啟動后默認為這一函數就失去了價值就把相關的內存釋放了,我們自然什么都看不到,那么我們如何獲得這個函數的真正信息呢?  在操作系統啟動前WinDbg攔截就可以了。

 

 

kd> u kisystemstartup l 100
nt!KiSystemStartup:
806907e0 55              push    ebp
806907e1 8bec            mov     ebp,esp
806907e3 83ec20          sub     esp,20h
806907e6 8b5d08          mov     ebx,dword ptr [ebp+8]
806907e9 891ddcd45480    mov     dword ptr [nt!KeLoaderBlock (8054d4dc)],ebx
806907ef 0fb60de0d45480  movzx   ecx,byte ptr [nt!KeNumberProcessors (8054d4e0)]
806907f6 894de8          mov     dword ptr [ebp-18h],ecx
806907f9 0bc9            or      ecx,ecx
806907fb 7519            jne     nt!KiSystemStartup+0x36 (80690816)
806907fd c7432440375580  mov     dword ptr [ebx+24h],offset nt!KiIdleThread0 (80553740)
80690804 c7431800af5480  mov     dword ptr [ebx+18h],offset nt!P0BootStack (8054af00)
8069080b 6a30            push    30h
8069080d 0fa1            pop     fs
8069080f 64880d30010000  mov     byte ptr fs:[130h],cl
80690816 8b4324          mov     eax,dword ptr [ebx+24h]
80690819 8945e0          mov     dword ptr [ebp-20h],eax
8069081c 8b4318          mov     eax,dword ptr [ebx+18h]
8069081f 8945e4          mov     dword ptr [ebp-1Ch],eax
80690822 e8d10b0000      call    nt!KiInitializeMachineType (806913f8)
80690827 807de800        cmp     byte ptr [ebp-18h],0
8069082b 0f859f010000    jne     nt!KiSystemStartup+0x1f0 (806909d0)
80690831 e8b216ebff      call    nt!GetMachineBootPointers (80541ee8)
80690836 897dfc          mov     dword ptr [ebp-4],edi
80690839 8975f8          mov     dword ptr [ebp-8],esi
8069083c 8955f4          mov     dword ptr [ebp-0Ch],edx
8069083f 8945f0          mov     dword ptr [ebp-10h],eax
80690842 8d4f28          lea     ecx,[edi+28h]
80690845 c6410589        mov     byte ptr [ecx+5],89h
80690849 51              push    ecx
8069084a ff75f4          push    dword ptr [ebp-0Ch]
8069084d e81c110000      call    nt!KiInitializeTSS2 (8069196e)
80690852 ff75f4          push    dword ptr [ebp-0Ch]
80690855 e872fbe6ff      call    nt!KiInitializeTSS (805003cc)
8069085a 66b92800        mov     cx,28h
8069085e 0f00d9          ltr     cx
80690861 8b45f0          mov     eax,dword ptr [ebp-10h]
80690864 8d4840          lea     ecx,[eax+40h]
80690867 c6410585        mov     byte ptr [ecx+5],85h
8069086b 66c741025000    mov     word ptr [ecx+2],50h
80690871 8d4f50          lea     ecx,[edi+50h]
80690874 c6410589        mov     byte ptr [ecx+5],89h
80690878 ba00af5480      mov     edx,offset nt!P0BootStack (8054af00)
8069087d 8bc2            mov     eax,edx
8069087f 66894102        mov     word ptr [ecx+2],ax
80690883 c1e810          shr     eax,10h
80690886 886107          mov     byte ptr [ecx+7],ah
80690889 884104          mov     byte ptr [ecx+4],al
8069088c b868000000      mov     eax,68h
80690891 668901          mov     word ptr [ecx],ax
80690894 52              push    edx
80690895 e832fbe6ff      call    nt!KiInitializeTSS (805003cc)
8069089a 0f20d8          mov     eax,cr3
8069089d 89421c          mov     dword ptr [edx+1Ch],eax
806908a0 b8007f5480      mov     eax,offset nt!KiDoubleFaultStack (80547f00)
806908a5 894238          mov     dword ptr [edx+38h],eax
806908a8 894204          mov     dword ptr [edx+4],eax
806908ab c74220ce045480  mov     dword ptr [edx+20h],offset nt!KiTrap08 (805404ce)
806908b2 c7422400000000  mov     dword ptr [edx+24h],0
806908b9 66c7424c0800    mov     word ptr [edx+4Ch],8
806908bf 66c742583000    mov     word ptr [edx+58h],30h
806908c5 8c5250          mov     word ptr [edx+50h],ss
806908c8 66c742482300    mov     word ptr [edx+48h],23h
806908ce 66c742542300    mov     word ptr [edx+54h],23h
806908d4 8b45f0          mov     eax,dword ptr [ebp-10h]
806908d7 8d4810          lea     ecx,[eax+10h]
806908da c6410585        mov     byte ptr [ecx+5],85h
806908de 66c741025800    mov     word ptr [ecx+2],58h
806908e4 8d4f58          lea     ecx,[edi+58h]
806908e7 c6410589        mov     byte ptr [ecx+5],89h
806908eb ba68af5480      mov     edx,offset nt!KiNMITSS (8054af68)
806908f0 8bc2            mov     eax,edx
806908f2 66894102        mov     word ptr [ecx+2],ax
806908f6 c1e810          shr     eax,10h
806908f9 886107          mov     byte ptr [ecx+7],ah
806908fc 884104          mov     byte ptr [ecx+4],al
806908ff b868000000      mov     eax,68h
80690904 668901          mov     word ptr [ecx],ax
80690907 52              push    edx
80690908 52              push    edx
80690909 e8befae6ff      call    nt!KiInitializeTSS (805003cc)
8069090e 0f20d8          mov     eax,cr3
80690911 89421c          mov     dword ptr [edx+1Ch],eax
80690914 b800af5480      mov     eax,offset nt!P0BootStack (8054af00)
80690919 8b4038          mov     eax,dword ptr [eax+38h]
8069091c 894204          mov     dword ptr [edx+4],eax
8069091f 894238          mov     dword ptr [edx+38h],eax
80690922 c74220fcf35380  mov     dword ptr [edx+20h],offset nt!KiTrap02 (8053f3fc)
80690929 c7422400000000  mov     dword ptr [edx+24h],0
80690930 66c7424c0800    mov     word ptr [edx+4Ch],8
80690936 66c742583000    mov     word ptr [edx+58h],30h
8069093c 8c5250          mov     word ptr [edx+50h],ss
8069093f 66c742482300    mov     word ptr [edx+48h],23h
80690945 66c742542300    mov     word ptr [edx+54h],23h
8069094b 68007f5480      push    offset nt!KiDoubleFaultStack (80547f00)
80690950 ff75e0          push    dword ptr [ebp-20h]
80690953 ff75f4          push    dword ptr [ebp-0Ch]
80690956 ff75fc          push    dword ptr [ebp-4]
80690959 ff75f0          push    dword ptr [ebp-10h]
8069095c ff75f8          push    dword ptr [ebp-8]
8069095f ff75e8          push    dword ptr [ebp-18h]
80690962 e8630f0000      call    nt!KiInitializePcr (806918ca)
80690967 8b55e0          mov     edx,dword ptr [ebp-20h]
8069096a b9a0395580      mov     ecx,offset nt!KiIdleProcess (805539a0)
8069096f 894a44          mov     dword ptr [edx+44h],ecx
80690972 64c7051800000000000000 mov dword ptr fs:[18h],0
8069097d 64c7052804000000000000 mov dword ptr fs:[428h],0
80690988 64c7052c04000000000000 mov dword ptr fs:[42Ch],0
80690993 e83a100000      call    nt!KiSwapIDT (806919d2)
80690998 b823000000      mov     eax,23h
8069099d 668ed8          mov     ds,ax
806909a0 668ec0          mov     es,ax
806909a3 8b45f0          mov     eax,dword ptr [ebp-10h]
806909a6 ff7040          push    dword ptr [eax+40h]
806909a9 ff7044          push    dword ptr [eax+44h]
806909ac ff7010          push    dword ptr [eax+10h]
806909af ff7014          push    dword ptr [eax+14h]
806909b2 8b7df0          mov     edi,dword ptr [ebp-10h]
806909b5 befc0a6980      mov     esi,offset nt!IDT (80690afc)
806909ba b900080000      mov     ecx,800h
806909bf c1e902          shr     ecx,2
806909c2 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
806909c4 8f4014          pop     dword ptr [eax+14h]
806909c7 8f4010          pop     dword ptr [eax+10h]
806909ca 8f4044          pop     dword ptr [eax+44h]
806909cd 8f4040          pop     dword ptr [eax+40h]
806909d0 f70558bd548001000000 test dword ptr [nt!KiFreezeExecutionLock (8054bd58)],1
806909da 75f4            jne     nt!KiSystemStartup+0x1f0 (806909d0)
806909dc f00fba2d58bd548000 lock bts dword ptr [nt!KiFreezeExecutionLock (8054bd58)],0
806909e5 72e9            jb      nt!KiSystemStartup+0x1f0 (806909d0)
806909e7 8b4de8          mov     ecx,dword ptr [ebp-18h]
806909ea 64880d51000000  mov     byte ptr fs:[51h],cl
806909f1 b801000000      mov     eax,1
806909f6 d3e0            shl     eax,cl
806909f8 64a348000000    mov     dword ptr fs:[00000048h],eax
806909fe 64a334010000    mov     dword ptr fs:[00000134h],eax
80690a04 ff7508          push    dword ptr [ebp+8]
80690a07 ff75e8          push    dword ptr [ebp-18h]
80690a0a ff1574864d80    call    dword ptr [nt!_imp__HalInitializeProcessor (804d8674)]
80690a10 64a148000000    mov     eax,dword ptr fs:[00000048h]
80690a16 0905d0d45480    or      dword ptr [nt!KeActiveProcessors (8054d4d0)],eax
80690a1c ff75e8          push    dword ptr [ebp-18h]
80690a1f e876abe6ff      call    nt!KiInitializeAbios (804fb59a)
80690a24 fe05e0d45480    inc     byte ptr [nt!KeNumberProcessors (8054d4e0)]
80690a2a 33c0            xor     eax,eax
80690a2c a358bd5480      mov     dword ptr [nt!KiFreezeExecutionLock (8054bd58)],eax
80690a31 807de800        cmp     byte ptr [ebp-18h],0
80690a35 751d            jne     nt!KiSystemStartup+0x274 (80690a54)
80690a37 ff35dcd45480    push    dword ptr [nt!KeLoaderBlock (8054d4dc)]
80690a3d 6a00            push    0
80690a3f e87a00fdff      call    nt!KdInitSystem (80660abe)
80690a44 e8956ee6ff      call    nt!KdPollBreakIn (804f78de)
80690a49 0ac0            or      al,al
80690a4b 7407            je      nt!KiSystemStartup+0x274 (80690a54)
80690a4d 6a01            push    1
80690a4f e88481e9ff      call    nt!DbgBreakPointWithStatus (80528bd8)
80690a54 90              nop
80690a55 b91f000000      mov     ecx,1Fh
80690a5a ff15f4864d80    call    dword ptr [nt!_imp_KfRaiseIrql (804d86f4)]
80690a60 8845ec          mov     byte ptr [ebp-14h],al
80690a63 810dcc3c558080000000 or  dword ptr [nt!KiBootFeatureBits (80553ccc)],80h
80690a6d 8b5de0          mov     ebx,dword ptr [ebp-20h]
80690a70 8b55e4          mov     edx,dword ptr [ebp-1Ch]
80690a73 8b45e8          mov     eax,dword ptr [ebp-18h]
80690a76 83e2fc          and     edx,0FFFFFFFCh
80690a79 33ed            xor     ebp,ebp
80690a7b 8be2            mov     esp,edx
80690a7d 81eca0020000    sub     esp,2A0h
80690a83 6a0e            push    0Eh
80690a85 ff35dcd45480    push    dword ptr [nt!KeLoaderBlock (8054d4dc)]
80690a8b 50              push    eax
80690a8c 64ff3520000000  push    dword ptr fs:[20h]
80690a93 52              push    edx
80690a94 53              push    ebx
80690a95 68a0395580      push    offset nt!KiIdleProcess (805539a0)
80690a9a e8d7200000      call    nt!KiInitializeKernel (80692b76)
80690a9f 648b1d24010000  mov     ebx,dword ptr fs:[124h]
80690aa6 c6433310        mov     byte ptr [ebx+33h],10h
80690aaa fb              sti
80690aab b902000000      mov     ecx,2
80690ab0 ff151c874d80    call    dword ptr [nt!_imp_KfLowerIrql (804d871c)]
80690ab6 c6435802        mov     byte ptr [ebx+58h],2
80690aba 8b1d1cf0dfff    mov     ebx,dword ptr ds:[0FFDFF01Ch]
80690ac0 6a00            push    0
80690ac2 e91920ebff      jmp     nt!KiIdleLoop (80542ae0)
80690ac7 90              nop
View Code

 

在kisystemstartup函數中我們可以清楚的看到IDT

 

806909b2 8b7df0          mov     edi,dword ptr [ebp-10h]
806909b5 befc0a6980      mov     esi,offset nt!IDT (80690afc)
806909ba b900080000      mov     ecx,800h
806909bf c1e902          shr     ecx,2

 

我們看一下IDT,此時應該注意在操作系統啟動前,不然我們和kisystemstartup一樣什么都得不到。

 

kd> dq 80690afc 
80690afc  80538e00`0008f19c 80538e00`0008f314
80690b0c  80538e00`0008f3fc 8053ee00`0008f6e4
80690b1c  8053ee00`0008f864 80538e00`0008f9c0
80690b2c  80538e00`0008fb34 80548e00`0008019c
80690b3c  80548e00`000804ce 80548e00`000805c0
80690b4c  80548e00`000806e0 80548e00`00080820
80690b5c  80548e00`00080a7c 80548e00`00080d60
80690b6c  80548e00`00081450 80548e00`00081780

 

到此已經通過這些獲得Ntoskrnl.exe文件中IDT地址,那么寫出恢復IDT HOOK的代碼了,但是我們要尋找的是Kifastcallentry地址。所以我們繼續看看。

 

kd> u kitrap01 l 50
nt!KiTrap01:
8053f314 6a00            push    0
8053f316 66c74424020000  mov     word ptr [esp+2],0
8053f31d 55              push    ebp
8053f31e 53              push    ebx
8053f31f 56              push    esi
8053f320 57              push    edi
8053f321 0fa0            push    fs
8053f323 bb30000000      mov     ebx,30h
8053f328 668ee3          mov     fs,bx
8053f32b 648b1d00000000  mov     ebx,dword ptr fs:[0]
8053f332 53              push    ebx
8053f333 83ec04          sub     esp,4
8053f336 50              push    eax
8053f337 51              push    ecx
8053f338 52              push    edx
8053f339 1e              push    ds
8053f33a 06              push    es
8053f33b 0fa8            push    gs
8053f33d 66b82300        mov     ax,23h
8053f341 83ec30          sub     esp,30h
8053f344 668ed8          mov     ds,ax
8053f347 668ec0          mov     es,ax
8053f34a 8bec            mov     ebp,esp
8053f34c f744247000000200 test    dword ptr [esp+70h],20000h
8053f354 7596            jne     nt!V86_kit1_a (8053f2ec)
8053f356 fc              cld
8053f357 8b5d60          mov     ebx,dword ptr [ebp+60h]
8053f35a 8b7d68          mov     edi,dword ptr [ebp+68h]
8053f35d 89550c          mov     dword ptr [ebp+0Ch],edx
8053f360 c74508000ddbba  mov     dword ptr [ebp+8],0BADB0D00h
8053f367 895d00          mov     dword ptr [ebp],ebx
8053f36a 897d04          mov     dword ptr [ebp+4],edi
8053f36d f60550f0dfffff  test    byte ptr ds:[0FFDFF050h],0FFh
8053f374 0f85eefeffff    jne     nt!Dr_kit1_a (8053f268)
8053f37a 833d54f0dfff00  cmp     dword ptr ds:[0FFDFF054h],0
8053f381 7560            jne     nt!KiTrap01+0xcf (8053f3e3)
8053f383 8b4d68          mov     ecx,dword ptr [ebp+68h]
8053f386 81f940e55380 cmp ecx,offset nt!KiFastCallEntry (8053e540)
8053f38c 0f84c6feffff    je      nt!KiTrap00+0xbc (8053f258)
8053f392 f7457000000200  test    dword ptr [ebp+70h],20000h
8053f399 7524            jne     nt!KiTrap01+0xab (8053f3bf)
8053f39b 66f7456c0100    test    word ptr [ebp+6Ch],1
8053f3a1 7408            je      nt!KiTrap01+0x97 (8053f3ab)
8053f3a3 66837d6c1b      cmp     word ptr [ebp+6Ch],1Bh
8053f3a8 7515            jne     nt!KiTrap01+0xab (8053f3bf)
8053f3aa fb              sti
8053f3ab 816570fffeffff  and     dword ptr [ebp+70h],0FFFFFEFFh
8053f3b2 8b5d68          mov     ebx,dword ptr [ebp+68h]
8053f3b5 b804000080      mov     eax,80000004h
8053f3ba e954fcffff      jmp     nt!KiExceptionExit+0x16b (8053f013)
8053f3bf 8b1d24f1dfff    mov     ebx,dword ptr ds:[0FFDFF124h]
8053f3c5 8b5b44          mov     ebx,dword ptr [ebx+44h]
8053f3c8 83bb5801000000  cmp     dword ptr [ebx+158h],0
8053f3cf 74d9            je      nt!KiTrap01+0x96 (8053f3aa)
8053f3d1 6a01            push    1
8053f3d3 e8b42a0000      call    nt!Ki386VdmReflectException_A (80541e8c)
8053f3d8 66a9ffff        test    ax,0FFFFh
8053f3dc 74cd            je      nt!KiTrap01+0x97 (8053f3ab)
8053f3de e9c5faffff      jmp     nt!Kei386EoiHelper (8053eea8)
8053f3e3 a154f0dfff      mov     eax,dword ptr ds:[FFDFF054h]
8053f3e8 c70554f0dfff00000000 mov dword ptr ds:[0FFDFF054h],0
8053f3f2 894568          mov     dword ptr [ebp+68h],eax
8053f3f5 8be5            mov     esp,ebp
8053f3f7 e9acfaffff      jmp     nt!Kei386EoiHelper (8053eea8)

 

我們在IDT的KiTrap01 處理調試異常(Debug Exception)的例程可以看到Kifastcallentry的地址,那么我們就可以用它來進行恢復Sysentry hook以及Kifastcallentry hook了。

 

下面我們來看看完成代碼。

 

#include "CheckKiFastCall.h"
#include "Asm.H"


NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{

    CheckKiFastCallHook(TRUE);


    DriverObject->DriverUnload = UnloadDriver;

    return STATUS_SUCCESS;
}

VOID
UnloadDriver(PDRIVER_OBJECT  DriverObject)
{

}



int  CheckKiFastCallHook(BOOLEAN UnHook)
{
    MODULE_INFO  KernelModule;
    PULONG       KernelBaseAddress = NULL;
    PIMAGE_NT_HEADERS     Ntheader = NULL;
    PUCHAR       EntryPointer = NULL;    //OEP
    int          Strlen = 0;
    PRAW_IDT     rawIDT = NULL;
    ULONG        IDTBaseAddr = 0;
    ULONG        ImageBase = 0;
    int          Diff = 0;
    PULONG       Temp = NULL;
    ULONG        Address = 0;
    ULONG        KiFmAddr = 0;
    KIRQL         Irq;

    if (GetKernelBase(&KernelModule)==0)
    {
        DbgPrint("Get ntkrnlpa.exe Error\r\n");
        return -1;
    }
    

    KernelBaseAddress = (PVOID)MapViewOfImage(KernelModule.FullPath);
    if(!KernelBaseAddress)
    {
        return -1;
    }

    Ntheader = (PIMAGE_NT_HEADERS)((ULONG)KernelBaseAddress+((PIMAGE_DOS_HEADER)(KernelBaseAddress))->e_lfanew);

    EntryPointer = (PUCHAR)((ULONG)KernelBaseAddress+Ntheader->OptionalHeader.AddressOfEntryPoint);   //獲得代碼的入口OEP


    DbgPrint("OEP:%x\r\n",EntryPointer);


    while (1)
    {

        PUCHAR Code = 0;

        Strlen = SizeOfCode((VOID*)EntryPointer,&Code);

        if (Strlen<=0)   //沒有獲得指令
        {
            break;
        }

        if (*Code==0xc2)
        {
            break;
        }

        if (*Code==0xc3)
        {
            break;             
        }
        //以上兩條Opcode都是return 可以使用查看Demo


        if (Strlen==5)
        {
            rawIDT = (PRAW_IDT)EntryPointer;

    
            DbgPrint("%x       %x            %x\r\n",rawIDT->d_800h,rawIDT->Opcode1,rawIDT->Opcode2);

            if((rawIDT->d_800h==0x800)&&(rawIDT->Opcode1==0xbe)&&(rawIDT->Opcode2==0xb9))
            {

                IDTBaseAddr = rawIDT->OrigBase;  //DbgPrint("%x\r\n",IDTBaseAddr);

                break;
            }


        }


        EntryPointer+=Strlen;

    }

    if (IDTBaseAddr==0)
    {
        ZwUnmapViewOfSection((HANDLE)-1,(PVOID)KernelBaseAddress);

        return -1;
    }


    ImageBase = GetImageBase(KernelBaseAddress);                 

    Diff = (ULONG)KernelBaseAddress - (ULONG)ImageBase;         

    IDTBaseAddr += Diff;                                         


    Temp = (PULONG)IDTBaseAddr;

    Temp+=2;   

    Address = *(Temp)+Diff;


    DbgPrint("%x\r\n",Address);  



    Address = GetKiFastCallEntryOrigEntry((PUCHAR)Address);  


    if (Address==0)
    {
        ZwUnmapViewOfSection((HANDLE)-1,(PVOID)KernelBaseAddress);
        return -1;
    }


    _asm
    {
        mov ecx,0x176
        rdmsr
        mov KiFmAddr,eax
    }


    if((Address+(ULONG)KernelModule.Base-ImageBase)!=KiFmAddr)
    {
        DbgPrint("KiFastCallEntry Hooked!\n");
        KdPrint(("KiFastCallEntry Current Addr :%08X Orig Address:%08X\n",KiFmAddr,Address+(ULONG)KernelModule.Base-ImageBase));
        
        if(UnHook)
        {
            Irq=WPOFF();
            HookKiFastCallEntry(Address+(ULONG)KernelModule.Base-ImageBase);
            WPON(Irq);
        }

    }


    ZwUnmapViewOfSection((HANDLE)-1,(PVOID)KernelBaseAddress);
    return 1;
}


ULONG GetKernelBase(PMODULE_INFO OutInfo)
{

    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    ULONG Base = 0;
    ULONG BufferSize = 0x3000;
    PVOID Buffer = NULL;
    char  NameBuffer[256] = {0};
    __try
    {    
        
        Buffer= ExAllocatePool(PagedPool,BufferSize);
        if(Buffer==0)
        {
            return 0;
        }

        NtQuerySystemInformation(SystemModuleInformation,Buffer,BufferSize,&Base);

        
        Base = 0;
        

        if(*(ULONG*)Buffer>0)
        {
            PSYSTEM_MODULE_INFORMATION_ENTRY  pInfo=
                (PSYSTEM_MODULE_INFORMATION_ENTRY)((char*)Buffer+sizeof(ULONG));
            Base = (ULONG)pInfo[0].Base;
        
            if(OutInfo)
            {
                OutInfo->Base=pInfo[0].Base;
                OutInfo->ImageSize=pInfo[0].Size;//ImageSize;


                DbgPrint("%x\r\n",OutInfo->Base);
                DbgPrint("%d\r\n",OutInfo->ImageSize);


                DbgPrint("%s\r\n",pInfo[0].ImageName);

                ConvertFileName(pInfo[0].ImageName,NameBuffer);   //查看注冊表  Regedit
                ByteToWChar(NameBuffer,OutInfo->FullPath,256*2);
            }
        }
        if(Buffer!=NULL)
        {
            ExFreePool(Buffer);
        }
        
        return Base;
    }
    __except(1)
    {
        DbgPrint("Can't Get KernelBase!\r\n");
        return 0;
    }
}



VOID ConvertFileName(CHAR *ImageName, CHAR* FileName)
{
    int Pos = strlen(ImageName)-1;
    for(;Pos>0;Pos--)
    {
        if(ImageName[Pos]=='\\')
        {
            Pos++;
            break;
        }
    }

    if (ImageName[0]=='\\'&&(_strnicmp(ImageName, "\\windows\\system32\\", 18)==0))
    {
        strcpy(FileName, "\\SystemRoot\\System32\\");
        strcat(FileName,ImageName + Pos);
    }
}





PULONG
MapViewOfImage(PWCHAR ImagePath)
{

    HANDLE             hFile    = NULL;
    HANDLE             hSection = NULL;
    OBJECT_ATTRIBUTES  oa = {0};
    UNICODE_STRING     FileName;
    IO_STATUS_BLOCK    iosb;
    NTSTATUS           Status;
    PULONG             BaseAddress = NULL;
    ULONG              Size     = 0;

    
    RtlInitUnicodeString(&FileName,ImagePath);
    
    InitializeObjectAttributes(&oa,&FileName,OBJ_CASE_INSENSITIVE |OBJ_KERNEL_HANDLE,NULL,NULL);



    Status = ZwCreateFile(&hFile,GENERIC_READ,&oa,&iosb,0,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_OPEN,FILE_SYNCHRONOUS_IO_NONALERT,
        0,0);

    if(!NT_SUCCESS(Status))
    {
        return NULL;
    }

    if(hFile==NULL)
    {
        DbgPrint("ZwCreateFile() Failed!\r\n");
        return NULL;
    }
    
     oa.ObjectName = 0;
    

     Status = ZwCreateSection(&hSection,SECTION_MAP_READ,&oa,0,PAGE_READONLY,SEC_IMAGE,hFile);
    
     if(!NT_SUCCESS(Status))
     {

         DbgPrint("ZwCreateSection() Failed!\r\n");
    
         ZwClose(hFile);
        
         return NULL;
     }


    Status = ZwMapViewOfSection(hSection,
        ZwCurrentProcess(),&BaseAddress,0,1000,NULL,&Size,1,MEM_TOP_DOWN,PAGE_READONLY);
    
    if(!NT_SUCCESS(Status))
    {
        DbgPrint("ZwMapViewOfSection() Failed!\r\n");
        ZwClose(hSection);
        ZwClose(hFile);
    }

    ZwClose(hSection);
    
    ZwClose(hFile);
    
    DbgPrint("BaseAddress:%x\r\n",BaseAddress);
    
    return BaseAddress;
}

ULONG
GetImageBase(PULONG  BaseAddr)
{
    PIMAGE_DOS_HEADER  DosHeader = NULL;
    PIMAGE_NT_HEADERS  NtHeader  = NULL;

    DosHeader = (PIMAGE_DOS_HEADER)BaseAddr;

    if (!MmIsAddressValid(DosHeader))
    {
        return 0;
    }

    if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
    {
        return 0;
    }

    NtHeader = (PIMAGE_NT_HEADERS)((ULONG)DosHeader + DosHeader->e_lfanew);


    if (!MmIsAddressValid(NtHeader))
    {
        return 0;
    }

    if (NtHeader->Signature!=IMAGE_NT_SIGNATURE)
    {
        return 0;
    }

    return NtHeader->OptionalHeader.ImageBase;


}


ULONG GetKiFastCallEntryOrigEntry(UCHAR* Address)
{
    int i = 0;
    UCHAR* Temp = Address;
    for(i=0;i<1000;i++)
    {
        if(*Temp==0x81)   //查看Windbg
        {
            return *(ULONG*)(Temp+2);
        }
        Temp++;
    }
    return 0;
}


BOOLEAN
ByteToWChar(char* szSour,wchar_t* szDest,ULONG Size)
{
    
    if (mbstowcs(szDest,szSour,Size)>0)
    {
        return TRUE;
    }
    
    return FALSE;

    
}



ULONG HookKiFastCallEntry(ULONG Addr)
{
    ULONG OldAddr;
    _asm
    {
        mov ecx,0x176
        rdmsr
        mov OldAddr,eax
        mov eax,Addr
        wrmsr
    }
    return OldAddr;
}


KIRQL WPOFF()
{
    KIRQL            OldIrql; 
    
    KeRaiseIrql(2, &OldIrql);
    _asm
    {
        push    eax
        mov     eax, cr0
        and     eax, 0xFFFEFFFF
        mov     cr0, eax
        pop        eax
        cli
    }
    
    
    return OldIrql;        
}

VOID WPON(KIRQL Irq)
{
    _asm
    {
    
        push    eax
        mov     eax, cr0
        or      eax, 0x10000
        mov     cr0, eax
        pop        eax
        sti
    }
    KeLowerIrql(Irq);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM