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

About

KSuRoot 4.0.0 — 基于 CVE-2026-43499(GhostLock) 的一键 KernelSU 提权工具。多内核支持:6.1 / 6.6 / 6.12 三族各有专属基线,另有 50 档上游内核适配;多机型动态库内置:122 条厂商载荷(vivo/iQOO、小米、三星、Pixel 等)离线可用、按机型+内核+commit 三级匹配;新增「载荷构建」用本机 boot.img 解析偏移打出适配本机的载荷(通用 / vivo 专用);免 ADB。Mod by hmascs

Resources

Stars

267 stars

Watchers

1 watching

Forks

Repository files navigation

KSuRoot

⚠️ 温馨提示:蓝厂机型调度策略较为严格,提权时子进程易被系统回收。请先在「开发者选项」中开启「停止限制子进程」后再执行提权,成功率更高。

基于 CVE-2026-43499(GhostLock) 内核漏洞的一键 KernelSU 提权工具。

本分支以 KSuRoot 为蓝本,完整同步 Root-My-Galaxy v0.2.6 主线更新,并在此基础上增加了载荷构建、厂商载荷内置与一整套液态玻璃 UI。

Mod by hmascs · 版本 4.1.2 · Apache-2.0 仓库:https://github.com/hmascs/KSuRoot


4.1.2 有什么变化

本轮(4.1.2)新增:从镜像读出 vr.ko 的标记偏移

vr.ko 给来自 app 的 task 打标记,那个偏移有 0x04 / 0x06 两种,而且是编译期 烤进载荷、patch 不了的。更麻烦的是同一台设备的两份 vr.ko 就各一种 (Y300 Pro+ 的 vendor_boot 里就有两份,srcversion 完全相同)—— 选错的表现是「清错字节、标记没抹掉、子进程照样被杀」,而日志里一切正常。

现在蓝厂方案会要求你给一份 vendor_boot.img:应用从里面那份实际加载的 lib/modules/vr.ko 读出本机真正的偏移,再改写载荷。四份自带/自编库 (libbaseline_6_1 / libbaseline_6_12 / libbs / libionstack)都强制配自己的档位, 选岔了会被零命中闸门当场拦下,而不是给你一个原样拷贝的产物。

另外新增**「导入完整刷机包」**:直接选你下载的 OTA zip 或 fastboot tgz, 它自己把 boot 和 vendor_boot 取出来,不用你先解压、也不用手动提取。

⚠️ 完整包要整份拷进应用缓存才能随机读(ZIP 中央目录在包尾,而 SAF 的 uri 变不成 File)。空间不够会当场拒绝,抽完立刻删缓存。

4.1.2 = 4.1.0 + 19 个提交。 这些提交原本停在 fix/baseline-routing 分支上, 现已并入 main。已发布的 4.1.0 安装包不含它们 —— 下面每一条都是那之后才修掉的。

修掉的静默失败

# 缺陷 后果
1 6.1 的 VR_TAG_A_OFF 填成 0x06(实测该是 0x04) 蓝厂 6.1 机型上标记一个字节都没抹掉,而自检报成功。表现是"提权成功之后子进程立刻被杀",看不出是这个原因
2 kallsyms 偏移表定位用了负数取模(Python 语义直译) 6.4+ 内核整档失败,基址取到一段 ASCII 文本
3 偏移表判据只看「前三项单调」 几乎零区分度(表内任意位置都单调);已改成查表的形状
4 BASELINE_6_12.imageBase 填成目标基址 绝对地址形式的构造点全部漏改(39 处 → 9 处)
5 符号对不齐时只置空产物、gate 仍是 Proceed blocked=false 且产物 0 B,UI 不弹阻断框
6 FopsSlot 的 fallback 从来没被用上 表找不到就直接放弃,退不到备用符号

功能补齐

  • 6.12 真正跑通:ashmem 在 6.12 变成 Rust 实现、符号名全 mangled → 改成运行时从 miscdevice 的 fops 槽读出来(TARGET_ASHMEM_FOPS_UNSYMBOLED)
  • 6.1 / 6.12 在通用 / 蓝厂两个方案下都可用(四个组合各 16 / 16 / 13 / 13 档), 清单见归档 07-文档/6.1-6.12-双方案清单.md
  • vr.ko 标记偏移逐台实测:6.1 = 0x04,6.6 / 6.12 = 0x06(三台真机厂商固件里的 vr.ko)
  • 载荷构建配方随仓(载荷构建/):此前仓库里有 15 处引用指向一个不存在的目录

★ 真机上抓到的:6.1 上 26 项偏移一处都没改到,还照样出包

X100 Pro(6.1.145)跑构建的结果是:

偏移解析: 28 / 28 项
需要改写: 26 项 · 校验通过: 0 项
该动态库未引用 26 项偏移

这不是"没什么可改",是"这两样东西不是一套"。 根因是两条独立的路选岔了:

选什么 按什么选 6.1.145 上选到
基础库 结构体族(F6_1) libbaseline_6_1.so(旧值来自 baseline-6.1-tokay/target.h)
档位 三级路由(内核串) up-6-1-145-…(旧值来自 GhostLock 的 offsets.h)

打补丁的方式是「拿档位里的旧值去 .so 里找字面量」。两套旧值毫无交集, 所以 26 项一处都匹配不上,产物等于把基础库原样拷贝了一份。

为什么原来的硬闸门没拦住:hasFailures 的判据是 changed && !ok && !absent —— absent 被明确排除在外。那个理由("老版本 .so 可能没有对应代码路径")对个别键成立, 对"全部键都 absent"不成立。

修法两条:

  1. 库与档位强制同源:自编族基线(libbaseline_6_1.so / libbaseline_6_12.so) 必须配它自己的档(baseline-6-1-tokay / baseline-6-12-honor), 上游 up-* 档只适用于上游那份 .so。新增 BaselineLibraries.profileIdForLibrary()。
  2. 零命中硬闸门:只要偏移规格一条都没落到站点上就停止打包 (基址那条不计入 —— 它即使全不匹配也常常会变,会把"一条偏移都没改"掩盖过去)。 为此给 SpecOutcome 加了 kind 字段。

回归用例在 BaselineLibraryPairingTest(4 条),其中一条直接断言两套旧值没有交集 —— 把"为什么必须配对"变成了可执行的事实。

动态库:导入之后"点了没用"的那一类问题

# 缺陷 后果
1 「载荷构建 → 用作载荷」用的是内存里的产物,进程被回收后 outputLibrary 为 null,而旧代码是 ?: return 点了什么都不会发生:没 Toast、没报错、按钮不变 —— 用户看到的就是"点了没用"
2 PayloadStaging 的缓存键是「同名 + 同长度」 自定义载荷在私有目录里固定叫 payload.so,换一份字节数恰好相同的载荷时会静默复用上一份
3 shizukuStage 的缓存键只有长度 同一个坑在 Shizuku 路径上又踩一次
4 只能存一份自定义载荷 导入第二份就覆盖第一份,没有提示
5 文件全在应用私有目录 用户在文件管理器里看不到,也没法自己备份/整理

动态库库房:Download/动态库/<机型>/<文件名>.so

  • 库房(用户可见、可自己整理):Download/动态库/<机型>/<文件名>.so
  • 活动副本(真正被加载的那份):files/active_payload/payload.so —— 见下面的"为什么必须是两份"
  • 界面新增按机型分组的库房列表,每份可直接「使用」设为当前
  • 同名但内容不同的两份不会互相覆盖(自动加哈希后缀)

为什么库房那份不能直接 dlopen:分区存储下应用只能读自己经 MediaStore 创建的那批文件; 而且 /storage 是 FUSE(u:object_r:fuse:s0),非 untrusted_app 的域根本读不到 —— 这一条是 pm install 时被 SELinux 当场拦出来的(avc: denied { read } ... tclass=file)。 所以库房负责"让用户看得见、管得住",私有副本负责"一定能被加载"。

⚠️ 搜寻能力的边界:库房不能自动扫描 Download/动态库/ 里用户自己丢进去的文件 —— 分区存储不允许应用读取别的应用(包括文件管理器)创建的下载文件。 条目只有两个来源:本应用写进去的、以及用户通过系统选择器显式授权的那一个。

闸门补强

  • CI 补上 :app:testDebugUnitTest —— 之前只证明"编得过",不证明"测得对"
  • BundledPayloadVrKoAuditTest:展示用标注表与磁盘真实字节逐条对一遍,不许有沉默的缺口
  • 单测 38 个类 / 394 个用例(4.1.0 为 37 / 382)

已实测的边界(不掩饰)

偏移是实测的,「抹标记」这一步没在任何真机上跑过。 vr detag 只证明代码编进去了, 不证明它抹对了、更不证明抹完就不被杀 —— 所以三族基线一律仍标 beta。


4.1.0 有什么变化

⚠️ 4.0.0 的安装包早于下面这批改动(4.0.0 打包于 03:55,蓝厂那批改动在 04:32 之后)。 也就是说 4.1.0 才是第一个真正带上 vr.ko 反 root 绕过的正式版本。

蓝厂 vr.ko 反 root:两份自编族基线终于带上了绕过

4.0.0 里 libbaseline_6_1.so / libbaseline_6_12.so 的 vr detag 计数是 0 —— 它们不带任何 vr.ko 抹标记。蓝厂机型上选这两份基线,等于把 vr.ko 的反 root 直接留在原地。

4.1.0 重编了两份基线,并修掉两个独立缺陷:

  1. 不带 vr.ko 抹标记(vr detag 计数 0 → 2);
  2. 旧产物根本 load 不起来 —— 旧构建没编 root.c / io_daemon.c,也没提供 wallpaper_blob.S 需要的素材,导致 install_android_root 等是指向 UND 的动态重定位, dlopen 会直接失败。这一条不在原任务书里,是重编过程中实测发现的。

可重放配方在 载荷构建/README.md(含出处分级与已知限制)。

上面是源码树尺寸。APK 里那两份更小(154856 B / 154840 B)—— release 构建会做 native 符号剥离,与 vr detag 无关(已从成品包取出复核,仍是 2)。

能力与闸门成对出现:com.kernelpack.vivo 下新增 VrKoPayloadCheck(只读字节判据) 与 VrKoPayloadGate(只对蓝厂方案生效,通用方案短路、不做任何检查)。 判据是「日志串 vr detag」+「机器码特征(add #0x2c 且 AND ~0x400)」两条组合 —— 全量 126 份载荷实测:36/36 正例命中、89 份负例零假阳性。

新增:解析完整包链接(不必自己去固件包里翻 boot.img)

载荷构建页多了第三条路:直接粘一个完整包(OTA ZIP)的直链。

完整包直链  ──►  只取需要的几块  ──►  boot 镜像  ──►  已有的构建流程

它不是"下载整个包再解压" —— 完整包通常 4–8 GiB,手机上那是几十 GB 流量。 实际网络代价是:

取什么 大约
文件尾部(找 ZIP 中央目录) 64 KiB
ZIP 中央目录本体 几百 KiB
payload.bin 头 + 分区清单 24 B + 几百 KiB
boot 分区真正用到的那几块 ~64–96 MiB

两种完整包形态都认:

  • A/B 完整包(payload.bin):读 update_engine 清单,按 dst_extents 把块还原成镜像; 支持 REPLACE / REPLACE_XZ / ZERO / DISCARD;
  • recovery 风格完整包:包里直接放 boot.img / init_boot.img(国内厂商常见), 支持 Stored 与 Deflate。

能力边界(如实列出,不粉饰):

  • 服务器必须支持 HTTP Range。不支持时直接拒绝,不会在用户没同意的情况下下几个 GB;
  • 内置 XZ 解码器只支持单块 XZ 流。实测多块流(xz --block-size=16384)会在第 2 块发散; 遇到时会给出明确报错,而不是静默产出错误镜像。没有验证过真实 OTA 的 REPLACE_XZ 操作是单块还是多块 —— 这条是未验证的;
  • REPLACE_BZ(bzip2)不支持:为它引 commons-compress 不值得,遇到时明确报错;
  • 解出的镜像放在应用缓存目录,只保留最近一份;被系统清掉时构建会给出明确提示。

其它打磨

  • 清掉了构建里全部 5 条警告(1 条生产代码 + 4 条测试代码);
  • 载荷构建页的输入现在有两条互斥来源(content:// 与本地文件), ViewModel 里两者互斥赋值,避免出现"界面写着 A、实际用的是 B"。

4.0.0 有什么变化

内核覆盖:从「一条 6.6」到「三族 6.1 / 6.6 / 6.12」

3.2.0 的内核支持是 6.6 一条线(外加 6.12 的口径声明)。4.0.0 扩到三个结构体族, 并且不是靠"版本号外推",而是每一族都有自己的基线库:

结构体族 pi_lock cred tasks 基线库
6_1 0x924 0x838 0x550 libbaseline_6_1.so(自编)
6_6 0x90C 0x820 0x550 libionstack.so / libbs.so(沿用)
6_12 0x9EC 0x900 0x638 libbaseline_6_12.so(自编)

为什么必须按族选库:结构体偏移是编译期烤死的,patch 改不了。 拿 6.6 的库去打 6.1 的内核,符号就算全部 patch 对,写进去的也是错位置的字段 —— 比"符号对不上"更隐蔽。所以 BaselineLibraries.resolve 先由内核串推出族,再选库。

6.1 的口径变更留档:6.1 曾在 2026-09-12 被移出主线,理由是"它是 flat 形态 (88 字节 / task@0x30),与 6.6/6.12 的 nested(112 字节 / task@0x50)不是一套"。 这个理由本身是对的;变的是我们后来为 6.1 编出了专属基线, 于是"拿 6.6 的偏移硬打 6.1"这个危险不再存在。 ⚠️ 两条要一起读:6.1 能进主线的唯一前提是它有自己的族基线 —— 那份基线若被拿掉,6.1 必须同时退回拒绝。

蓝厂 vr.ko 反 root:能力在载荷里,闸门在构建前

vr.ko 是 vivo/iQOO 的私有反 root 模块:它给每个来自 app 的 task 打两个标记字节 (task+0x06 / task+0x2c),并在 thread_info.flags 里置 VR_SYSCALL_TP_FLAG (0x400); 该 task 一旦持有 euid 0,sys_exit tracepoint 探针就会把它杀掉。 所以蓝厂机型上装一份不带抹标记的载荷,结果不是"提权失败",而是 提权成功之后子进程立刻被杀 —— 表面上完全看不出是这个原因。

这件事有一条容易走错的分工:

层 能做什么 不能做什么
载荷(C,root.c 的 patch_task_vr_tag) 真的抹标记:先清 0x400,再逐字节清 tag A / tag B,最后回读自证 —
Kotlin 判定(VrKoBypass)· 证明(VrKoPayloadCheck)· 拦(VrKoPayloadGate) 写不了内核内存 —— 它没有那个原语

早先 Kotlin 侧曾有一套 VrKoBypass.plan(),规划"往哪几个内核地址写什么"。 那套代码已删除:它做的事没有任何人能执行,接上去只会得到一个 "看起来做了事、其实什么都没发生"的假动作。现在它的位置由 VrKoPayloadCheck 顶上。

归属:仅蓝厂方案。 通用方案不带、也不检查(VrKoPayloadGate 在 scheme != VIVO 时直接短路,连 ELF 都不解析)。vr.ko 是 vivo 的私有模块, 把它横切到所有方案等于让别的厂商也走一条没验证过的路径。

构建前闸门

方案 载荷 实测 闸门
蓝厂 6.6 libbs.so 带 ✅ 放行
蓝厂 6.1 libbaseline_6_1.so 重编后带 ✅ 放行
蓝厂 6.12 libbaseline_6_12.so 重编后带 ✅ 放行
蓝厂 · 两份无源码厂商载荷 libksu_vivo_iqoo12_a15.so 等 不带 ❌ 构建期拦住 + 列表里标红 + 选中时确认
通用 · 任意 libionstack.so … 不带(本就不该带) 不触发

判据(VrKoPayloadCheck,只读字节)

两条,任一成立即判"带":

  1. 日志串 "vr detag" —— patch_task_vr_tag() 打的两条日志里共有的那段;
  2. 机器码特征 —— 同一段函数体里同时出现 add xN, xM, #0x2c(算 tag B 地址) 与 AND 立即数、掩码 == ~0x400(清 VR_SYSCALL_TP_FLAG)。

⚠️ 对早先一条建议的实测更正:曾建议"扫 movz/movk 里的 0x2c 与 0x400"。 实测不是这样 —— clang 把 task + 0x2c 折成 add 立即数、把 & ~0x400 折成 AND 逻辑立即数,两者都不是 movz/movk。照 movz 扫会全量漏判。 为此在 AArch64 里补了 decodeAddImmediate / decodeLogicalImmediate 两个解码器。

实测区分度(jniLibs/arm64-v8a 全量 127 份 .so):

份数 日志串 机器码特征
带绕过 37 37 / 37 37 / 37
不带 89 0 / 89 0 / 89

两条判据在真实语料上完全一致、零假阳性;另 1 份 ELF 头损坏 → 判 UNPARSEABLE (与 ABSENT 分开:闸门对两者都拦,但给的原因不同)。

BundledPayloadVrKoAuditTest 会把"展示用标注表"和磁盘上的真实字节逐条对一遍: 任何一份实测不带绕过却没标注的蓝厂载荷都会让用例变红 —— 不允许沉默的缺口。

两份自编族基线的重编

libbaseline_6_1.so / libbaseline_6_12.so 本轮重编,修掉两个独立缺陷:

  1. 不带 vr.ko 抹标记(vr detag 计数 0 → 2);
  2. 旧产物根本 load 不起来 —— 旧构建没编 root.c / io_daemon.c,也没提供 wallpaper_blob.S 需要的素材,导致 install_android_root 等是指向 UND 的动态重定位, dlopen 会直接失败。

可重放配方在 载荷构建/README.md。 产物:175776 B / 175760 B(旧 135184 B)。

登记档位:53(通用)+ 54(蓝厂)= 107 档

引入上游 GhostLock 源码登记的 50 个内核适配(每档 9 个符号地址 + 结构体族), 让"通用方案"从 1 档扩到 51 档;蓝厂方案把这 51 档全部挂上 vr.ko 绕过,成为 52 档 (含手写实测的 PD2520)。

⚠️ 这 50 档一律标 UPSTREAM_TARGET_H + beta:数据是真的(来自上游源码), 但我方未在真机上验证过。界面上与实测档分开显示,不谎报验证状态。

双向符号对齐闸门(新的安全闸)

打补丁只能改写基线 .so 里本来就有的字面量。所以"基线有哪些键"和 "boot.img 解出哪些键"必须双向对齐,缺任何一边都会让产物里留下一批 "为别的内核烤死的旧值"—— 而那是静默的:不报错、也不表现为失败,装机后才炸。

原先的写法是 baseline.symbolOffsets[key] ?: continue(直接跳过), 于是"看起来支持、实际写错内存"。现在 SymbolAlignment 对不齐就阻断打包。

与 GhostLock 的 offsets.json 互通

采用 GhostLock 的 offsets.json 作为互通格式(字段命名与结构已逐键核对,见下节), 实现读 / 写 / 合并(三种冲突策略),并且往返不丢未知键—— 别人文件里我们不认识的键会原样保留,不会被静默丢掉。

设置页新增「基线覆盖面」

把注册表的真实覆盖面摊开给用户看,而不是让人猜:

  • 三个主线系列 × 两个方案各自已登记多少档(实测 / beta 分开计数)
  • 上游清单对账:GhostLock 源码登记的 50 档 vs 我方已登记档位(必须零差异)
  • 偏移可信度直方图(已验证 / 交叉参考 / 占位符)

内置厂商载荷:39 → 122 条

新增并入批次 83 份(Pixel 全系、三星全系、OPPO / realme / 一加 / 华硕等), 随包 .so 共 127 个。读不出内核版本的 69 份一律 kernelUnknown, 只允许手动选择、绝不参与自动匹配 —— 载荷靠编译期常量寻址内核符号,拿错一份就是提权失败。

修掉的两处「基线 ABI 冲突」误报(4.0.0 发布前)

用户实测 6.1.145 的 boot.img 时被拒,提示「基线 ABI 档位是 GKI 6.6,而 boot.img 是 6.1」。 根因有两层,都是"两套东西对不上":

症状 根因 修法
第 1 层 两张表 路由查 BaselineRegistry.allEntries(107 档),打包却查 BaselineProfiles.byId(只有 2 档 6.6)→ 查不到就兜底回落 PD2520 统一到 BaselineRegistry.byId / findByBytes
第 2 层 两套词汇 上游档的 abi.kernelSeries 填的是三段小版本(6.6.118),闸门比的却是两段大系列(6.6)→ 50 档一档都构建不出来 拆开两个语义:路由键保留三段,ABI 比较键压成两段

顺带修掉同源的第 3 处:lookup() / coverageReport() / availableLabels() 也只查那 2 档, 导致报缺文案会在明明有档位时说"没有基线"。

并且不再兜底猜系列:认不出基础 .so 就如实报缺并停止打包, 而不是"取第一档顶上"—— 那等于拿 6.6 的旧值去打 6.1 的库。

其它

  • 删除孤儿库 libgl_universal.so(全工程 0 引用)与重复载荷 libksu_vivo_sixmodels_a.so
  • 单测 304 条(3.2.0 为 154 条),debug / release 双变体编译通过

参考了 GhostLock 的哪些源码

上游仓库:YuKongA/ghostlock-app(Apache-2.0)。 本项目只取方法与数据,不复制其 C 代码;其许可证随包携带于 app/src/main/assets/GL_LICENSE_Apache2.txt。

逐文件引用清单

上游路径 取用了什么 落在本项目哪里
src/kernels/<内核串>/offsets.h 50 个内核各自的 9 个符号地址 GhostLockKernelOffsets.KERNELS(50 档 × 9 符号)
src/kernels/offsets.h 3 个结构体族(6_1 / 6_6 / 6_12)的字段偏移 GhostLockKernelOffsets.STRUCT_FAMILIES
src/core/main.c _RSO(field, fallback) 覆盖模型:运行时值 > 编译期基线 > 载荷兜底常量 UnifiedOffsetResolver(三级优先级 + 逐字段来源标注)
src/core/offsets_json.c / .h offsets.json 的读写与字段命名 GhostLockOffsets(schema)· GhostLockOffsetsIo(读写合并)· MiniJsonCodec
src/core/runtime_struct_offsets.h 运行时结构体偏移的键名 SymbolKeyMapping(上游 9 键 ↔ 我方 11 键,一对多映射)
src/core/target.h 目标描述形态 BaselineProfile / AbiProfile 的字段对照
buildSrc/.../GenerateSupportedKernelsTask.kt 内核清单由扫描源码树生成的做法 GhostLockKernelCatalog(50 条内核串 + 出处标记)

反向核对:它的数据经我们独立验证过(4 处零差异)

不是"抄了就信"。三族结构体偏移与手写档全部拿独立来源对过:

上游数据 独立佐证 结果
STRUCT_OFFSETS_6_6 frankel-CP2A.260605.012/target.h 一致
STRUCT_OFFSETS_6_12 pyyyc 荣耀 YLP-W00 6.12.38 BTF 实测 offsets.json 15 字段 0 差异
编译期兜底常量(11 项) 荣耀 struct_fields 一致
STRUCT_OFFSETS_6_1 tokay-CP2A.260605.012/target.h 一致(pi_lock=0x924、compact_waiter=1)
手写档 PD2520 boxiaolanya2008 PD2520-BP2A.250605.031.A3/target.h 28/28 键 0 差异

明确没有引用(高风险,拒绝照搬)

  • libextract.so(3.88 MB Rust 黑盒):它的 kallsyms 提取口径我方没审过, 且具备 LZ4 重压缩回写 boot.img 的能力。在没验证其提取结果与我方口径一致之前, 引入它等于把校验权外包 —— 不得用于生成可刷写产物。
  • libghostlock.so 的运行时架构:它是"1 份通用载荷 + 运行时读 json", 与我方"编译期常量写进 .so"根本不同。我们只采用它的格式与覆盖模型, 主线仍是直接写入 .so(本项目主打方案)。

功能亮点

提权与载荷

  • 一键提权:基于 CVE-2026-43499 内核漏洞完成提权并安装 KernelSU,无需解锁 Bootloader
  • 免 ADB:内核 6.1 / 6.6 / 6.12 三族可直接在设备上完成提权,不需要电脑、不需要 ADB;更早的内核才需要 Shizuku(ADB)授权
  • 两种载荷来源,主页自由切换(切换即时生效,无需重启):
    • 内置厂商载荷 —— 随包携带 122 条登记(127 个 .so),完全离线,按设备型号 + 内核版本 + 内核 commit 自动匹配
    • 自定义导入 / 构建产物 —— 导入任意 .so(ELF 魔数校验、256MB 上限、SHA-256 指纹),随时移除
  • 双执行模式:默认原生执行,可选 Shizuku 模式

载荷构建(新增页面)

把「换机型就要重新编译」这件事搬到手机上:

本机 boot.img  ──►  内核符号表(kallsyms)  ──►  这条链需要的偏移  ──►  打好补丁的动态库
  • 点「开始构建」会先问用哪套方案:
    1. 通用方案(推荐) —— IonStack 上游分支,不带厂商适配,适用于大部分 GKI 设备
    2. vivo / iQOO(vr.ko 反 su 绕过) —— 额外做厂商反 root 绕过,蓝厂机型必须选它
  • 也可以直接粘完整包直链(4.1.0 新增):不用自己去固件包里翻 boot.img。 只取需要的几块,不会下载整个包;服务器不支持 Range 时会直接拒绝
  • 三级路由选档:完整内核串 → 小版本 → 大系列,每一级都要求精确相等, 认不出来就如实报缺,绝不拿邻近版本顶替
  • 产物自动做两件事:写进 /storage/emulated/0/Download/(不需要任何存储权限),并写入「自定义动态库」并切换载荷源
  • 全程离线,构建日志实时上屏;界面上直接摊开"打的是哪一份库"(文件名 / 大小 / SHA-256 / 来源版本)
  • 算法来自独立的纯 Kotlin 模块 com.kernelpack:boot.img 头 v0~v4 / 裸 Image / Image.gz、 Linux 6.4 前后两种 kallsyms 排布、按寄存器数据流改写 movz/movk/movn 常量, 原地覆盖、不增删字节,改完重新扫描自证(旧值残留必须为 0)

载荷匹配:三级判定 + 同源机型提示

同一机型往往有多个内核版本,而内核 commit 才是真正的区分维度。因此匹配按三级降级:

等级 判据 含义
Exact 机型 + 内核版本 + 内核 commit 全中 精确匹配,直接用
SameKernel 机型 + 内核版本命中,commit 不同 大概率可用
SimilarDevice 仅机型命中 兜底,日志里会说明

命中后两档时安装页与载荷列表都会标注**「可能可用」**,由用户自己决定是否继续 —— 而不是默默塞一份不匹配的库、也不是直接判"不支持"。

界面与记录

  • 液态玻璃 UI:悬浮玻璃底栏 + 滑块(backdrop 折射/模糊)、MIUIX 卡片与分组、跟随主题的配色
  • 设备信息:设备 / 固件 / 系统 / 系统 ABI / 内核版本(并直接给出"是否支持免 ADB 提权"的判定)
  • 运行记录只记过程,不判成败:蓝厂机型上"跑完了但没拿到 root"与"真的跑挂了"无法区分, 因此不再显示成功/失败,只保留「进行中 / 已记录」;是否真的装上以主页 KernelSU 状态为准
  • 日志:安装页实时日志与运行记录详情都支持一键复制与保存到指定目录
  • 基线覆盖面(设置 → 内核支持):注册表真实覆盖面 + 上游清单对账 + 偏移可信度直方图

支持设备

内核支持范围

系列 级别 说明
6.1 主线 有专属族基线 libbaseline_6_1.so
6.6 主线 内置载荷主力(vivo / iQOO / 小米 / 三星 / Pixel 等)
6.12 主线 有专属族基线 libbaseline_6_12.so
5.10 / 5.15 测试(beta) 需在设置里显式打开「5.x 内核支持」;布局锚点只有上游 target.h 一条腿
其它 6.x(6.2 / 6.5 / 6.7…) 拒绝 没有专属基线,硬按主线偏移构建会打到错误的结构体字段

内置厂商载荷(122 条登记 / 127 个 .so)

来源 份数 说明
vivo / iQOO 36 6.6.30 / 6.6.57 / 6.6.89 / 6.6.127 分组互认;另含 X100(6.1.145)
三星 Galaxy 34 按 support/targets-v3.json 的权威机型↔内核对照登记
Google Pixel 29 Pixel 6 ~ 11 全系
小米 / Redmi / POCO 13 按 SoC 家族分组(SM8550 / SM8650 / SM8750 / 天玑 6895)
OPPO 5 —
其它 5 realme / 一加 / 华硕 / 魅族等
合计 122 对应随包 .so 127 个

读不出内核版本的 69 份一律标 kernelUnknown:只能手动选择,绝不参与自动匹配。 口径:jniLibs/arm64-v8a 下 127 个 .so,减去登记表中 kernelVersion 非空的那批所覆盖的 58 个。 载荷靠编译期常量寻址内核符号,拿错一份就是提权失败。

其它机型

不限品牌:内核 6.1 / 6.6 / 6.12 即可用「载荷构建」把自己机器的 boot.img 解析成偏移, 打出适配本机的载荷。

⚠️ 「有全量包」≠「能加适配」 —— 这条容易被误解,值得单独说清楚:

  • 全量包 / boot.img 只能解决「算偏移」:解出本机内核的符号地址与结构体字段位置。
  • 偏移只是配方的一半。真正完成提权的是该机型可用的漏洞利用载荷本体 —— 它带着触发路径的编译期常量与调参(STACK_STAMP / PAGE_RECLAIM_VIA / STAMP_ATTEMPTS 等), 这些推不出来,只能来自那台机器上实际跑通过的构建。
  • 所以「手上有某台机器的全量包」不足以为它做出适配;内置列表里的每一条, 背后都是那台机器上已经跑通过的一份载荷。
  • 认不出内核、或该系列没有基线产物时,构建器会明确拒绝打包并说明原因, 不会拿别的系列的偏移顶上 —— 顶上就是常量对不上、提权必然失败。

使用说明

  1. 安装 APK(minSdk 33,即 Android 13+)
  2. 在主页选择载荷来源:
    • iQOO / vivo / 小米 / Redmi / POCO / 三星 / Pixel 等 → 内置厂商载荷(自动匹配,或从列表手动点选)
    • 其它机型 → 先到「载荷构建」用本机 boot.img 生成载荷(产物会自动进入「自定义动态库」)
  3. 点击"安装"并确认,等待提权与 KernelSU 加载完成
  4. 按提示安装 KernelSU Manager 管理模块

从源码构建

./gradlew assembleRelease
  • JDK 21 · Android Gradle Plugin 9.2 · compileSdk 37 · NDK 30.0.16248370 · CMake 3.22.1
  • 产物位于 app/build/outputs/apk/release/
  • 签名参数从 GRADLE_USER_HOME/gradle.properties 读取(KSU_ROOT_STORE_FILE 等),不写入仓库

载荷构建模块(com.kernelpack)

载荷引擎是独立的纯 Kotlin 模块,不依赖 Android 框架,可以单独拿出来读:

app/src/main/java/com/kernelpack/
├── boot/      boot.img 头 v0~v4 / 裸 Image / Image.gz;LZ4 / zstd / gzip 解压
├── kallsyms/  Linux 6.4 前后两种 kallsyms 排布
├── patch/     SharedObjectPatcher:按寄存器数据流改写 movz/movk/movn,原地覆盖
├── resolve/   OffsetResolver:符号 → 偏移,推导值单独标注
├── model/     KernelImageAnalysis / TargetProfile / OffsetEntry
├── policy/    BuildGate(硬闸门)· KernelSchemeSelector(选线)
├── profile/   BaselineRegistry(107 档)· GhostLockKernelOffsets · GhostLockKernelCatalog
├── offsets/   GhostLock offsets.json 互通:schema / IO / 合并 / 键映射
├── offset/    OffsetProvenance:逐条偏移的来源与可信度
├── vivo/      VrKoBypass:蓝厂 vr.ko 反 root 绕过(数据层)
├── export/    target.h / offsets.json 导出
└── SymbolAlignment.kt  双向符号对齐闸门

对应的单测在 app/src/test/java/com/kernelpack/(33 个文件)。

已知限制(如实说明)

  • 50 档上游内核 + 两份自编族基线均未在真机验证(一律标 beta)。 数据来源可核查,但"未实测"就是未实测。
  • 6.12 基线的符号是 CROSS_REFERENCE(取自荣耀 YLP-W00 6.12.38)—— 它是别的机型。构建时会被 boot.img 解析出的新值逐项改写, 且 SymbolAlignment 保证改写不齐就阻断。结构体偏移才是编译期烤死、决定成败的那一半。
  • 蓝厂 vr.ko 绕过尚未接入提权路径:数据层(VrKoBypass,12 条单测)已完成, 但"清零 0x28-0x2f"这一步需要在你的设备上先确认安全才敢接线。
  • offsets.json 导入目前是阶段 1(读取与呈现):UnifiedOffsetResolver 的合并流水线已实现并有 10 条单测,但尚未接入构建路径。

致谢

免责声明

本项目仅用于安全研究与学习目的。提权操作可能导致设备保修失效、数据丢失或设备损坏, 请仅在自有且受控的设备上使用,风险自负。

许可证

Apache License 2.0


English Summary

KSuRoot is a one-click KernelSU rooting tool built on the CVE-2026-43499 (GhostLock) kernel vulnerability. This branch syncs Root-My-Galaxy v0.2.6 and adds a payload builder, bundled vendor payloads and a liquid-glass UI.

Version 4.1.0. Highlights:

  • Three struct families: 6.1 / 6.6 / 6.12. Not inferred from version numbers — each family has its own baseline library (libbaseline_6_1.so, libionstack.so / libbs.so, libbaseline_6_12.so), because struct offsets are baked in at compile time and cannot be patched.
  • 107 registered baseline entries (53 universal + 54 vivo), including 50 kernel adaptations taken from ghostlock-app — data and method only, its C code is not copied (Apache-2.0, license shipped in app/src/main/assets/). All 50 are marked UPSTREAM + beta: the data is real, but we have not verified it on hardware.
  • Bidirectional symbol-alignment gate: patching can only rewrite literals already present in the baseline .so, so both sides must line up — otherwise the build is blocked instead of silently shipping stale constants for the wrong kernel.
  • offsets.json interoperability with GhostLock: read / write / merge, round-trip safe for unknown keys.
  • 122 bundled vendor payloads (127 .so), fully offline, matched by model + kernel version + commit with a three-tier fallback that labels the weaker tiers as "may work" so you decide.
  • 389 unit tests, debug + release both compile.

For research and educational use only. Licensed under Apache-2.0.

About

KSuRoot 4.0.0 — 基于 CVE-2026-43499(GhostLock) 的一键 KernelSU 提权工具。多内核支持:6.1 / 6.6 / 6.12 三族各有专属基线,另有 50 档上游内核适配;多机型动态库内置:122 条厂商载荷(vivo/iQOO、小米、三星、Pixel 等)离线可用、按机型+内核+commit 三级匹配;新增「载荷构建」用本机 boot.img 解析偏移打出适配本机的载荷(通用 / vivo 专用);免 ADB。Mod by hmascs

Resources

Stars

267 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages