SELinux 处理 — Hook 绕过 vs 修改 Policy
SELinux 是什么
SELinux(Security-Enhanced Linux)是 Android(基于 Linux)的强制访问控制(MAC)机制。它定义了一套"域—类型"的规则,限制每个进程(域)能访问哪些文件、网络端口、其他进程(类型)。
比如:
untrusted_app域的 App 不能访问/data下其他 App 的数据init域的进程可以访问很多东西,包括挂载分区shell域的进程(通过 adb shell 进来的)权限比普通 App 高但比 init 低
root 操作天然会碰到 SELinux——因为 root 进程需要跨越正常的域限制去操作文件。
Magisk 的做法:修改 SELinux Policy
Magisk 的做法很直接:修改 SELinux policy(sepolicy)本身。
它内置了一个叫 magiskpolicy 的工具,在开机时找到 SELinux policy 文件(通常在 /vendor/sepolicy 或 /sepolicy),然后往里面追加规则,让 root 相关的域(magisk、su 守护进程等)能做它们需要做的事。
优点:简单直接,规则永久生效缺点:修改 SELinux policy 本身是个敏感操作,某些检测机制会扫描 policy 是否被篡改
APatch 的做法:Hook 绕过(默认)
APatch 用了一个完全不同的思路:不修改 SELinux policy,而是在内核里 hook SELinux 的检查函数,让检查直接通过。
内核里有一个函数叫 avc_has_perm——每次某个进程想做某个操作时,内核会调用这个函数来问 SELinux "允许吗"。APatch 在这个函数上装了 inline-hook,当发起请求的是 root 线程时,hook 直接返回"允许",不真正去查 SELinux policy。
优点:SELinux policy 文件完全没被修改,任何扫描 policy 的检测机制都看不到异常缺点:hook 有性能开销,某些极端场景下可能不生效
APatch 的补充:magiskpolicy
APatch 并不排斥修改 policy 这条路——它直接引用了 Magisk 的 magiskpolicy 作为可选的补充。某些 KPM 或 APM 可能需要额外的 SELinux 支持,这时可以通过 magiskpolicy 追加规则。
所以 APatch 的 SELinux 处理是两层:
- 默认层:内核 hook 绕过(不修改 policy,最隐蔽)
- 补充层:可选的 magiskpolicy 追加规则(某些场景需要)
两种方案的取舍
| 维度 | Hook 绕过(默认) | magiskpolicy 修改 |
|---|---|---|
| SELinux policy 可见性 | 完全未被修改 | 被追加了规则,扫描可检测 |
| 性能 | 每次操作多一次 hook 检查 | 规则查一次,后续正常走 SELinux |
| 灵活性 | 所有请求都绕过 | 只修改特定规则 |
| 兼容性 | 理论上更好(不碰 policy) | 某些 OEM 的自定义 policy 结构可能不兼容 |
为什么这很重要
Magisk 修改 SELinux policy 的行为是 root 检测的一个重要靶点——某些检测 App 会直接扫描 SELinux policy 文件的哈希值,或者检查里面有没有 magisk 相关的规则。APatch 因为默认不碰 policy,在这类检测上具有天然的优势。