☰
APatch FAQ 深度解读:基于 boot.img 的内核级 Root 方案、KPM 内核模块与 SuperKey 认证机制详解
2026/9/27 3:25:25 网站建设 项目流程
  • 系统编程
  • 移动开发

【免费下载链接】APatch

The patching of Android kernel and Android system

项目地址:https://gitcode.com/gh_mirrors/ap/APatch
点击查看免费下载

APatch 是一个面向 Android 的、以“直接修补内核”为核心的全新 Root 方案,它在安装体验上继承了 Magisk 通过boot.img快速部署的优势,在能力上继承了 KernelSU 内核级修补的强大扩展性。本文以仓库docs/id/faq.md(与docs/en/faq.md同源的官方 FAQ)为骨架,结合 apd 守护进程与 SuperCall UAPI 等源码实现,逐一拆解 APatch 与 Magisk、KernelSU 的差异、Kernel Patch Module(KPM)、SuperKey 认证机制与 SELinux 处理策略,帮助读者理解这套方案的底层工作原理,并掌握相关命令与配置的落地方式。

APatch 是什么:Magisk 与 KernelSU 的融合

官方 FAQ 对 APatch 的定义非常直接:APatch 是一种类似于 Magisk 或 KernelSU 的 Root 解决方案,它取两者之长——既拥有 Magisk 通过boot.img进行的便捷安装方式,又具备 KernelSU 强大的内核修补(kernel patching)能力。仓库 README.md 将其概括为一句定位语:

The patching of Android kernel and Android system.

APatch 的完整能力面包括三部分:

  • APM(APatch Module):提供与 Magisk 类似的模块化支持(systemless 机制),模块目录位于/data/adb/modules,详细开发指南见 模块(APM)开发指南;
  • KPM(Kernel Patch Module):支持向内核注入任意代码,提供内核级inline-hook与syscall-table-hook能力;
  • SuperKey / SuperCall:由内核新增系统调用提供的 userspace 能力入口与访问凭证。

在部署前提上,官方 README.md 明确了两点约束:

  • 仅支持ARM64 架构;
  • 仅支持Android 内核版本 3.18 – 6.12。

此外,内核需要开启符号导出相关配置:CONFIG_KALLSYMS=y且CONFIG_KALLSYMS_ALL=y可获得完整支持;若CONFIG_KALLSYMS_ALL=n则提供初步支持。这些约束决定了 APatch 与 Magisk(几乎不依赖内核配置)在底层实现上的根本差异。

APatch 与 Magisk 的区别:修补 ramdisk 还是直接修补内核

FAQ 用一句话点出了 APatch 与 Magisk 的核心分水岭:

Magisk 通过在 boot image 的 ramdisk 中加入补丁来修改系统的 init 流程,而 APatch 是直接修补内核(kernel)本身。

Magisk 的工作方式是在启动早期对 init 进程进行注入(patch 位于boot.img的 ramdisk 部分),从而在 userspace 层接管系统;而 APatch 的“直接修补内核”体现在:它依赖 KernelPatch 在内核镜像上直接植入代码,再通过内核中的 SuperCall 机制为 userspace 提供能力。

仓库的构建资产也能印证这一点——app/src/main/assets 下提供了boot_extract.sh、boot_patch.sh、boot_unpatch.sh等脚本,其操作对象是设备的boot.img:先提取(extract),再修补(patch),并支持还原(unpatch)。而安装完成后真正承载运行时的,是位于/data/adb/apd的 apd 守护进程(见 apd/src/defs.rs 中DAEMON_PATH定义)以及/data/adb/ap工作目录(WORKING_DIR)。

APatch 与 KernelSU 的对比:只需原厂 boot.img,无需内核源码

KernelSU 是另一款知名的内核级 Root 方案,但它的部署强依赖设备的内核源码。FAQ 指出:

KernelSU 需要你设备内核的源代码,而 OEM 并不总是提供它;APatch 只需你手上的原厂boot.img即可工作。

这一点对普通用户极为关键:内核源码往往是厂商闭源或未公开的,导致 KernelSU 在大量机型上无法部署。而 APatch 直接对官方boot.img进行修补,绕开了源码依赖,大大拓宽了适用机型范围。

从源码看,这一设计还延伸到“越狱模式(jailbreak mode)”:apd/src/late_load.rs 中的late-load流程允许在未预置修补的原厂内核上运行时加载 KernelPatch 内核模块:

  1. 自动检测内核 KMI(Kernel Module Interface,形如android14-5.15),支持从内核 release 字符串解析(parse_kmi);
  2. 查找/data/adb/ap/{kmi}_kernelpatch.ko,若无显式--module参数则使用该默认路径;
  3. 通过 apd/src/insmod.rs 绕过内核严格的版本校验(vermagic / modversions CRC 检查)加载模块,未定义符号从/proc/kallsyms解析;
  4. 在线注入 Magisk 策略(apply_magisk_policy_live),写入/data/adb/ap/jailbreak标记,重启管理器应用并恢复 SELinux enforcing。

其中 apd/src/insmod.rs 的实现细节——临时置kptr_restrict=1以便读取/proc/kallsyms地址、解析 ELF 重定位、调用init_module(2)——正是“无需内核源码也能完成内核级修补”的技术支撑。

APatch vs Magisk 与 KernelSU 的组合对比:线程级 Root 与可选 SELinux 修改

FAQ 进一步指出 APatch 相对 Magisk、KernelSU 的两个差异化能力:

  • APatch 允许你选择不修改 SELinux,这意味着应用(APP)的线程本身就可以被 Root,libsu 与 IPC 都不是必需的。
  • 提供Kernel Patch Module(KPM)。

线程级 Root:免 libsu、免 IPC

在传统方案(如 Magisk)中,Root 一个应用通常需要通过su启动一个全新的进程,再由客户端通过 IPC 与服务端通信——即 libsu 体系。APatch 借助内核直接注入的 SuperCall,可以在应用自己的线程上下文内完成 Root 化,无需拉起新进程,自然也就不需要 libsu 与 IPC。

UAPI 头文件 app/src/main/cpp/uapi/scdefs.h 中对此有直接佐证:

#define SUPERCALL_SU 0x1010 #define SUPERCALL_SU_TASK 0x1011 // syscall(__NR_gettid)

SUPERCALL_SU_TASK的注释表明它基于线程 ID(gettid)工作,可以在指定线程上执行提权操作——这正是“APP 线程可被 Root”的内核侧实现通道。

KPM:内核空间的代码注入能力

FAQ 对 KPM 的定义是:

一些代码运行在 Kernel Space(内核空间),类似于可加载内核模块(Loadable Kernel Modules,LKM)。此外,KPM 还提供在内核空间进行inline-hook和syscall-table-hook的能力。

UAPI 中同样能看到 KPM 的管理命令族:

#define SUPERCALL_KPM_LOAD 0x1020 #define SUPERCALL_KPM_UNLOAD 0x1021 #define SUPERCALL_KPM_CONTROL 0x1022 #define SUPERCALL_KPM_NUMS 0x1030 #define SUPERCALL_KPM_LIST 0x1031 #define SUPERCALL_KPM_INFO 0x1032

这与 apd 守护进程的两个相关子命令对应:apd insmod <module.ko>(不带版本检查地加载内核模块,见 apd/src/cli.rs)以及apd late-load(越狱模式,见 apd/src/cli.rs)。更完整的 KPM 编写指南由上游 KernelPatch 项目提供(其仓库中的doc/module.md),属于内核模块开发者的进阶主题。

APatch 与 KernelPatch 的关系:依赖、继承与扩展

FAQ 明确了二者的关系:

APatch 依赖 KernelPatch,继承了它的全部能力,并在此之上进行了扩展。你也可以只安装 KernelPatch,但这样你将无法使用 Magisk 模块(APM)。

也就是说,KernelPatch 是 APatch 的内核底座(README 的 Credits 部分也把 KernelPatch 称为 “The core”),负责内核修补、SuperCall 注入等底层能力;APatch 在其上叠加了模块机制(APM)、SELinux 策略支持(magiskpolicy)、管理器 UI 等 userspace 生态。只装 KernelPatch 只能获得内核层能力,无法享受 APatch 的模块化生态。

从代码层面看,apd 甚至把 KernelPatch 的版本号作为常量编译进 SuperCall 调用中:apd/src/supercall.rs 通过build.rs生成kp_version.rs,并在ver_and_cmd()中把KP_MAJOR/KP_MINOR/KP_PATCH编码进系统调用的高 32 位(apd/src/supercall.rs):

fn ver_and_cmd(cmd: c_long) -> c_long { let version_code: u32 = ((KP_MAJOR << 16) + (KP_MINOR << 8) + KP_PATCH) .try_into() .unwrap(); ((version_code as c_long) << 32) | (0x1158 << 16) | (cmd & 0xFFFF) }

这里的0x1158正是 UAPI 中定义的SUPERCALL_HELLO_MAGIC低 16 位(app/src/main/cpp/uapi/scdefs.h),用于内核侧校验调用协议的合法性。

SuperKey 与 SuperCall:内核级的能力入口与访问凭证

这是 FAQ 中最具技术分量的部分:

KernelPatch 新增了一个系统调用(syscall),为 userspace 的应用与程序提供全部能力,这个系统调用被称为SuperCall。当应用/程序尝试调用 SuperCall 时,需要提供访问凭证,即SuperKey。只有当 SuperKey 正确时 SuperCall 才能被成功调用;否则调用方不会受到任何影响。

调用约定与命令码

SuperCall 复用了truncate的系统调用号(ARM64 上为 45),通过命令码分发不同功能。UAPI 头文件 app/src/main/cpp/uapi/scdefs.h 明确定义:

// #define __NR_supercall __NR3264_truncate // 45 #define __NR_supercall 45

所有功能按命令码组织,涵盖:

命令码宏定义功能
0x1000SUPERCALL_HELLO握手探测(hello)
0x1008 / 0x1009SUPERCALL_KERNELPATCH_VER/SUPERCALL_KERNEL_VER查询 KernelPatch 与内核版本
0x100a–0x100cSUPERCALL_SKEY_GET/SET/ROOT_ENABLESuperKey 读取、设置与 Root 使能
0x1010 / 0x1011SUPERCALL_SU/SUPERCALL_SU_TASK提权(进程级 / 线程级)
0x1020–0x1032SUPERCALL_KPM_*KPM 模块的加载、卸载、控制与枚举
0x1040–0x1046SUPERCALL_KSTORAGE_*内核存储(kernel storage)读写与分组管理
0x1100–0x1112SUPERCALL_SU_*SU 授权管理:授予/撤销 UID、列表、安全模式等

其中与“Root 授权管理”直接相关的一组(SUPERCALL_SU_GRANT_UID 0x1100、SUPERCALL_SU_REVOKE_UID 0x1101、SUPERCALL_SU_NUMS 0x1102、SUPERCALL_SU_LIST 0x1103)在 apd 中被封装为完整的管理流程:apd/src/supercall.rs 的refresh_ap_package_list()会先查询已授权 UID 数量、拉取列表、逐个撤销,再依据包配置重新授予,实现 Root 授权列表与系统包管理的同步。

密钥校验:SuperKey 如何工作

SuperCall 的身份验证发生在内核侧:调用者把 SuperKey 以 C 字符串指针传入系统调用,内核用与 UAPI 中hash_key()相同的算法(app/src/main/cpp/uapi/scdefs.h,初值1000000007、逐字符hash * 31 + c)对密钥做哈希比对,匹配才放行。密钥有长度上限SUPERCALL_KEY_MAX_LEN 0x40(64 字节)。

提权时的目标描述结构su_profile(app/src/main/cpp/uapi/scdefs.h)包含三个字段:

struct su_profile { uid_t uid; uid_t to_uid; char scontext[SUPERCALL_SCONTEXT_LEN]; // 0x60 };

即“当前 UID → 目标 UID(通常为 0/root)”以及目标 SELinux 上下文。apd 在启动时若带有--superkey参数,会先以该结构自我提权(privilege_apd_profile,见 apd/src/supercall.rs),使用的上下文为u:r:magisk:s0。

在 userspace,apd 的 CLI 把 SuperKey 作为全局参数暴露(apd/src/cli.rs):

-s, --superkey <KEY> Super key for authentication root

所有需要内核能力的子命令(如post-fs-data、boot-completed、soft-reboot)都会携带该参数。日常使用中,内核也会以argv[0]为/system/bin/kp或/system/bin/su的方式直接 exec apd,进入 su 兼容的 Root Shell(见 apd/src/cli.rs 与 apd/src/apd.rs 的root_shell())。

安全警告:SuperKey 权限高于 Root

由于 SuperKey 直接控制内核注入的 SuperCall 通道,README 的 Security Alert 特别强调:

SuperKey 拥有比 Root 更高的权限。弱密钥或被泄露的密钥可能导致设备被未授权控制。使用强健的密钥并妥善保管至关重要。

这与 FAQ 中“SuperCall 只有在 SuperKey 正确时才能成功调用”的描述互为印证——SuperKey 本质上是内核级能力总开关,其安全级别高于普通的su授权。

SELinux 处理:hook 绕过不改变上下文,magiskpolicy 补充策略

FAQ 的最后一个技术点聚焦 SELinux:

  • KernelPatch不修改 SELinux 上下文,而是通过 hook 绕过 SELinux 检查。这使得你可以直接在应用上下文内 Root 一个 Android 线程,而无需借助 libsu 启动新进程再做 IPC,非常实用。
  • 此外,APatch直接使用 magiskpolicy提供额外的 SELinux 支持。

两套并行的 SELinux 策略

理解这一点需要区分“绕过”与“补充”两条路径:

  1. KernelPatch 的 hook 绕过:不触碰 SELinux 的上下文属性(context),也不改动策略文件,而是在内核中对 SELinux 检查点做 hook,从而在保留原上下文的条件下放行目标操作——这正是线程级 Root 得以实现的前提。
  2. APatch 的 magiskpolicy 注入:apd 移植了 Magisk 的 magiskpolicy 工具,在启动阶段向内核加载策略补丁。相关实现位于 apd/src/sepolicy.rs:其apply_magisk_policy_live()(apd/src/sepolicy.rs)等价于执行magiskpolicy --magisk --live——从/sys/fs/selinux/policy加载当前策略、注入内置的 Magisk 规则、再写回/sys/fs/selinux/load。

magiskpolicy 的完整用法

apd 还通过 multicall 方式直接提供magiskpolicy命令(argv[0]以magiskpolicy结尾时进入该模式,见 apd/src/cli.rs),选项与 Magisk 原生工具一致,见 apd/src/sepolicy.rs:

选项说明
--load FILE从指定文件加载单一 sepolicy
--load-split从预编译 sepolicy 或编译 split cil 策略加载
--compile-split编译 split cil 策略
--save FILE将策略导出到文件
--live立即将策略载入内核(写入/sys/fs/selinux/load)
--magisk应用内置的 Magisk sepolicy 规则
--apply FILE按行读取并应用策略语句文件(可多次指定)
--print-rules打印已加载策略中的全部规则
(位置参数)直接追加的 policy statements

在启动事件中的实际应用

SELinux 策略注入不是孤立操作,它被编排进完整的启动事件流。以post-fs-data阶段为例(apd/src/event.rs),apd 依次执行:加载 live policy 并应用 Magisk 规则、写入/sys/fs/selinux/load、重新为自身提权(刷新 SuperCall 上下文)、执行模块脚本与 Lua 阶段钩子、加载system.prop、触发post-mount等。整个生命周期由 apd/src/cli.rs 中的子命令驱动:

apd post-fs-data # 触发 post-fs-data 事件 apd services # 触发 service 事件 apd boot-completed # 触发 boot-completed 事件 apd uid-listener # 监听包列表变化,同步 Root 授权 apd soft-reboot # 模拟系统重启(保留运行时加载的模块) apd resetprop ... # Magisk 兼容的属性读写工具 apd sepolicy ... # magiskpolicy 的封装入口

从 FAQ 到实践:常用路径、命令与注意事项

为了让 FAQ 中的概念落地,这里汇总仓库中可确认的运行时关键路径与常用入口:

  • 工作目录:/data/adb/ap,二进制位于/data/adb/ap/bin(含 Magisk 同源编译的 BusyBox,见 apd/src/defs.rs 与 模块开发指南);
  • 守护进程:/data/adb/apd,同时承担su/kp/resetprop/magiskpolicy的 multicall 入口;
  • 模块目录:/data/adb/modules(APM),/data/adb/metamodule(元模块),详见 apd/src/defs.rs;
  • SuperCall 事件通道:内核通过truncate二进制(SUPERCMD,app/src/main/cpp/uapi/scdefs.h)向 apd 上报事件(见 apd/src/event.rs 的report_kernel);
  • 安全模式:/dev/.safemode标记(app/src/main/cpp/uapi/scdefs.h),进入安全模式会跳过模块脚本并禁用全部模块,避免 bootloop。

需要留意的部署限制

  • 仅支持 ARM64,且内核版本需在 3.18 – 6.12 区间内(README.md);
  • 内核需满足CONFIG_KALLSYMS相关配置要求(详见本文第一节);
  • 安装基于官方boot.img的修补流程,脚本见 app/src/main/assets(boot_extract.sh、boot_patch.sh、boot_unpatch.sh、InstallAP.sh、UninstallAP.sh);
  • 启用/卸载请务必遵循官方安装说明;SuperKey 请使用高强度的密钥并妥善保管。

结语

APatch 的 FAQ 虽短,但每个条目都指向一组清晰的工程决策:用直接修补内核的方式取代 ramdisk 注入(vs Magisk),用原厂boot.img取代内核源码依赖(vs KernelSU),用 SuperCall + SuperKey 实现线程级 Root 与内核级能力开放(vs libsu/IPC 体系),并用“hook 绕过 + magiskpolicy 补充”双轨处理 SELinux。理解这些底层机制,有助于开发者更安全、更高效地使用 APM/KPM 生态,也能在排障时(如安全模式、SuperKey 失效、SELinux 策略冲突)快速定位问题所在的层次——是内核侧(KernelPatch/SuperCall)还是 userspace 侧(apd/模块脚本/magiskpolicy)。

  • 系统编程
  • 移动开发

【免费下载链接】APatch

The patching of Android kernel and Android system

项目地址:https://gitcode.com/gh_mirrors/ap/APatch
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询