关于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

相关文章:

  • 2021-07-04
  • 2021-09-08
  • 2022-12-23
  • 2021-08-06
  • 2021-10-08
  • 2022-12-23
  • 2022-12-23
  • 2021-06-20
猜你喜欢
  • 2021-09-21
  • 2021-12-17
  • 2021-07-31
  • 2021-06-05
  • 2021-11-23
  • 2021-11-28
  • 2022-12-23
相关资源
相似解决方案