·6 分钟阅读

逆向一台 MT6261 山寨功能机:BROM 协议、固件备份与刷机变砖实录

完整记录一台 MT6261 2G 功能机的逆向:从 USB 设备识别、AT 命令探测、BROM 下载协议逆向,到用 mtkclient 完成固件备份与写回,以及刷第三方固件变砖的教训。

逆向MTK固件嵌入式刷机

逆向一台 MT6261 山寨功能机

一台 MT6261 2G 功能机(山寨机)的完整逆向:设备识别 → AT 命令探测 → BROM 协议逆向 → 固件备份/刷写 → 第三方固件分析。最终目标是搞清「这类老式功能机能不能刷机、能不能装软件、能不能跑自己的代码」。

本文隐去了设备 IMEI、硬件项目号等敏感信息。

设备识别:别信 lsusb 的名字

设备插上 USB,内核把它枚举成一个 GSM modem,串口挂到 ttyUSB4。lsusb 显示厂商 ID 0e8d(MediaTek Inc)。

第一个坑就在这:usb.ids 数据库把 0e8d:0003 标成 "MT6227 phone"。这是个误导性的通用名——0003 这个 PID 在功能机上同时被两种状态共用:

flowchart LR
    USB[USB 0e8d:0003] -->|关机插电 ~2.8s| BROM[BROM 下载口]
    USB -->|开机运行| AT[AT/modem 口]
    BROM -->|之后跳转| MSC[0e8d:0002 充电壳]

真实芯片型号不能靠 lsusb,要靠 AT 命令读回,或者靠 mtkclient 的 chip 识别——最后确认是 MT6261(ARM7EJ-S 内核,Thumb 指令集)。

AT 命令:高度裁剪,EGMR 是核心

功能机固件的 AT 命令子集小得可怜。大部分标准 3GPP 命令直接返回 +CME ERROR: 100(不支持/被屏蔽)。能用的只有:AT、ATE0/1、ATV0/1、AT+CGMM、AT+CGMR、AT+CSQ、AT+COPS?、AT+CFUN(0/1/4),以及最关键的 AT+EGMR。

EGMR 是 MTK 的私有身份命令,既能读工厂身份段,又能改写 IMEI(改串号,敏感)。读出来的索引表大致是:

index 内容
0 芯片名(MT6261)
3 软件版本
4 硬件项目/板号
7 / 10 SIM1 / SIM2 的 IMEI
8 资源版本(音频/图片/字体/字符串)

这一段读下来,设备的「完整身份证」就到手了——芯片、软硬件版本、产线批次、IMEI 全都暴露在一个命令里。

BROM 协议逆向:老 MAUI bootloader 不按套路出牌

想备份固件,得走 BROM(Boot ROM)下载口。mtkclient 是 MTK 刷机/备份的标准工具,但它主要面向智能机(MT65xx+),对 MT6261 这种老式 MAUI bootloader 有系统性不兼容。

第一个坎:BROM 窗口只有 2.8 秒

关机插 USB,设备先进 BROM(0e8d:0003),但只停留约 2.8 秒,然后就跳去充电壳(0e8d:0002)或自动开机。按键没法延长这个窗口。握手代码慢了半拍就抓不到。

第二个坎:握手后的命令集对不上

mtkclient 握手成功后,会发 GET_HW_CODE(0xFD) 去要硬件码。但 MT6261 的 BROM 只 echo 这个字节、根本不返回 hwcode,于是 rdword() 干等,直到 BROM 自己超时重启。

用独立 pyusb 脚本逐个命令字节探过去,才摸清真实命令集:

命令 响应
简单 echo(0xFE/0xFD/0xFC/0xBF/…) 立即回显
0xFF(GET_VERSION) 返回 05
0xA2(READ16_A2) 唯一可用的读内存命令
0xD0/0xD1(READ16/READ32) 无响应(不支持)

关键结论:0xA2 是全班唯一能读内存的命令,hwcode 可以从内存地址 0x80000008 用 read_a2 读出来,根本不用 GET_HW_CODE。

改造 mtkclient:7 处代码修改

摸清协议后,对 mtkclient 打了 7 处补丁,让它能完整备份 + 写回 MT6261:

文件 修改 解决
Port.py echo() 显式超时 read 握手后 EIO
Port.py run_handshake() 跳过 CDC 控制传输 端点状态被干扰
Port.py 握手循环 sleep 0.3/0.1 → 0.05 抢 2.8s 窗口
mtk_preloader.py 跳过 rdword() GET_HW_CODE 不返回
mtk_preloader.py read32() list 类型保护 TypeError
dalegacy_lib.py 新增 nor_write_data() 补 NOR 写分支
mtk_main.py 跳过 crasher 功能机已 BROM

改完后 rf(读全 flash)成功读出 4MB 原厂固件,wf(写全 flash)也补上了对称的 NOR 写路径(WRITE_CMD 0xD5,擦除块 16KB 对齐)。

第三方固件分析:硬件兼容,但都装不了软件

网上找了 4 个 MT6261 的第三方固件想刷,逐个做了二进制对比——LCD 驱动、运行时、硬件配置:

固件 LCD 驱动 应用运行时
5Star GR7 GC9304, ST7789V ❌ 无 MRE
Symphony B17 GC9102D, ILI9163C, ST7735S ❌ 无 MRE
iSmart IS-203i GC9312 ❌ 无 MRE
Karbonn E3 GC9303, ILI9341, ST7789S ❌ 无 MRE

结论很明确:

  1. 硬件大概率兼容——4 个固件都是同一个「11C」参考设计,且每个都内置多款 LCD 驱动自动检测
  2. 但全都没有 MRE 应用运行时——刷了也装不了软件,只是换个品牌界面
  3. 这些固件多是海外版(英国/印度),射频频段和国行不同,刷了很可能插卡没信号

刷机变砖:bootloader 前 16KB 的教训

最终还是刷了 5Star(4MB 完整镜像,最方便)。刷完设备半砖了——屏幕不亮。

复盘根因:整片 wf 写入时,flash 前 16KB(bootloader)被第三方固件的 bootloader 覆盖。之后想刷回原厂备份,DA(下载代理)在读取 flash 分区信息阶段就崩溃重启,因为 bootloader 区布局已经对不上。

但半砖不是死刑:BROM 入口完好 + 原厂完整备份完好,两条命都在。恢复只是时间问题——多试几次碰 DA 稳定、让 DA 跳过 bootloader 区校验、或者丢给 Windows 下的 MTK Flash Tool 整片刷回。

这场事故换来一条铁律:刷机前必须完整备份。这次能全身而退,靠的就是先 rf 出来的那 4MB。

总结

这个项目最大的收获不是「成功刷机」,而是把整条链路打通了:

  • ✅ 设备识别:别信 lsusb,用 EGMR / dacode 确认芯片
  • ✅ AT 命令:功能机高度裁剪,EGMR 是身份与 IMEI 的核心入口
  • ✅ BROM 协议:0xA2 唯一读内存、窗口 2.8s、命令集与智能机不同
  • ✅ 工具链改造:7 处补丁让 mtkclient 支持 MT6261 备份 + NOR 写回
  • ❌ 装软件:固件无 MRE,刷第三方固件也装不了应用,唯一路径是 BROM 代码注入
  • ⚠️ 教训:刷机前必须完整备份,bootloader 前 16KB 是变砖高危区