Hook基本知识
一、什么是HOOK(钩子)
Windows系统,建立在事件驱动机制上,就是整个系统都是通过消息传递实现的。hook(钩子)是一种特殊的消息处理机制,它可以监视系统或者进程中的各种事件消息,截获发往目标窗口的消息并进行处理。
钩子的种类很多,每种钩子可以截获相应的消息,如键盘钩子可以截获键盘消息,外壳钩子可以截取、启动和关闭应用程序的消息等。钩子可以分为线程钩子和系统钩子,线程钩子可以监视指定线程的事件消息,系统钩子监视系统中的所有线程的事件消息。因为系统钩子会影响系统中所有的应用程序,所以钩子函数必须放在独立的动态链接库(DLL) 中。
所以说,hook(钩子)就是一个Windows消息的拦截机制,可以拦截单个进程的消息(线程钩子),也可以拦截所有进程的消息(系统钩子),也可以对拦截的消息进行自定义的处理。
二、HOOK分类:

1、 Ring3 层的 Hook 基本上可以分为两种大的类型:
第一类即是 Windows 消息的 Hook,第二类则是 Windows API 的 Hook。
消息 Hook 是通过 SetWindowsHookEx 可以实现将自己的钩子插入到钩子链的最前端,
而对于发送给被 Hook 的窗口(也有可能是所有的窗口,即全局 Hook)的消息都会被我们的钩子处理函数所捕获到,
也就是我们可以优先于窗体先捕获到这些消息
(1)进程内消息 Hook:可以简单的将 Hook 处理函数直接写在这个进程内,即是自己 Hook 自己。
(2)全局消息HOOK:
需要将 Hook 处理函数写在一个 DLL 中,这样才可以让你的处理函数被所有的进程所加载(进程自动加载包含 Hook 消息处理函数的 DLL)。
2、Ring0 层的 Hook
(1)SSDT hook,一句话——Windows把需要调用的内核API地址全都保存在一个表中(System Service Dispatch Table),要想hook一个内核API,比较简单的办法就是把该内核API在表(SSDT)中保存的地址修改为自己撰写的函数地址。
(2)HOOK INT 2E 方法:IDT HOOK
IDT是中断描述表,可以替换其中的中断处理程序。
这种方法对于跟踪、分析系统调用来说用的比较多。原理是通过替换 IDT
表中的 INT 2E 中断,使之指向我们自己的中断服务处理例程来实现的。掌握
此方法需要你对保护模式有一定的基础。
(3) HOOK PE 方法:EAT HOOK
这种方法对于拦截、分析其他内核驱动的函数调用来说用的比较多。原理
是根据替换 PE 格式导出表中的相应函数来实现的。
EAT是可执行文件的导出表,记录DLL中可供其他程序使用的函数,可执行文件装载时会使用相应DLL的EAT表来初始化IAT表,通过替换EAT表中的函数地址,就可以使依赖于本DLL的程序得到一个假的地址。
(4)IAT HOOK (ring3 用)
IAT是可执行文件的导入表,记录可执行文件使用的其它DLL中的函数,通过替换IAT表中的函数地址,可以hook相应DLL中的函数调用。
(5)Inline Hook方法 (ring 0和ring3 都可以用)
Inline hook的工作流程:
1)验证内核API的版本(特征码匹配)。
2)撰写自己的函数,要完成以上三项任务。
2)获取自己函数的地址,覆盖内核API内存,供跳转。
Inline Hook的缺点:
1)
不够通用。各个windows版本中,内核API的开始一段不尽相同,要想通吃,就要多写几个版
本或者做一个特征码搜索(因为有的内核API在各个版本中非常相似,只是在“特征码”之前或之
后加一点东西)。
2)
已被一些检测工具列入检测范围,如果直接从内核API第一个字节开始覆盖,那么很容易被检
测,如果把覆盖范围往后推,并加以变形,也许能抵挡一气。具体情况,我才疏学浅,尚未试验
(6)SYSENTRY hook
为了性能的考虑,xp后的系统都改用sysentry命令来进入ring0,去调用SSDT中的服务,不再是通过IDT中的 int 2E。这也使得我们hook也变得相对容易了。
首先获得sysentry的地址,然后改之,不用再考虑IDT了
(7)IRP hook
IRP是 I/O request packets,驱动程序中有一系列分发例程来处理请求,这些例程保存在驱动设备对象的数据结构中的一个表中,也很容易替换。
三、HOOK(钩子)的工作原理
当创建一个钩子时,WINDOWS会先在内存中创建一个数据结构,该数据结构包含了钩子的相关信息,然后把该结构体加到已经存在的钩子链表中去。新的钩子将加到老的前面。当一个事件发生时,如果安装的是一个线程钩子,进程中的钩子函数将被调用。如果是一个系统钩子,系统就必须把钩子函数插入到其它进程的地址空间,要做到这一点要求钩子函数必须在一个动态链接库中。
当然有两个例外:工作日志钩子和工作日志回放钩子。这两个钩子的钩子函数必须在安装钩子的线程中。原因是:这两个钩子是用来监控比较底层的硬件事件的,既然是记录和回放,所有的事件就当然都是有先后次序的。所以如果把回调函数放在DLL中,输入的事件被放在几个线程中记录,所以我们无法保证得到正确的次序。故解决的办法是:把钩子函数放到单个的线程中,譬如安装钩子的线程。
几点需要说明的地方:
(1) 如果对于同一事件(如鼠标消息)既安装了线程钩子又安装了系统钩子,那么系统会自动先调用线程钩子,然后调用系统钩子。
(2) 对同一事件消息可安装多个钩子处理过程,这些钩子处理过程形成了钩子链。当前钩子处理结束后应把钩子信息传递给下一个钩子函数。而且最近安装的钩子放在链的开始,而最早安装的钩子放在最后,也就是后加入的先获得控制权。
(3) 钩子特别是系统钩子会消耗消息处理时间,降低系统性能。只有在必要的时候才安装钩子,在使用完毕后要及时卸载。
Hook基本知识的更多相关文章
- IPVS实现分析
IPVS实现分析 IPVS实现分析 根据LVS官方网站的介绍,LVS支持三种负载均衡模式:NAT,tunnel和direct routing(DR). NAT是通用模式,所有交互数据必须通过均衡器:后 ...
- 20145319 《网络渗透》免考—API拦截技术
20145319 <网络渗透>免考-API拦截技术 概述 本次实验在window环境下进行,主要通过编写hook代码和注入程序,将我们的hook代码通过dll文件的形式注入到目标中,拦截其 ...
- pytest封神之路第五步 参数化进阶
用过unittest的朋友,肯定知道可以借助DDT实现参数化.用过JMeter的朋友,肯定知道JMeter自带了4种参数化方式(见参考资料).pytest同样支持参数化,而且很简单很实用. 语法 在& ...
- 【Hook技术】实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展
[Hook技术]实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展 公司有个监控程序涉及到进程的保护问题,需要避免用户通过任务管理器结束掉监控进程,这里使用 ...
- 学习Hook的必备知识
1.汇编 2.API 3.内存 4.进程 5.窗口 必须熟悉的汇编指令: PUSH 入栈 MOV 赋值 JMP(JNZ JE) 跳转 CALL 调用函数 RET 返回 Cmp 比较 T ...
- INLINE HOOK过简单驱动保护的理论知识和大概思路
这里的简单驱动保护就是简单的HOOK掉内核API的现象 找到被HOOK的函数的当前地址在此地址处先修改页面保护属性然后写入5个字节.5个字节就是一个简单的JMP指令.这里说一下JMP指令,如下: 00 ...
- Hook(钩子技术)基本知识讲解,原理
一.什么是HOOK(钩子) API Windows消息传递机制,当在应用程序进行相关操作,例如点击鼠标.按下键盘,操作窗口等,操作系统能够感知这一事件,接着把此消息放到系统消息队列,然后到应用程序的 ...
- Android Hook技术
原文:http://blog.csdn.net/u011068702/article/details/53208825 附:Android Hook 全面入侵监听器 第一步.先爆项目demo照片,代码 ...
- ebtables hook
1 概述 netfliter框架不仅仅在ipv4中有应用,bridge,ipv4,ipv6,decnet 这四种协议中都有应用,其中ipv4中又分开了arp和ip的两种 其实netfliter是个大的 ...
随机推荐
- Centos 7 SSh--端口号的更改
前言:开启某服务或软件的端口,要从该服务或软件监听的端口(多以修改配置文件为主),SeLinux和防火墙(FireWall)的安全策略下手.如果使用阿里云,腾讯等第三方服务器还需要对管理控制台的安全组 ...
- 区块链共识算法|RAFT和PBFT的区别
这里有个很形象的比喻: 一个团队一定会有一个老大和普通成员.对于 raft 算法,共识过程就是:只要老大还没挂,老大说什么,我们(团队普通成员)就做什么,坚决执行.那什么时候重新老大呢?只有当老大挂了 ...
- [uboot] (第二章)uboot流程——uboot-spl编译流程(转)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/ooonebook/article/det ...
- 错误:The selected wizard could not be started Plug-in com.genuitec.eclipse.j2ee.ui was unable to load class com.genuitec.eclipse.j2ee.ui.wizard.WebProjectWizard
错误:The selected wizard could not be started Plug-in com.genuitec.eclipse.j2ee.ui was unable to load ...
- pt-online-schema-change的用法
pt-online-schema-change的用法 环境: 10.192.30.53 主库 10.192.30.60 从库 mysql版本:8.0.17 为了方便操作,简单的写了如下的脚本. #!/ ...
- Docker(六):Dockerfile命令详解
Dockerfile 指令详解 1 FROM 指定基础镜像 FROM 指令用于指定其后构建新镜像所使用的基础镜像.FROM 指令必是 Dockerfile 文件中的首条命令,启动构建流程后,Docke ...
- 页面禁止刷新处理Js实现
document.onkeydown = function(e) { e = window.event || e; var k = e.keyCode; //屏蔽ctrl+R,F5键,ctrl+F5键 ...
- LNK1104 无法打开文件“proj.lib”
两种可能: 1.proj.lib不存在 2.proj.lib不符合编译的debug(release)版本
- Redis缓存雪崩和缓存穿透等问题
穿透 缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透. 解决办法:①用一个bitma ...
- Java数据结构之排序---快速排序
快速排序是对冒泡排序的一种改进. 快速排序的基本思想: 假设我们以升序为例,它的执行流程可以概括为,每一趟选择当前所有子序列中的一个关键字(通常我们选择第一个,下述代码实现选择的也是第一个数)作为枢纽 ...