钩子(HOOK)技术
一、Win32 全局钩子的运行机制
钩子函数实际上是一个处理消息的程序段,每当一个应用程序调用函数 GetMessage
或 PeekMessage 而恰有一个消息即将被处理时,系统调用钩子函数。也就是说,当特定的
息发出,在没有到达目的窗口前,钩子函数先捕获消息,亦即钩子函数先获得控制权。这
时钩子函数既可以加工处理该消息,也可以不作处理而继续传递消息,还可以强制结束消
息传递。系统为每种类型的钩子维护一个钩子链,最近安装的钩子放在链的开始,而最先
安装的钩子放在最后,也就是后加入的钩子先获得控制权。
Windows API 函数 SetWindowsHookEx 用来安装钩子函数,这个函数的原型是
HHOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE
hMod,DWORD dwThreadId),其中第一个参数是钩子的类型;第二个参数是钩子函数的
地址;第三个参数是包含钩子函数的模块句柄;第四个参数指定监视的线程,如果指定确
定的线程,即为线程钩子,如果指定为空,则为全局钩子。其中,全局钩子必须包含在
DLL 中,线程专用钩子可以包含在可执行文件中。得到控制权的钩子函数在完成对消息的
处理后,如果想要该消息继续传递,那么它必须调用另一个 API 函数 CallNextHookEx 来
传递它,钩子函数也可以通过直接返回 0 来丢弃该消息,以阻止消息的传递。
UnhookWindowsHookEx 函数用于将一个由函数 SetWindowsHookEx 安装的钩子
函数从钩子链中删除(即脱钩)。
二、在 BCB 下建立和使用包含鼠标钩子函数的动态连接库
建立一个 DLL Project,在 hookdll.cpp 中定义钩子函数的实现过程
在 BCB 开发环境下选择 File/New,在 New Items 对话框中双击 DLL Wizard,BCB
自动为我们产生一个 DLL 的相关文档,其中源文件只是一个包含 DLL 入中点的空壳,DLL
入口函数的程序如下:
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
return 1;
}
在此基础上我增加三个函数、两个指针变量和一个表示自定义消息的符号常量,并修
改 DLL 入口函数。代码如下:
#de<ne WM_MOUSE_HOOK 1001 //自定义消息
extern "C" {
__declspec(dllexport) BOOL APIENTRY StartHook(); //安装鼠标钩子
__declspec(dllexport) BOOL APIENTRY EndHook(); //删除钩子
LRESULT WINAPI MouseProc(int nCode,WPARAM wparam,LPARAM lparam);
}
HHOOK hHook=NULL; //鼠标钩子函数句柄
HINSTANCE hInstance=NULL; //DLL 实例句柄
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
hInstance=hinst;
return 1;
评论6