11.3 钩子技术
众所周知,Windows系统是建立在事件驱动机制上的,也就是说整个系统都是通过消息的传递来实现的。钩子是Windows系统中非常重要的系统接口,它可以截获并处理送给 任意应用程序的消息,来完成普通应用程序难以实现的功能。本实例正是利用了钩子的这个特性来实现捕获Ctrl+p组合键的功能。本节将详细介绍钩子技术及本实例键盘钩子的实现方法。
11.3.1 钩子技术简介
钩子可以监视并截获系统或进程中的各种事件消息,并可将截获的消息发往目标窗口的消息并进行处理。系统中安装自定义的钩子,监视系统中特定事件的发生,便可完成特定的功能,比如盗号的键盘钩子、游戏外挂的鼠标钩子,金山词霸的屏幕取词,日志监视等。由此可见钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,外壳钩子可以截取、启动和关闭应用程序的消息等。
根据钩子的作用对象不同,可将钩子分为线程钩子和系统钩子。线程钩子监视指定线程的事件消息,系统钩子监视系统中所有线程的事件消息。由于系统钩子会影响系统中所有的应用程序,所以钩子函数必须放在独立的动态链接库中。钩子有3个重要函数,如下所示。
1.安装函数SetWindowsHookEx()
钩子的安装函数SetWindowsHookEx()原型如下:
- hhook setwindowshookex(
- int idhook,
- HOOKPROC lpfn,
- HINSTANCE hmod,
- DWORD dwthreadid
- );
该函数有4个参数,说明如下。
idHook:要安装的钩子类型,可参考表11.1中的idHook值。
表11.1 钩子类型表
|
值< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> |
说 明 |
|
WH_CALLWNDPROC |
窗口钩子,当系统向目标窗口发送消息时将触发此钩子 |
|
WH_CALLWNDPROCRET |
窗口钩子,当窗口处理完消息后将触发此钩子 |
|
WH_CBT |
当Windows激活、产生、释放(关闭)、
最小化、最大化或改变窗口时都将触发此事件 |
|
WH_DEBUG |
调试钩子 |
|
WH_GETMESSAGE |
当往消息队列中增加一个消息时将触发此钩子 |
|
WH_JOURNALPLAYBACK |
回放钩子,可以用于播放已记录的鼠标和键盘的操作 |
|
WH_JOURNALRECORD |
记录钩子,可以用于记录鼠标和键盘的
操作,木马程序可以使用此钩子窃取受控方
在屏幕中输入的密码 |
|
WH_KEYBOARD |
当敲击键盘时将触发此钩子 |
|
WH_MOUSE |
当有鼠标操作时将触发此钩子 |
|
WH_MSGFILTER |
消息过滤钩子 |
|
WH_SHELL |
Shell钩子 |
|
WH_SYSMSGFILTER |
系统消息过滤钩子 |
Lpfn:钩子过程的指针,即拦截到指定系统消息后的预处理过程即钩子的回调函数,须定义在DLL中。
hMod:应用程序实例的句柄如果是全局钩子,hInstance是DLL句柄(DllMain中给的模块地址,就是包含HookProc的动态库加载地址);否则赋值为0,只钩向自己。
dwThreadId:要安装钩子的线程ID,指定被监视的线程,如果明确指定了某个线程的ID就只监视该线程,此时的钩子即为线程钩子;如果该参数被设置为0,则表示此钩子为监视系统所有线程的全局钩子。
2.消息传递函数CallNextHookEx ()
消息传递函数CallNextHookEx ()负责将消息向下传递,下一个钩子处理将截获这一消息,函数原型如下:
- LRESULT CallNextHookEx (
- HHOOK hhk, //当前钩子的句柄
- Int ncode, //钩子代码,为下一个钩子下达的指令
- WPARAM wParam, //要传递的参数,由钩子类型决定是什么参数
- LPARAM lParam //要传递的参数,由钩子类型决定是什么参数
- );
3.注销钩子函数unhookwindowshookex()
注销钩子函数unhookwindowshookex(),它负责撤销钩子,函数原型如下:
- bool unhookwindowshookex(
- hhook hhk
- );
参数是将要注销钩子的句柄。