Windows消息钩取
简单地说,消息钩取就是偷看、截取信息。
常规Windows消息流:
1、发生键盘输入事件时,WM_KEYDOWN消息被添加到[OS message queue];
2、OS判断哪个应用程序中发生了事件,然后从[OS message queue]中取出消息,添加到相应应用程序的[application message queue]中;
3、应用程序监视自身的[application message queue],发现新添加的WM_KEYDOWN消息后,调用相应的事件处理程序处理。
消息钩子:
Windows OS向用户提供GUI,其是以事件驱动的方式进行工作的。每当发生这样的事件时,OS会将事先定义好的消息发送给相应的应用程序,应用程序分析收到的信息后执行相应动作。即在敲击键盘时,消息从OS传递到应用程序,此过程中消息钩子可以偷看其中的信息。
消息钩子是Windows OS提供的基本功能,其中最具代表性的是VS Visual Studio中提供的SPY++,其是一个功能强大的消息钩取程序,能够查看OS中来往的所有消息。
如下图,OS消息队列和应用程序消息队列之间存在一条钩链(Hook Chain),设置好键盘消息钩子后,处于钩链中的键盘消息钩子会比应用程序先一步看到相应信息。在键盘消息钩子函数的内部,除了可以查看消息之外,还可以修改消息本身,而且还能对消息实施拦截,阻止消息传递。可以同时设置多个相同的键盘消息钩子,按照设置的顺序依次调用,从而组成的链条称为钩链。
Windows消息钩取的实现——SetWindowsHookEx():
在Windows编程中,使用SetWindowsHookEx() API可以简便地实现消息钩子,其用于将指定的钩子注册到钩链中,无论在DLL内部或外部都可调用。
SetWindowsHookEx() API定义如下:
HHOOK SetWindowsHookEx(
int idHook, //hook type
HOOKPROC lpfn, //hook procedure
HINSTANCE hMod, //hook procedure所属的DLL句柄
DWORD dwThreadId //将要挂钩的目标线程ID
);
HHOOK:返回值,钩子句柄,需要保留,等不使用钩子时通过UnhookWindowsHookEx函数卸载钩子。
idHook:钩子的拦截消息类型,选择钩子程序的拦截范围,具体值参考文章结尾的消息类型。
Lpfn:消息的回调函数地址,一般是填函数名。
hMod:钩子函数所在的实例的句柄。对于线程钩子,该参数为NULL;对于系统钩子,该参数为钩子函数所在的DLL句柄。在dll中可通过AfxInitExtensionModule(MousehookDLL, hInstance)获得DLL句柄。
dwThreadId:钩子所监视的线程的线程号,可通过GetCurrentThreadId()获得线程号。对于全