Skip to content
This repository was archived by the owner on Oct 3, 2026. It is now read-only.

KSuRoot 4.1.2 —— 从镜像读 vr.ko 标记偏移 + 导入完整刷机包

Latest

Choose a tag to compare

@hmascs hmascs released this 02 Oct 08:20

KSuRoot 4.1.2 —— 从镜像读 vr.ko 标记偏移 + 导入完整刷机包

versionCode = 412 · versionName = 4.1.2 · AOSP testkey 签名(a40da80a…5dc,可直接覆盖 4.1.1 原地升级)
上一个正式版本:4.1.1
单测 41 个类 / 417 个用例 · 0 失败(1 条环境门控跳过)


一、vr.ko 的标记偏移:从「赌一个」变成「读出来」

vr.ko 会给来自 app 的 task 打两个标记字节,该 task 一旦持有 euid 0,
sys_exit 探针就把它杀掉 —— 提权看着成功,子进程随即被杀,日志里一切正常。

要抹掉那两个字节,就得知道它们在哪个偏移。而那是编译期烤进载荷、patch 不了的。
麻烦在于它有 0x04 / 0x06 两种取值 —— 而且同一台设备的两份 vr.ko 就各一种:

路径 vermagic tag A
lib/modules/vr.ko …aarch64 vivo 0x04
lib/modules/6.1-gki/vr.ko …aarch64 0x06

两份的 srcversion 完全相同(同一份源码编的),差别只在编译配置。

这台机器实际加载的那份 vr.ko,就在 vendor_boot.img 里。 所以:

  • 蓝厂方案现在要求你提供 vendor_boot.img —— 应用从里面那份平铺的
    lib/modules/vr.ko(按 Android 的 modprobe 查找顺序,uname -r 是完整串而非
    6.1-gki,命中的就是平铺那份)反汇编出真正的偏移;
  • 然后改写载荷里那个值,而不是"对不上就停下";
  • 通用方案不需要它:通用方案不做 vr.ko 绕过,也就没有这个偏移要定。

界面上会直接把结论摊开:本机 vr.ko tag A = 0x04 · 已改写载荷 3 处。

二、四份自带/自编库强制配自己的档位

打补丁是「拿档位里的旧值去 .so 里找字面量」,所以库与档位必须同源。
而"选哪份库"按结构体族走、"选哪一档"按三级路由(内核串)走 —— 两条路会选岔:

  • X100 Pro 6.1.145:库是 libbaseline_6_1.so(旧值来自 tokay target.h),
    档位却命中上游档 up-6-1-145-…(旧值来自 GhostLock offsets.h)→ 26 项一处没匹配上
  • 本机 PD2463 6.6.89:库是 libbs.so(旧值来自 PD2520 target.h),
    档位命中 up-6-6-89-…-vivo → 25 项一处没匹配上

两次的产物都只是原样拷贝,装到机器上必然失败 —— 而界面显示的是"跑完了"。

现在四份库全部强制配对,选岔了由零命中闸门当场拦下:

库 配到
libbaseline_6_1.so baseline-6-1-tokay
libbaseline_6_12.so baseline-6-12-honor
libbs.so PD2520-BP2A.250605.031.A3
libionstack.so IONSTACK-P10-CP2A.260605.012

三、导入完整刷机包

载荷构建页新增入口:直接选你下载的 OTA zip 或 fastboot tgz,
它自己把 boot 和 vendor_boot 一起取出来 —— 不用你先解压,也不用手动提取。

  • OTA zip:认 payload.bin,支持 REPLACE / REPLACE_XZ / REPLACE_ZSTD / REPLACE_BZ / ZERO / DISCARD,ZIP64 也认
  • fastboot tgz:流式解析 gzip + tar,只把需要的那一个文件读出来

实测:真实的 6.5 GB 完整包上跑通,boot / vendor_boot 与独立参考实现
(Python + zstd CLI)逐字节一致。

⚠️ 代价要说明白:完整包要整份拷进应用缓存才能随机读(ZIP 中央目录在包尾,
而 SAF 的 uri 变不成 File)。6.5 GB 的包就要拷 6.5 GB —— 空间不够会当场拒绝
并说清差多少,抽完立刻删缓存(失败路径也删)。

四、本版修掉的其它问题

  • 蓝厂方案被自己的闸门 100% 拦死:构建开始时重建状态时把 vendorBootName 清成了 "",
    而闸门正是拿它判的 → 选不选 vendor_boot 都被拦。现在状态重置用 copy 保留输入,
    且判据改用真正的输入句柄,不再拿展示名当控制变量。
  • payloadSource 两份来源不同步:Compose 状态与持久化偏好各一份,
    而真正决定装哪份载荷的是偏好。构建自动落库那条路径只写了偏好 →
    界面高亮「内置」,点安装装的却是刚构建的自定义载荷。
  • 移交 root 那一串弹窗统一到 miuix(确认 / 进行中 / 结果 / 选管理器)。
    它们原来还是 Material3 AlertDialog;换成 miuix OverlayDialog 时
    必须放进 Scaffold 里 —— miuix 的 Overlay 组件依赖 Scaffold 提供的
    CompositionLocal,放在外面根本不渲染(表现就是"点了没反应")。
  • KallsymsFinder.kt 里有个裸 NUL 字节(注释里想写 x\0,写进了真的 0x00)→
    grep 把整个 1161 行文件当二进制跳过。

五、边界(不掩饰)

  1. 「抹标记」这一步仍然没有在任何真机上跑过。 vr detag 只证明代码编进去了,
    不证明它抹对了、更不证明抹完就不被杀 —— 三族基线一律仍标 beta。
  2. 整包导入没在真机跑过(只做了编译 + 单测 + 在真实包上的离线验证)。
  3. fastboot tgz 没有厂商真包样本:成功路径是用 GNU tar 现场造包验证的,
    错误路径用了真实 tar.gz。
  4. 0x04 / 0x06 由什么决定还没查清:目前只有"vermagic 里含 vivo"这条
    5 样本的相关性,因果未查明。所以别把它当规律用。
  5. 第三方载荷的许可证正文仍未补齐:随包 127 份 .so 来自多个上游仓库,
    登记表里逐条署了名(source 字段写明仓库与文件名),但许可证正文只带了
    GhostLock 的 Apache-2.0。其中一份来自
    qsvggff-spec/oppo-A5-PRO-5G-CVE-2026-43499(MIT,
    与包内 libksu_oppo_oppoa5pro5gcve202643499_any_d77f.so sha256 完全相同)——
    那个仓库是失败研究的归档,作者自己的结论是「利用链无法收敛」。
    该载荷仍在软件中(可供对照与研究),但不建议作为提权载荷使用,
    列表里会标红说明原因。