当前位置: 首页 > news >正文

【免杀】C2免杀技术(十三)Inline Hook 概念篇

Hook 技术

Hook 技术是操作系统、软件开发和安全攻防中非常核心的技术手段之一。它的本质是“截获函数调用并插入自定义逻辑”。你可以把它理解为“在别人执行某个功能之前或之后偷偷插一脚”。

一、Hook 技术本质

Hook = 挂钩技术,指的是:

修改程序运行过程中某些函数或代码的执行流程,使其转而执行攻击者(或开发者)定义的代码。

二、常见 Hook 分类

按实现方式分类: 

类型描述常见用途
Inline Hook(函数内联)在目标函数的开头插入跳转指令木马注入、监控、反作弊
IAT Hook修改 Import Address Table 表项,改变函数调用地址DLL 注入、API 替换、持久化
EAT Hook修改 Export Address Table,劫持导出的函数DLL 劫持,系统调用重定向
SSDT Hook修改系统服务描述表(系统调用表)地址(内核级)Rootkit、驱动监控、内核后门
VMT Hook(虚函数表)修改 C++ 类的虚函数表指针游戏外挂、面向对象劫持
Windows 消息 Hook使用 SetWindowsHookEx 挂钩消息(键盘、鼠标等)键盘记录器、自动化脚本、UI拦截
VEH/SEH Hook设置异常处理函数拦截访问/异常等行为Anti-debug、内存控制

Inline Hook

Inline Hook(内联钩子)是所有 Hook 技术中最强大也最危险的一种,它属于修改目标函数指令流的一种方式,本质上是在函数入口直接插入跳转指令来重定向执行流。

一、Inline Hook 原理详解

通过修改目标函数的机器指令,使其执行流程跳转到自定义的代码(Hook函数),然后再返回原函数继续执行或完全替代原函数。

示意图(Hook MessageBoxA):

原始指令:
MessageBoxA:push ebpmov ebp, esp...Hook后变成:
MessageBoxA:jmp my_hook_func   ← 插入跳转指令; 原来的 push ebp mov ebp 被覆盖(备份)your_hook_func:; 你想干的事(比如打印、修改参数、记录调用); 如果你要调用原始函数,则需要:- 还原前几条原始指令(trampoline)- jmp 回 MessageBoxA + x

二、主要实现步骤

其中(2、3、4步)如果使用 MinHook 库,由 MinHook 内部自动完成,代码中看不见 

1、定位目标函数:确定需要Hook的函数的地址

2、备份原指令:保存将被覆盖的原始指令

3、构造跳转指令:编写跳转到Hook函数的指令

4、修改目标函数:用跳转指令覆盖目标函数的开始部分

5、处理执行流:在Hook函数中处理逻辑后决定是否返回原函数

三、常见实现方式

#典型写法指令序列(十六进制)说明 / 关键代码片段
1JMP rel32 (x86/x64 通用,±2 GB 内)E9 XX XX XX XX (总 5 字节)cpp DWORD src = (DWORD)pTarget; DWORD dst = (DWORD)pHook; DWORD rel = dst - src - 5; BYTE patch[5] = {0xE9}; memcpy(patch+1,&rel,4); WritePatch(pTarget, patch, 5);
2PUSH addr ; RET(绝对跳转,避开特征检测)68 XX XX XX XX C3 (6 字节)cpp DWORD addr = (DWORD)pHook; BYTE patch[6] = {0x68}; memcpy(patch+1,&addr,4); patch[5]=0xC3; WritePatch(pTarget, patch, 6);
3MOV RAX, addr ; JMP RAX(x64 远距)48 B8 <addr64> FF E0(12 字节)cpp uint8_t patch[12] = { 0x48,0xB8 }; *(uint64_t*)(patch+2) = (uint64_t)pHook; patch[10]=0xFF; patch[11]=0xE0; WritePatch(pTarget, patch, 12);

代码示例

下面是一个 Inline Hook 示例(64位),我们将 Hook MessageBoxA 函数,在不改变其正常行为的前提下,劫持它并打印额外信息。 

在该代码中,构造跳转指令的操作是由 MinHook 库内部完成的,并没有直接在代码中显式地编写跳转指令(如 JMPCALL)。MinHook 封装了这些底层细节,开发者只需调用 MH_CreateHookMH_EnableHook 即可完成 Hook。

#include <windows.h>
#include <iostream>
#include "MinHook.h"typedef int (WINAPI* MessageBoxA_t)(HWND, LPCSTR, LPCSTR, UINT);
MessageBoxA_t fpMessageBoxA = NULL;  // 保存原始函数指针int WINAPI MyHookMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) {std::cout << "[HOOKED] MessageBoxA intercepted!" << std::endl;// 修改文本内容LPCSTR newText = "你被 x64 Inline Hook 成功拦截!";return fpMessageBoxA(hWnd, newText, lpCaption, uType);
}int main() {// 初始化 MinHookif (MH_Initialize() != MH_OK) {std::cerr << "MinHook 初始化失败" << std::endl;return 1;}// 获取 MessageBoxA 地址void* pTarget = GetProcAddress(GetModuleHandleA("user32"), "MessageBoxA");// 创建 Hookif (MH_CreateHook(pTarget, &MyHookMessageBoxA, reinterpret_cast<LPVOID*>(&fpMessageBoxA)) != MH_OK) {std::cerr << "创建 Hook 失败" << std::endl;return 1;}// 启用 Hookif (MH_EnableHook(pTarget) != MH_OK) {std::cerr << "启用 Hook 失败" << std::endl;return 1;}// 测试调用MessageBoxA(NULL, "测试内容", "测试标题", MB_OK);// 等待std::cin.get();// 清理MH_DisableHook(pTarget);MH_Uninitialize();return 0;
}

这段代码是怎么 Hook MessageBoxA 的?

1、找到 MessageBoxA 的地址(就像查电话簿找某个人的电话号码)

void* pTarget = GetProcAddress(GetModuleHandleA("user32"), "MessageBoxA");

2、告诉 MinHook:

  • “我要 Hook MessageBoxA
  • “如果 MessageBoxA 被调用,先跳转到我的函数 MyHookMessageBoxA
  • “记得把原来的 MessageBoxA 存起来,我后面还要用”
MH_CreateHook(pTarget, &MyHookMessageBoxA, reinterpret_cast<LPVOID*>(&fpMessageBoxA));

3、MinHook 偷偷修改 MessageBoxA 的代码(让它一执行就先跳转到我们的函数)

MH_EnableHook(pTarget); // 启用 Hook(真正“劫持”快递)

4、我们的 MyHookMessageBoxA 函数接管控制权,可以改参数、记录日志等

int WINAPI MyHookMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) {std::cout << "[HOOKED] MessageBoxA intercepted!" << std::endl;LPCSTR newText = "你被 x64 Inline Hook 成功拦截!";  // 修改弹窗内容return fpMessageBoxA(hWnd, newText, lpCaption, uType);  // 再调用原函数
}

5、最后再调用原来的 MessageBoxA(如果不调用,弹窗就不会显示)

MinHook 框架 

MinHook 是一个轻量级的 Windows API 钩取(hooking)库,主要用于拦截和修改函数调用。

优势 

为什么要用,尤其是64位环境?

  • 自动反汇编前几条指令

  • 检查这些指令有没有 rip 相对寻址

  • 自动构造 trampoline,重新修复相对地址或选择更长的覆盖范围

  • 自动补跳转返回指令(jmp back)

  • 处理 x64 栈对齐(shadow space)

安装 

1、我这里使用 vcpkg 安装 MinHook

vcpkg install minhook:x64-windows #动态版本
vcpkg install minhook:x64-windows-static #静态版本(推荐)

2、继续使用以下命令自动集成,这会将 vcpkg 的库路径自动挂入 VS 项目的环境中

vcpkg integrate install

 3、VS设置

4、项目中引入头文件

#include <MinHook.h>
http://www.xdnf.cn/news/759025.html

相关文章:

  • C# winform 教程(一)
  • Hartree-Fock 自洽场计算流程
  • Oracle正则表达式学习
  • 正则表达式笔记
  • yolo目标检测助手:具有模型预测、图像标注功能
  • 【复杂网络分析】什么是modularity?
  • maven中的maven-antrun-plugin插件详解
  • Go语言中的rune和byte类型详解
  • MySQL(49)如何使用DEFAULT指定默认值?
  • 配置Ollama环境变量,实现远程访问
  • 怎么样提高研发质量?
  • 七.MySQL内置函数
  • Practice 2025.6.1—— 二叉树进阶面试题(2)
  • 研读论文《Attention Is All You Need》(13)
  • 【笔记】MSYS2 安装 Python 构建依赖记录Cython + Ninja + Meson + meson-python
  • 七、物理.
  • Flickr30k_Entities数据集
  • 【项目记录】登录认证(下)
  • 6.运算放大器—电源抑制比(五)
  • 2002-2022年 城市市政公用设施水平、环境、绿地等数据-社科经管实证数据
  • 殷咏梅教授:OptiTROP-Breast05亮相2025 ASCO,中国原创TROP2 ADC为mTNBC一线治疗带来新希望
  • 2024年数维杯国际大学生数学建模挑战赛B题空间变量协同估计方法研究解题全过程论文及程序
  • ZIP Cracker版本更新了
  • java中IO流分为几种
  • 深入Java NIO:构建高性能网络应用
  • AAA基础配置
  • LeetCode - 234. 回文链表
  • Roller: 抽奖系统测试的幕后剧本-测试报告
  • Spring AI Image Model、TTS,RAG
  • PINN模型相关原理