首页
论坛
课程
招聘
Windows hook链相关学习
2021-10-14 22:22 4208

Windows hook链相关学习

2021-10-14 22:22
4208

Windows Hook链

本文是Windows hook系列的一文。

引入

hook是Windows操作系统消息处理机制的一个平台,应用程序可以通过设置Hook对某个进程或窗口进行监视,即对特定事件“挂钩”;

 

一旦预定义特定事件发生,Windows操作系统即会向钩子hook发送通知消息,这时,应用程序可进行响应。

 

HOOK的处理主要有以下三个阶段:

 

阶段1:定义Hook;

 

阶段2:在Hook链表中传递Hook;

 

阶段3:卸载Hook。

 

今天主要学习第二阶段的 HOOK链

HOOK链

我一直以来的方法论,就是学习一个东西,要搞清楚五件事情:

 

1.它是什么?

 

2.它的作用是什么?

 

3.它怎么使用?

Hook链是什么?

每一个Hook都有一个与之相关联的指针列表,称之为钩子链表,由系统来维护。

 

这个列表的指针指向指定的,应用程序定义的。

Hook链的作用

被Hook子程调用的回调函数,也就是该钩子的各个处理子程。当与指定的Hook类型关联的消息发生时,系统就把这个消息传递到Hook子程。一些Hook子程可以只监视消息,或者修改消息,或者停止消息的前进,避免这些消息传递到下一个Hook子程或者目的窗口。最近安装的钩子放在链的开始,而最早安装的钩子放在最后,也就是后加入的先获得控制权。

Hook链怎么使用

Windows 并不要求钩子子程的卸载顺序一定得和安装顺序相反。每当有一个钩子被卸载,Windows 便释放其占用的内存,并更新整个Hook链表。如果程序安装了钩子,但是在尚未卸载钩子之前就结束了,那么系统会自动为它做卸载钩子的操作。

 

hook链并不单独使用,需要hook的安装与释放

hook安装

使用API函数SetWindowsHookEx()把一个应用程序定义的钩子子程安装到钩子链表中。SetWindowsHookEx函数总是在Hook链的开头安装Hook子程。当指定类型的Hook监视的事件发生时,系统就调用与这个Hook关联的Hook链的开头的Hook子程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
HHOOK SetWindowsHookEx(
     int idHook,      // 钩子的类型,即它处理的消息类型
     HOOKPROC lpfn,   // 钩子子程的地址指针。如果dwThreadId参数为0
               // 或是一个由别的进程创建的线程的标识,
               // lpfn必须指向DLL中的钩子子程。
               // 除此以外,lpfn可以指向当前进程的一段钩子子程代码。
               // 钩子函数的入口地址,当钩子钩到任何消息后便调用这个函数。
     HINSTANCE hMod,  // 应用程序实例的句柄。标识包含lpfn所指的子程的DLL。
               // 如果dwThreadId 标识当前进程创建的一个线程,
               // 而且子程代码位于当前进程,hMod必须为NULL。
               // 可以很简单的设定其为本应用程序的实例句柄。
     DWORD dwThreadId // 与安装的钩子子程相关联的线程的标识符。
               // 如果为0,钩子子程与所有的线程关联,即为全局钩子。
                 );

CallNextHookEx()

实现传递Hook,具体解释如下:(MSDN定义链接:CallNextHookEx function

 

在钩子子程中调用得到控制权的钩子函数在完成对消息的处理后,如果想要该消息继续传递,那么它必须调用另外一个 SDK中的API函数CallNextHookEx来传递它,以执行钩子链表所指的下一个钩子子程。这个函数成功时返回钩子链中下一个钩子过程的返回值, 返回值的类型依赖于钩子的类型。

1
2
3
4
5
6
7
LRESULT CallNextHookEx
            (
                HHOOK hhk;
                int nCode;
                WPARAM wParam;
                LPARAM lParam;
             );
  • hhk为当前钩子的句柄,由SetWindowsHookEx()函数返回。
  • NCode为传给钩子过程的事件代码。
  • wParam和lParam 分别是传给钩子子程的wParam值,其具体含义与钩子类型有关。

这里留一个问题:如果没有CallNextHookEx(),hook机制会怎么样?

卸载Hook

钩子在使用完之后需要用UnHookWindowsHookEx()卸载,否则会造成麻烦。释放钩子比较简单,UnHookWindowsHookEx()只有一个参数。函数原型如下:

1
2
3
4
UnHookWindowsHookEx
(
    HHOOK hhk;
);

函数成功返回TRUE,否则返回FALSE。

系统钩子和线程钩子

SetWindowsHookEx()函数的最后一个参数决定了此钩子是系统钩子还是线程钩子。

 

线程勾子用于监视指定线程的事件消息。线程勾子一般在当前线程或者当前线程派生的线程内。

 

系统勾子监视系统中的所有线程的事件消息。因为系统勾子会影响系统中所有的应用程序,所以勾子函数必须放在独立的动态链接库(DLL) 中。系统自动将包含"钩子回调函数"的DLL映射到受钩子函数影响的所有进程的地址空间中,即将这个DLL注入了那些进程。

 

几点说明:

 

(1)如果对于同一事件(如鼠标消息)既安装了线程勾子又安装了系统勾子,那么系统会自动先调用线程勾子,然后调用系统勾子。

 

(2)对同一事件消息可安装多个勾子处理过程,这些勾子处理过程形成了勾子链。当前勾子处理结束后应把勾子信息传递给下一个勾子函数。

 

(3)勾子特别是系统勾子会消耗消息处理时间,降低系统性能。只有在必要的时候才安装勾子,在使用完毕后要及时卸载。

思考题

是否可以根据Hook链的先后顺序,来实现AntiHook,欢迎交流。


【公告】 讲师招募 | 全新“预付费”模式,不想来试试吗?

收藏
点赞1
打赏
分享
最新回复 (1)
雪    币: 70
活跃值: 活跃值 (622)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hixhi 活跃值 2021-10-15 07:45
2
0
思考题:可以参考wegame的登录保护。
游客
登录 | 注册 方可回帖
返回