【免杀】C2免杀技术(十三)Inline Hook 前置篇

admin 2025年6月2日01:20:34评论31 views字数 4370阅读14分34秒阅读模式
Hook技术

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

一、Hook技术本质

Hook = 挂钩技术,指的是:

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

二、常见Hook分类
【免杀】C2免杀技术(十三)Inline 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 ebp  mov 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函数中处理逻辑后决定是否返回原函数

三、常见实现方式

序号
典型写法
指令序列(十六进制)
说明 / 关键代码片段
1
JMP 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); 
2
PUSH addr ; RET

(绝对跳转,避开特征检测)
68 XX XX XX XXC3

 (6 字节)
cpp DWORD addr = (DWORD)pHook; BYTE patch[6] = {0x68}; memcpy(patch+1,&addr,4); patch[5]=0xC3; WritePatch(pTarget, patch, 6); 
3
MOV 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 库内部完成的,并没有直接在代码中显式地编写跳转指令(如 JMP 或 CALL)。MinHook 封装了这些底层细节,开发者只需调用 MH_CreateHook 和 MH_EnableHook 即可完成 Hook。

#include<windows.h>#include<iostream>#include"MinHook.h"typedefint(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);}intmain(){    // 初始化 MinHook    if (MH_Initialize() != MH_OK) {        std::cerr << "MinHook 初始化失败" << std::endl;        return 1;    }    // 获取 MessageBoxA 地址    void* pTarget = GetProcAddress(GetModuleHandleA("user32"), "MessageBoxA");    // 创建 Hook    if (MH_CreateHook(pTarget, &MyHookMessageBoxA, reinterpret_cast<LPVOID*>(&fpMessageBoxA)) != MH_OK) {        std::cerr << "创建 Hook 失败" << std::endl;        return 1;    }    // 启用 Hook    if (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;}
【免杀】C2免杀技术(十三)Inline Hook 前置篇

这段代码是怎么 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设置

【免杀】C2免杀技术(十三)Inline Hook 前置篇

4、项目中引入头文件

#include <MinHook.h>

本文免责声明

本文所涉及的技术内容,纯属技术研究与安全学习交流之用。请务必别拿去干坏事,不然出问题了,别来找我——我不会背锅的!

简单点说:

👉 看了本文去练技术,不犯法我们是朋友;

👉 看了本文去搞破坏,进去了咱也爱莫能助!

因使用、传播或“脑洞过大”地运用本公众号“仇辉攻防”所发布的信息,所造成的一切后果与损失,全由您自己负责!

本公众号和作者既不负责、也不赔钱、更不探监!

最后友情提示:网络世界虽精彩,法律红线不能踩!技术无罪,使用请善良!

今天是儿童节

🎉 祝所有大小朋友儿童节快乐!愿我们永远保持对技术的童心与好奇,像孩子拆解玩具一样探索代码的奥秘,用简单的快乐面对复杂的逻辑。

“每个大人都曾是小孩,虽然只有少数人记得。” ——《小王子》

#免杀 #C2 #Hook #Inlinehook

原文始发于微信公众号(仇辉攻防):【免杀】C2免杀技术(十三)Inline Hook 前置篇

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月2日01:20:34
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【免杀】C2免杀技术(十三)Inline Hook 前置篇https://cn-sec.com/archives/4122712.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息