一。生成钩子
1、利用VC生成一个DLL框架,可以用MFC的,也可以用win32的,这个并不是很重要,只要是DLL就行。
2、编写自己的钩子过滤函数
钩子过滤函数必须是回调函数,其函数的形式:
LRESULT WINAPI CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) ;
3、在生成的DLL框架中加入自己钩子的处理函数。
4、用SetWindowsHookEx函数,安装HOOK;
系统是通过调用位于钩子链表最开始处的钩子函数而进行消息拦截处理的,因此在设置钩子时要把回调函数放置于钩子链表的链首,操作系统会使其首先被调用。由函数SetWindowsHookEx()负责将回调函数放置于钩子链表的开始位置。SetWindowsHookEx()函数原型声明为:
HHOOK SetWindowsHookEx(int idHook;HOOKPROC lpfn;HINSTANCE hMod;DWORD dwThreadId);
其中,参数idHook 指定了钩子的类型,可以使用的类型有以下13种:
WH_CALLWNDPROC 系统将消息发送到指定窗口之前的“钩子” WH_CALLWNDPROCRET 消息已经在窗口中处理的“钩子” WH_CBT 基于计算机培训的“钩子” WH_DEBUG 差错“钩子” WH_FOREGROUNDIDLE 前台空闲窗口“钩子” WH_GETMESSAGE 接收消息投递的“钩子” WH_JOURNALPLAYBACK 回放以前通过WH_JOURNALRECORD“钩子”记录的输入消息 WH_JOURNALRECORD 输入消息记录“钩子” WH_KEYBOARD 键盘消息“钩子” WH_MOUSE 鼠标消息“钩子” WH_MSGFILTER 对话框、消息框、菜单或滚动条输入消息“钩子” WH_SHELL 外壳“钩子” WH_SYSMSGFILTER 系统消息“钩子” |
参数lpfn为指向钩子函数的指针,也即回调函数的首地址;参数hMod标识了钩子处理函数所处模块的句柄;参数dwThreadId 指定被监视的线程,如果明确指定了某个线程的ID就只监视该线程,此时的钩子即为线程钩子;如果该参数被设置为0,则表示此钩子为监视系统所有线程的全局钩子。此函数在执行完后将返回一个钩子句柄。
在SetWindowsHookEx()函数完成对钩子的安装后,如果被监视的事件发生,系统会立即调用位于相应钩子链表开始处的钩子函数进行处理,每一个钩子函数在进行处理时都要考虑是否需要把事件传递给下一个钩子处理函数。如果需要传递,就要调用函数CallNestHookEx()。尽管在理论上不调用CallNestHookEx()也并不算错,但在实际使用时还是强烈建议无论是否需要进行事件传递都要在过程的最后调用一次CallNextHookEx( ),否则将会引起一些无法预知的系统行为或是系统锁定。该函数将返回位于钩子链表中的下一个钩子处理过程的地址,至于具体的返回值类型则要视所设置的钩子类型而定。CallNextHookEx( )的函数原型为:
LRESULT CallNextHookEx(HHOOK hhk;int nCode;WPARAM wParam;LPARAM lParam); |
CallNextHookEx函数一般都是在调用完钩子的回调函数以后:
return CallNextHookEx();
其中,参数hhk为由SetWindowsHookEx()函数返回的当前钩子句柄;参数nCode为传给钩子过程的事件代码;参数wParam和lParam 则为传给钩子处理函数的参数值,其具体含义同设置的钩子类型有关。
钩子用完以后最好马上卸载,钩子会对系统的性能有影响。
HHOOK SetWindowsHookEx(int idHook;HOOKPROC lpfn;HINSTANCE hMod;DWORD dwThreadId);
其中,参数idHook 指定了钩子的类型,可以使用的类型有以下13种:
WH_CALLWNDPROC 系统将消息发送到指定窗口之前的“钩子” WH_CALLWNDPROCRET 消息已经在窗口中处理的“钩子” WH_CBT 基于计算机培训的“钩子” WH_DEBUG 差错“钩子” WH_FOREGROUNDIDLE 前台空闲窗口“钩子” WH_GETMESSAGE 接收消息投递的“钩子” WH_JOURNALPLAYBACK 回放以前通过WH_JOURNALRECORD“钩子”记录的输入消息 WH_JOURNALRECORD 输入消息记录“钩子” WH_KEYBOARD 键盘消息“钩子” WH_MOUSE 鼠标消息“钩子” WH_MSGFILTER 对话框、消息框、菜单或滚动条输入消息“钩子” WH_SHELL 外壳“钩子” WH_SYSMSGFILTER 系统消息“钩子” |
参数lpfn为指向钩子函数的指针,也即回调函数的首地址;参数hMod标识了钩子处理函数所处模块的句柄;参数dwThreadId 指定被监视的线程,如果明确指定了某个线程的ID就只监视该线程,此时的钩子即为线程钩子;如果该参数被设置为0,则表示此钩子为监视系统所有线程的全局钩子。此函数在执行完后将返回一个钩子句柄。
在SetWindowsHookEx()函数完成对钩子的安装后,如果被监视的事件发生,系统会立即调用位于相应钩子链表开始处的钩子函数进行处理,每一个钩子函数在进行处理时都要考虑是否需要把事件传递给下一个钩子处理函数。如果需要传递,就要调用函数CallNestHookEx()。尽管在理论上不调用CallNestHookEx()也并不算错,但在实际使用时还是强烈建议无论是否需要进行事件传递都要在过程的最后调用一次CallNextHookEx( ),否则将会引起一些无法预知的系统行为或是系统锁定。该函数将返回位于钩子链表中的下一个钩子处理过程的地址,至于具体的返回值类型则要视所设置的钩子类型而定。CallNextHookEx( )的函数原型为:
LRESULT CallNextHookEx(HHOOK hhk;int nCode;WPARAM wParam;LPARAM lParam); |
CallNextHookEx函数一般都是在调用完钩子的回调函数以后:
return CallNextHookEx();
其中,参数hhk为由SetWindowsHookEx()函数返回的当前钩子句柄;参数nCode为传给钩子过程的事件代码;参数wParam和lParam 则为传给钩子处理函数的参数值,其具体含义同设置的钩子类型有关。
钩子用完以后最好马上卸载,钩子会对系统的性能有影响。
5、用UnHookWindowsHookEx卸载钩子
二、利用钩子
1、生成一个exe文件,然后调用钩子的DLL,这里也可以是.h+lib;
2、在程序中安装钩子
3、利用钩子的功能
4、一定不要忘了卸装钩子,调用钩子的函数注销钩子
注意:其实DLL是实现钩子的最主要地方,而利用钩子的EXE文件,只是起到一个调用DLL注册DLL的作用:)
ps:感谢http://www.18ceo.com/的文章:)