首页
社区
课程
招聘
hook学习:使用SetWindowsHookEx实现一个简单的键盘记录器
发表于: 2021-9-8 22:57 21145

hook学习:使用SetWindowsHookEx实现一个简单的键盘记录器

2021-9-8 22:57
21145

“无忌,我教你的还记得多少?”
“回太师傅,我只记得一大半。”
“那,现在呢?”
“已经剩下一小半了。”
“那,现在呢?”
“我已经把所有的全忘记了!”
“好,你可以上了!”

羡慕张无忌,忘记了武功,打败了敌人;而我自己,忘记了武功,菜哭了自己。

已经一年多没有接触这个了,忘得干干净净,幸亏肌肉记忆还在,学起来十分亲切,废话不多说,进入正题。

Hook是程序设计中最为灵活多变的技巧之一,在windows下,Hook有两种含义:
1、系统提供的消息Hook机制,也就是我们今天要实现的hook,在后面会讲到。
2、自定义的Hook编程技巧

​ 自定义的Hook编程技巧则是基于特定系统结构、文件结构、汇编语言的一种高级技术,运用自如后犹如手握屠龙刀倚天剑。

操作环境:

visual studio 2015

Windows 10

Windows消息hook主要通过SetWindowsHookEx去下钩,通过UnhookWindowsHookEx()去断钩,所以我们接下来主要学会用这俩个函数。

我们之所以可以进行消息Hook,是因为Windows的消息机制;简单来说:

Windows系统是建立在事件驱动的机制上的,每一个事件就是一个消息,每个运行中的程序,也就是所谓的进程,都维护者一个或多个消息队列,消息队列的个数取决于进程内包含的线程的个数。由于一个进程至少要拥有一个线程,所以进程至少要有一个消息队列。虽然Windows系统的消息分派是以线程为单位的,但并不是所有的线程都有消息队列,一个新创建的线程是没有消息队列的,只有当线程第一次调用GDI或USER32库函数的时候Windows才为线程创建消息队列。消息最终由属于线程的窗口来处理,普通的应用程序只能获取本线程的消息队列中的消息,也就是只能获得系统分派的、属于本线程的消息,换句话说,一个线程在运行过程中是不知道其它线程发生了什么事情的。但是有一类特殊的程序却可以访问其他线程的消息队列,那就是钩子程序。

(Windows消息机制还是十分重要的,这里我不多赘述,了解这些内容,足够咱们接下来的学习了,想要了解更多,建议看这篇文章https://zhuanlan.zhihu.com/p/42992978)

编写钩子程序是Windows系统提供给用户的一种对Windows运行过程进行干预的机制,通过钩子程序,Windows将内部流动的消息暴露给用户,使用户能够在消息被窗口管理器分派之前对其进行特殊的处理,比如在调试程序的时候跟踪消息流程。但是,任何事情都有其两面性,一些密码窃取工具就是利用系统键盘钩子截获其他程序的键盘消息,从而获取用户输入的密码,可见非法的钩子程序对计算机信息安全具有极大的危害性。

(那么我们今天就通过消息hook实现一个简单的键盘记录器,嘿嘿,知己知彼,百战不殆)!

第一步:安装钩子(钩子链)

最后一步:卸载钩子

中间步骤:我们要实现回调函数,实现我们自己的操作。例如获得键盘输入信息,并将其保存到txt文件中

当按下键盘,产生一个消息,按键消息加入到系统消息队列 操作系统从消息队列中取出消息,添加到相应的程序的消息队列中 ;

应用程序使用消息Hook从自身的消息队列中取出消息WM_KEYDOWN,调用消息处理函数。 我们可以在系统消息队列之间添加消息钩子,从而使得在系统消息队列消息发给应用程序之前捕获到消息。

可以多次添加钩子,从而形成一个钩子链,可以依次调用函数。

SetWindowsHookEx

能设置的hook类型如下:

我们这里hook键盘消息:

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

为钩子链中的下一个子程序设置钩子。在钩子子程中调用得到控制权的钩子函数在完成对消息的处理后,如果想要该消息继续传递,那么它必须调用另外一个 SDK中的API函数CallNextHookEx来传递它,以执行钩子链表所指的下一个钩子子程。

卸载钩子API,钩子在使用完之后需要用UnhookWindowsHookEx()卸载,否则会造成麻烦。

主要的功能我们通过SetwindowsHookEx()参数中的回调函数HookProcedure()来实现。

在里面我们会实现获得256个虚拟键的状态,并将其转换为真实字符
图片描述

输出:这里我们写了俩种方式

1.输出到控制台

2.输出到文本,并保存

获得当前窗口和当前时间;

将记录的键盘消息保存到文件中;

x86效果:

图片描述

x64位

图片描述

保存在txt文件中

图片描述

github下载,可直接使用,或修改测试
windows hook

【windows核心编程】系统消息与自定义钩子(Hook)使用

HOOK教程一_使用SetWindowsHookEx进行Windows消息HOOK

这个技术可能已经过时,但是学习它的目的,主要是想让自己静下心来,脚踏实地,逐步向着更高深的技术探索,成为一个牛逼的人;另一方面总结出来,也是因为发现网上搜到的大部分资料都是08年左右的文章,不太适合阅读,总结出来,也希望可以帮到有需要的人。

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
WINUSERAPI
HHOOK
WINAPI
SetWindowsHookEx(
     //钩子类型
    _In_ int idHook,
    //回调函数地址
    _In_ HOOKPROC lpfn,
    //实例句柄(包含有钩子函数)
    _In_opt_ HINSTANCE hmod,
    //线程ID,欲勾住的线程(为0则不指定,全局)
    _In_ DWORD dwThreadId);
WINUSERAPI
HHOOK
WINAPI

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2021-9-8 23:19 被大碗宽面编辑 ,原因:
收藏
免费 3
支持
分享
最新回复 (5)
雪    币: 1861
活跃值: (1173)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
做了最简单的SetWindowsHookEx之后,有几件事情也想做一下:
消息hook用来防护,有什么好的用处?
怎么检查和对抗全局Hook,同时并不影响正常的消息Hook?
希望师傅们给点思路
2021-9-8 23:03
0
雪    币: 1861
活跃值: (1173)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
大碗宽面 做了最简单的SetWindowsHookEx之后,有几件事情也想做一下: 消息hook用来防护,有什么好的用处? 怎么检查和对抗全局Hook,同时并不影响正常的消息Hook? 希望师傅们给点思路 ...
网上的方案大多对抗的是利用setwindowshookex的dll注入,通过拦截loadlibrary(),不太适合直接的hook
2021-9-8 23:22
0
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
楼主漏了vld.h头文件吧
2021-9-10 09:04
0
雪    币: 5144
活跃值: (9652)
能力值: ( LV9,RANK:181 )
在线值:
发帖
回帖
粉丝
5
感觉是有点缺雪币了!!!
2021-9-10 09:12
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
666666
2022-11-26 08:40
0
游客
登录 | 注册 方可回帖
返回
//