MSDN上对消息钩子的描述:
The SetWindowsHookEx function installs an application-defined hook procedure into a hook chain. You would install a hook procedure to monitor the system for certain types of events. These events are associated either with a specific thread or with all threads in the same desktop as the calling thread.
----------------------------------------------------------------------------------------------------------------------------
1.在内核中,NtUserSetWindowsHookEx函数会首先取得当前线程、当前进程、TEB等的一些信息。然后会调用IntAddHook函数。
2.IntAddHook函数会根据是全局HOOK,还是单进程的HOOK,把钩子插入不同的链表中
3.CallNextHookEx函数会根据不同的消息钩子类型调用不同的函数,如果是WH_CALLWNDPROC和WH_CALLWNDPROCRET类型的,就直接调用NtUserMessageCall函数。如果不是以上两者就会调用NtUserCallNextHookEx函数。
4.NtUserMessageCall又会根据传进来的typeid参数调用不同的函数。其中如果是上述的WH_CALLWNDPROC和WH_CALLWNDPROCRET类型的,则会调用co_IntCallHookProc函数。
5.co_IntCallHookProc函数经过一系列的参数赋值,初始化后,最后调用的是KeUserModeCallback返回Ring3去执行相应的回调函数。
6.当然上面的NtUserCallNextHookEx函数,经过稍微更加复杂的初始化后,最后调用的还是KeUserModeCallback函数去Ring3执行相应的回调函数。
NtUserCallNextHookEx->UserCallNextHookEx->co_HOOK_CallHookNext->co_IntCallHookProc->KeUserModeCallback
总结:
消息钩子的初始化和执行过程看起来思路都比较清晰。要Anti的话从SetWindowsHookEx开始,一路的调用都是可以做手脚的。
当然,还有比较猥琐的XX方法。
--------------------------------------------------------------------------------------------------------------------------
ps:
QQ管家的TCSafeBox.sys是采用的IAT HOOK KeUserModeCallback的方法来防止消息钩子注入的。不过其在判断注入的模块是否是系统常用模块时,采用了strstr函数。这样的话,我们可以随便构造一个目录就可以绕过了。
module_name_array 列表如下,是写死在代码里面的:
因此,我们只要构造一个类似“c:\\my\\Windows\\system32\\csrss.exe\\1.dll”这样的路径便可以实现注入QQ管家了。