傲笑 发表于 2011-8-6 08:41:41

Anti SSDT Hook

前几天去当面膜拜了女王大牛,果然****,还让我等了一个来小时。。。

在xp中ntdll.dll的调用都是通过sysenter切换到内核的,sysenter调用了KiFastCallEntry,而KiFastCallEntry函数则是在ssdt表找到相应的
函数地址,然后call,所以只要伪造一张原始的ssdt表,并且欺骗过KiFastCallEntry函数,这样ssdt hook就无效了。。。
先看KiFastCallEntry函数:

nt!KiFastCallEntry:
80541790 b923000000      mov   ecx,23h
80541795 6a30            push    30h
80541797 0fa1            pop   fs
80541799 8ed9            mov   ds,cx
8054179b 8ec1            mov   es,cx
8054179d 648b0d40000000mov   ecx,dword ptr fs:
805417a4 8b6104          mov   esp,dword ptr
805417a7 6a23            push    23h
805417a9 52            push    edx
805417aa 9c            pushfd
805417ab 6a02            push    2
805417ad 83c208          add   edx,8
805417b0 9d            popfd
805417b1 804c240102      or      byte ptr ,2
805417b6 6a1b            push    1Bh
805417b8 ff350403dfff    push    dword ptr ds:
805417be 6a00            push    0
805417c0 55            push    ebp
805417c1 53            push    ebx
805417c2 56            push    esi
805417c3 57            push    edi
//ebx=_KPCR.SelfPcr
805417c4 648b1d1c000000mov   ebx,dword ptr fs:
805417cb 6a3b            push    3Bh
//esi=_KPCR.PrcbData.CurrentThread
805417cd 8bb324010000    mov   esi,dword ptr
805417d3 ff33            push    dword ptr
805417d5 c703ffffffff    mov   dword ptr ,0FFFFFFFFh   
805417db 8b6e18          mov   ebp,dword ptr
805417de 6a01            push    1
805417e0 83ec48          sub   esp,48h
805417e3 81ed9c020000    sub   ebp,29Ch
805417e9 c6864001000001mov   byte ptr ,1
805417f0 3bec            cmp   ebp,esp
805417f2 758d            jne   nt!KiFastCallEntry2+0x49 (80541781)
805417f4 83652c00      and   dword ptr ,0
805417f8 f6462cff      test    byte ptr ,0FFh
805417fc 89ae34010000    mov   dword ptr ,ebp
80541802 0f8538feffff    jne   nt!Dr_FastCallDrSave (80541640)
80541808 8b5d60          mov   ebx,dword ptr
8054180b 8b7d68          mov   edi,dword ptr
8054180e 89550c          mov   dword ptr ,edx
80541811 c74508000ddbbamov   dword ptr ,0BADB0D00h
80541818 895d00          mov   dword ptr ,ebx
8054181b 897d04          mov   dword ptr ,edi
8054181e fb            sti
//eax为函数序号,但是在KeServiceDescriptorTableShadow时是函数序号+1000h,
//所以在KeServiceDescriptorTableShadow经过下面运算ecx最终为10h,否则为0
8054181f 8bf8            mov   edi,eax
80541821 c1ef08          shr   edi,8
80541824 83e730          and   edi,30h
80541827 8bcf            mov   ecx,edi
//KTHREAD.ServiceTable gdi32.dll和user32.dll调用时,
//ServiceTable为KeServiceDescriptorTableShadow,
//ntdll.dll调用时ServiceTable为KeServiceDescriptorTable
//在KeServiceDescriptorTableShadow时+10正好得到win32.sys调用
80541829 03bee0000000    add   edi,dword ptr    
8054182f 8bd8            mov   ebx,eax
//保留三个字节,得到正真的序号
80541831 25ff0f0000      and   eax,0FFFh
//和ssdt或shadow ssdt总共项数比较,eax大则跳
80541836 3b4708          cmp   eax,dword ptr
80541839 0f8333fdffff    jae   nt!KiBBTUnexpectedRange (80541572)
//判断是shadow ssdt还是ssdt,不跳则是shadow ssdt,跳则是ssdt
8054183f 83f910          cmp   ecx,10h
80541842 751b            jne   nt!KiFastCallEntry+0xcf (8054185f)
80541844 648b0d18000000mov   ecx,dword ptr fs:
8054184b 33db            xor   ebx,ebx
8054184d 0b99700f0000    or      ebx,dword ptr
80541853 740a            je      nt!KiFastCallEntry+0xcf (8054185f)
80541855 52            push    edx
80541856 50            push    eax
80541857 ff1528c75580    call    dword ptr
8054185d 58            pop   eax
8054185e 5a            pop   edx
8054185f 64ff0538060000inc   dword ptr fs:
80541866 8bf2            mov   esi,edx
80541868 8b5f0c          mov   ebx,dword ptr
8054186b 33c9            xor   ecx,ecx
8054186d 8a0c18          mov   cl,byte ptr
//edi=KeServiceDescriptorTable->ServiceTableBase
//在这里patch 把edi指向构造的ssdt
80541870 8b3f            mov   edi,dword ptr
//得到真实地址,edi为KiServiceTable,eax为函数序号
80541872 8b1c87          mov   ebx,dword ptr
80541875 2be1            sub   esp,ecx
80541878 c1e902          shr   ecx,2
8054187a 8bfc            mov   edi,esp
8054187c 3b3574f73ff4    cmp   esi,dword ptr ds:
80541882 0f83a8010000    jae   nt!KiSystemCallExit2+0x9f (80541a30)
//把参数复制到内核
80541888 f3a5            rep movs dword ptr es:,dword ptr
//调用函数
8054188a ffd3            call    ebx
8054188c 8be5            mov   esp,ebp
8054188e 648b0d24010000mov   ecx,dword ptr fs:
80541895 8b553c          mov   edx,dword ptr
80541898 899134010000    mov   dword ptr ,edx


KiFastCallEntry函数先通过fs寄存器的_KPCR得到了当前线程的ETHREAD,然后通过ETHREAD得到ServiceTable
这个就是main SDT或者是shadow sdt,在shadow sdt中要保留24位得到函数序号,之后根据main sdt或者shadow sdt
和函数序号得到函数地址,最后call这个函数。

所以可以在

80541868 8b5f0c          mov   ebx,dword ptr
8054186b 33c9            xor   ecx,ecx
8054186d 8a0c18          mov   cl,byte ptr
//edi=KeServiceDescriptorTable->ServiceTableBase
//在这里patch 把edi指向构造的ssdt
80541870 8b3f            mov   edi,dword ptr


这里inline hook

完整代码如下:
**** Hidden Message *****

假如要anit shadow ssdt hook 只要同时hook KiFastCallEntry和KiSystemService俩函数就可以了。。。

又度过了一个没有情人的情人节了。。。。

zh63573351 发表于 2012-1-14 22:44:49

回复 1# 傲笑


    dddddddd

lisone 发表于 2012-1-18 02:59:36

看看被隐藏的内容。。

lezhen98 发表于 2020-4-4 17:57:09

支持楼主,支持看流星社区,以后我会经常来!
页: [1]
查看完整版本: Anti SSDT Hook