黑客爱用的HOOK技术大揭秘!

浅谈hook攻防 攻与防都是相对的,只有掌握细节才能更好的对抗。 基础知识 对于Windows系统,它是建立在事件驱动机制上的,说白了就是整个系统都是通过消息传递实现的。hook(钩子)是一种特殊的消息处理机制,它可以监视系统或者进程中的各种事件消息,截获发往目标窗口的消息并进行处理。所以说,我们可以在系统中自定义钩子,用来监视系统中特定事件的发生,完成特定功能,如屏幕取词,监视日志,截获键盘、鼠标输入等等。 钩子的种类很多,每种钩子可以截获相应的消息,如键盘钩子可以截获键盘消息,外壳钩子可以截取、启动和关闭应用程序的消息 阅读详情

什么是HOOK技术?

病毒木马为何惨遭杀软拦截?

商业软件为何频遭免费破解?

系统漏洞为何能被补丁修复?

这一切的背后到底是人性的扭曲,还是道德的沦丧,尽请收看今天的专题文章:《什么是HOOK技术?》

上面是开个玩笑,言归正传,今天来聊的话题就是安全领域一个非常重要的技术:HOOK技术。

HOOK,英文意思是“钩子”
在这里插入图片描述
在计算机编程中,HOOK是一种「劫持」程序原有执行流程,添加额外处理逻辑的一种技术。

按照这个定义,其实我们Python中的装饰器和Java中的注解,这种面向切面编程的手法在某种程度上来说,也算是HOOK。

不同的是,本文要探讨的HOOK并非属于程序原有的逻辑,而是在程序已经编译成可执行文件甚至已经在运行中的时候,如何劫持和修改程序的流程。

按照劫持的目标不同,常见的HOOK有以下这些类型:

  • Inline HOOK
  • IAT HOOK
  • C++ virtable HOOK
  • SEH HOOK
  • IDT HOOK
  • SSDT HOOK
  • IRP HOOK
  • TDI HOOK && NDIS HOOK
  • Windows Message HOOK

接下来,咱们挨个来看一下。

Inline HOOK

程序和代码是给程序员们看的,计算机要运行,最终是要编译成CPU的机器指令才能执行。

Inline HOOK的目标就是直接修改程序编译后的指令,属于最基础也最常见的HOOK技术。

下面我们以一个实例来感受一下Inline HOOK的效果:

void functionA() {
 cout << "this is function A" << endl;
}

void hookFunction() {
 cout << "this is hookFunction" << endl;
}

int main() {

 cout << "before hook" << endl;
 functionA();

 // prepare hook
 unsigned char code[5] = { 0xe9, 0x00, 0x00, 0x00, 0x00 };
 unsigned int offset = (unsigned int)hookFunction - ((unsigned int)functionA + 5);
 *(unsigned int*)&code[1] = offset;
 
 // install hook
 unsigned long old = 0; 
 VirtualProtect(functionA, 0x1000, PAGE_EXECUTE_READWRITE, &old);
 memcpy(functionA, code, 5);

 cout << "after hook" << endl;
 functionA();

 return 0;
}

输出:
在这里插入图片描述
代码中定义了目标函数functionA和hook函数hookFunction。

第一次调用,输出显示调用了原函数。

然后安装一个HOOK,准备了一条jmp指令,覆盖函数入口处的指令。此时观察覆盖前后的函数指令变化对比:
在这里插入图片描述
再次调用该函数,则一进入就发生跳转,我们安装的HOOK函数得到了执行。

所以第二次输出显示HOOK函数得到了调用。
在这里插入图片描述
大部分情况下,我们习惯于在函数入口处执行HOOK,但这并不是绝对的,还需要具体问题具体分析。比如如果我们需要等待函数执行完毕时拿到返回值才能介入处理,这个时候就需要在函数return的地方进行HOOK。甚至有可能需要在函数中途某个地方介入,这个时候就需要更进一步的对函数的反编译指令进行分析,确定HOOK的点位和处理逻辑。

执行Inline HOOK非常关键的几点:

  • 指令所在的内存页是否允许写入操作,若只读,须先添加写入权限
  • 需要动态解析目标位置处的指令,不能像上面那样暴力覆盖,否则会影响原来函数的执行逻辑
  • 如果在HOOK处理函数中需要调用原函数,注意别陷入死循环
  • 如果有参数,需要处理好堆栈平衡

Inline HOOK由于是直接在CPU机器指令层面上的操作,所以首先是无法做到跨平台。同时,还需要对CPU的指令集有一定程序的了解,具备一定的汇编语言功底。

好在,IT行业从来不缺造轮子的人,已经有不少优秀的开源项目将Inline HOOK封装成库,比如:Detours。

除了直接修改函数的机器指令,还有一类HOOK,它们修改的是某些重要的函数指针,从而达到劫持执行的目的。

形形色色的函数指针,就衍生出各式各样的HOOK技术。

IAT HOOK

一个程序的所有代码一般不会全部都编译到一个模块中,分拆到不同的模块既有利于合作开发,也有利于代码管理,降低耦合。

动态链接库就提供了这样的能力,将不同的模块编译成一个个的动态库文件,在使用时引入调用。

在Windows平台上,动态链接库一般以DLL文件的形式存在,主程序模块一般是EXE文件形式存在。无论是EXE还是DLL,都是属于PE文件。

一个模块引用了哪些模块的哪些函数,是被记录在PE文件的导入表IAT中。这个表格位于PE文件的头部,里面记录了模块的名字,函数的名字。

在模块加载时,模块加载器将解析对应函数的实际地址,填入到导入表中。

通过修改导入表IAT中函数的地址,这种HOOK叫IAT HOOK。

SEH HOOK

SEH是Windows操作系统上结构化异常处理的缩写,在代码中通过try/except来捕获异常时,操作系统将会在线程的栈空间里安置一个异常处理器(其实就是一个数据结构),里面定义了发生异常时该去执行哪里的代码处理异常。

异常处理可以多级嵌套,那多个异常处理就构成了一个链表,存在于栈空间之上。
在这里插入图片描述
当发生异常时,操作系统系统就从最近的异常处理器进行寻求处理,如果能处理则罢了,不能处理就继续寻求更上一级的异常处理器,直到找到能处理的异常处理器。如果都没法处理,那对不起,只好弹出那个经典的报错对话框,进程崩溃。
在这里插入图片描述
SEH HOOK针对的目标就是修改这些异常处理器中记录的函数指针,当异常发生时就能获得执行,从而劫持到执行流!因为这些异常处理器都位于线程的栈空间,修改起来并非难事。

C++ virtable HOOK

C++是一门面向对象的编程语言,支持面向对象的三大特性:封装性、继承性、多态性。

其中的多态性,各个C++编译器基本上都是通过一种叫虚函数表的机制来实现。

下面通过一个实际的例子来感受一下虚函数表在C++多态性上发挥的作用。

#include <iostream>
using namespace std;

class Animal {
public:
 virtual void breathe() {
  cout << "Animal breathe" << endl;
 }
 virtual void eat() {
  cout << "Animal eat" << endl;
 }
};

class Fish : public Animal {
public:
 virtual void breathe() {
  cout << "Fish breathe" << endl;
 }
 virtual void eat() {
  cout << "Fish eat" << endl;
 }
};

class Cat : public Animal {
public:
 virtual void breathe() {
  cout << "Cat breathe" << endl;
 }
 virtual void eat() {
  cout << "Cat eat" << endl;
 }
};

int main() {
 Animal* animal = nullptr;
 Fish* fish = new Fish();
 Cat* cat = new Cat();

 animal = fish;
 animal->breathe();
 animal->eat();

 cout << "--------------" << endl;
 cout << "sizeof(fish) = " << sizeof(fish) << endl;
 cout << "sizeof(cat) = " << sizeof(cat) << endl;
 cout << "--------------" << endl;

 animal = cat;
 animal->breathe();
 animal->eat();

 delete fish;
 delete cat;
 return 0;
}

输出:
在这里插入图片描述
通过上面的输出,可以看到,fish和cat对象都只占据4个字节。因为这两个类都没有成员变量,唯一需要存储的就是一个虚函数表指针。

以cat对象为例,看一下它的地址,是0x005cfc30:
在这里插入图片描述
看一下这个地址起始的4个字节,是什么:
在这里插入图片描述
虚表指针是0x000d9b90(这里需要注意字节顺序)。

通过这个地址,找到虚函数表,里面有两个函数地址:
在这里插入图片描述
查看这两个地址,都是指向了一个jmp指令,分别跳到了Cat类的两个虚函数。
在这里插入图片描述
在这里插入图片描述
通过上面的实例,总结一下对象、虚函数表和虚函数代码之间的关系如下图所示:
在这里插入图片描述
每个包含虚函数的类对象,在内存中都有一个指针,位于对象头部,指向的是一个虚函数表,表中的每一项都是虚函数地址。

类继承后,如果重写了父类的虚函数,子类对象指向的表格中对应函数的地址将会更新为子类的函数。

这样,使用父类指针指向子类对象,通过指针调用虚函数时,就能调用到子类重写的虚函数,从而实现多态性。

既然是记录函数地址的表格,那就有存在被篡改的可能,这就是C++ virtable HOOK。

通过篡改对应虚函数的地址,实现对相应函数调用的拦截。

实施这种HOOK,需要逆向分析目标C++对象的结构,掌握虚函数表中各个函数的位置,才能精准打击。

上面几种HOOK,修改的都是应用层的函数指针,而操作系统内核中还有一些非常重要的表格,它们的表项中记录了一些更加关键的函数,HOOK这些表格中的函数是非常高危的操作,操作不当将导致操作系统崩溃。当然,高风险高回报,HOOK这些函数,能实现一些非常强大的功能,是病毒、木马、安全软件非常爱干的事情。

SSDT HOOK

系统调用是操作系统提供给应用程序的编程接口API,应用程序通过这些API得以操作计算机的资源(如进程、网络、文件等)。

执行系统调用的时候,CPU将从用户模式切换到内核模式,进入内核后,将会根据系统调用的API编号,去找到对应的系统服务函数,实现对应API的功能。

操作系统将所有的系统服务函数地址,存放在了一个表格中,这个表格就是系统服务描述符表。在Linux上,这个表格的名字叫sys_call_table,在Windows上,它叫KeServiceDescriptorTable,简称SSDT。
在这里插入图片描述
Windows上的SSDT向来是兵家必争之地,安全软件为了监控应用程序的行为,通常都会替换SSDT表格中的系统服务函数地址为它们的函数。当系统调用触发时,安全软件将会及时知晓,并通过应用程序的参数来判定是否“放行”这次调用。

IDT HOOK

内核中除了记录系统服务的SSDT,还有一个非常重要的表格:中断描述符表IDT。

IDT用于记录CPU执行过程中遇到中断、异常等情况时,该转向哪里去处理这些情况的函数地址。

HOOK IDT有一个注意事项,不同于SSDT是全局唯一的,IDT是与CPU核心紧密相关的,对于多核处理器,会对应多个IDT表。如果想通过HOOK IDT中的函数来搞事情的话,可能需要同时处理多个表。
在这里插入图片描述
除了直接修改函数指令和修改函数指针之外,还有一类特殊的HOOK,它们通过系统提供的机制拦截某些消息、通知,从而有机会介入监听、拦截。

IRP HOOK

在Windows系统上,用户程序和内核驱动之间的交互是通过一种称为IRP的数据结构实现的,你可以简单将其理解为应用程序发送了一个消息下去,这个消息就是一个IRP。

而接收消息的目标,是驱动程序创建的设备Device。注意,这个设备不一定是物理设备,也可能完全不存在的虚拟设备,驱动程序可以任意创建一个不存在的设备。

Windows内核中提供了驱动设备的挂载操作,允许别的驱动程序对指定设备进行挂载,从而可以截获发送给该设备的“消息”,这种HOOK方式被称为IRP HOOK。
在这里插入图片描述
国内一些安全软件为了互相攻击,经常用这种方式拦截对方驱动程序的消息,从而可以“保护”自己不被对方干掉。

TDI HOOK && NDIS HOOK

这两种HOOK方式与Windows内核中的网络子系统密切相关。

Windows内核中的网络结构是分层式设计。从最上层的API socket层、到TCP/IP协议栈层、再到底层的网卡驱动程序,分了很多个层次。

而层与层之间的交互,是通过一系列标准接口来实现的,其中最重要的两个接口标准就是TDI和NDIS。TDI封装了不同协议栈的差异(Windows不止支持TCP/IP协议栈)提供给上层统一的调用接口。NDIS则封装了底层不同网卡的驱动程序接口差异,提供给上层统一的收发数据包接口。

Windows为了扩展性支持,允许类似防火墙之类的软件通过这些接口接入,从而能够截获到网络通信流量,进行安全审计。

既然开了这些接口,一些流氓软件和木马病毒也就盯上了它们,通过这些接口就能轻松监听、篡改网络数据,达到邪恶的目的。

Windows Message HOOK

Windows操作系统的UI交互是以消息来驱动的,用户的键盘输入、鼠标操作都会被操作系统以消息的形式发送到各个应用程序处理。

Windows提供了API接口,可以被程序用于捕获这些消息,从而实现一些特定的功能。

HHOOK SetWindowsHookEx(
  int       idHook,
  HOOKPROC  lpfn,
  HINSTANCE hmod,
  DWORD     dwThreadId
);

这种机制叫做Windows消息钩子,最常见的就要数键盘钩子了,在十多年前流氓软件和木马病毒大行其道的时候,这些恶意软件经常喜欢通过这种方式来监听用户的键盘输入,从而来盗取QQ密码(当然,现在肯定是不行的了)。

总结

以上就是要介绍的全部HOOK技术了。当然有HOOK,就有反HOOK,很多安全软件都会检查关键的位置是否被篡改。不仅如此,因为流氓软件随意修改系统,Windows从Win7 x64开始加入了PatchGuard机制,针对操作系统核心数据结构都加入了定时检测机制,一旦发现被篡改,立刻蓝屏给你看,而且在随着系统升级换代,这个检查的粒度和强度变得越来越强。

最后来回到文章开头的几个问题:

病毒木马为何惨遭杀软拦截?

因为安全软件在内核中HOOK了大量的关键位置,病毒木马的进程、文件、网络行为都将受到监控,一举一动都难逃杀软的眼睛,想要拦截易如反掌。

商业软件为何频遭免费破解?

通过逆向分析加上Inline HOOK,破解者可以篡改掉商业软件的注册校验机制,让校验函数返回成功,绕开软件的限制。

系统漏洞为何能被补丁修复?

统一通过Inline HOOK,操作系统能够修改原来有bug的代码,转而执行修复后的新版本,解决系统漏洞。

点击下方即可免费领取技术文档
**

【HOOK技术文档】

**
你看,技术就是一柄双刃剑,善或恶,一念之间。

请添加图片描述

手写代码详解Android Hook入门demo(1) 对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。下面是部分资料截图,诚意满满:特别适合有开发经验的Android程序员们学习。不论遇到什么困难,都不应该成为我们放弃的理由!如果你看到了这里,觉得文章写得不错就给个赞呗?《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》 阅读详情

相关推荐

HOOK学习笔记与心得

一、  Hook介绍 钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。  我们知道Windows系统API函数都是被封装到DLL中,在某个应用程序要调用一个API函数的时候,如果这个函数所在的D

码莎拉蒂 4883

Hook技术

linux上基于C和C++的hook尝试

jinking01的专栏 4418

高通camera驱动 camx read xml 和 probe 流程 和 sensor I2C读写的波形图 (三)

Camx 刚接触的时候对于这个xml 一脸懵逼,实际上和mm-camera差不多就是以xml node节点的方式标准化了driver相关的code,exposure 和 gain的逻辑实现还是在同级目录的cpp中,并且将 xml 的解析工作放在了 out/target/<product>/gen/STATIC_LIBERARIES/libcamxgenerated_intermediates/generated/ 中主要是包含了: g_chromatix : tuning 相关xml的解析co

shangbolei的博客 1万+

黑客爱用的 HOOK 技术大揭秘

病毒木马为何惨遭杀软拦截?商业软件为何频遭免费破解?系统漏洞为何能被补丁修复?这一切的背后到底是人性的扭曲,还是道德的沦丧,敬请收看今天的专题文章:《什么是 HOOK 技术?

A_991128a的博客 2434

模型算力需求估算

(Billion Parameters,简称B)和训练/推理的计算任务复杂度,结合硬件计算能力(例如每秒浮点运算次数,FLOPS)来估算。以下是详细的方法和公式说明,以及实际的计算示例。算力需求的估算依赖于参数量、模型架构及硬件性能,结合训练/推理场景的特定要求来计算。通过上述公式和示例,我们可以定量分析不同任务的算力需求,并合理配置硬件资源以优化运行效率。结论:推理任务相对较轻,单台H100可以在30秒内完成此任务。推理算力需求一般远低于训练,因为只需要执行前向传播。,可以将训练时间缩短到约。

形上得其象,形下合于数;阴阳自济,玄理自明。 8953

汇川EASY系列之以太网通讯(MODBUS_TCP做主站)

汇川Easy系列以太网通讯中(MODBUSTCP,plc做主站),终于可以不用使用指令就可以完成了,全程通过简单的配置就可通讯。本文将通过EASY系列PLC与调试助手之间完成此操作。

这是一个长期关注工控行业技术的博客,实现0-1的突破,期待您的关注和留言 3302

黑客爱用的 HOOK 技术大揭秘!

上面几种 HOOK,修改的都是应用层的函数指针,而操作系统内核中还有一些非常重要的表格,它们的表项中记录了一些更加关键的函数,HOOK 这些表格中的函数是非常高危的操作,操作不当将导致操作系统崩溃。当发生异常时,操作系统就从最近的异常处理器进行寻求处理,如果能处理则罢了,不能处理就继续寻求更上一级的异常处理器,直到找到能处理的异常处理器。执行系统调用的时候,CPU 将从用户模式切换到内核模式,进入内核后,将会根据系统调用的 API 编号,去找到对应的系统服务函数,实现对应 API 的功能。

ZL_1618的博客 1555

SOLIDWORKS2024安装卡顿?Edge WebView2 Runtime冲突的排查与修复

本文针对SOLIDWORKS 2024安装时setup.exe无响应或卡死的常见问题,深入剖析了其根本原因在于Microsoft Edge WebView2 Runtime的版本冲突或组件损坏。文章提供了三种经过验证的解决方案:一是通过运行安装包内swwi\data目录下的setup.exe直接绕过图形界面;二是彻底卸载并重装官方Edge WebView2 Runtime组件;三是进行系统级修复与排查。旨在帮助用户快速定位并解决安装障碍,顺利完成软件部署。

4k5l6j7h8的博客 289

黑客爱用的 HOOK 技术

上面几种 HOOK,修改的都是应用层的函数指针,而操作系统内核中还有一些非常重要的表格,它们的表项中记录了一些更加关键的函数,HOOK 这些表格中的函数是非常高危的操作,操作不当将导致操作系统崩溃。从时代发展的角度看,网络安全的知识是学不完的,而且以后要学的会更多,同学们要摆正心态,既然选择入门网络安全,就不能仅仅只是入门程度而已,能力越强机会才越多。执行系统调用的时候,CPU 将从用户模式切换到内核模式,进入内核后,将会根据系统调用的 API 编号,去找到对应的系统服务函数,实现对应 API 的功能。

dzqxwzoe的博客 2227

怎么选?一文读懂12种SPC控制图,从基础到进阶,再到Python代码实现

本文系统介绍了12种常用SPC控制图的应用场景和特点,包括计量型(Xbar-R图、Xbar-s图、I-MR图等)、计数型(P图、NP图、U图等)及进阶控制图(EWMA图、CUSUM图、多元控制图)。文章强调控制图是SPC的核心工具,能有效区分过程变异类型,实现"预防优于检测"的质量管理目标。通过数据示例和Python代码展示了各类控制图的实现方法,为质量管理人员提供了实用参考。

m0_56592100的博客 4136

合肥工业大学操作系统实验9

依据操作系统课程所介绍的页面置换算法与动态内存分配的原理,本实验的目的是掌握OPT、FIFO、LRU、LFU、Clock等页面置换算法;掌握可用空间表及分配方法;掌握边界标识法以及伙伴系统的内存分配方法和回收方法。从而深入理解操作系统的内存管理。从而加深对教材上页面置换算法与动态内存分配的理解。

Martin-share的博客 1094

一网打尽!每个程序猿都该了解的黑客技术大汇总_黑客hook

信息摘要算法其实不算是一种加密算法,加密的前提是可以通过解密还原,而信息摘要算法的目的并不是对数据进行保护,也无法解密还原。在一些语境下,信息摘要我们听得少,听的更多的名词是哈希信息摘要算法的目的之一是校验数据的正确性,算法公开,数据通过该算法得出一个摘要值,收到数据后通过该算法计算出这个摘要,前后对比就知道是否有被篡改。MD5SHA1SHA256本文罗列了一些常见的信息安全技术,主要分网络安全、系统安全和密码学三个领域展开。

2401_83620927的博客 1074

自助结账商品检测(Scanned Item Detection)——基于YOLOv8的RPC数据集实战

RPC数据集是由中国科学院自动化研究所发布的零售商品结账检测公开数据集,广泛用于自助结账和零售场景下的目标检测与识别。YOLOv8是YOLO系列最新版本,由Ultralytics推出,继承了YOLO家族的高效快速和高准确性,适用于实时检测场景。本文系统介绍了基于YOLOv8的RPC数据集自助结账商品检测方案,涵盖数据准备、训练、推理及UI界面设计。未来,可结合多模态感知、RFID融合技术,打造更加智能和稳定的自助结账系统。

YOLO 250
上一篇: 这是什么骚批代码!
下一篇: 网络安全的学习方向和路线是怎么样的?
AI小模型
博客等级 码龄6年 6863粉丝 487原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI小模型

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值