MyHookMgr是一个大小为0x5DDC的巨大结构,是360挂钩中的一个重要数据,它记录了挂钩函数的原地址、代理函数地址及相应函数是否挂钩的标志位。
它的数据结构是这样的:
struct MyHookMgr{ DWORD ssdtSize; //ssdt大小 DWORD ssdtOriginFunc[1001]; //ssdt对应的原函数地址 DWORD ssdtFakeFunc[1001]; //ssdt对应的代理函数地址 DWORD shadowSsdtOriginFunc[1001]; //ssdtShadow原函数地址 DWORD shadowSsdtFakeFunc[1001]; //ssdtShadow代理函数地址 DWORD ssdtSwitch[1001]; //ssdt代理函数开关 DWORD shadowSsdtSwitch [1001]; //ssdtShadow代理函数开关 }; |
ssdtSize是ssdt的大小,这个域被用的并不多,这里不做过多解释。
SsdtOriginFunc和shadowSsdtOriginFunc数组分别包含了两个表中所有的原函数地址。但这个域在初始化时并没有被填写,在过滤函数真正开始工作时才逐渐被代理函数填写完毕。
ssdtFakeFunc和shadowSsdtFakeFunc是对应的代理函数表,初始化时被填写。
ssdtSwitch和shadowSsdtSwitch是代理函数开关,为1时代表函数被挂载,为0时直接执行原始函数,不进行过滤,初始化时所有开关均置0。
结构中的6个数组都是以ssdt编号作为索引的,由于win7的ssdtShadow表函数最多——827个,所以这里使用了足够大的数组保证稳定,当然这里浪费了一些内存。
关于SSDT编号的获取有两种方法,对于导出函数,因为其形式都如:
ntdll!ZwSetEvent:
7c92e570 b8db000000 mov eax,0DBh ;0DBh就是ssdt编号
7c92e575 ba0003fe7f mov edx,offsetSharedUserData!SystemCallStub (7ffe0300)
7c92e57a ff12 call dword ptr [edx]
7c92e57c c20800 ret 8
7c92e57f 90 nop
从第一条指令中就可以读取ssdt索引了。
对于未导出函数360使用了根据操作系统进行硬编码的方式。(详情见IDB文件)
联系客服