钩子可以用来截获系统中的消息流 通过SetWindowsHookEx函数定义了监视函数的位置和监视消息的类型,这样,每当发生我们感兴趣的消息时,Windows就会将消息发送给监视函数,监视函数是一个处理消息的回调函数,也称为“钩子函数”。(会影响系统的性能)
局部钩子仅钩挂属于自身进程的事件;(SetWindowsHook)
远程钩子分两种:基于线程的和系统范围的(包括自身)。
1 基于线程的远程钩子用来捕获其他进程中某一特定线程的事件;
2 系统范围的远程钩子将捕捉系统中所有进程中发生的事件消息。
|
钩 子 名 称 |
监视消息的类型和时机 |
|
WH_CALLWNDPROC |
每当调用SendMessage函数时,函数将消息发送给目标窗口过程前首先调用钩子函数 |
|
WH_CALLWNDPROCRET |
每当调用SendMessage函数时,函数将消息发送给目标窗口过程后再调用钩子函数 |
|
WH_GETMESSAGE |
每当调用GetMessage或PeekMessage函数时,函数从程序的消息队列中获取一个消息后调用钩子函数 |
|
WH_KEYBOARD |
每当调用GetMessage或PeekMessage函数时,如果从消息队列中得到的是WM_KEYUP或WM_KEYDOWN消息,则调用钩子函数(键盘消息) |
|
WH_MOUSE |
每当调用GetMessage或PeekMessage函数时,如果从消息队列中得到的是鼠标消息,则调用钩子函数(鼠标消息) |
|
WH_HARDWARE |
每当调用GetMessage或PeekMessage函数时,如果从消息队列中得到的是非鼠标和键盘消息,则调用钩子函数 |
|
WH_MSGFILTER |
当用户对对话框、菜单和滚动条有所操作时,系统在发送对应的消息之前调用钩子函数,这种钩子只能是局部的 |
|
WH_SYSMSGFILTER |
同WH_MSGFILTER,不过是系统范围的 |
|
WH_SHELL |
当Windows shell程序准备接收一些通知事件前调用钩子函数,如shell被激活和重画等 |
|
WH_DEBUG |
用来给其他钩子函数除错(调试) |
|
WH_CBT |
当基于计算机的训练(CBT)事件发生时调用钩子函数 |
|
WH_JOURNALRECORD |
日志记录钩子,用来记录发送给系统消息队列的所有消息 只能全局 |
|
WH_JOURNALPLAYBACK |
日志回放钩子,用来回放日志记录钩子记录的系统事件 只能全局 |
|
WH_FOREGROUNDIDLE |
系统空闲钩子,当系统空闲的时候调用钩子函数,这样就可以在这里安排一些优先级很低的任务 |
远程钩子的钩子函数必须位于一个动态链接库中,而且必须是共享数据段的动态链接库
钩子程序一般包括3个功能模块:
(1)主程序——用来实现界面或者其他功能。
(2)钩子回调函数——用来接收系统发过来的消息。
(3)钩子的安装和卸载程序。
键盘钩子示例 -(链接库)
<HookDll.asm>
.386 .model flat, stdcall option casemap :none ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; Include 文件定义 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> include windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .data hInstance dd ? .data? hWnd dd ? hHook dd ? dwMessage dd ? szAscii db 4 dup (?) ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .code ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DllEntry proc _hInstance,_dwReason,_dwReserved Push _hInstance pop hInstance mov eax,TRUE ret DllEntry Endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 键盘钩子回调函数 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> HookProc proc _dwCode,_wParam,_lParam local @szKeyState[256]:byte invoke CallNextHookEx,hHook,_dwCode,_wParam,_lParam invoke GetKeyboardState,addr @szKeyState invoke GetKeyState,VK_SHIFT mov @szKeyState + VK_SHIFT,al mov ecx,_lParam shr ecx,16 invoke ToAscii,_wParam,ecx,addr @szKeyState,addr szAscii,0 mov byte ptr szAscii [eax],0 invoke SendMessage,hWnd,dwMessage,dword ptr szAscii,NULL xor eax,eax ret HookProc endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 安装钩子 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> InstallHook proc _hWnd,_dwMessage push _hWnd pop hWnd push _dwMessage pop dwMessage invoke SetWindowsHookEx,WH_KEYBOARD,addr HookProc,\ hInstance,NULL mov hHook,eax ret InstallHook endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 卸载钩子 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> UninstallHook proc invoke UnhookWindowsHookEx,hHook ret UninstallHook endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> End DllEntry
<HookDll.def>文件中包括了它们的名称:
EXPORTS HookProc
InstallHook
UninstallHook