Jz8Root/xiaomi-hyperos-bootloader-unlock
GitHub: Jz8Root/xiaomi-hyperos-bootloader-unlock
解决小米HyperOS/MIUI14+系统中bootloader解锁后仍显示锁定的bug,通过RPMB魔术字符串擦除实现绕过。
Stars: 0 | Forks: 0
# 小米 MTK 引导加载程序解锁 — HyperOS/MIUI14+ RPMB 绕过方案
**测试设备:** POCO M4 Pro 4G (fleur, MT6781) | **状态:** 阶段 3 — 完整方法已发布
**XDA论坛帖子:** [xdaforums.com/t/4784527](https://xdaforums.com/t/4784527/)
**作者:** [Jz8root](https://github.com/Jz8Root)
## 问题描述
自 MIUI 14.0.3+ 和 HyperOS 起,执行 `mtkclient da seccfg unlock` 命令无报错——但重启后引导加载程序仍处于锁定状态。此问题已被报告超过 2 年且未解决:
- [mtkclient #81](https://github.com/bkerler/mtkclient/issues/81) — Redmi 9A/9C (MT6762G) — 自 2021 年起
- [mtkclient #764](https://github.com/bkerler/mtkclient/issues/764) — Redmi 10 5G (MT6833)
- [mtkclient #1405](https://github.com/bkerler/mtkclient/issues/1405) — MT6762G 设备
- [mtkclient #1219](https://github.com/bkerler/mtkclient/issues/1219) — Redmi Note 8 Pro (MT6785)
## 根本原因
使用 Ghidra 对 HyperOS 的 Little Kernel (LK) 引导加载程序进行逆向工程后,我发现小米引入了**双层锁验证机制**:
```
get_lock_state():
1. seccfg_state = read_seccfg() <-- FALLBACK (what mtkclient writes)
2. rpmb_state = mi_get_lock_state() <-- PRIORITY (overrides seccfg!)
if rpmb_state == 1 (DEFAULT / no magic):
return seccfg_state <-- seccfg decides
else:
return rpmb_state <-- RPMB OVERRIDES seccfg
```
从 HyperOS 开始,小米将一个魔术字符串存储在 **RPMB**(重放保护内存块)中。当该字符串存在时,RPMB 会覆盖 seccfg 的状态——即使 seccfg 显示“解锁”,RPMB 也会以“锁定”状态胜出。
**解决方法:** 擦除 RPMB 中的魔术字符串。这将强制 LK 回退到使用 seccfg,而 mtkclient 可以自由地将其写为“解锁”状态。
**为何重启后仍有效:** 当魔术字符串不存在 **且** seccfg = UNLOCK 时,LK **不会**重写该字符串。恢复魔术字符串的代码路径仅在 seccfg ≠ UNLOCK 时触发。此行为是从 Ghidra 对 `mi_get_lock_state()` 的反编译结果推断出的,并通过实验验证:多次重启后转储的 RPMB 数据显示魔术区域保持全零。转储证据见 [proof/VERIFICATION.md](proof/VERIFICATION.md)。
| 锁状态值 | 含义 |
|----------|------|
| 1 | 默认 (RPMB 未初始化,回退到 seccfg) |
| 3 | 已解锁 |
| 4 | 已锁定 |
## 方法 — 3 条命令
### 前置条件
- 已集成 Kamakiri BROM 漏洞利用的 [mtkclient](https://github.com/bkerler/mtkclient)
- 能够进入 BROM 模式(通常在连接 USB 时按住音量+/-键,因设备而异)
- 优质 USB 数据线(非仅充电线)
- **强制要求:** 完整备份 NV 分区 (nvdata, nvcfg, nvram, persist, protect1, protect2)
### 适用于 HyperOS / MIUI 14+ 设备
```
cd mtkclient
# 步骤一:备份 RPMB — 请勿跳过此步骤
python mtk.py da rpmb r rpmb_backup.bin
# 步骤二:擦除 RPMB 锁定区域
python mtk.py da rpmb e --sector 57344 --sectors 4
# 步骤三:解锁 seccfg
python mtk.py da seccfg unlock
```
**每条命令之间:断开手机连接,重新以 BROM 模式(音量+/-键)连接。**
若您的设备需要特定的预引导加载程序:
```
python mtk.py --preloader preloader_CODENAME.bin da rpmb r rpmb_backup.bin
python mtk.py --preloader preloader_CODENAME.bin da rpmb e --sector 57344 --sectors 4
python mtk.py --preloader preloader_CODENAME.bin da seccfg unlock
```
**步骤 2 说明:** 我们仅擦除从扇区 57344 开始的 4 个扇区——这仅针对魔术字符串区域。锁状态长度(扇区 57600)和签名数据(扇区 57856)保持不变。仅擦除魔术字符串即可:没有魔术字符串将强制执行默认→seccfg 回退路径。
### 验证
```
fastboot oem lks # Expected: lks = 0
fastboot getvar unlocked # Expected: unlocked: yes
```
启动时出现打开的挂锁标志 = 成功。
### 适用于 MIUI 11/12/13 (旧版固件 — 无 RPMB 锁)
```
python mtk.py da seccfg unlock
```
一条命令即可。旧版固件中不存在 RPMB 机制。
### 我需要哪种方法?
| 固件版本 | 是否存在 RPMB 锁 | 方法 |
|----------|------------------|------|
| HyperOS 1 (2024, OS1.0.x) | 是 — 已测试 | RPMB 擦除 + seccfg 解锁 |
| HyperOS 2/3 (2025-2026) | 未知 — 未测试 | 请谨慎使用,并报告结果 |
| MIUI 14 (2023) | 不一定 | 使用 scan_lk.py 检查您的 LK 二进制文件 |
| MIUI 13 (2022) | 否 | 仅 seccfg |
| MIUI 11/12 (2021) | 否 | 仅 seccfg |
## RPMB 扇区参考
### 已验证:POCO M4 Pro 4G (fleur, Samsung UFS)
通过 RPMB 转储分析验证。完整证据见 [proof/VERIFICATION.md](proof/VERIFICATION.md)。
| 数据 | 转储字节偏移 | mtkclient 扇区 |
|------|-------------|---------------|
| 锁定魔术字符串 | **0xE00000** | **57344** |
| 锁状态长度 | 0xE10000 | 57600 |
| 签名数据 | 0xE20000 | 57856 |
扇区计算:`字节偏移 / 256 = 扇区` → `0xE00000 / 0x100 = 57344`
命令:`da rpmb e --sector 57344 --sectors 4`
### 其他 UFS 类型 (未验证)
具有不同 UFS RPMB 配置的设备可能使用不同的扇区号。如果您的设备扇区不是 57344,请先转储您的 RPMB(`da rpmb r rpmb_dump.bin`),然后搜索魔术字符串:`grep -boa "Jz8PNRUF" rpmb_dump.bin` 以找到正确的偏移量。
转换为扇区:`字节偏移 / 256 = 扇区`。
## scan_lk.py — 兼容性扫描器
使用字符串搜索和字节模式匹配分析任何小米 MTK LK 二进制文件:
- 检查二进制文件中是否存在 RPMB 魔术字符串(精确匹配)
- UFS RPMB 类型检测(基于常量值的启发式分析)
- RSA 密钥检测(对已知小米密钥前缀进行精确匹配,回退到熵启发式分析)
- 通过字符串引用检测函数存在性(**非** ARM 指令分析 — 需要未剥离的调试字符串)
- 兼容性判定及评分 (0-100%)
```
# 从固件 ZIP 文件中
unzip firmware.zip # -> images/lk.img or lk_a.img
# 从设备通过 mtkclient 获取
python mtk.py da r lk_a lk_a.bin
# 运行扫描仪
python3 scan_lk.py lk.img
python3 scan_lk.py lk.img --json # structured output
```
完整设备数据库见 [COMPATIBILITY.md](COMPATIBILITY.md)。
## 常见问题解答
**问:没有设备特定的 RPMB 密钥,如何擦除 RPMB?**
答:mtkclient 在 Kamakiri BROM 漏洞利用后,通过 SEJ 的 HACC 引擎推导 RPMB 认证密钥——与其处理 SecCfgV4 加密使用的是相同机制。当您运行 `da rpmb e` 命令时,密钥推导会自动完成。
**问:这会清除我的数据吗?**
答:会。首次启动解锁后的引导加载程序会触发恢复出厂设置。请备份所有数据。
**问:之后可以重新锁定吗?**
答:可以。`mtk da seccfg lock` 会重新锁定。完整的锁定/解锁循环已测试且可逆。
**问:为什么只擦除 4 个扇区?**
答:我们只需要移除魔术字符串。一旦魔术字符串不存在,位于更高扇区的锁状态长度和签名数据就无关紧要了——LK 会在不读取它们的情况下回退到使用 seccfg。
## 警告
1. **首先备份 RPMB。** 步骤 1 是您的安全保障。切勿跳过。
2. **备份 NV 分区** (nvdata, nvcfg, nvram, persist, protect1, protect2) — 没有这些数据,您将面临“NV 数据损坏”的风险,这会导致 IMEI 和基带无法使用。
3. **此操作将清除您的数据。** 解锁后首次启动将恢复出厂设置。
4. **BROM V6 = 无法使用。** 如果您的 SoC 是 MT6789 或更新型号,Kamakiri 漏洞已被硬件修补。
5. **仅限 HyperOS 1 (已测试)。** HyperOS 2/3 尚未经过验证。
6. 解锁引导加载程序将导致制造商保修失效。
## 致谢
- [bkerler/mtkclient](https://github.com/bkerler/mtkclient) — 实现 BROM 访问的基础
- Kamakiri 漏洞利用研究者们
- 所有在 GitHub 上报告 seccfg 问题的用户 — 你们的报告帮助确定了问题范围
## 许可证
[AGPL-3.0](LICENSE) — 如果您使用此代码,您也必须发布您的源代码。禁止闭源付费工具。
研究与测试者:**Jz8root**
标签:Android安全, bootloader解锁, Ghidra分析, HyperOS绕过, MediaTek, MIUI14解锁, MTK设备, POCO手机, RPMB擦除, seccfg绕过, 云资产清单, 兼容性扫描, 刷机工具, 安全绕过, 安卓定制, 小米系统, 测试设备, 目录枚举, 移动安全, 脚本扫描, 芯片漏洞, 解锁工具, 设备测试, 逆向工具, 逆向工程