mfc防止键盘钩子_Windows 网络编程:钩子函数

本文介绍了Windows钩子函数的工作原理和应用,包括局部与全局钩子的区别,以及如何通过DLL文件实现全局键盘钩子。通过实例展示了如何创建一个DLL,实现在目标进程中注入DLL并捕获键盘输入。最后提到了WH_GETMESSAGE钩子在DLL注入中的作用。
摘要由CSDN通过智能技术生成

一次性进群,长期免费索取教程,没有付费教程。

教程列表见微信公众号底部菜单

进微信群回复公众号:微信群;QQ群:460500587


9c39aa701e6098779955e4dbab9bfe7d.png

微信公众号:计算机与网络安全

ID:Computer-network

钩子函数是Windows消息处理机制的一部分,通过设置“钩子”,应用程序可以在系统级对所有消息、事件进行过滤,访问在正常情况下无法访问的消息。钩子的本质是一段用以处理系统消息的程序,通过系统调用,把它挂入系统。

WINDOWS的钩子函数可以认为是WINDOWS的主要特性之一。利用它们,您可以捕捉您自己进程或其它进程发生的事件。通过“钩挂”,您可以给WINDOWS一个处理或过滤事件的回调函数,该函数也叫做“钩子函数”,当每次发生您感兴趣的事件时,WINDOWS都将调用该函数。

一、钩子原理

Windows下的应用程序大部分是基于消息模式机制的,一些CUI的程序不是基于消息的。Windows下的应用程序都有一个消息函数,根据不同的消息来完成不同的功能。Windows操作系统提供的钩子机制的作用是用来截获、监视系统中的消息的。Windows操作系统提供了很多不同种类的钩子,不同的钩子可以处理不同的消息。

钩子分为局部钩子和全局钩子。局部钩子是针对一个线程的,而全局钩子则是针对整个操作系统内基于消息机制的应用程序的。全局钩子需要使用DLL文件,DLL文件里存放了钩子函数的代码。

在操作系统中安装了全局钩子以后,只要进程接收到可以发出钩子的消息后,全局钩子的DLL文件会被操作系统自动或强行地加载到该进程中。由此可见,设置消息钩子也是一种可以进行DLL注入的方法。

二、钩子函数

上面简单地讲述了Windows钩子的基本原理,现在来学习一下Windows下的钩子函数,主要有3个,分别是SetWindowsHookEx()、CallNextHookEx()和UnhookWindowsHookEx()。下面介绍这些函数的使用方法。

0227d68b60f729a50410fcccfbd0e7a8.png

该函数的返回值为一个钩子句柄。这个函数有4个参数,下面分别进行介绍。

(1)lpfn:该参数指定为Hook函数的地址。如果dwThreadId参数被赋值为0,或者被设置为一个其他进程中的线程ID,那么lpfn则属于DLL中的函数过程。如果dwThreadId为当前进程中的线程ID,那么lpfn可以是指向当前进程中的函数过程,也可以是属于DLL中的函数过程。

(2)hMod:该参数指定钩子函数所在模块的模块句柄。该模块句柄就是lpfn所在的模块的句柄。如果dwThreadId为当前进程中的线程ID,而且lpfn所指向的函数在当前进程中,那么hMod将被设置为NULL。

(3)dwThreadId:该参数设置为需要被挂钩的线程的线程ID号。如果设置为0,那么表示在所有的线程中挂钩(这里的所有的线程表示基于消息机制的所有的线程)。如果指定为具体的线程的ID号,那么表示要在指定的线程中进行挂钩。该参数影响上面两个参数的取值,该参数的取值决定了该钩子属于全局钩子,还是局部钩子。

(4)idHook:该参数表示钩子的类型。由于钩子的类型非常多,因此放在所有的参数后面进行介绍。钩子的类型非常多,下面介绍几个常用到的,也可能是大家比较关心的几个钩子类型。

1、WH_GETMESSAGE

安装该钩子的作用是监视被投递到消息队列中的消息。也就是当调用GetMessage()或PeekMessage()函数时,函数从程序的消息队列中获取一个消息后则调用该钩子。WH_GETMESSAGE钩子函数的定义如下:

73207c1bf3a64165163ea4c08ccc0d6f.png

2、WH_MOUSE

安装该钩子的作用是监视鼠标消息。该钩子函数的定义如下:

108999aacbcd64205af729796d54782a.png

3、WH_KEYBOARD

安装该钩子的作用是监视键盘消息。该钩子函数的定义如下:

cb2126ad5a6bb07908c5dfa981ad32b6.png

4、WH_DEBUG

安装该钩子的作用是调试其他钩子的钩子函数。该钩子函数的定义如下:

a2d8c50df96979812e0e58f4754c8349.png

从上面的这些钩子函数定义可以看出,每个钩子函数的定义都是一样的。每种类型的钩子监视、截获的消息不同,虽然它们的定义都是相同的,但是函数参数的意义是不同的。

接着介绍跟钩子有关的函数,UnhookWindowsHookEx(),该函数的定义如下:

4a87f6e7c18ca5356cfa0c230ba72c69.png

这个函数是用来移除先前用SetWindowsHookEx()安装的钩子。该参数只有一个参数,是钩子句柄。也就是用该函数用通过制定的钩子句柄来移除与其相对应的钩子。

在操作系统中,可以多次反复地使用SetWindowsHookEx()函数来安装钩子,而且可以安装多个同样类型的钩子。这样,钩子就会形成一条钩子链,最后安装的钩子会首先截获到消息,当该钩子对消息处理完毕以后,会选择返回,或者选择把消息继续传递下去。在通常情况下,为了消息可以传达到目标窗口,我们会选择将消息继续传递,使消息能继续传递的函数的定义如下:

52fb5b6a5cd0bd13e766a179741c9ce7.png

该函数有4个参数,第一个参数是钩子句柄,就是SetWindowsHookEx()函数的返回值。后面3个参数是钩子函数的参数,直接抄过来即可。例如:

dea149ac1a7216be71c2fc6e846f8be1.png

三、键盘钩子实例

下面来写一个可以截获键盘消息的钩子程序,这个程序的功能非常简单,就是把按下的键对应的字符显示出来。既然要截获键盘消息,那么肯定是截获系统范围内的键盘消息,因此需要安装全局钩子,这样就需要DLL文件的支持。先来新建一个DLL文件,在该DLL文件中,需要定义两个导出函数和两个全局变量,定义如下:

aa3f036c9f4ea6f0f2e16ab696762d41.png

在DllMain()函数中,需要保存该DLL模块的句柄,以方便安装全局钩子。代码如下:

5fcabbb012d7d62958b6990327183738.png

安装与卸载钩子的函数如下:

d0369c4ab422947b2fd1c4eb53594226.png

对于Windows钩子来说,上面的这些步骤基本上都是必须有的,或者是差别不大的,关键在于钩子函数。这里是为了获取键盘按下的键,钩子函数如下:

322a19ad322776c0c712ad547fbb1e5b.png

关于钩子函数,这里简单地解释一下,首先是进入钩子函数的第一个判断。

258193daa079d2e8b555fbc661370e74.png

如果code的值小于0,则必须调用CallNextHookEx(),将消息继续传递下去,不对该消息进行处理,并返回CallNextHookEx()函数的返回值。这一点是MSDN上要求这么做的。

f889f182fbb639c635e40a3a8666dc78.png

如果code等于HC_ACTION,表示消息中包含按键消息,如果为WM_KEYDOWN,则显示按键对应的文本。

将该DLL文件编译连接。为了测试该DLL文件,新建一个MFC的Dialog工程,添加两个按钮,如图1所示。

3d9b3bfd93a17c038ca3451f1609e067.png

图1  键盘钩子的测试程序

分别对这两个按钮添加代码,如下:

c86d0e428c60533949e8c13ac1a95617.png

直接调用DLL文件导出这两个函数,不过在使用之前要先对这两个函数进行声明,否则编译器因无法找到这两个函数的原型而导致连接失败。定义如下:

5b9c196b07b7537e95964d24f28754b7.png

进行编译连接,提示出错,出错内容如下:

5242dc6f1ca8b144f7b814a5570e4809.png

从给出的提示可以看出是连接错误,是找不到外部的符号。将DLL编译连接后生成的DLL文件和LIB文件都复制到测试工程的目录下,并将LIB文件添加到工程中。在代码中添加如下语句:

#pragma comment (lib, KeyBoradHookTest)

再次连接,成功!

运行测试程序,并单击“HookOn”按钮,随便按下键盘上的任意一个键,会出现提示对话框,如图2所示。

0d05ab69c3741cf83a69cbfcf175a243.png

图2  截获到的键盘输入

从图2中可以看出,当我们按下键盘上的按键时,程序将捕获到我们的按键。到此,键盘钩子的例子程序就完成了。

四、使用钩子进行DLL注入

Windows提供的钩子类型非常多,其中有一种类型的钩子非常实用,那就是WH_GETMESSAGE这个类型的钩子。它可以很方便地将DLL文件注入到所有的基于消息机制的程序中。

在有些情况下,需要DLL文件完成一些功能,但是完成功能时需要DLL在目标进程的空间当中。这时,就需要使用WH_GETMESSAGE这个消息把DLL注入到目标的进程中。代码非常简单,这里直接给出DLL文件的代码,代码如下:

2a870fcca1f023a32b63fda834badfdb.png

自己要实现功能的代码:

d28ca4e98908cff4f112e661fd1d6abb.png

整个代码就是这样,只要大家知道,在需要DLL大范围的注入到基于消息的进程中时可以使用这种方法。

微信公众号:计算机与网络安全

ID:Computer-network

【推荐书籍】
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值