Hookport.sys是360安全卫士对系统进行挂钩操作的核心模块。它主要通过安装钩子函数来实现对SSDT和shadowSSDT的操作。然而,由于采用了一种特殊的实现方法,使得许多常规ARK软件很难检测出360安全卫士的钩子。这种方法对系统表操作较少,因此相对稳定。
Hookport.sys仅提供了最基本的过滤操作和桩函数,本身并未实现策略部分。策略部分由360SelfProtection.sys实现,并通过设备扩展进行沟通。本报告简要解释了360安全卫士所使用的挂钩方法,并给出了一些关键数据结构和使用方法。
由于SSDT是内核的导出表,因此确定其地址较为方便。可以直接使用MmGetSystemRoutineAddress函数。但由于系统中其他安全软件可能对此函数进行挂钩,所以360采用了更加稳妥的方式。
首先,向ZwQuerySystemInformation传递0x0B号参数,获得SYSTEM_MODULE_INFORMATION结构数组。数组的第一个元素就是内核模块,取得内核模块的imageBase和imageSize。然后按照PE格式解析映射入内存的系统内核,从导出表中找到KeServiceDescriptorTable的地址,进行重定位后得到SSDT表在内存中的真实地址。
上述过程被360封装在MyGetFuncAddrFromKrnl函数中,并在以后被多次调用。函数原型如下:
```c
int __stdcall MyGetFuncAddrFromKrnl(PUNICODE_STRING funcName)
funcName为内核导出函数的名称
返回值为函数地址或NULL。(详细分析请参考IDB文件)
```
1. 使用MyGetFuncAddrFromKrnl获得KeAddSystemServiceTable函数地址。其反汇编代码如下:
```assembly
80596542 8bff mov edi,edi
80596544 55 push ebp
80596545 8bec mov ebp,esp
```
经过搜索和分析,我们找到了以下内容:
原始代码:
```
80596547 837d1803 cmp dword ptr [ebp+18h],3
8059654b 7760 ja nt!KeAddSystemServiceTable+0x6b (805965ad)
8059654d 8b4518 mov eax,dword ptr [ebp+18h]
80596550 c1e004 shl eax,4
80596553 83b88031558000 cmp dword ptr nt!KeServiceDescriptorTable (80553180)[eax],0
8059655a 7551 jne nt!KeAddSystemServiceTable+0x6b (805965ad)
8059655c 8d8840315580 lea ecx,nt!KeServiceDescriptorTableShadow (80553140)[eax]
```
去除后的代码:
```
8D 88
```
接下来,我们需要找到与原始代码中的红色部分对应的地址。原始代码中的红色部分是:
```
注意红色代码:这里出现了 KeServiceDescriptorTableShadow 的地址,对应的机器码为 8D 88 40 31 55 80 ,从 KeAddSystemServiceTable 开始搜索 8D 88 ,紧接着的 4 字节数据就是 shadowSSDT 在内存中的地址。
```
我们可以观察到,在去除后的代码中,只剩下一个 `8D` 指令。因此,我们可以得出结论,`shadowSSDT` 在内存中的地址就是 `KeAddSystemServiceTable` 开始搜索的第一个 `8D` 指令的地址加上 `4` 字节。
所以,`shadowSSDT` 在内存中的地址为:`KeAddSystemServiceTable + 2 + 4 = KeAddSystemServiceTable + 6`。