windows消息钩取
消息钩取
Windows向用户提供GUI界面,它以事件驱动方式工作(如按钮事件,鼠标事件)
发生事件时,OS会把事先定好的消息发送给相应的应用程序,应用程序接收到后就会执行相应的动作。举个例子,当我想在记事本上输入字体时,我点击键盘,记事本就会出现相应的字符。而在计算机中的顺序就是:我点击键盘产生消息——>触发按键事件——>os接受到按键事件的消息并将消息发送给应用程序——>应用程序进行响应,因为我们输入的消息先要到达os,才会传送给应用程序,因此如果我们在os和应用程序中间,建立一个”监视器“,我们就可以监视用户的输入了。而这个”监视器“,我们叫起”钩链“
SetWindowsHookEx()
SetWindowsHookEx()是一个可以实现消息钩子的API,其定义如下:
钩子过程是由操作系统调用的回调函数。安装消息钩子时,钩子过程需要存在于某个DLL内部,且该DLL的实例句柄是hMod。
keyhook.dll是一个含有钩子过程的DLL文件。HookMain.exe加载KeyHook.dll文件后使用SetWindowsHookEx()安装键盘钩子(KeyboardProc )。若其他进程( explorer.exe、iexplore.exe、notepad.exe等)中发生键盘输入事件,OS就会强制将KeyHook.dll加载到相应进程的内存,然后调用KeyboardProc()函数。
我会将书上HookMain.exe的代码附上,因为keyhook.dll是一个X86的dll,与其配套的dll都是x86的,所以编译时请选择x86版本,并且在x86平台运行,如果选择x64版本并在x64平台运行会产生许多难以解决的dll问题
HookMain.exe的代码:
#include "stdio.h"
#include "conio.h"
#include "windows.h"
#define DEF_DLL_NAME "KeyHook.dll"
#define DEF_HOOKSTART "HookStart"
#define DEF_HOOKSTOP "HookStop"
typedef void (*PFN_HOOKSTART)();
typedef void (*PFN_HOOKSTOP)();
void main()
{
HMODULE hDll = NULL;
PFN_HOOKSTART HookStart = NULL;
PFN_HOOKSTOP HookStop = NULL;
char ch = 0;
// 加载KeyHook.dll
hDll = LoadLibraryA(DEF_DLL_NAME);
if( hDll == NULL )
{
printf("LoadLibrary(%s) failed!!! [%d]", DEF_DLL_NAME, GetLastError());
return;
}
//获取到处函数地址
HookStart = (PFN_HOOKSTART)GetProcAddress(hDll, DEF_HOOKSTART);
HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll, DEF_HOOKSTOP);
// 开始钩取
HookStart();
//等待用户输入q
printf("press 'q' to quit!
");
while( _getch() != 'q' ) ;
// 终止钩取
HookStop();
// 卸载KeyHook.dll
FreeLibrary(hDll);
}