● GHOSTLOCK · CVE-2026-43499 · HONOR FNE-AN00

把内核提权
做成一份可配置的 Profile

FNERoot 是 GhostLock 在荣耀 FNE-AN00 上的封装形态:一套 HOCON 配置驱动的 内核提权工具链。路由、几何字段、凭据模板全部写在配置里,Kotlin 侧解析校验, native 侧只做几何使用——换内核不改代码,改一行配置。

5.4.289
qgki · g6cb1f712a6e
3
提权路由
0x0D000721
v2 wire magic
9.19 MB
APK 体积
01 / OVERVIEW

它到底是什么

不是"一键 root 按钮",而是一套把内核利用参数化的框架。每个内核的偏移、路由、凭据布局 差异极大,传统做法是一机一份硬编码二进制;FNERoot 把这些全部抽成配置文件。

◆Profile 驱动

HOCON 配置文件声明路由、task_struct / cred / offset 三组几何字段。Kotlin 侧解析合并后, 以类型化二进制送入 native,native 不再做参数校验,只按几何使用。

◆执行前拦截

字段校验在 validateProfileFields 完成,任何越界或不满足的字段都会进入 invalidPaths,UI 把执行按钮置灰——不等到运行时才崩。

◆失败自动回退

fallback.to 支持 tcp_zerocopy 失败后切到 select_stack 重试, 两套路由用独立的字段,互不干扰。

◆七层配置合并

shared → builtin → imported → general override → route override → advanced override → 快照。 低优先级只提供默认值,你只写差异,不重复劳动。

◆KASLR 滑移探测

内置 KernelSnitch 采样,用 slide_* 锚点推算运行时基址, 配合 kernel_phys_load 完成 symbol → direct-map 换算。

◆Shizuku / Root 同构

direct 与 Shizuku 两条执行通道都把同一份二进制字节写进 native 的 stdin, 不存在"两种模式行为不同"的问题。

02 / ARCHITECTURE

数据流:从一份 .conf 到一次提权

整条链路只有一次类型转换,Kotlin 负责"懂配置",native 负责"用几何"。这个边界是刻意设计的。

A
加载 HOCONassets/kernel_profiles/*.conf + filesDir/offsets.conf,支持 include 与 ${var}
B
分层合并ProfileConfigController.resolve 产出单个全字段合并后的 resolved profile
C
字段校验越界项写入 invalidPaths;不通过就置灰执行按钮
D
序列化 v2magic 0x0D000721 + 16 字节头 + section/entry 编码
E
送入 nativedirect 与 Shizuku 都把字节写进 native 的 stdin
F
几何执行解析后按 offset 布局构造 fake object,走选定路由

▸为什么用二进制而不是 JSON 传参

native 侧 legacy/ 的 JSON 解码器已删除。v2 类型化二进制省掉解析开销, 也让 Kotlin 与 native 的版本强制绑定——写错版本就解不出来,不会静默用错字段。

▸为什么校验放在 Kotlin

配置是用户可改的。把校验提到 Java 层,能给出具名错误路径(cred.caps_offset 之类), 而不是在 native 里段错误。native 只信已经验过的输入。

03 / ROUTE

三条路由,一个字段矩阵

路由不再靠内核版本或字段存在性推断,而是配置里显式声明。一个 profile 只允许命中一条路由分支, 未采用的分支完全不写。

关键字段tcp_zerocopyselect_stackmulticast_waiter
offset.init_task / init_cred必填必填必填
task_struct.prio / pi_lock / pi_waiters必填必填必填
cred.copy_size / caps_count必填必填必填
route.*.compact_waiter必填—必填
waiter_shift—必填(0 合法)—
waiter_off(>0)——必填
buffer_size / task_offset / lock_offset——必填
offset.empty_zero_page——必填
kernelsnitch.mm_struct_sz——必填

▸tcp_zerocopy

靠 compact_waiter 调整 waiter 布局,适合 pinfo 与 waiter 相邻的紧凑内核。 失败可回退到 select_stack。

▸select_stack

用 waiter_shift 做小幅位移,0 也是合法值——这是最轻的一档, 偏移刚好的内核用它最稳。

▸multicast_waiter

字段最多的一档:需要伪造多播对象,waiter_off、buffer_size 和 cred.ref_count 全部要算准。

04 / PROFILE

配置长什么样

就是 HOCON。JSON 是它的子集,所以老配置直接能用;额外支持注释、尾逗号、 ${var} 变量替换和 include。

# GhostLock kernel profile (HOCON; JSON stays valid)
release = "5.4.289-qgki-gf6cb1f712a6e"
schema_version = 1
kernel_major = 5

route { select_stack { waiter_shift = -2 } }
fallback { to = "none" }

kernelsnitch { collisions = 4, mm_struct_sz = 4096 }
task_struct { prio = 132, cred = 2080, pi_lock = 2316 }
cred { copy_size = 136, caps_offset = 48, caps_count = 5 }
offset { init_task = 34464384, init_cred = 34538824 }

▸凭据模板的硬边界

usage_offset + 4 ≤ copy_size; caps_offset + caps_count × 8 ≤ copy_size; ref_count ≤ 4。越一条就直接进 invalidPaths, 这是防"差一点点"导致写坏内核的最后一道闸。

▸提取器不猜

ghostlock-extract 从镜像里拿到多少字段就写多少, 拿不到的留空,绝不借相邻内核族的猜值。所以生成成功 ≠ 设备受支持, 真正的判据是导入后 invalidPaths 是否为空。

05 / FIELD REPORT

Honor 70 实测状态

这里写的是真的。跑通的部分和卡住的部分分开列,不做模糊处理。

▸目标设备

HONOR FNE-AN00 · MagicOS 8.0.0.220

Kernel 5.4.289-qgki-gf6cb1f712a6e · Android 14

包名 com.edge.Jinglian.fneroot, 基线 v1.6 / versionCode 7,APK 9,581,961 字节,minSdk 24 / targetSdk 33。

▸权限通道

通过 Shizuku(moe.shizuku / rikka.shizuku / rikka.sui)获得 shell 级权限,工作目录 /data/local/tmp/ksu_fne。 执行链路:runExploit → checkKernel → unpackAssets → execStream(fne_local.sh)。

64 个 ms_spans 与设备 kallsyms 完全吻合 对照 kallsyms_honor70.txt:_text、handle_mm_fault、do_mmap、seq_read 全部一致。span 表不是问题来源。
Heap spray → futex PI collision → payload 链路跑通 SLUB 跨缓存对齐验证通过,非随机化 slab 可被稳定利用。
内核版本校验已可绕过 checkKernel 用 uname -r 与 kernelsu.ko 的 vermagic 做全等比较; 已做出仅跳该分支的字节级补丁(dex 偏移 21160,39 00 1d 00 → 28 1d 00 00), 逐字节审计后除该 3 字节与 header 校验外全部一致。
memstart probe 命中率不稳定 —— 当前主要瓶颈 perf 采样(sample_period=20000)随机命中函数窗口,实测 votes=99 / iter=1729 ≈ 5.7%。 算错时 memstart 落为负物理地址,W1 阶段按错误地址写内核,最终 kernel panic。 三处缺陷已定位在 memstart.c:候选下界过宽、日志打印错索引、提前退出按总票数触发而让垃圾候选挤占槽位。
⚠ 危险开关:GL_HOLD_WAITER=1 会故意留下悬空的 pi_blocked_on,任何 walk 都会 panic。 在 memstart 修复验证之前反复触发提权,大概率只能刷机。实测前务必确认能进 fastboot 并有完整固件。

▸关于"固定地址"的误区

KASLR 每次重启都会重新随机化 phys_offset / page_offset / slide, 写死一个真值只在单次 boot 内有效。调试时可以用 GL_MEMSTART=<真值> 跳过整个 perf 采样直接 apply, 但那是验证手段,不是产品形态。

06 / CREDITS

致谢与来源

★MSEDGE · 原作者

GitHub:MSEDGE-CORE/GhostLock-HonorFne

整条链路的骨架都出自他:exploit 核心、offset 拓扑与符号表、 电脑端工具链(profile 提取器与配置生成),以及三路由设计、 v2 二进制协议、KernelSnitch 采样思路。

没有他那套 offset 体系和电脑端产出,手机侧无从谈起——本页所述的全部配置字段, 追到根都是他的工作。

★本移植者 · 设备适配

设备:HONOR FNE-AN00(Honor 70)

负责把上游产物落到这台机器上:

· 手机端 com.edge.Jinglian.fneroot 封装与 assets/e native 交叉编译
· 5.4.289-qgki 的 ms_spans 对齐 kallsyms 校验(64 项全对)
· 内核校验分支的字节级 patch 与 dex 头重算
· memstart probe 三处缺陷定位(下界 / 索引 / 提前退出)
· APK 重组、zipalign、v1+v2+v3 签名与装机验证

▸上游基线

exploit 核心工程基线来自 JoinChang/ghostlock-oneplus (commit 9b2a7ba),含 memstart.c / slide.c / pipe.c / umh_root.c 等模块。oneplus 分支的适配经验是本次移植的直接参考。

▸使用边界

这是内核漏洞利用工具,仅用于自有设备的合法安全研究。它可能触发 kernel panic、 导致数据丢失或设备无法启动。请确认你拥有设备完全控制权、能自行恢复, 并遵守所在地法律。作者与本封装不承担任何因使用造成的损失。