5 分钟上手 syscall_intercept:从源码编译到第一个 Hook 的快速入门教程

📅 2026/8/16 20:53:55
5 分钟上手 syscall_intercept:从源码编译到第一个 Hook 的快速入门教程
5 分钟上手 syscall_intercept从源码编译到第一个 Hook 的快速入门教程【免费下载链接】syscall_interceptThe system call intercepting library项目地址: https://gitcode.com/gh_mirrors/sy/syscall_interceptsyscall_intercept 是一个运行在用户空间的系统调用拦截库The system call intercepting library它无需修改内核、无需加载内核模块就能在进程内部截胡几乎所有的 Linux 系统调用。本教程将带你从零开始下载源码、编译安装、理解 Hook API并在 5 分钟内写出并运行你的第一个系统调用拦截程序。整个过程只需几行 C 代码加一条LD_PRELOAD环境变量非常适合对系统编程、沙箱与安全审计感兴趣的初学者快速入门。syscall_intercept 是什么为什么需要系统调用拦截库在 Linux 上应用程序的文件读写、进程创建、网络通信等操作最终都会转化为系统调用syscall交给内核执行。syscall_intercept 的思路很巧妙它通过hotpatch热补丁的方式在进程内存中改写 glibc 的机器码把其中的syscall指令替换为跳转指令从而把系统调用引流到你自定义的回调函数里。这意味着你可以做到️安全防护禁止程序执行fork、execve等危险操作审计日志记录程序发起的每一次系统调用及其参数行为模拟在用户空间伪造系统调用结果骗过应用程序它的核心源码和实现思路都集中在src/目录如 patcher.c、intercept.c底层依赖反汇编引擎libcapstone来定位并改写机器码。快速上手前的准备环境与依赖清单编译 syscall_intercept 需要满足以下条件缺一不可依赖项说明Linux 操作系统仅支持 Linux不支持其他平台x86_64 架构库的补丁逻辑针对 x86_64 指令集设计glibc官方只测试过 glibc其他 libc 实现不保证可用cmake构建系统需要 3.3 及以上版本gcc 或 clang任一支持 C99 的编译器均可libcapstone运行时依赖的反汇编引擎构建前需安装从源码编译 syscall_intercept 的一键步骤拿到源码最直接的方式就是克隆仓库git clone https://gitcode.com/gh_mirrors/sy/syscall_intercept然后进入目录用 cmake 配置并编译建议指定 Release 模式以获得最佳性能cd syscall_intercept cmake . -DCMAKE_INSTALL_PREFIX/usr -DCMAKE_BUILD_TYPERelease make编译完成后安装库和头文件sudo make install安装后你会得到共享库libsyscall_intercept.so以及位于include/目录下的核心头文件 libsyscall_intercept_hook_point.h——这是整个库唯一的对外接口也是我们接下来要写的 Hook 程序需要包含的头文件。 构建选项提示如果只想快速体验可以用-DBUILD_TESTSOFF -DBUILD_EXAMPLESOFF跳过测试和示例的编译加快构建速度。理解核心 API一个函数指针搞定系统调用拦截syscall_intercept 的 API 简单到令人惊讶你只需要向全局函数指针intercept_hook_point赋值一个回调函数拦截就自动生效了。回调的签名如下int (*intercept_hook_point)(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result);回调函数的返回值是关键约定返回非 0表示这个系统调用我不拦截库会把调用原样转发给内核执行返回 0表示这个系统调用我接管了此时通过*result指针设置系统调用的返回值另外如果你的 Hook 代码内部也需要发起系统调用切记使用库提供的syscall_no_intercept()函数而不是 glibc 的syscall()——否则会陷入无限递归的窘境。5 分钟写出你的第一个 Hook拦截 write 系统调用理论讲完现在动手。我们写一个最简单也最有趣的例子拦截所有write系统调用把输出内容中的小写字母i全部改成大写I灵感来自官方示例 examples/icap.c。新建icap.c内容如下#include stddef.h #include string.h #include syscall.h #include libsyscall_intercept_hook_point.h static int hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { if (syscall_number SYS_write) { char buf[0x1000]; size_t size (size_t)arg2; if (size sizeof(buf)) size sizeof(buf); memcpy(buf, (char *)arg1, size); for (size_t i 0; i size; i) if (buf[i] i) buf[i] I; *result syscall_no_intercept(SYS_write, arg0, buf, size); return 0; /* 接管这个系统调用 */ } return 1; /* 其他系统调用放行 */ } __attribute__((constructor)) static void start(void) { intercept_hook_point hook; }编译成共享库cc icap.c -lsyscall_intercept -fpic -shared -o icap.so最后用LD_PRELOAD把 Hook 注入到任意程序里试试效果LD_LIBRARY_PATH. LD_PRELOAD./icap.so ls运行后你会发现ls输出的所有小写i都变成了大写I而程序本身毫不知情——你的第一个系统调用拦截器就这样跑起来了实用技巧用环境变量控制拦截行为库内置了三个环境变量能帮你更好地控制拦截过程在调试时尤其有用环境变量作用INTERCEPT_LOG设置后库会把每次拦截的系统调用记录到指定日志文件路径以-结尾时会自动追加进程 PIDINTERCEPT_LOG_TRUNC设为 0 时不截断已有日志文件INTERCEPT_HOOK_CMDLINE_FILTER设置后只有命令行末段与指定字符串匹配的进程才会被拦截其余进程加载了库也不生效例如只想拦截ls命令同时用 gdb 调试且不希望 gdb 自身被拦截可以这样组合使用INTERCEPT_HOOK_CMDLINE_FILTERls \ LD_PRELOADlibsyscall_intercept.so \ gdb ls现成例子从官方示例快速进阶如果觉得手写回调不够过瘾仓库的examples/目录已经准备好了三个完整的可直接编译的示例examples/icap.c上面的字母改写例子最简入门examples/fork_ban.c限制进程 fork 次数超过上限后返回EAGAIN展示拦截系统调用后的拒绝能力examples/syscall_logger.c配合 examples/syscall_desc.c 实现的完整系统调用日志记录器参数格式化非常详细是审计工具的理想模板此外test/目录下的测试代码如 hook_test.c、fork_logging.c也展示了多进程、多线程场景下的拦截用法进阶学习时值得一读。注意事项与已知限制上手很快但以下几点限制务必提前知晓⚠️ 仅拦截glibc 发起的系统调用绕过 libc 直接用汇编syscall指令的程序无法被拦截⚠️clone和rt_sigreturn两个系统调用存在已知问题拦截时需格外小心⚠️ 同一进程中不要有其他工具也去热补丁 glibc否则可能互相冲突⚠️ 回调函数在加载库时通过构造函数注册务必保证库在目标程序启动前完成注入小结你的下一步从源码编译到第一个 Hook 生效整个过程确实只需要 5 分钟。syscall_intercept 用极简的 API 换来了强大的能力一个函数指针 一条LD_PRELOAD你就能在用户空间掌控几乎全部系统调用。下一步不妨动手改一改fork_ban.c或syscall_logger.c实现一个属于你自己的沙箱或审计工具吧【免费下载链接】syscall_interceptThe system call intercepting library项目地址: https://gitcode.com/gh_mirrors/sy/syscall_intercept创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考