Author:achillis
blog :http://hi.baidu.com/_achillis
上一篇的分析中漏掉了三个函数,现补上:
NtSetSystemInformation 0x24
ProcessNotify 0x45 //这个并非Hook,只是HookPort安装的一个Notify
KeUserModeCallback 0x4B
这样一共是从0到0x4B,共0x4C个过滤函数,齐了~~
上次先列出了360所hook的系统服务,让大家对它做了什么有了一些了解。这次分析的重点是360的KiFastCallEntry钩子安装全过程,更为重点的是360这样一个安全软件,是如何理好地处理好这众全多的Hook,即我所谓的“架构”问题。一、准备工作
(1)准备要Hook的系统服务的服务号ServiceIndex,对于导出的服务,采用获取Zw*函数地址后再取服务号的方法,这个想必大家都很熟悉。未导出的,则根据不同系统版本,采用硬编码的方法。
(2)准备缓冲区,存放原始服务例程地址、过滤开关、代理函数地址等,记为ServiceFilterInfoTable,这些都是HOOK中要使用到的数据。
HookPort.sys申请了一块很大的内存用于存放这些数据,该内存大小为0x5DDC=6007*4=(6006+1)*4,为什么这么写呢?因为它实际上是下面一个结构:
typedef struct _SERVICE_FILTER_INFO_TABLE{
ULONG SSDTCnt;
ULONG SavedSSDTServiceAddress[1001]; //起始偏移0001*4,保存被Hook的SSDT函数的地址
ULONG ProxySSDTServiceAddress[1001]; //起始偏移1002*4,保存被Hook的SSDT函数对应的代理函数的地址
ULONG SavedShadowSSDTServiceAddress[1001]; //起始偏移2003*4,保存被Hook的ShadowSSDT函数的地址
ULONG ProxyShadowSSDTServiceAddress[1001]; //起始偏移3004*4,保存被Hook的ShadowSSDT函数对应的代理函数的地址
ULONG SwitchTableForSSDT[1001]; //起始偏移4005*4,保存SSDT Hook开关,决定该函数是否会被Hook
ULONG SwitchTableForShadowSSDT[1001]; //起始偏移5006*4,保存ShadowSSDT Hook开关,决定该函数是否会被Hook
}SERVICE_FILTER_INFO_TABLE;
#define FILTERFUNCNT 0x4C //过滤函数的个数
typedef struct _FILTERFUN_RULE_TABLE{
ULONG bSize; //本结构的大小,为0x144=0x51*4=(0x4C+5)*4=(FILTERFUNCNT+5)*4
ULONG Unknown1; //未明确
ULONG IsFilterFunFilledReady; //标志,表明过滤函数表是否准备好
ULONG FakeServiceRoutine[FILTERFUNCNT] //偏移为0xC,过滤函数数组,共有过滤函数0x4C个
PULONG SSDTRuleTableBase; //偏移为0x13C,是SSDT函数的过滤规则表,表的大小为SSDTCnt*4
PULONG ShadowSSDTRuleTableBase; //偏移为0x140,是ShadowSSDT函数的过滤规则表,表的大小为ShadowSSDTCnt*4
}FILTERFUN_RULE_TABLE;
kd>
8053d7e4 8b5f0c mov ebx,dword ptr [edi+0Ch] //edi指向SSDT或ShadowSSDT
8053d7e7 33c9 xor ecx,ecx //ecx清零
8053d7e9 8a0c18 mov cl,byte ptr [eax+ebx] //cl得到参数的长度,即参数个数*4
8053d7ec 8b3f mov edi,dword ptr [edi] //edi指向KiServiceTable或W32pServiceTable
8053d7ee 8b1c87 mov ebx,dword ptr [edi+eax*4] //eax是服务号,然后ebx得到服务函数地址
8053d7f1 2be1 sub esp,ecx //ecx得到参数的总长度,这里是开辟栈空间
8053d7f3 c1e902 shr ecx,2 //除以4,得参数个数
8053d7f6 8bfc mov edi,esp //准备复制参数
8053d7f8 3b35b48b5580 cmp esi,dword ptr [nt!MmUserProbeAddress (80558bb4)] //判断参数地址是否有效
8053d7fe 0f83a8010000 jae nt!KiSystemCallExit2+0x9f (8053d9ac)
8053d804 f3a5 rep movs dword ptr es:[edi],dword ptr [esi] //复制参数
8053d806 ffd3 call ebx //调用系统服务
kd>
nt!KiFastCallEntry+0xcc:
8053d7dc ff0538f6dfff inc dword ptr ds:[0FFDFF638h]
8053d7e2 8bf2 mov esi,edx
8053d7e4 8b5f0c mov ebx,dword ptr [edi+0Ch]
8053d7e7 33c9 xor ecx,ecx
8053d7e9 8a0c18 mov cl,byte ptr [eax+ebx]
8053d7ec 8b3f mov edi,dword ptr [edi]
8053d7ee 8b1c87 mov ebx,dword ptr [edi+eax*4]
8053d7f1 e94a49e901 jmp 823d2140 //这里被改成了一个跳转
8053d7f6 8bfc mov edi,esp
8053d7f8 3b35b48b5580 cmp esi,dword ptr [nt!MmUserProbeAddress (80558bb4)]
8053d7fe 0f83a8010000 jae nt!KiSystemCallExit2+0x9f (8053d9ac)
8053d804 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
8053d806 ffd3 call ebx
8053d808 8be5 mov esp,ebp
8053d80a 8b0d24f1dfff mov ecx,dword ptr ds:[0FFDFF124h]
8053d810 8b553c mov edx,dword ptr [ebp+3Ch]
kd> u 823d2140
823d2140 e95d982a76 jmp Hookport+0x79a2 (f867b9a2)
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!