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俩函数就可以了。。。
又度过了一个没有情人的情人节了。。。。 回复 1# 傲笑
dddddddd 看看被隐藏的内容。。 支持楼主,支持看流星社区,以后我会经常来!
页:
[1]