hook技术需要了解windows消息机制吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hook技术需要了解windows消息机制吗相关的知识,希望对你有一定的参考价值。

钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程序,window消息或特定事件。钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。ZG电力自动化9 e" g# T' Z3 Y3 T" I* EZG电力自动化,变电检修,继电保护,远动通信,电力技术,高压试验,输电线路,变电运行,整定计算,规章规程,电力论坛,电力技术,高压实验,电网,供电局,供电公司,电业局. J! l- f+ . ^* H' o+ 3 u/ Q& _: _: W- F$ P HZG电力自动化不仅为电力职工提供一个可以交流的网络平台而且也为电力技术的爱好者和电力大中专学生提供一个可以展现自我的一个舞台。这个平台与传统知识交流平台相比具有:获取信息速度快,信息量大,互动性强,成本低。这几个特性是传统知识交流平台所不具备的。ZG电力自动化就是要利用这种互动方式为大家铺设桥梁,使各位朋友的技术共同进步、提高!可能上面的官方定义对一部分读者理解有点困难,ZG电力自动化,变电检修,继电保护,远动通信,电力技术,高压试验,输电线路,变电运行,整定计算,规章规程,电力论坛,电力技术,高压实验,电网,供电局,供电公司,电业局6 & e8 W" X3 w1 P( \# Z4 ) P8 Y其实,钩子就像是一切程序的“先知”,一个实现了钩子的程序自身虽然也是普通程序,但是它总能在别的程序得到数据之前就已经知道了一切,这是为什么呢?对Windows系统有一定了解的读者应该知道, Windows系统是一个通过“信息处理机制”运作的系统,在这个系统里传递的数据都是通过“消息”(Message)的形式发送的,各个消息都遵循了官方的约定,否则就不能让系统产生回应。而且这个传递步骤是颠倒的,例如我们关闭了某个程序,我们可能会认为是程序自己关闭后通知系统的,其实不然,当用户点击关闭按钮的时候,Windows就会把一个叫做WM_CLOSE的消息传递给这个程序,程序接收到消息后就执行卸载自身例程的操作。理解了这点,就能知道钩子的原理了,所谓钩子程序,就是利用了系统提供的Hook API,让自己比每一个程序都提前接收到系统消息,然后做出处理,如果一个钩子拦截了系统给某个程序的WM_CLOSE消息,那么这个程序就会因为接收不到关闭消息而无法关闭自身。除了消息以外,钩子还可以拦截API,像我们都熟悉的屏幕翻译软件就是Hook了一些文本输出函数如TextOutA而达到了目的。 Hook技术让编程人员可以轻松获取其他程序的一些有用数据或传递相关数据,像现在常见的一些游戏外挂,它们就是利用Hook技术钩住了游戏窗体,然后就可以识别游戏里面的行为和模拟发送按键鼠标消息,最终实现电脑自己玩游戏的功能。把这个技术应用到浏览器上面,就成了另一种控制浏览器行为的方法。! E6 C: k0 T* z: l9 [ 1 i& `7 H( ~" + b! O: w1 ^钩子有两种,本地钩子(Local Hook)和全局钩子(Global Hook),本地钩子只在本进程里起作用,故不属于讨论范围;全局钩子代码必须以DLL形式编写,以便在钩子生效时被其它进程所加载调用,因此我们看到的大部分Hook程序都是DLL形式的。$ V' [0 u7 o8 : Z5 h6 6 o3 pZG电力自动化,变电检修,继电保护,远动通信,电力技术,高压试验,输电线路,变电运行,整定计算,规章规程,电力论坛,电力技术,高压实验,电网,供电局,供电公司,电业局! R. V( y* f: E! q) C% e其实之前提到的BHO也可以视为一种针对IE的钩子,它钩的是IE的事件,这就是IE与BHO交互的起点,但是对于再复杂一点的操作,例如判断 IE下载的是GIF图片还是JPEG图片,BHO无能为力,因为它仅仅知道IE的事件为DownloadBegin和DownloadComplete,对于具体内容,IE本身是不会告诉它的,否则IE岂不是要忙死了?至少我也没见过哪个领导还需要向秘书汇报中午吃了鸡肉还是鸭肉的吧,BHO可不是IE的老婆,或者说IE没有气管炎。 所以,为了得到IE的更多数据,程序员开始钩IE了。# V) g2 q0 y7 Z- K2 z' L" z/ n+ PZG电力自动化不仅为电力职工提供一个可以交流的网络平台而且也为电力技术的爱好者和电力大中专学生提供一个可以展现自我的一个舞台。这个平台与传统知识交流平台相比具有:获取信息速度快,信息量大,互动性强,成本低。这几个特性是传统知识交流平台所不具备的。ZG电力自动化就是要利用这种互动方式为大家铺设桥梁,使各位朋友的技术共同进步、提高!* ) m1 f6 X; F4 o( F+ C; b与BHO不同,钩子不需要被动的等待IE事件,它直接和IE形成上司对下属的关系,这次轮到IE要做什么都得经过它批准了。Hook形式的控制不需要DLL文件必须与IE的注册表入口产生组件关系,它可以是一个独立的DLL,通过 Rundll32.exe或自带的Loader EXE启动,而且由于它属于Hook形式,在钩子有效的情况下会被系统自动插入其他程序的进程中,是不是有点像DLL木马呢? IE钩子程序载入进程后便能获知所有的消息类型、API和内容,一旦发现某个符合要求的消息,如IE执行了某个事件,或者用户输入了特定内容,钩子的处理代码就开始工作了,它先拦截系统发送给IE的消息,然后分析消息内容,根据不同消息内容作出修改后再发给IE,就完成了一次Hook篡改过程。$ V# U4 u5 U' zZG电力自动化8 Z$ Y/ E& N/ @: L$ @* B用著名的3721实名搜索做例子,一些人会以为它是采用了BHO或者IURLSearchHook完成中文域名的识别跳转的,其实它是用了能够第一个得到 Windows消息的Hook技术,这样一来就可以避免被其他的竞争对手抢先解析域名了:3721的主程序就是一个Hook DLL,它监视IE地址栏的消息,一旦用户输入的是中文,它便在其他BHO类插件工作之前拦截了这个消息,并调用自身代码完成中文域名到英文URL的转换工作,然后返回(也可能与自己的BHO DLL配合)一个让IE跳转到英文URL的消息,完成域名的翻译任务。 IE钩子能帮助程序员用少量代码完成更多的IE交互工作,但是一旦这个钩子被用于犯罪,其后果也是严重的,恶意程序员可以写一个拦截IE输入的键盘钩子,达到窃取密码的作用,这样无论你是用HTTP明文协议还是SecurityHTTP加密协议都不能逃避密码被盗的下场了,因为它抓的是你在IE 里的输入,后面的数据传输已经不重要了。 参考技术A Windows系统是一个消息驱动的OS,什么是消息呢?很难下一个定义,下面从不同的几个方面讲解一下:

1、消息的组成:一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)。当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。例如当菜单转中之后会有WM_COMMAND消息发送,WPARAM的高字中(HIWORD(wParam))是命令的ID号,对菜单来讲就是菜单ID。当然用户也可以定义自己的消息名称,也可以利用自定义消息来发送通知和传送数据。

2、谁将收到消息:一个消息必须由一个窗口接收。在窗口的过程(WNDPROC)中可以对消息进行分析,对自己感兴趣的消息进行处理。例如你希望对菜单选择进行处理那么你可以定义对WM_COMMAND进行处理的代码,如果希望在窗口中进行图形输出就必须对WM_PAINT进行处理。

3、未处理的消息到那里去了:M$为窗口编写了默认的窗口过程,这个窗口过程将负责处理那些你不处理消息。正因为有了这个默认窗口过程我们才可以利用Windows的窗口进行开发而不必过多关注窗口各种消息的处理。例如窗口在被拖动时会有很多消息发送,而我们都可以不予理睬让系统自己去处理。

4、窗口句柄:说到消息就不能不说窗口句柄,系统通过窗口句柄来在整个系统中唯一标识一个窗口,发送一个消息时必须指定一个窗口句柄表明该消息由那个窗口接收。而每个窗口都会有自己的窗口过程,所以用户的输入就会被正确的处理。例如有两个窗口共用一个窗口过程代码,你在窗口一上按下鼠标时消息就会通过窗口一的句柄被发送到窗口一而不是窗口二。

5、示例:下面有一段伪代码演示如何在窗口过程中处理消息

LONG yourWndProc(HWND hWnd,UINT uMessageType,WPARAM wP,LPARAM)

switch(uMessageType)
//使用SWITCH语句将各种消息分开
case(WM_PAINT):
doYourWindow(...);//在窗口需要重新绘制时进行输出
break;
case(WM_LBUTTONDOWN):
doYourWork(...);//在鼠标左键被按下时进行处理
break;
default:
callDefaultWndProc(...);//对于其它情况就让系统自己处理
break;

参考技术B 需要的,即使是hook系统api也要了解

Windows Hook链机制详解

Windows Hook链

本文是Windows hook系列的一文。
上一文:《手把手教你用SetWindowsHookEx做一个键盘记录器》.
是本文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子程。

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来传递它,以执行钩子链表所指的下一个钩子子程。这个函数成功时返回钩子链中下一个钩子过程的返回值, 返回值的类型依赖于钩子的类型。

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

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

卸载Hook

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

UnHookWindowsHookEx
(
	HHOOK hhk;
);

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

系统钩子和线程钩子

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

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

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

几点说明:

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

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

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

思考题

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

以上是关于hook技术需要了解windows消息机制吗的主要内容,如果未能解决你的问题,请参考以下文章

HOOK技术

hook是啥意思

Hook(钩子技术)基本知识讲解,原理

钩子(hook)编程

编程中常说的hook是啥意思?

钩子教程 - 原理