钩子函数和键盘记录

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

钩子必备函数

要安装钩子,必须用SetWindowsHookEx函数,函数原型如下:

HHOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId);

idhook参数指定钩子的类型,钩子的类型如下:

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_SHELL 当windows shell 程序准备接受一些通知事件前调用钩子函数,如shell被激活

WH_DEBUG用来给其它钩子函数除错。

WH_CBT当基于计算机的训练事件时调用钩子函数。

WH_JOURNALRECORD日志记录钩子,用来记录发送给系统消息队列的所有消息,只能用作全局钩子。

WH_JOURNALPLAYBACK,日志回放钩子,用来回放日志记录钩子记录的事件,只能用作全局钩子。

WH_FOREGROUNDIDLE系统空闲钩子,当系统空闲时调用钩子函数,这样就可以在这里安排一些优先级很低的任务。

Lpfn参数用来传入钩子函数的入口地址。

hInstance参数用来指定钩子回调函数所在DLL的实例句柄,如果安装的是局部钩子的话,由于句柄钩子的回调函数不需要放在DLL中,这个参数就可以用NULL。

DWThreadID是安装钩子后想监控的线程的ID,这个参数可以决定钩子是局部的还是系统范围的。如果参数指定的是自己进程中某个线程的ID,那么该钩子是一个局部钩子,如果指定的是另一个进程中某个线程的ID,那么这个钩子就是一个局部的远程钩子,可以将这个参数设置为NULL,被解释为系统范围的,可以监控所有的进程中的线程。



返回值:如果调用成功,返回的是钩子函数的句柄,否则为NULL,需要指出是这个钩子句柄必须保存下来,因为在回调函数和卸载钩子时还有用这个句柄。

卸载函数:

UnhookWindowsHookEx(HHOOK hhk);



钩子函数编写思路:

下面我们结合WH_JOURNALRECORD类型的钩子,来对键盘记录进行介绍。

LPRESULT CALLB

ACK JournalRecordProc(int code,WPARAM wParam,LPARAM lParam);各类钩子的回调函数的三个参数都是这样三个,但它们的定义各不相同,就像窗口过程在收到各种不同消息的时候,wParam和lParam的定义各不相同,不同钩子函数的回调函数的返回值定义也各不相同。

对于日志记录钩子来说,参数的定义如下:

code-指定如何处理消息,如果是HC_ACTION,标识lParam指向了一个EVENTMSG结构,这个结构中包含了一个从系统消息队列中移除的消息,同时,钩子的处理过程必须通过将这些记录的信息拷贝到缓冲区或文件中,来记录EVENTMSG结构体的内容,如果是HC_SYSMODALOFF,表示一个系统模式对话框已经被销毁,钩子过程必须继续记录,HC_SYSMODALON,表示一个系统模式对话框正在被显现出来,直到对话框被销毁掉,钩子的处理过程才会停止记录。

wParam-这个参数目前没用到,用NULL

lParam-这个参数指向一个EVENTMSG结构体。

来看看EVENTMSG结构体的定义

typedef struct tagEVENTMSG

{

UINT message;

UINT paramL;

UINT paramH;

DWORD time;

HWND hwnd;
}EVENTMSG;

message-指定捕获的消息,如果是针对键盘捕获,那么这个消息就是WM_KEYUP和WM_KEYDOWN消息。另外,这个参数还有可能传递系统的击键消息,如WM_SYSKEYUP,WM_SYSKEYDOWN,WM_SYSCHAR等消息,,不过,我们指定是捕获键盘的字符消息,只关系WM_KEYUP和WM_KEYDOWN就可以了。

paramL-这个要看具体的消息来定,像我们捕获的键盘消息,那么这个参数中将存放按键 的虚拟码。

paramH-这个要看具体的消息来定,像我们捕获的键盘消息,那么这个参数中存放了按键的重复次数,扫描码和标志等数据,不同数据位定义如下:

?位0-15:按键的重复次数

?位16-24:按键的扫描码

?位24:按键是否是扩展键,(F1与F2等Fx键等,小键盘的数字键等),如果此位是1表示按键是扩展键

?位25-28:未定义

?位29:如果ALT键在按下状态,此位设置为1,否则为0

?位30: 按键的原始状态,消息发送前按键是按下的,此位被设置为1,否则为0

?位31:按键的当前动作,如果是按键按下,那么此位被设置为0,按键释放的话被设置为1

对于每个击键动作,回调函数会在按键按下和释放时被调用两次,只需根据lParam位的31中的标志来记录一次,否则得到的是重复信息。

另外,回调函数收到的参数是以按键的扫描码和虚拟码表示,在送给窗口之前应该转换为ACSII码,windows提供了一个APIh函数,专门完成转换

ToAscii(UINT uVirtKey,UINT uScanCode,PBYTE lpKeyState,LPWORD lpChar,UINT uFlags);

各参数的意义如下:

uVirtKey-这个参数要传入按键的虚拟码,在使用时直接使用钩子

回调函数的EVENTMSG中的paramL参数就可以了


相关文档
最新文档