>_ DevTrendszh

语言

首页

语言

板块

前端 后端 移动端 DevOps AI / ML 游戏开发 区块链 嵌入式 安全
C

如何在无源代码和调试符号的情况下向Linux内核注入代码

想象这样一个场景:你有一个现成的Linux内核二进制文件,用于移动设备或嵌入式ARM64开发板。没有源代码可用,调试信息在构建时被剥离了,而你需要在内核层面拦截系统调用或添加自己的逻辑。

这种情况下,通常的做法既冗长又繁琐。你需要在IDA Pro或Ghidra中对二进制文件进行逆向工程,手动查找函数偏移量,然后编写脆弱的补丁。一位昵称为bmax121的开发者决定简化这个过程,并发布了KernelPatch项目。

为什么需要KernelPatch

KernelPatch是一个框架,用于在只有剥离的内核映像(如vmlinuxboot.img)的情况下修补和hook Linux内核。

当内核在构建时没有包含调试信息时,传统的调试工具(如kprobes)需要额外的变通方法才能工作。KernelPatch自己解决了这个问题。它直接从内核二进制文件中恢复符号表,并提供了一个方便的API来修改可执行代码。

该项目对逆向工程师、Android安全研究人员和嵌入式系统的底层软件开发人员都很有用。

该框架能做什么

开发者在该项目中构建了几个重要的内核操作能力:

  • 无需源代码的符号搜索。该工具解析现成映像中的内部kallsyms结构。它不需要外部的System.map文件或源代码。类似的方法也被用于vmlinux-to-elf工具中,作者借鉴了其中的一些思路。
  • 两种代码注入模式。你可以对映像进行静态修补(例如,覆盖磁盘上的boot.img),也可以在运行时动态加载代码。
  • 通过内联hook进行函数拦截。对于ARM64架构,调用拦截基于android-inline-hook的工作。该框架正确处理相对寻址指令(bbladrp),以免破坏原始代码的执行。
  • 系统调用hook。替换sys_call_table表中的地址只需几条命令。
  • 内置SU模块。对于Android设备,该项目包含了自己的超级用户实现。

内部工作原理

为了动态加载用户模块(KPM — Kernel Patch Modules),该框架需要内核内部的内存。为此,KernelPatch包含了一个紧凑的TLSF分配器。它帮助在内核地址空间中直接分配可执行内存页(ROX)。

执行内联hook时,框架读取目标函数的前几条指令,从中形成一个所谓的蹦床(trampoline),然后写入跳转到你的处理程序。当你的代码执行完毕后,控制权通过蹦床返回到原始函数。

+-------------------+      +---------------------+      +-------------------+
|  Целевая функция  | ---> |  Ваш обработчик KPM | ---> | Трамплин (Orig)   |
|  (инструкция JMP) |      |  (пользовательский) |      |  (продолжение)    |
+-------------------+      +---------------------+      +-------------------+

系统要求与限制

该项目有明确的适用边界,事先了解很重要:

  • 仅支持ARM64架构。尚无x86_64或RISC-V版本。
  • 内核版本范围——从Linux 3.18到6.6。
  • 主要要求是内核必须启用CONFIG_KALLSYMS=y标志。

如果固件供应商在构建阶段完全移除了CONFIG_KALLSYMS,KernelPatch将无法自动解析函数地址。幸运的是,大多数Android和ARM设备固件都保留了这个标志。

实际使用示例

假设你需要在一台测试用Android设备上追踪所有通过sys_execve调用启动的进程,但不想从供应商源代码重新构建内核。

以前,你不得不构建一个完整的内核可加载模块(LKM),处理数字签名验证问题,以及内核中缺少模块加载器的问题。

使用KernelPatch,流程就不同了:

  1. 你编写一小段带有拦截逻辑的C代码。
  2. 将其编译为KPM格式。
  3. 将你的boot.img和编译好的KPM模块提供给KernelPatch工具。
  4. 获得修改后的boot.img并通过fastboot刷入。

设备启动后,每次调用execve都会先经过你的处理程序。

该项目的README相当简略,所有详细文档都需要从源代码和doc/文件夹中研究。尽管如此,该项目正在积极开发中,已在GitHub上获得了超过14,000颗星。

顺便说一句,如果你不需要该框架本身进行实验,而是需要基于它构建现成的Android root方案,作者建议查看他的另一个项目——APatch。这是Magisk和KernelSU的高级替代方案,底层使用KernelPatch。

对于安全研究人员和ARM64开发者来说,KernelPatch是一个极好的发现,在分析闭源内核时可以节省数十小时的时间。

相关项目