第三章 固件获取与提取:从源头到二进制

做固件逆向,第一步不是反汇编,而是拿到固件本身。很多人一上来就想着怎么分析,结果卡在“没固件”这一步,白白浪费时间。

这一章,我就带你走一遍固件获取的完整路径。从官网下载,到设备备份,再到最硬核的Flash读取。每一步都有坑,我会把踩过的坑都指出来。

3.1 固件来源:三条路,各有千秋

固件从哪来?说白了就三个渠道。我按推荐程度排个序:

来源 难度 完整性 适用场景
官网下载 ★☆☆ 通常完整 消费类产品、开源硬件
设备备份 ★★☆ 可能被裁剪 已部署设备、无网络环境
Flash读取 ★★★ 最完整 加密设备、定制固件

官网下载是最省事的。但有个问题——厂商经常只放最新版,旧版本固件可能已经下架了。我习惯用 wget 配合 --recursive 参数把整个固件目录扒下来,存到本地归档。

小技巧:很多厂商的固件更新包其实是 ZIP 或 TAR 压缩包,里面除了二进制固件,还有文件系统镜像、配置文件甚至调试符号表。别只盯着 .bin 文件,把整个包解压看看。

设备备份这条路,我是在做工业路由器逆向时学会的。设备本身有固件升级功能,但升级包往往需要校验签名。怎么办?

我的做法是:通过串口或 SSH 登录设备,用 dd 命令把 Flash 分区整个读出来。

# 查看分区表
cat /proc/mtd

# 备份整个 Flash
dd if=/dev/mtd0 of=/tmp/full_flash.bin bs=65536

# 通过 TFTP 传回本地
tftp -p -l /tmp/full_flash.bin 192.168.1.100

嗯,这里要注意:很多嵌入式设备的内存很小,直接 dd 到 /tmp 可能撑爆。我建议分块读取,或者用 nc 直接管道传输。

3.2 使用编程器读取Flash:硬核玩家的必修课

当软件手段走不通时,就得动硬件了。编程器读取Flash,是逆向工程师的看家本领。

3.2.1 J-Link vs ST-Link:选对工具

特性 J-Link ST-Link
支持芯片范围 ARM Cortex全系列 + 部分RISC-V STM32全系列
速度 最高50 MHz SWO 最高4 MHz SWD
价格 ¥200-2000+ ¥20-100
调试功能 完整(RTT、ETM、实时跟踪) 基础(断点、单步)
固件提取 支持通过SWD/JTAG直接读Flash 需配合STM32 Utility

我个人习惯:日常调试用ST-Link,便宜够用。但做逆向提取时,我必用J-Link。为什么?因为J-Link的 JLinkExe 命令行工具太强了,可以写脚本批量操作。

实战命令:用 J-Link 读取 STM32F4 的整个 Flash
# 启动 JLinkExe
JLinkExe -device STM32F407VG -if SWD -speed 4000 -autoconnect 1

# 在 JLink 命令行中执行
connect
savebin C:\dump\flash_dump.bin 0x08000000 0x100000
exit

这段命令会从 0x08000000 开始,读取 1MB 的 Flash 内容,保存为二进制文件。

3.2.2 接线与飞线:BGA芯片的噩梦

遇到BGA封装的芯片,才是真正的考验。我记得有一次,客户送来一块工业控制板,主控是BGA封装的i.MX6。Flash芯片藏在BGA下面,根本没法直接夹。

怎么办?飞线。

警告:飞线操作风险极高,稍有不慎就会焊盘脱落、短路甚至烧毁芯片。没有烙铁经验的人,千万别轻易尝试。

我的飞线流程是这样的:

  1. 定位引脚:用万用表测量BGA焊盘到PCB过孔的通路,找到Flash的CS、MISO、MOSI、SCLK、VCC、GND。
  2. 刮开阻焊层:用刀片轻轻刮掉过孔上的绿油,露出铜面。
  3. 上锡:用细尖烙铁给过孔上锡,锡量要少,否则会连到旁边的过孔。
  4. 焊接飞线:用0.1mm的漆包线,一端焊在过孔上,另一端焊在编程器的转接板上。
  5. 固定:用热熔胶把飞线固定在PCB上,防止拉扯脱落。

这里有个坑:BGA芯片的Flash引脚往往和CPU共用,飞线时如果CPU还在供电,可能会造成总线冲突。我习惯先把CPU的供电断开,或者把CPU的复位引脚拉低,让CPU处于复位状态。

3.3 固件加密与保护机制:道高一尺

拿到固件只是第一步。如果固件被加密或保护了,你拿到的只是一堆乱码。

3.3.1 常见的保护手段

保护类型 原理 破解难度 典型芯片
读保护(RDP) 禁止通过调试接口读取Flash ★★☆ STM32(RDP Level 1/2)
加密固件 固件本身被AES/RSA加密 ★★★ NXP i.MX、TI Sitara
安全启动 签名验证,防止篡改 ★★★★ 高通、MTK、全志
熔丝/OTP 一次性编程,烧断后不可恢复 ★★★★★ 很多车规级MCU

3.3.2 绕过读保护:我的实战经验

STM32的RDP Level 1是最常见的。怎么绕过?

我试过几种方法:

  • 电压毛刺攻击:在读取Flash的瞬间,给VDD引脚注入一个短时高压脉冲,让CPU跳过读保护检查。成功率大概30%,而且容易烧芯片。
  • 冷启动攻击:把芯片降温到-40°C以下,利用SRAM的数据保持特性,在复位瞬间读取残留数据。这个方法对某些老芯片有效。
  • 固件漏洞利用:通过串口或网络接口,利用固件本身的漏洞(如缓冲区溢出)来dump内存。这是最优雅的方式。
避坑指南:我曾经在RDP Level 2的芯片上浪费了两周时间。Level 2是永久不可逆的,任何试图读取Flash的操作都会导致芯片自毁。遇到Level 2,直接放弃硬件读取,转而寻找固件更新包或备份。

3.3.3 加密固件的处理思路

加密固件看起来无解,但其实有突破口:

  1. 密钥存储位置:密钥通常存储在芯片的OTP区域或eFuse中。如果能通过物理手段读取OTP(比如用聚焦离子束FIB),就能拿到密钥。
  2. 解密过程监控:芯片在启动时,会从Flash读取加密固件,用内置密钥解密后执行。如果能用逻辑分析仪抓取CPU和Flash之间的数据总线,就能捕获解密后的明文。
  3. 侧信道攻击:通过分析芯片的功耗或电磁辐射,推断出密钥。这个需要专业设备,但确实可行。

嗯,这些方法都挺硬核的。对于大多数场景,我建议优先寻找固件更新包——很多厂商的更新包是未加密的,或者加密密钥就硬编码在更新程序里。

3.4 本章知识结构图

下面这张图,把固件获取与提取的完整流程串起来了:

固件获取与提取流程 固件获取与提取流程 官网下载 设备备份 Flash读取 固件提取与解密 无保护 → 直接分析 读保护 → 绕过攻击 加密 → 密钥提取 最终输出:明文固件二进制文件 说明:固件获取路径取决于设备的安全等级。官网下载最省事,Flash读取最完整但风险最高。 遇到加密固件时,优先寻找更新包中的解密密钥,而不是直接攻击硬件。

3.5 小结

固件获取是逆向分析的基础。我的建议是:

  • 先走软件路线(官网、设备备份),实在不行再动硬件。
  • 动硬件时,优先用编程器通过SWD/JTAG读取,飞线是最后的选择。
  • 遇到加密保护,别硬刚。先看看有没有固件更新包、有没有调试接口、有没有已知漏洞。

你想想看,如果连固件都拿不到,后面的分析就是空中楼阁。把这一步走扎实了,后面的路就好走了。