Author:快来救救我
ps:快乐废宅
文章目录
- 前言
- 一、钩子函数(Hook)是什么?
- 理解:
- 特点:
- 举例
- 钩子类型
- 钩子程序组成部分
- 钩子操作流程
- 钩子函数的回调函数
- 最后
- 三、参考文章
前言
我看了其他博客有些对钩子函数讲述的篇幅要不太长,要不太短,所以我打算写一个中等篇幅的,易于看完也能对它大体概况。我也会在后面附上参考的其他人的博客,想要看简短或者详细的,可以点击链接去看。
在开发当作有碰见过几次钩子函数但是一直对这个没有什么概念,所以特意来了解了解,如若有理解错误,请再底下评论,后续会持续更改~
一、钩子函数(Hook)是什么?
理解:
钩子函数是在系统在进行消息的传递处理时候利用钩子机制截取消息,可以对一些特定的消息进行处理。
像一些系统的开发功能可以基于消息处理机制,对消息进行初始化、动态创建分配空间,然后转发消息,对各个模块的消息进行实时监听,而钩子函数就是监听消息在传递到制定的模块窗口时候的操作,如果消息没有满足条件,钩子函数就可以把它进行处理然后让它无法最后成功达到目的地。如果满足了条件,就可以继续往后面传递。
特点:
1、是个函数,在系统消息触发时被系统调用
2、不是用户自己触发的
3、使用时直接编写函数体
4、钩子函数的名称是确定的,当系统消息触发,自动会调用。
举例
在window系统里,对键盘的获取,鼠标输入、屏幕取词等都是利用了钩子函数来实现。
钩子类型
创建钩子函数:
当创建一个钩子函数时,WINDOWS会先在内存中创建一个数据结构,该数据结构包含了钩子的相关信息,然后把该结构体加到已经存在的钩子链表中去。新的钩子将加到老的前面。
钩子类型分为
- 局部:仅钩挂自己进程的事件。
- 远程:钩挂其它进程发生的事件。
远程钩子分为:
1.系统级的全局钩子,
2.线程级的钩子
系统级的全局钩子
系统范围的 将捕捉系统中所有进程将发生的事件消息。
全局钩子函数需要定义在 DLL(动态链接库) 中,提供设置钩子的方法接口,然后再建立一个新的测试程序,来加载这个dll,调用钩子接口
线程级的钩子
作用范围只是限定在某个进程中,或者某个线程中。
钩子程序组成部分
主程序——用来实现界面或其他功能
钩子回调函数——用来接收系统发过来的消息
钩子的安装和卸载模块
钩子操作流程
1.关于钩子的操作方法都可以从一个函数出发,推导出来:
HHOOKWINAPISetWindowsHookEx(
int idHook,\钩子类型
HOOK PROClpfn,\回调函数地址
HINSTANCE hMod,\实例句柄
DWORD dwThreadId);\线程ID
)
2.idHook指明了要安装钩子的类型:
2.回调函数地址,一般只需写函数名:
回调函数是用来处理消息,一个全局钩子,lpfn参数指向的钩子函数必须位于一个DLL中。这是因为进程的地址空间是相互隔离的,发生事件的进程不能调用其他进程地址空间的钩子函数。如果钩子函数的实现代码在DLL中,在相关事件发生时,系统会把这个DLL插入到发生事件的进程的地址空间,使它能够调用钩子函数,这样就可以作用于系统所有的进程中。
3.hMod是钩子回调函数所在的dll的实例句柄
4.dwThreadId是线程id,用来指定要监控的线程id,全局钩子置0。
钩子函数的回调函数
nCode参数是Hook代码,钩子函数使用这个参数来确定任务,它的值依赖Hook的类型。wParam和lParam参数的值依赖于Hook代码,但是它们典型的值是一些关于发送或者接收消息的信息。
系统中可能会有多个钩子存在,所以要调用CallNextHookEx函数把消息传到链中下一个钩子函数。hHook参数是安装钩子时得到的钩子句柄,也就是SetWindowsHookEx的返回值。我们应该把这个返回值保存在一个全局变量比如g_hook中,供这里使用。
在处理消息的代码中,我们可能会向安装钩子dll的主程序或窗口发送消息。与主窗口通信需要一个messageid,也就是类似于WM_COMMAND的东西。
最后
全局钩子需要写在dll中,核心函数是SetWindowsHookEx,回调函数是主体。数据段需要共享。
不使用钩子的时候,我们使用UnhookWindowsHookEx函数卸载钩子。