第三章 固件提取实战:从Flash到文件
做逆向分析,第一步永远是拿到固件。没有固件,后面全是空谈。这一章我带你走一遍nRF52固件提取的完整流程——从硬件连接、命令行工具使用,到文件格式解析,再到绕过读保护的基本思路。
说实话,我见过不少新手上来就想着怎么破解加密,结果连Flash都没读出来过。嗯,咱们先把基础打牢。
3.1 硬件准备与连接
你需要一块nRF52开发板或目标设备,外加一个J-Link调试器。我个人习惯用J-Link Plus,稳定,速度快。如果你手头只有J-Link EDU Mini,也能用,就是慢点。
连接方式很简单:
- SWDIO → 目标板SWDIO引脚
- SWCLK → 目标板SWCLK引脚
- GND → 共地
- VCC → 目标板供电(可选,J-Link可提供3.3V)
3.2 使用nrfjprog读取Flash内容
Nordic官方提供了nrfjprog工具,这是最直接的读取方式。安装完nRF Command Line Tools后,打开终端。
先确认连接:
nrfjprog --ids
如果返回一个序列号,说明连接成功。返回空?检查接线和驱动。
读取整个Flash:
nrfjprog --readcode my_firmware.hex
这条命令会把整个Flash(通常是0x00000000到0x0007FFFF,512KB)读出来,保存为Intel HEX格式。
如果你只想读特定区域:
nrfjprog --read 0x00000000 0x10000 firmware_part.bin
这里0x10000是64KB,适合读Bootloader区域。
3.3 使用JLink Commander导出固件
nrfjprog虽然方便,但有时候你手头只有J-Link,没有装Nordic工具链。这时候JLink Commander就派上用场了。
启动JLinkExe(Windows下是JLink.exe):
JLinkExe -device nRF52840_xxAA -if SWD -speed 4000 -autoconnect 1
进入命令行后:
mem 0x00000000 0x100
savebin flash_dump.bin 0x00000000 0x80000
exit
mem命令查看内存内容,savebin把指定地址范围保存为二进制文件。0x80000是512KB,对应nRF52840的Flash大小。
关键区别:
- nrfjprog:自动处理UICR、FICR等特殊区域,适合完整备份
- JLink Commander:更底层,适合调试和部分读取
3.4 固件文件格式解析
读出来的文件有三种常见格式:HEX、BIN、ELF。很多人搞不清它们的区别,我简单说一下。
| 格式 | 特点 | 适用场景 |
|---|---|---|
| HEX | 文本格式,包含地址信息,可分段 | 烧录、传输、部分修改 |
| BIN | 纯二进制,无地址信息,连续存储 | 逆向分析、反汇编 |
| ELF | 包含符号表、调试信息、段信息 | 调试、符号恢复 |
HEX文件长这样:
:020000040800F2
:1000000000000020E1000000F1000000F3000000
:1000100000000000000000000000000000000000
:0400000508000000F7
:00000001FF
每一行以冒号开头,后面是长度、地址、类型、数据、校验和。逆向分析时,我通常先把HEX转成BIN,再用反汇编工具打开。
转换命令:
nrfjprog --hex2bin my_firmware.hex my_firmware.bin
或者用第三方工具:
objcopy -I ihex -O binary my_firmware.hex my_firmware.bin
3.5 固件加密与读保护绕过思路
这是很多人最关心的部分。nRF52的读保护机制主要分两层:
- UICR(用户信息配置寄存器):APPROTECT位控制是否允许调试访问
- ACL(访问控制列表):nRF5340等新芯片引入,更细粒度的内存保护
当APPROTECT被置位后,nrfjprog会报错:
ERROR: Could not read memory. The device is protected.
这时候怎么办?我总结了几种思路:
绕过思路(按难度排序):
- 硬件攻击:通过电压毛刺(Glitch)或激光切割绕过读保护。需要专业设备,成功率看运气。
- 恢复出厂设置:nRF52支持全擦除(Mass Erase),但会清空所有数据。如果你只是想拿到固件,这条路走不通。
- 调试接口劫持:在芯片启动早期、APPROTECT生效前,通过SWD注入代码。我试过几次,时序要求极高。
- 侧信道分析:通过功耗或电磁辐射分析,提取加密密钥。这属于高阶玩法,需要示波器和信号处理知识。
- 固件漏洞利用:如果设备上有未保护的Bootloader或OTA接口,可能通过漏洞直接读取Flash。
我个人最常用的方法是第5种——找固件漏洞。很多物联网设备在OTA更新时没有做充分校验,你可以伪造一个更新包,把Flash内容读出来。具体怎么做?后面章节会详细讲。
3.6 本章知识体系
下面这张图概括了固件提取的核心流程和关键决策点:
这张图把流程分成了两条路径。左边是理想情况——芯片没保护,直接读。右边是现实情况——大多数商业设备都开了保护,需要想办法绕过。
3.7 实战经验总结
最后分享几个我踩过的坑:
- 读出来的固件全是0xFF? 检查地址范围。nRF52的Flash起始地址是0x00000000,不是0x08000000(STM32的习惯)。我一开始就犯过这个错。
- JLink连接不上? 试试降低SWD速度。有些目标板在4000kHz下不稳定,降到1000kHz就好了。
- HEX文件转BIN后大小不对? HEX文件可能包含非连续地址段,转BIN时会填充空白区域。用
--fill参数控制填充值。 - 读保护擦不掉? 有些设备在APPROTECT置位后,连Mass Erase都不允许。这时候只能换芯片,或者用更暴力的方法。