
KernelSU 环境下隐藏 Root 检测实战:大麦、淘宝全部正常打开
机型:OnePlus PJX110(OnePlus 13) · Android 16 · 内核 6.1.141
适用:KernelSU(含 LKM 模式)用户,被大麦、淘宝等阿里系 App 检测到 Root 而无法打开的场景
一、前言
事情起因很简单:手机 ROOT 之后,大麦(cn.damai) 打开就提示”检测到系统处于不安全状态”之类的风险提示,直接退出;淘宝(com.taobao.taobao) 同样被阿里安全组件(SecurityGuard / 安全SDK)拦下。
这类 App 的检测手段无非那几样:
- 检测
su二进制是否存在 - 检测
/data/adb目录(Magisk / KernelSU 的数据目录) - 检测 Root 管理器包名(
com.topjohnwu.magisk、me.weishu.kernelsu) - 检测模块挂载(
/data/adb/modules) - 检测 Xposed / LSPosed / Frida 痕迹
- 检测 Bootloader 解锁状态(Key Attestation)
我的环境里其实早就装了 Shamiko(隐藏 Root 的经典模块)和 Tricky Store(绕过 Key Attestation),但大麦依然打不开。排查到最后发现:问题出在我对”新版 KernelSU 的隐藏机制”理解过时了——新版本早就没有”排除名单(DenyList)”了,而 Shamiko 在白名单模式下恰好依赖这个东西,等于完全没在工作。
这篇文章把我从”App 打不开”到”全部正常打开”的完整排查过程写下来,每一步都附上实测命令,希望能帮到同样被检测困扰的朋友。
二、环境清单
| 项目 | 版本/内容 |
|---|---|
| 手机 | OnePlus PJX110(OnePlus 13) |
| 系统 | Android 16(ColorOS 分支) |
| 内核 | 6.1.141-android14-11 |
| Root 方案 | KernelSU v3.2.4(ksud 3.2.4 / 管理器 v3.2.4,LKM 模式) |
| Zygisk | ZygiskNext v1.3.3(zygisksu 模块) |
| 隐藏模块 | Shamiko v1.2.5(白名单模式) |
| 认证绕过 | Tricky Store v6.0.0-235(TEESimulator) |
| Xposed | Zygisk-LSPosed v2.0.2 |
| 其他模块 | RescueBrick、TA_utl、WorkSettingPro、reqable-magisk |
| 目标 App | 大麦 cn.damai、淘宝 com.taobao.taobao |
内核功能状态(ksud feature list):
[ENABLED (1)] su_compat -- 允许已授权 App 通过 su 获取 Root
[ENABLED (1)] kernel_umount -- 内核自动为不需要的进程卸载模块挂载
[ENABLED (1)] sulog -- su 日志
[DISABLED] adb_root -- adbd root(未开启)
三、核心认知:新版 KernelSU 的隐藏机制(先读懂再动手)
老玩家都知道,Magisk 时代隐藏 Root 的标准姿势是:把目标 App 加进 Magisk 排除名单(DenyList)+ 开 Shamiko 白名单模式。
KernelSU 早期(v1.x 之前)也照搬了这套:管理器里有”排除名单”页,把 App 加进去,内核就会对这个 App 卸载模块挂载。
但是新版 KernelSU(v2/v3,ksud 3.x)把排除名单整个删掉了。 我在 GitHub 上拉了源码(tiann/KernelSU 主分支)确认:
- 全仓库搜索
denylist/deny_list/ “排除”,零结果 - 取而代之的是
kernel/feature/kernel_umount.c这套全局内核卸载机制
它的逻辑(读源码 kernel_umount.c 可以看得很清楚):
static bool ksu_kernel_umount_enabled = true; // 默认开启
int ksu_handle_umount(uid_t old_uid, uid_t new_uid) {
// 1. 有模块挂载才处理
if (!ksu_module_mounted) return 0;
// 2. 开关没开就跳过
if (!ksu_kernel_umount_enabled) return 0;
// 3. 只处理"App uid"和"隔离进程"(zygote fork 出来的)
if (!is_appuid(new_uid) && !is_isolated_process(new_uid)) return 0;
// 4. 白名单(已授权 Root 的 App)不卸载
if (!ksu_uid_should_umount(new_uid) && !is_isolated_process(new_uid)) return 0;
// 5. 只处理 zygote 子进程(防止误伤全局命名空间的进程)
if (!is_zygote_child) return 0;
// 6. 把 mount_list 里的挂载点全部卸载
list_for_each_entry(entry, &mount_list, list) {
try_umount(entry->umountable, entry->flags);
}
}
翻译成人话:
新版 KernelSU 默认给所有普通 App 卸掉模块挂载(含 su、管理器 APK、模块目录),只有”已授权 Root 的 App”(白名单)能保留。不需要也不存在排除名单。
所以旧经验”加排除名单 + Shamiko 白名单”在新版 KernelSU 上完全失效——因为名单本身没了,Shamiko 在白名单模式下找不到任何要处理的 App,等于挂机。
这一条是整个排查中最关键的一步:先搞清楚你的 Root 方案的隐藏机制是什么版本,再谈怎么配。
四、排查全流程(每一步都实测)
步骤 0:准备工作
- 手机已 ROOT(KernelSU)
- Termux 里能拿到 root shell(我全程用 Termux +
su操作) - 建议先把关键信息存档:
ksud -V、模块列表、内核功能状态
步骤 1:摸清 Root 环境
# Root 方案与版本
ksud -V # 输出: ksud 3.2.4
dumpsys package me.weishu.kernelsu | grep versionName # 管理器 v3.2.4
# 已安装模块
ls /data/adb/modules/
# 输出: RescueBrick TA_utl WorkSettingPro reqable-magisk shamiko tricky_store zygisk_lsposed zygisksu
# 内核功能开关(重点看 kernel_umount)
ksud feature list
⚠️ 注意:不同 KernelSU 版本命令可能不同(老版本是
ksud denylist,新版本没有)。以ksud --help实际输出为准。
步骤 2:确认目标 App 的包名
pm list packages | grep -E "damai|taobao"
# 输出:
# package:cn.damai ← 大麦
# package:com.taobao.taobao ← 淘宝
# package:com.taobao.idlefish ← 闲鱼(顺带发现)
# 拿 uid(后面验证要用)
pm list packages -U | grep cn.damai
# 输出: package:cn.damai uid:10421,1010421 ← 大麦的 uid 是 10421
# 解析启动入口(别猜 Activity 名,猜了会 Error type 3)
cmd package resolve-activity --brief cn.damai
# 输出: cn.damai/.launcher.splash.SplashMainActivity
步骤 3:读源码,确认隐藏机制(不读源码全靠猜会走弯路)
# 稀疏克隆 KernelSU 源码(只拉需要的目录,很快)
git clone --depth 1 --filter=blob:none --sparse https://github.com/tiann/KernelSU /tmp/ksu-src
cd /tmp/ksu-src
# 全仓搜排除名单 —— 结果:没有了
git grep -i "denylist" HEAD # 空
# 看内核卸载实现
git show HEAD:kernel/feature/kernel_umount.c
结论在第三节已经说了:新版是”全局卸载 + 授权白名单“,没有排除名单。同时确认了几个关键事实:
ksu_uid_should_umount()只对已授权 Root 的 App 返回 false(不卸载)- 卸载发生在 zygote fork 的 setresuid 阶段,普通 App 一出生就看不到模块挂载
kernel_umount功能默认开启(ksu_kernel_umount_enabled = true)
步骤 4:从目标 App 的进程视角验证(本文最核心的方法)
光看源码不算数,要站在 App 的角度看它到底能”看见”什么。方法是:启动目标 App,拿到它的 pid,然后钻进它的进程视角检查。
# 启动大麦(用步骤 2 解析出来的真实入口)
am start -n cn.damai/.launcher.splash.SplashMainActivity
sleep 5
PID=$(pidof cn.damai | awk '{print $1}')
echo $PID # 例:29946
# ① 检查模块挂载是否已从它的挂载命名空间消失
cat /proc/$PID/mounts | grep -iE "modules|ksu|magisk"
# (输出为空 = 模块挂载已被内核卸载 ✅)
# ② 检查 su 二进制对它是否可见
ls /proc/$PID/root/system/bin/su
# (No such file or directory = su 已隐藏 ✅)
# ③ 检查 Root 管理器 APK 目录对它是否可见
ls /proc/$PID/root/data/app | grep -i weishu
# (输出为空 = 管理器已隐藏 ✅)
# ④ 检查它是否有独立挂载命名空间
readlink /proc/$PID/ns/mnt
# 输出形如 mnt:[4026535821](独立命名空间 ✅)
# ⑤ 检查它的 SELinux 上下文是否正常
cat /proc/$PID/attr/current
# 输出形如 u:r:untrusted_app:s0:c165,...(普通 App 上下文 ✅)
正确读法:①②③ 都是”空/不存在”才是对的——这正是我们要的效果。
步骤 5:一次误报的教训(非常容易踩)
我第一次检查 /data/adb 时,用的命令是:
ls /proc/$PID/root/data/adb
# 居然输出了 ksu ksud lspd 三个目录!
当场以为内核隐藏失效了,差点去改 Shamiko 配置。但仔细一想:我是用 root 身份执行的这条命令——/proc/$PID/root 只是把路径解析到 App 的命名空间里,真正做权限检查的依然是我的 root 凭据。root 当然什么都能读!
正确做法是用 App 自己的 uid 去探测(KernelSU 的 su 支持切到任意 uid):
# 大麦 uid = 10421
su 10421 -c 'ls -ld /data/adb'
# 输出: drwx------ 11 root root ... /data/adb
# (能 stat 到,但下面的 ls 会…)
su 10421 -c 'ls /data/adb'
# 输出: ls: /data/adb: Permission denied ✅ 这才是 App 的真实视角
真实情况:/data/adb 是 drwx------ root root + u:object_r:adb_data_file:s0,普通 App 根本进不去,Permission denied 就是它唯一能得到的答案。用 root 身份测试会得到完全错误的结论。
方法论总结:验证”App 能看到什么”,就必须以 App 的 uid/SELinux 上下文去测。用 root 测等于白测。
步骤 6:重启一次,问题消失
所有验证都显示”内核隐藏已生效”,但 App 依然打不开。这时候我做了一件简单的事:重启手机。
重启之后:
- 大麦正常打开,正常登录、浏览 ✅
- 淘宝正常打开 ✅(同一套机制,顺带也解决了)
复盘为什么重启是关键:
- 重启前系统处于”修复过环境”的中间状态(之前 gateway 进程曾以 root 身份运行、目录属主混乱、还遇到过
app_process链接libmediandk.so失败的怪问题),zygote 和内核模块状态不干净 - 重启后内核模块、zygote、挂载命名空间全部从干净状态初始化,
kernel_umount在每次 zygote fork 时稳定生效 - 之前 App”检测到 Root”很可能就是因为某个进程/挂载状态残留被阿里安全 SDK 抓到
结论:改完隐藏相关的任何配置(模块、内核功能、属主),都建议重启一次再验证。 重启是最便宜也最彻底的”状态重置”。
五、最终生效的配置清单
以下是我这台机器上最终生效的组合(不是全部必要条件,但值得参考):
| 组件 | 状态 | 作用 |
|---|---|---|
KernelSU v3.2.4 kernel_umount |
✅ 默认开启 | 内核级:为普通 App 卸载模块挂载、隐藏 su、隐藏管理器 APK |
| Shamiko v1.2.5 | ✅ 白名单模式 | 兜底:隐藏 Xposed 痕迹等(新版内核下不依赖排除名单) |
| Tricky Store v6.0.0 | ✅ 已安装 | 绕过 Key Attestation,处理”Bootloader 已解锁”检测 |
| ZygiskNext v1.3.3 | ✅ 已安装 | Shamiko / LSPosed 的运行底座 |
| Zygisk-LSPosed v2.0.2 | ✅ 已安装 | 可选,装其他模块用(注意它本身是检测目标之一) |
几个补充说明:
- kernel_umount 是这一切的地基,它由内核实现,App 层面几乎无法对抗(除非检测到内核模块本身)
- Tricky Store 负责”身份”层面(Play Integrity / Key Attestation),和”痕迹”层面的隐藏互补
- 我没有动 Shamiko 的配置(保持白名单模式),也没有新增任何模块——问题不在模块数量,而在机制理解
六、注意事项与 FAQ
Q1:为什么我加了排除名单还是被检测?
先确认你的 KernelSU 版本:ksud -V。v2/v3 已经没有排除名单功能,旧教程不适用。Magisk 用户不受影响(Magisk 的排除名单还在)。
Q2:Shamiko 还需要吗?
需要,作为兜底。但要注意:Shamiko 的白名单/黑名单模式语义依赖”名单”存在。在新版 KernelSU 上白名单模式可能什么都不处理(我当时就是这状态),是否要改成黑名单模式请先测试 Termux 等需要 Root 的 App 是否还能正常 su。
Q3:为什么验证时用 root 身份会误判?/proc/<pid>/root/... 只切换”路径解析的根”,不切换”权限检查的身份”。要测 App 的真实可见性,用 su <app_uid> -c '...'。
Q4:淘宝能开,别的 App 呢?
同一套机制对绝大多数 App 有效。银行类 App 如果还检测,多半是 Key Attestation 层面(检查 Tricky Store 配置)或检测到 Zygisk/LSPosed 本身。
Q5:会不会影响保修/OTA?
ROOT 本身就会破坏完整性校验,与本方案无关。KernelSU(LKM 模式)一般可以无痕卸载,但这是另一个话题。
七、命令速查表
# 环境
ksud -V # KernelSU 版本
ksud feature list # 内核功能开关
ls /data/adb/modules/ # 模块列表
dumpsys package me.weishu.kernelsu | grep versionName # 管理器版本
# 目标 App
pm list packages | grep -E "damai|taobao" # 找包名
pm list packages -U | grep cn.damai # 拿 uid
cmd package resolve-activity --brief cn.damai # 解析启动入口
am start -n <入口> # 启动
# 进程视角验证(PID=目标进程)
cat /proc/$PID/mounts | grep -iE "modules|ksu|magisk" # 模块挂载(空=已隐藏)
ls /proc/$PID/root/system/bin/su # su(不存在=已隐藏)
ls /proc/$PID/root/data/app | grep -i weishu # 管理器(空=已隐藏)
readlink /proc/$PID/ns/mnt # 独立命名空间
cat /proc/$PID/attr/current # SELinux 上下文
# 以 App uid 验证(关键!)
su <app_uid> -c 'ls /data/adb' # Permission denied = 正常(进不去)
su <app_uid> -c 'ls /system/bin/su' # No such file = 已隐藏
# 源码研究
git clone --depth 1 --filter=blob:none --sparse https://github.com/tiann/KernelSU
git grep -i "denylist" HEAD # 新版 KernelSU:查无此功能
git show HEAD:kernel/feature/kernel_umount.c # 内核卸载实现
八、结语
这次排查看似折腾,其实核心就三件事:
- 读懂你的 Root 方案的隐藏机制(新版 KernelSU = 内核全局卸载 + 授权白名单,没有排除名单)
- 用正确的方法验证(以 App 自己的身份去探测,别用 root)
- 改完配置记得重启(干净的状态比堆模块更重要)
最后送上一句这次踩坑换来的心得:“隐藏 Root”这件事,机制理解 > 模块数量。 装十个模块不如搞清楚内核帮你做了什么、还差什么。
希望这篇记录对你有帮助。如果 KernelSU 后续版本又有机制变化,也欢迎对照这篇的排查方法重新验证——方法论不会过时,结论会。
(本文所有命令均在 OnePlus PJX110 / Android 16 / KernelSU v3.2.4 上实测通过)








暂无评论内容