windows内核开发学习笔记二十一:补充基本概念的学习——钩子函数

windows内核开发学习笔记二十一:补充基本概念的学习——钩子函数

    Windows操作系统是建立在事件驱动的消息处理机制之上,系统各部分之间的沟通也都是通过消息的相互传递而实现的。 钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。通常情况下,应用程序只能处理当前进程的消息,如果需要对其它进程的消息进行拦截处理就必须采钩子技术。

一、 钩子的概念(what)
钩子实际上是一段用以处理系统消息的程序(钩子函数),通过系统调用,将其挂入到系统。每当特定的消息发出,在没有到达目标窗口前,钩子程序就先捕获该消息,即钩子函数先得到控制权。在钩子函数中,可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。钩子函数是一个应用程序定义的回调函数,不能定义成某个类的成员函数,只能定义为普通的C函数。
二、钩子链表?(what)
系统提供多种不同类型的钩子用于处理不同的消息。在某一时刻可能有多个进程安装了相同类型的钩子,即同一种钩子有多个不同的钩子处理函数。这多个不同的钩子处理函数的指针构成了钩子链表,由操作系统维护。当某种类型的消息发生时系统向该类型的钩子链表的第一个函数发送该消息,在第一函数处理完该消息后由该函数向链表中的下一个函数传递消息,依次向下。如果链中某个函数没有向下传送该消息,那么链表中后面的函数将得不到此消息。(对于某些类型的钩子,不管钩子链中的函数是否向下传递消息,与此类型钩子关联的所有钩子函数都会收到系统发送的消息)最近安装的钩子放在链的开始,而最早安装的钩子放在最后,也就是后加入的先获得控制权。系统并不要求钩子子程的卸载顺序一定得和安装顺序相反。每当有一个钩子被卸载,系统便释放其占用的内存,并更新整个钩子链表。如果应用程序安装了钩子,但是在尚未卸载钩子之前就结束了,那么系统会自动卸载钩子。
三、 钩子的作用范围(where)
   一共有两种范围(类型)的钩子:局部的和远程的。
   1.局部钩子仅钩挂您自己进程的事件。 
   2.远程的钩子还可以将钩挂其它进程发生的事件。 
   远程的钩子又有两种:
   2.1 基于线程的它将捕获其它进程中某一特定线程的事件。简言之,就是可以用来观察其它进程中的某一特定线程将发生的事件。 
   2.2系统范围的将捕捉系统中所有进程将发生的事件消息。

四 钩子的使用步骤(How)
   1 安装钩子
     SetWindowsHookEx函数可以把应用程序定义的钩子函数安装到系统中。
     HHOOK SetWindowsHookEx(
       int idHook ;   // 指定钩子的类型
       HOOKPROC lpfn; //钩子函数的地址。如果是远程钩子,钩子函数必须放在一个DLL中。
       HINSTANCE hMod; // 钩子函数所在的DLL的实例句柄。局部的钩子,该参数为NULL。
       DWORD  dwThreadID; //指定要为哪个线程安装钩子。若该值为0被解释成系统范围内的。
     );

   2 定义钩子函数
     钩子函数的一般形式如下:
     LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
       // 处理该消息的代码 …..
 
       Return ::CallNextHookEx(hHook,nCode,wParam,lParam);
    }
    HookProc是钩子函数的名称。nCode参数是Hook代码,钩子函数使用这个参数来确定任务,它的值依赖于Hook的类型。wParam和lParam参   数的值依赖于Hook代码,但是它们典型的值是一些关于发送或者接收消息的信息。因为系统中可能会有多个钩子的存在,所以要调用那个    CallNextHookEx函数把消息传到链中下一个钩子函数。hHook参数是安装钩子时得到的钩子句柄(SetWindowsHookEx的返回值)。

   3 卸载钩子 
    要卸载钩子,可以调用UnhookWindowsHookEx函数。
    BOOL UnhookWindowsHookEx(HHOOK hhk); // hhk 为要卸载的钩子的句柄
    注意:
    安装钩子的代码可以在DLL模块中,也可以在主模块中,但是一般在DLL里实现它,主要是为了使程序更加模块化。
五、 钩子总结
1.钩子是用截获系统中的消息流。利用钩子,可以处理任何感兴趣的消息,包括其他进程的消息。
2.截获消息后,用于处理消息的子程序叫做钩子函数,它是应用程序自定义的一个函数,在安装钩子时要把这个函数的地址告诉系统。
3.在操作系统中,同一时间可能有多个进程安装了同一种类型的钩子,即会有多个钩子函数,多个钩子函数在一起组成钩子链。所以在处理截获到的消息时,应该把消息事件传递下去,以便其他钩子函数也有机会处理这一消息。
4.钩子会使得系统变慢,因为它增加了系统对每个消息的处理量。仅应该在必要时才安装钩子,而且在不需要时应尽快移除。

5. 如果指定确定的线程,即为线程专用钩子;如果指定为空,即为全局钩子。其中,全局钩子函数必须包含在DLL(动态链接库)中,而线程专用钩子还可以包含在可执行文件中。得到控制权的钩子函数在完成对消息的处理后,如果想要该消息继续传递,那么它必须调用另外一个SDK中的API函数CallNextHookEx来传递它。钩子函数也可以通过直接返回TRUE来丢弃该消息,并阻止该消息的传递。

 6.钩子函数是回调函数的一个特例。习惯上把与 SetWindowsHookEx 函数一起使用的回调函数称为钩子函数。也有人把利用 VirtualQueryEx 安装的函数称为钩子函数,不过这种叫法不太流行。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jyl_sh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值