3种方式集成SafetyHook:CMake FetchContent、vcpkg与Amalgamated构建完整教程
【免费下载链接】safetyhookC++23 procedure hooking library.项目地址: https://gitcode.com/gh_mirrors/sa/safetyhook
SafetyHook 是一款C++23 过程函数 Hooking(过程挂钩)库,本教程将带你用CMake FetchContent、vcpkg、Amalgamated 构建3 种方式把它集成进自己的项目。无论你用 CMake 管理构建、依赖 vcpkg 包管理器,还是只想"两个文件"直接嵌入,5 分钟就能配好。
开始之前:SafetyHook 是什么?
SafetyHook 的目标是让运行时函数 Hook"尽可能安全"。它在创建/删除钩子时会:
- 🛑 自动暂停其他线程,并修正可能受影响的线程指令指针
- 🧩 修正重定位指令的相对偏移(如
jmp、lea rip) - ⚡ 自动把短分支拓宽为近分支,支持落入跳板的短分支
- 基于Zydis现代反汇编引擎,API 设计上手即用不易出错
硬性前提(3 种方式都需要):
| 要求 | 说明 |
|---|---|
| C++23 编译器 | 库以cxx_std_23编译(见 cmake.toml 中compile-features) |
| Zydis 依赖 | 反汇编引擎,下面每种方式都能自动带上 |
| 平台 | Windows / Linux,x86 与 x86_64(对应src/os.windows.cpp、src/os.linux.cpp) |
方式一:CMake FetchContent 自动拉取(推荐)
如果你用 CMake,这是最省心的方式——配置时自动克隆并构建 SafetyHook,版本可控、更新方便。
在你的CMakeLists.txt中加入:
include(FetchContent) FetchContent_Declare( safetyhook GIT_REPOSITORY "https://gitcode.com/gh_mirrors/sa/safetyhook" GIT_TAG "main" ) FetchContent_MakeAvailable(safetyhook) # 链接到你的目标 target_link_libraries(your_target PRIVATE safetyhook::safetyhook)再让 SafetyHook 顺带拉取 Zydis(v4.0.0,定义见cmake.toml的fetch-zydis段):
cmake -B build -DSAFETYHOOK_FETCH_ZYDIS=ON cmake --build build✅ 效果:首次配置后 CMake 自动克隆、编译出静态库safetyhook::safetyhook,你的目标直接链接即可,无需手动维护第三方源码。
方式二:vcpkg 一行命令安装
项目自带 vcpkg.json 清单文件,其中已声明反汇编依赖bddisasm。如果你的工程使用 vcpkg 清单模式(manifest mode),在自己的vcpkg.json里加入:
{ "dependencies": ["safetyhook"] }然后执行:
vcpkg installvcpkg 会自动拉取 SafetyHook 及其反汇编依赖,并生成对应的 CMake 配置,你只需在 CMakeLists 里find_package(safetyhook REQUIRED)后链接safetyhook::safetyhook即可。
💡 适合团队环境统一依赖版本、或不想在 CMakeLists 里写 FetchContent 块的项目。
方式三:Amalgamated 构建——两个文件直接嵌入
SafetyHook 提供 amalgamate.py 脚本,可把全部头文件与源码合并成safetyhook.hpp+safetyhook.cpp两个文件,适合不用 CMake 集成或需要分发源码的场景。两种获取方式:
1. 直接下载预制包(最简单)
从项目 Releases 页面下载 Amalgamated ZIP(可选含 Zydis 的版本,若你项目里已有 Zydis 就选不含的),把文件拷进工程即可。使用静态编译的 Zydis 时,记得定义ZYDIS_STATIC_BUILD。
2. 本地自行生成(始终最新)
需要 Python 3(见CMakeLists.txt的SAFETYHOOK_AMALGAMATE目标):
cmake -B build -DSAFETYHOOK_AMALGAMATE=ON cmake --build build --target amalgamation产物输出到amalgamated-dist/目录,把两个文件加入你的工程参与编译即可——完全不需要构建系统支持,Makefile、MSBuild、手工编译都能用。
3 种方式怎么选?一张表看懂
| 方式 | 适用场景 | 优点 | 注意点 |
|---|---|---|---|
| CMake FetchContent | CMake 工程(首选) | 自动克隆构建、版本可控 | 首次配置需联网 |
| vcpkg | 已用 vcpkg 的团队 | 一行安装、依赖自动解决 | 需先配置 vcpkg |
| Amalgamated | 非 CMake 工程 / 代码分发 | 无构建系统依赖,仅两个文件 | 升级时需手动同步文件 |
常见坑位清单 ⚠️
- 编译器必须支持 C++23:否则在
cxx_std_23处直接报错。 - 找不到 Zydis?源码中会明确报
Zydis not found(见src/inline_hook.cpp),检查是否开启-DSAFETYHOOK_FETCH_ZYDIS=ON或补装依赖。 - 禁止源码目录内构建:必须在独立 build 目录执行
cmake -B build,否则直接 FATAL_ERROR。 - 被 Hook 的函数别被内联:用项目自带的
SAFETYHOOK_NOINLINE宏(定义于include/safetyhook/common.hpp)。
5 分钟跑通第一个例子
仓库自带示例 example/minimal.cpp:Hook 一个add函数把入参翻倍,再还原。构建并运行:
cmake -B build -DSAFETYHOOK_FETCH_ZYDIS=ON -DSAFETYHOOK_BUILD_EXAMPLES=ON cmake --build build --target example-minimal核心逻辑只有两行(易用的 Easy API 定义在include/safetyhook/easy.hpp):
g_add_hook = safetyhook::create_inline(add, hook_add); // 创建钩子 g_add_hook = {}; // 移除钩子恭喜!至此你已掌握 SafetyHook 的 3 种集成方式。按项目现状任选其一,即可安全地开始你的运行时函数 Hook 之旅。
【免费下载链接】safetyhookC++23 procedure hooking library.项目地址: https://gitcode.com/gh_mirrors/sa/safetyhook
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考