KPM 的内核 Inline-Hook 能力 — Hook 任何内核函数
什么是 Inline-Hook
Inline-hook 是内核模块最核心的能力之一:把目标函数开头的几条机器指令(通常是 jmp 跳转)替换成一段跳转到 hook 代码的指令。当目标函数被调用时,CPU 先跳到你的 hook 代码执行,然后(可选地)再跳到原函数继续,或者直接返回。
原函数调用流:call 目标函数 → 执行 A → 执行 B → 执行 C → 返回
Inline-Hook 后:call 目标函数 → 跳转 → 执行你的代码 → 可选跳回原函数 → 返回
KPM 如何实现 Inline-Hook
KernelPatch 框架在内部提供了一套 inline-hook API,KPM 模块可以直接调用:
// 伪代码示例
struct kp_hook *hook = kp_hook_create("do_read", my_hook_func);
kp_hook_install(hook);
上面的代码做了:
- 通过内核符号表找到
do_read函数的地址 - 创建一个 hook 对象,指定目标函数和你自己的替换函数
- 框架自动处理机器指令替换和 trampoline(让你能跳到原函数继续执行)
- 安装 hook,生效
整个过程不需要你写汇编,KernelPatch 框架都封装好了。
能做什么
隐藏 Root 痕迹
比如 hook access() 系统调用——当有 App 检查 /sbin/su 是否存在时,hook 返回"文件不存在"。比 APM 的白名单机制更彻底,因为 APM 还是在用户空间层面拦截,KPM 在内核层面拦截,检测 App 根本不知道自己被拦了。
保护系统分区镜像
hook do_fsync 或 vfs_write——阻止任何进程向 boot 分区写入,防止恶意修改或意外操作。
自定义进程行为
hook copy_process——在进程创建时做一些定制(比如给特定进程隐藏某些文件、标记特殊属性)。
绕过各种检测
SafetyNet、Play Integrity、银行 App 的 root 检测逻辑最终都会落到内核层面的某些操作(open syscall、stat syscall 等),用 KPM inline-hook 拦截这些 syscall 就能绕过检测。
写 Inline-Hook 的注意事项
- 写不好直接搞挂内核:内核 panic 重启、bootloop 都是 inline-hook 写错的常见后果
- hook 优先级:hook 同一个函数的多个 KPM 要注意调用链的顺序(hook A 先跳、hook B 后跳,顺序影响最终行为)
- 性能开销:inline-hook 每被调用一次都有一次跳转开销,hook 热路径函数(如调度器)要谨慎
- 不要在内核睡眠上下文做阻塞操作
从哪里学
KernelPatch 官方有 KPM 编写指南和示例代码,GitHub 上能找到:
- KernelPatch 仓库的 doc/zh-CN/module.md
- 示例 KPM(如 root-hide、partition-protect)可以作为起点