-
-
[分享]对百度杀毒软件hook的一点分析[更1]
-
发表于:
2013-4-11 15:40
10487
-
求职: qq->1815349357[DeDf]
程序开始的时候,建立如下一个表:
v7 0x2154 ---- Bhbase+A770
+0 *MmUserProbeAddress 4B
+4 ServiceTableBase 4B
+8 NumberOfServices 4B
+c Win32kApiTable 4B
+10 NumberOfWin32kApi 4B
+14 p_characteristic_KiFastCallEntry 4B KiFastCallEntry+0xe7
+18 p_characteristic_KiFastCallEntry+8 4B
+1C characteristic_KiFastCallEntry 8B
+24 KeServiceDescriptorTable 4B
+28 Ntoskrnl_ImageBase 4B
+2C Ntoskrnl_ImageSize 4B
+30 win32k_ImageBase 4B
+34 win32k_ImageSize 4B
+38 PID_csrss.exe 4B
+3C KiFastCallEntry_characteristic_Exist 1B
+3D is_PID_winlogon_csrss_0 1B
+40 HaveHooked==1 else==2 Init==0 4B
+44 OSversionI 4B
+48 pHookInfo[41] 4B
+154 pHookInfo[2][1024] 4B
HookInfo 0x428 ---- dynamic
+0 HookTable.Hook 4B
+4 -1 4B
+8 pwch_FunctionName 4B
+C Index_HookTable 4B
+10 Offset_diffOS 4B
+14 pRealSystemRoutine 4B
+18 It_Filter_Function 4B
+20 sub_10650 1B
HookTable 0x44 ---- Bhbase+8EE8
+0 4B
+4 pwch_FunctionName(NULL) 4B
+8 It_Filter_Function 4B
+C Offset_diffOS[13] 4B*13
+40 Index_HookTable 4B
首先SSDT hook ZwSetEvent,然后插入一个假Event,在Its_ZwSetEvent函数中判断该假Event,从栈里找到它在Caller(KiFastCallEntry)中的Return地址,然后从该地址向前搜索(8BFC3B35 XXXXXXXX 0F83),这里便是Hook点。随后移除ZwSetEvent的hook。
HOOK KiFastCallEntry的时候,多核的话向每个CPU投递DPC,参数是一个SpinLock,在DeferredRoutine里增加一个计数,然后就参与到争夺该SpinLock的行动中。
该SpinLock在HOOK KiFastCallEntry的线程里已经被KfAcquireSpinLock了,也就是说除了执行这个线程的核心,其他核心是得不到SpinLock的。执行HOOK的线程等上面那个计数达到(总核心数-1)的时候,也就是说其他核心都被挂到树上时,它就HOOK,然后扔掉SpinLock。其他核心得到该SpinLock,一看是个烂苹果也就扔掉了,DeferredRoutine就执行结束了。
值得一提的是无论上面计数的增加和替换KiFastCallEntry里Opcode的过程,都是使用原子操作的函数完成的,_InterlockedExchangeAdd与_InterlockedCompareExchange64。
最后会开一个线程:检测KiFastCallEntry有没有被恢复,如果被恢复的话,就转为SSDTHookAll,还会通知L"\\Callback\\bdProtectExpCallBack".
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)