软媒设计
This is my life!
spd_dump 的 macOS 移植与 BootROM 解锁

移植 spd_dump 在 macOS 上实现X猫 U20(展锐 UMS9621)的 BootROM 解锁。

风险提示:本文仅作技术记录与研究参考。BootROM 级操作有变砖风险,且可能影响设备保修与运营商合规性;涉及的安全漏洞信息仅用于自有设备研究。据此操作产生的一切后果自负。本文与工具仓库均不提供任何固件包的分发。

设备与平台

项值
设备X猫 U20 随身 WiFi(WiFi6 版,主板丝印 NR3E62/MN901,硬件 V1.00C,无屏、无内置电池)
SoC紫光展锐 UMS9621(代号 T158),8 × Cortex-A55
系统Android 13,内核 5.15,GKI 架构(ramdisk 位于 init_boot 分区)
存储eMMC,74 个分区

芯片结论的取证链:管理后台仅标注"国产八核";USB 枚举为 05c6:f00e 的 Android f_rndis 组合、TTL=64、dnsmasq 指纹指向 Linux/Android;最终在刷机包的 boot 镜像内核路径中出现 UMS9621_MN901UFI 构建串,与刷入后的 getprop ro.board.platform(ums9621)互相印证。

macOS 面临的三个障碍

  1. 无系统级下载工具。社区主流工具闭源,仅发布 Windows 与 Linux 版本;macOS 侧无现成方案。
  2. RNDIS 不被支持。该设备 USB 网口为 RNDIS 组合,macOS 不加载驱动,正常模式下连管理后台都要绕路(用户态 libusb 直驱 RNDIS 可读到链路层,但该固件未在 USB 网口启用服务)。
  3. 无屏设备。任何依赖屏幕点击的授权流程(如 Magisk 的 su 弹窗)都无法完成。

结论是绕开正常模式,直接走 BootROM 下载模式:断电状态按住 Reset 插线,设备枚举为 1782:4d00,约 20 秒内应答。

绕过签名校验:CVE-2022-38694

UNISOC BootROM 对 FDL1 镜像做签名校验,直接下发会被静默丢弃。社区闭源工具的 exec_addr2 命令实现了 CVE-2022-38694 的利用,其真实语义是单传输越界写,而非两次独立下载:

START_DATA{fdl1 地址, fdl1 大小}      ← 只声明 fdl1 的尺寸
MIDST × N    下发 fdl1(不发 END)
MIDST × K    零填充,跨过 fdl1 末尾写到 BootROM 栈区   ← 越界
MIDST        96 字节 blob,精确落在栈上的返回地址槽
(全程不发 EXEC,被劫持的返回地址直接进入免校验路径)

关键点:对受保护地址发起独立 START_DATA 会得到 0x8A(DOWN_SIZE_ERROR)拒绝,只有骑在单次传输内的越界写可以绕过。这一点在开源实现 ilyakurdyukov/spreadtrum_flash 上以约 65 行补丁完成移植,配合边沿触发的自动化脚本(只在新设备出现的瞬间发起会话),在 macOS 上稳定复现。

完整的补丁源码、协议笔记与脚本已整理为开源仓库:xun404/spd_dump-macos。

备份先于刷写

FDL2 就位后即可读写分区,但社区工具有一批没有写进文档的分区规则,违反会导致会话挂死或写入失败:

  • runtimenv:禁止写入,只能擦除(运行时 NV 由基带开机自建);
  • fixnv1:按名字读取会挂死会话,读孪生分区 fixnv2 代替;
  • calinv:跳过不写;
  • GPT 中 size 字段单位是 MB,不是 KB。

备份完成后按四道关校验:数量与字节级尺寸比对、镜像魔数(ANDROID!/VNDRBOOT/AVB0/DHTB/super 的 gDla 双副本)、NV 的 0x4E56 魔数、以及与已知同型静态分区做 md5 交叉比对。全部通过后才允许进入刷写。本例全量备份约 3.7 GB;FDL2 读不动的调制解调器 NV 分区族,留待刷后以 root 权限用 dd 补齐。

刷写与验证

共写入 36 个分区约 3.06 GiB(含 2.56 GiB 的 super),vbmeta 全族写前离线置 AVB flags=3(等价关闭 dm-verity 与校验),擦除 userdata 后 reset。重启后 ADB 即上线:

ro.board.platform  = ums9621
ro.soc.model       = T158
ro.product.board   = MN901UFI

至此芯片型号、主板丝印、系统属性三方互证闭环。

无屏设备的 root

第三方固件自带 Magisk(注入 init_boot)与 ADB,但 su 授权弹窗无人可点。解法是直接改策略库 /data/adb/magisk.db:给 policies 表写入 uid=2000(shell)→ policy=2,settings 表补 root_access=3,重启后 adb shell 即可免弹窗提权。注意 v30.x 的 policies 表没有 package_name 列,照抄旧教程会报错。

固件内置的 Web 终端(ttyd)默认弱口令且以 root 运行、监听全部接口——刷机后建议立刻修改其后台密码,并关闭预埋的网络 ADB 端口属性。对该固件的完整安全检查结论:未发现云端外联与远控通道,风险集中在默认凭据与"功能即攻击面"的设计上。

工具与参考

  • 本站整理的 macOS 工具链与全部笔记:https://github.com/xun404/spd_dump-macos
  • 上游开源实现:https://github.com/ilyakurdyukov/spreadtrum_flash
  • 漏洞背景:CVE-2022-38694(NCC Group 有公开分析)