微软提供了一个消息HOOK的API
SetWindowsHookEx();
一般情况下此API函数多用于注入。
HHOOK WINAPI SetWindowsHookEx( __in int idHook, //钩子类型 __in HOOKPROC lpfn, //回调函数地址 __in HINSTANCE hMod, //实例句柄 __in DWORD dwThreadId); //线程ID
详情:https://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx
此API参数钩子的种类很多。从不同的角度可以把钩子分为不同的种类。
按使用范围分类,主要有线程钩子和系统钩子:
(1)线程钩子监视指定线程的事件消息或者API函数。
(2)系统钩子监视系统中的所有线程的事件消息或者API函数。因为系统钩子会影响系统中所有的应用程序,所以钩子函数必须放在独立的动态链接库(DLL)中。
按拦截对象分类,主要有消息钩子和API钩子 :
(1)消息钩子是截获程序中的消息或事件的。
(2)API钩子是拦截目标程序中调用的函数,替换或者修改调用函数的功能。
消息钩子按事件消息分类,有如下的6种常用类型:
(1)键盘钩子和低级键盘钩子可以监视各种键盘消息。
(2)鼠标钩子和低级鼠标钩子可以监视各种鼠标消息。
(3)外壳钩子可以监视各种Shell事件消息,如启动和关闭应用程序。
(4)日志钩子可以记录从系统消息队列中取出的各种事件消息。
(5)窗口过程钩子监视所有从系统消息队列发往目标窗口的消息。
(6)还有一些其它的特定事件的钩子。
如通过 Hook 监视目标的屏幕
这里讲的监控跟平常的远程查看桌面不一样,也算是比较容易实现的版本。即,当用户鼠标发生点击的时候就把当前的页面截图留下。通过鼠标在多种情况下的屏幕截图来达到监视目标计算机的目的。
以下为逻辑示例代码:
/** * Hook 钩子处理函数 */ LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) { // 变量定义 ... if (nCode >= 0) { /* ... */ // 左键按下时将屏幕截图 if(wParam == WM_LBUTTONDOWN) { // 通过当前时间拼凑截图文件名 getCurrentDateTime( /*...*/ ); // 屏幕截图并保存到指定地址 CaptureImage( /*... */); } /* ... */ } // 将消息继续传递给窗口 return CallNextHookEx(myhook, nCode, wParam, lParam); // 如果不调用 CallNextHookEx 的话消息就被你的 Hook 截断了 }
监测API:
以上Ring3 层Hook方法都会用到修改opcode字节即修改硬编码实现,所以都会使用修改内存保护属性API来修改内存属性,VirtualProrectEx();
大多情况下会使用写内存API函数WriteProcessMemory()进行改写内存。
系统消息钩子API SetWindowsHookEx();
设置异常捕获函数 SetUnhandleExceptionFilter();
注册一个向量的异常处理程序 AddVectoredExceptionHandler();