HOOK编程流程
Posted Autumn の Box
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HOOK编程流程相关的知识,希望对你有一定的参考价值。
一、安装钩子过程
HHOOK SetWindowsHookEx(
int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId
);
idHook:指定将要安装的钩子过程的类型,包括:
WH_CALLWNDPROC --在操作系统将消息发送到目标窗口处理过程之前,对该消息进行监视
WH_CALLWNDPROCRET --对已被目标窗口过程处理过了的消息进行监视
WH_CBT --接受对CBT应用程序有用的消息
WH_DEBUG --对其他钩子过程进行调试
WH_FOREGROUNDIDLE --当应用程序的前台线程即将进入空闲状态时被调用,有助于在空闲时间内执行低优先级的任务
WH_GETMESSAGE --对发送到消息队列的消息进行监视
WH_JOURNALPLAYBACK --对此前由WH_JOURNALRECORD钩子过程记录的消息进行发送
WH_JOURNALRECORD --对发送到系统消息队列的输入消息进行记录
WH_KEYBOARD --对键盘按键消息进行监视
WH_KEYBOARD_LL --此钩子过程只能在WindowNT中安装,用来对底层的键盘输入事件进行监视
WH_MOUSE --对鼠标消息进行监视
WH_MOUSE_LL --此钩子过程只能在WindowNT中安装,用来对底层的鼠标输入事件进行监视
WH_MSGFILTER --监视由对话框、消息框、菜单条或滚动条中的输入事件引发的消息
WH_SHELL --接受对外壳应用程序有用的通知
WH_SYSMSGFILTER --监视由对话框、消息框、菜单条或滚动条中的输入事件引发的消息;该钩子过程对系统中所有应用程序的这类消息都进行监视
lpfn:指向相应的钩子过程;如果参数dwThreadId为0或者指定了一个其他进程创建的线程之标识符,则参数lpfn必须指向一个位于某动态链接库中的钩子过程;否则参数lpfn可以指向当前进程相关的代码中定义的一个钩子过程;
hMod:指定参数lpfn指向的钩子过程所在的DLL的句柄;如果参数dwThreadId指定的线程由当前进程创建,并且相应的钩子过程定义于与当前进程相关的代码中,则必须将参数hMod设为NULL;
dwThreadId:指定与钩子过程相关的线程标识;如果为0,则安装的钩子过程将与桌面上运行的所有线程都相关;
返回值:函数调用成功返回所安装的钩子过程的句柄,调用失败返回NULL;
二、安装鼠标钩子,监视鼠标消息
LRESULT CALLBACK MouseProc(
int nCode,
WPARAM wParam,
LPARAM lParam
);
nCode:确定钩子过程如何处理当前消息,包括:
HC_ACTION --表明参数wParam和lParam包含了关于鼠标消息的信息
HC_NOREMOVE --表明参数wParam和lParam包含了关于鼠标消息的信息,而且此鼠标消息尚未从消息队列中删除(程序调用了PeekMessage函数并设置了PM_NOREMOVE标志)
wParam:指示鼠标消息的标识;
lParam:指向MOUSEHOOKSTRUCT结构体指针;
LRESULT CALLBACK MouseProc( int nCode, WPARAM wParam, LPARAM lParam) { return 1; } . . . HHOOK g_hMouse=NULL; . . . g_hMouse=SetWindowsHookEx(WH_MOUSE,MouseProc,NULL,GetCurrentThreadId());
三、安装键盘钩子
LRESULT CALLBACK KeyboardProc(
int code,
WPARAM wParam,
LPARAM lParam
);
nCode:确定钩子过程如何处理当前消息,包括:
HC_ACTION --表明参数wParam和lParam包含了关于键盘消息的信息
HC_NOREMOVE --表明参数wParam和lParam包含了关于键盘消息的信息,而且此键盘消息尚未从消息队列中删除(程序调用了PeekMessage函数并设置了PM_NOREMOVE标志)
wParam:产生当前按键消息的键盘按键的虚拟键代码(“VK_”开头,如VK_SPACE);
lParam:一个32位的整数,用来指定按键重复的次数、扫描码、扩展键标记、上下文代码等标记,包括:
0~15位:指示重复次数,此值记录了由于用户连续按键引发的按键重复次数
16~23位:指示扫描码,此值依赖于键盘生产厂家
第24位:指示当前按键是否是功能键或数字小键盘上的键;如果是,其值为1
25~28位:保留未用
第29位:上下文代码,如果Alt键被按下,其值为1,否则为0
第30位:指示当前的键状态,如果在此消息被发送之前该键是按下的,其值为1,否则为0
第31位:指示变化状态,如果此键正在被按下,则其值为0
LRESULT CALLBACK KeyboardProc( int code, WPARAM wParam, LPARAM lParam) { if(VK_F1==wParam){ //按F1程序退出 ::SendMessage(g_hWnd,WM_CLOSE,0,0); UnhookWindowsHookEx(g_hKeyboard); //从钩子链中移走已安装的钩子 UnhookWindowsHookEx(g_hMouse); }else if( VK_F4==wParam || (1==(lParam>>29 & 1))){ return 1; //屏蔽Alt+F4的功能 }else{ return CallNextHookEx(g_hKeyboard,code,wParam,lParam); } } . . . HHOOK g_hKeyboard=NULL; . . . g_hKeyboard=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,NULL,GetCurrentThreadId());
四、把钩子信息传递给钩子链中下一个等待接收信息的钩子过程
LRESULT CallNextHookEx(
HHOOK hhk,
int nCode,
WPARAM wParam,
LPARAM lParam
);
hhk:指定当前钩子过程句柄,即SetWindowsHookEx函数的返回值;
nCode:确定钩子过程如何处理当前消息,包括:
HC_ACTION
HC_NOREMOVE
wParam:指示消息的标识;
lParam:指向结构体指针;
五、移除已安装的钩子过程
BOOL UnhookWindowsHookEx( HHOOK hhk );
六、全局钩子
如果要屏蔽当前正在运行的所有进程的鼠标消息和键盘消息,则安装钩子过程的SetWindowsHookEx函数代码必须放到动态链接库中实现,且将SetWindowsHookEx函数的第三个参数指定为安装钩子过程所在的DLL的句柄,将第四个参数设为0;
以上是关于HOOK编程流程的主要内容,如果未能解决你的问题,请参考以下文章
利用C++编程,将hook(钩子)加到程序每一个函数,其中hook后跳转到自己自定义函数代码,实现函数打印功能
VSCode自定义代码片段15——git命令操作一个完整流程