KernelSU 深度解析:基于内核的 Android GKI Root 解决方案
【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU
KernelSU 是一款面向 Android GKI(Generic Kernel Image,通用内核镜像)设备的 root 解决方案。它与传统 root 方案最大的区别在于:以内核模式(kernel mode)工作,并直接在内核空间为用户空间应用授予 root 权限,而不是通过用户空间的守护进程代理提权。本文将以官方文档为主线,结合本仓库的内核源码(kernel/目录)逐层拆解其"基于内核"的技术本质、内核级能力清单、metamodule 可插拔模块架构,以及安装与编译的基本路径,帮助你从原理到实践完整理解这一方案。
KernelSU 是什么:直接在内核空间授权的 root 方案
根据官方文档的定义(见 website/docs/pt_BR/guide/what-is-kernelsu.md,英文原文见 website/docs/guide/what-is-kernelsu.md):
KernelSU 是一个针对 Android GKI 设备的 root 解决方案,它以内核模式工作,并直接在内核空间为用户空间应用授予 root 权限。
这句话包含三个关键限定:
- 面向 GKI 设备:GKI 是 Google 为统一 Android 内核而推出的架构,其核心概念是 KMI(Kernel Module Interface,内核模块接口)。相同 KMI 的内核互相兼容,这是 KernelSU 能以通用镜像形式分发的前提。
- 内核模式工作:KernelSU 的主体以内核模块/内核补丁的形式运行在内核态,而不是像传统方案那样以内核加载的辅助进程 + 用户态守护进程协同工作。
- 内核空间直接授权:当应用申请 root 时,授权动作发生在内核态,由内核代码直接完成凭据(credential)切换与 SELinux 域转换,不依赖任何用户态 daemon 的转发。
核心特性:基于内核(Kernel-based)带来的内核级能力
KernelSU 的主要特性就是"基于内核"。由于整个 root 体系构建在内核态,它能够提供一个"此前从未拥有过的内核接口"。官方文档明确列出了以下典型能力:
- 在内核模式下向任意进程添加硬件断点(hardware breakpoints):内核态代码可以对任意进程的指令流设置硬件断点,用于调试、监控或动态修改执行流。
- 以不可见(invisible)的方式访问任意进程的物理内存:内核态可以直接操作物理内存映射,从而读取或修改任意进程的内存,且对目标进程完全透明。
- 在内核空间拦截任意系统调用(syscall):这是最核心的机制,也是 KernelSU 实现 root 授权、隐藏自身等能力的基础。
源码佐证:syscall 拦截机制如何实现
"拦截任意 syscall"在源码中有完整的实现支撑。以 ARM64 架构为例,kernel/hook/arm64/syscall_hook.c 展示了其关键设计:
- 解析
sys_call_table:初始化时通过符号解析拿到系统调用表基址(ksu_resolve_symbol_for_functable_hook("sys_call_table")); - 寻找空槽位:在表中寻找指向
__arm64_sys_ni_syscall的槽位(即未实现的 syscall 编号),作为统一分发器(dispatcher)的驻留位置(ksu_find_ni_syscall_slots); - 补丁系统调用表:通过
ksu_patch_text将 dispatcher 写入该槽位,同时保存原始函数指针,在模块退出时逐一恢复(ksu_syscall_table_unhook/ksu_syscall_hook_exit); - 统一分发:
ksu_syscall_dispatcher从寄存器中还原原始 syscall 编号,再查syscall_hooks[]路由表分发给对应的 hook 处理函数(ksu_register_syscall_hook/ksu_unregister_syscall_hook)。
也就是说,所有 syscall hook 共享同一个 dispatcher 槽位,通过一张路由表分发,这既避免了频繁修改只读的系统调用表,也保证了卸载时可完整恢复原状。
源码佐证:内核态授权与 ioctl 命令分发
内核态"直接授权"则体现在 supercall(超级调用)机制上。kernel/supercall/supercall.c 创建了一个匿名 inode([ksu_driver]/[ksu_driver_su]),用户空间通过ioctl与其通信;kernel/supercall/dispatch.c 维护了一张 IOCTL 命令分发表ksu_ioctl_handlers[],涵盖:
| 命令 | 用途 | 权限检查 |
|---|---|---|
GRANT_ROOT | 授予 root(切换凭据与 SELinux 域) | allowed_for_su |
GET_INFO/GET_INFO_LEGACY | 查询内核版本、LKM/Manager 标志、UAPI 版本 | always_allow |
REPORT_EVENT | 上报post-fs-data、boot-completed、module-mounted等启动事件 | only_root |
GET_ALLOW_LIST/GET_DENY_LIST | 读写 root 授权名单 | manager_or_root |
GET_APP_PROFILE/SET_APP_PROFILE | 读写应用配置文件(能力、groups 等) | only_manager |
ADD_TRY_UMOUNT | 注册/清理需要尝试卸载的挂载点 | manager_or_root |
GET_SULOG_FD | 获取 su 日志文件描述符 | only_root |
每个命令都带有独立的权限检查函数(见 kernel/supercall/perm.c:only_manager、only_root、manager_or_root、always_allow、allowed_for_su),在分发前统一校验,未通过则返回-EPERM。其中GRANT_ROOT的处理函数do_grant_root调用escape_with_root_profile()完成提权,并通过ksu_sulog_emit_grant_root记录审计日志。
初始化链路
内核侧的整体初始化集中在 kernel/core/init.c 的kernelsu_init中,顺序依次为:符号解析器(ksu_init_symbol_resolver)→ syscall hook(ksu_syscall_hook_init)→ feature 开关(ksu_feature_init)→ su 日志(ksu_sulog_init)→ adb root(ksu_adb_root_init)→ LSM hook(ksu_lsm_hook_init)→ SELinux 隐藏(ksu_selinux_hide_init)→ supercall(ksu_supercalls_init)→ 应用配置文件(ksu_app_profile_init)→ 白名单(ksu_allowlist_init)→ ksud 集成(ksu_ksud_init)等。kernelsu_exit则按相反顺序安全卸载,先停 hook、再同步 RCU、最后释放数据结构。
metamodule 系统:可插拔的模块管理架构
官方文档强调的第二大特性是metamodule(元模块)系统。与把挂载(mounting)逻辑写死在内核核心的传统 root 方案不同,KernelSU 将模块的安装与挂载逻辑委托给 metamodule,形成可插拔架构。详见 website/docs/pt_BR/guide/metamodule.md。
为什么需要 metamodule
传统方案把挂载逻辑内置于核心,导致两个问题:一是容易被检测(检测点集中),二是演进困难。metamodule 架构通过关注点分离解决:
- 降低检测面:KernelSU 自身不执行挂载,减少可被扫描的检测向量;
- 稳定性:核心保持稳定,挂载实现可以独立演进;
- 创新空间:社区无需 fork 即可开发替代挂载策略;
- 用户选择权:可选择无挂载、OverlayFS 挂载、兼容 Magisk 的 Magic mount、乃至 FUSE 自定义实现。
重要警告:未安装任何 metamodule 时,模块不会被挂载。全新安装 KernelSU 后,需要安装一个 metamodule(如官方的meta-overlayfs)才能让需要修改/system等分区的模块生效。仅使用脚本、sepolicy 规则或system.prop的模块则不需要 metamodule。
metamodule 的关键特征
- 基础设施角色:为普通模块提供依赖的基础服务;
- 单实例:同一时间只能安装一个 metamodule,避免冲突;
- 优先执行:metamodule 的脚本先于普通模块脚本执行;
- 三个专用 hook:
metamount.sh(挂载处理)、metainstall.sh(安装 hook)、metauninstall.sh(卸载清理)。
开发者视角:如何编写 metamodule
一个 metamodule 通过module.prop中的metamodule=1(或metamodule=true)属性标识,推荐以meta-前缀命名 ID。目录结构示意:
meta-example/ ├── module.prop (必须包含 metamodule=1) ├── metamount.sh (可选:自定义挂载处理) ├── metainstall.sh (可选:普通模块安装 hook) ├── metauninstall.sh (可选:普通模块卸载清理 hook) ├── customize.sh (标准模块文件,均可选) ├── post-fs-data.sh ├── service.sh ├── boot-completed.sh ├── uninstall.sh └── [其他文件]metamount.sh执行挂载时必须将挂载源(source/device)设置为"KSU",例如:
mount -t overlay -o lowerdir=/lower,upperdir=/upper,workdir=/work KSU /target或使用现代 mount API:
fsconfig_set_string(fs, "source", "KSU")?;这是内核卸载逻辑(kernel_umount)与 zygisk 卸载逻辑正确识别、管理这些挂载的前提。
安装 metamodule 后,KernelSU 会创建稳定符号链接:
/data/adb/metamodule -> /data/adb/modules/<metamodule_id>官方的meta-overlayfs是参考实现,采用"元数据目录(/data/adb/modules/)+ 内容目录(/data/adb/metamodule/mnt/,ext4 镜像modules.img)"的双目录架构,支持 system、vendor、product、system_ext、odm、oem 等多个分区的 systemless 修改。
如何安装与使用 KernelSU
官方文档将安装指引指向 安装指南(英文版见 website/docs/guide/installation.md)。其核心流程与前置知识如下。
前置检查
- 设备支持性检测:安装 KernelSU Manager 应用,若显示
Unsupported,说明需要自行编译内核(官方永不提供通用 boot.img);若显示Not installed,则设备受官方支持。 - 备份原始 boot.img:刷写前务必备份原厂 boot 镜像,bootloop 时可通过 fastboot 恢复。
- 理解 KMI:KMI(Kernel Module Interface)相同的内核版本互相兼容。内核版本格式为
w.x.y-zzz-k-something,其中w.x-zzz-k即 KMI(如5.10.101-android12-9-g30979850fc20的 KMI 是5.10-android12-9)。注意 SubLevel(.y)不属于 KMI。同时要关注安全补丁级别(Security patch level),较新的设备可能存在防回滚机制。
两种运行模式
自 0.9.0 起,KernelSU 在 GKI 设备上支持两种运行模式:
- LKM 模式:将可加载内核模块(Loadable Kernel Module)加载进设备内核,不替换原内核。优点:不替换原内核、升级与 OTA 更方便、不触发 AVB、可临时卸载。手机设备推荐优先使用。
- GKI 模式:用 KernelSU 提供的通用内核镜像替换设备原内核。优点:通用性强(如三星 KNOX 设备 LKM 无法工作)、无需依赖官方固件。模拟器、WSA、Waydroid 推荐使用。
安装方式摘要
- Manager 安装(LKM):选择文件自动补丁;已 root 时直接安装;支持安装到非活动槽位(A/B 分区)。
- 命令行安装(LKM):使用
ksud boot-patch补丁官方固件:
ksud boot-patch -b <boot.img> --kmi android13-5.10- GKI 模式:fastboot 刷写官方 boot.img(
fastboot flash boot boot.img)、使用 Kernel Flasher 等内核刷写应用、手动用 magiskboot 补丁 boot.img、或通过 TWRP 等自定义 Recovery 刷入 AnyKernel3 包。
安装后的模块支持
安装 KernelSU 后,若要使用修改/system文件的模块,需要额外安装 metamodule(参考 Metamodule 指南),官方实现为meta-overlayfs。
如何编译 KernelSU
官方文档将编译指引指向"如何构建"章节。结合本仓库,内核侧源码位于 kernel/ 目录,其中:
- kernel/Makefile 与 kernel/Kbuild 定义内核模块的构建规则;
- kernel/Kconfig 提供编译期特性开关(如调试模式、SELinux 策略支持等);
- kernel/setup.sh 提供环境准备脚本;
- 用户空间组件(ksud、ksuinit)位于 userspace/,使用 Rust 编写(见 userspace/ksud/Cargo.toml)。
注意:KernelSU 以"与内核源码共同编译"或"作为 LKM 模块加载"两种形态存在(对应kernelsu_init中#ifdef MODULE分支,见 kernel/core/init.c)。若设备显示Unsupported,则需要将内核源码与 KernelSU 集成后自行编译。
内核侧能力总览(延伸阅读)
结合仓库结构,内核模块按功能划分了清晰的子目录,可作为理解"基于内核"能力的索引:
| 目录 | 职责 |
|---|---|
| kernel/hook/ | syscall hook(arm64/x86_64)、LSM hook、setuid hook、tracepoint 标记 |
| kernel/supercall/ | 内核态超级调用:ioctl 分发、权限检查、提权 |
| kernel/policy/ | root 授权白名单(allowlist)、应用配置文件(app_profile)、特性开关 |
| kernel/selinux/ | SELinux 策略注入与 hiding |
| kernel/sulog/ | su 使用日志记录 |
| kernel/feature/ | adb root、内核卸载(kernel_umount)、SELinux 隐藏等特性实现 |
| kernel/infra/ | 事件队列、文件包装、符号解析、seccomp 缓存等基础设施 |
用户空间侧的 ksud(见 userspace/ksud/src/main.rs)负责模块管理、引导补丁、resetprop、sepolicy 处理等任务,与内核侧通过 supercall 接口协作。
讨论与社区
KernelSU 项目设有 Telegram 频道(@KernelSU)用于讨论与反馈。仓库根目录下的 README 文档(含多语言版本)可作为进一步了解项目定位的入口;本站文档以 website/docs/ 为总入口,提供安装、模块开发、metamodule、常见问题等多语言指南。
结语
KernelSU 的独特之处在于把 root 能力整体下沉到内核态:从 syscall 表补丁与统一分发(kernel/hook/arm64/syscall_hook.c),到基于匿名 inode 的 supercall 授权通道(kernel/supercall/supercall.c),再到将模块挂载逻辑外置的 metamodule 架构(metamodule 指南),每一层都体现了"以内核为核心、职责分离"的设计哲学。对于希望深入了解 root 实现原理的开发者,从本文梳理的源码路径入手,是理解这套体系最直接的途径。
【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考