2、固件获取与识别:从硬件提取固件、格式识别与加密压缩初探

做固件逆向,第一步就是拿到固件本身。听起来简单,对吧?但这里面的坑,我踩过不少。你想想看,如果连固件都拿错了,后面分析得再漂亮也是白搭。这一章,咱们就聊聊怎么从硬件里把固件“请”出来,以及拿到手后怎么识别它到底是什么东西。

2.1 从硬件提取固件:SPI Flash 与 eMMC

固件通常存储在非易失性存储器里。最常见的两种,就是 SPI Flash 和 eMMC。它们俩的提取方法,差别还挺大。

2.1.1 SPI Flash 提取

SPI Flash 多见于路由器、物联网设备、一些简单的嵌入式主板。它的引脚少,接口简单。提取它,我一般用编程器,比如 CH341A、树莓派,或者专业的 RT809H。

操作步骤大致如下:

  1. 识别芯片型号:先看芯片表面的丝印,比如 “W25Q64FV”、“MX25L12835F”。记下来,去查数据手册,确认引脚定义。
  2. 连接编程器:用夹子或者焊线,把编程器的 CS、MISO、MOSI、CLK、VCC、GND 对应接到芯片上。注意,有些板子上的 Flash 是 3.3V 供电,别接错电压烧了芯片。
  3. 读取数据:打开编程器软件,选择对应型号,点击“读取”。等进度条走完,保存为 .bin 文件。

小提示:如果芯片是焊在板子上的,用烧录夹最方便。但有些板子会“偷电”,导致读取失败。我遇到过好几次,夹上去后编程器认不到芯片。这时候,可以尝试给板子单独供电,或者断开板子上的 VCC 引脚,只让编程器供电。

警告:千万别在带电的情况下插拔夹子!我手抖过一次,瞬间短路,芯片直接冒烟了。嗯,那感觉,记忆犹新。

2.1.2 eMMC 提取

eMMC 常见于手机、平板、树莓派、高级点的路由器。它内部集成了 Flash 存储器和控制器,接口是 MMC 协议。提取它,比 SPI Flash 麻烦不少。

常用的方法有两种:

  • 直接读芯片:用支持 eMMC 的编程器(如 EasyJTAG、Medusa Pro),配合 eMMC 转接座或飞线。这种方法需要拆焊芯片,对焊接技术有要求。
  • 通过系统读:如果设备能开机,并且有 root 权限,可以用 dd 命令把整个 eMMC 分区镜像出来。比如:dd if=/dev/block/mmcblk0 of=/sdcard/emmc_dump.img bs=1M。这是我最喜欢的方式,省时省力。

我个人习惯,能开机就先尝试系统级提取。实在不行,再上热风枪。拆焊 eMMC 时,温度要控制好,我一般用 350-380 度,配合助焊剂,轻轻一推就下来了。千万别硬撬,容易掉焊盘。

2.2 固件格式识别:bin、hex、elf

拿到固件文件后,第一件事就是看它是什么格式。不同格式,解析方式完全不同。

格式 特点 常见场景 如何识别
.bin 纯二进制数据,没有地址信息。从 Flash 起始地址开始,原样存储。 SPI Flash 固件、Bootloader、裸机程序。 用十六进制编辑器打开,看开头有没有文件头。或者用 file 命令,通常显示为 “data”。
.hex Intel HEX 格式,文本文件。每行包含地址、数据和校验。 单片机程序(如 STM32、AVR)、一些老的编程器输出。 用文本编辑器打开,看到以 “:” 开头的一行行数据,就是 HEX。
.elf Executable and Linkable Format,包含代码、数据、符号表、调试信息等。 Linux 内核、应用程序、带操作系统的固件。 file 命令,会显示 “ELF 32-bit LSB executable” 或类似信息。

举个例子,你从路由器上读了个 16MB 的 .bin 文件。用 file firmware.bin 一看,显示 “data”。再用十六进制编辑器打开,开头是 “FF FF FF FF” 或者 “00 00 00 00”。嗯,基本可以确定是 SPI Flash 的原始镜像。

如果你拿到的是 .hex 文件,可以用 objcopybincopy 工具转成 .bin。比如:objcopy -I ihex -O binary input.hex output.bin。这样就能直接分析了。

至于 .elf 文件,它自带符号表,分析起来最方便。用 readelf -s firmware.elf 就能看到所有函数名和变量名。我在逆向一个智能门锁时,就靠 .elf 里的符号表,直接定位到了核心加密算法,省了不少功夫。

2.3 固件加密与压缩初探

很多厂商为了保护自己的代码,会对固件进行加密或压缩。你拿到的 .bin 文件,很可能不是真正的可执行代码。

2.3.1 固件压缩

压缩是为了节省存储空间。常见的压缩算法有 LZMA、LZSS、gzip、zlib。怎么判断固件是否被压缩了?

  • 看熵值:用 binwalk 或自己写脚本计算文件块的熵。压缩后的数据,熵值很高(接近 8.0),看起来像随机数。
  • 看文件头:gzip 文件头是 “1F 8B”,LZMA 文件头是 “5D 00”。用十六进制编辑器搜索这些魔数。
  • 用 binwalk 自动扫描binwalk firmware.bin,它会自动识别并提取出压缩段。

我曾经分析过一个 IP Camera 的固件,binwalk 扫出来一堆 LZMA 段。手动解压后,发现里面还有一层 gzip。这种套娃式的压缩,在 IoT 设备里很常见。

2.3.2 固件加密

加密比压缩更棘手。常见的有 AES、XOR、自定义算法。识别加密的方法:

  • 熵值极高且均匀:加密后的数据,熵值接近 8.0,而且分布非常均匀,没有明显的模式。
  • 没有明显的文件头:不像压缩数据有魔数,加密数据看起来就是一堆乱码。
  • 有解密程序或密钥:在固件的其他部分,或者 Bootloader 里,可能会找到解密函数和密钥。

重点:遇到加密固件,别慌。先找 Bootloader。很多设备的 Bootloader 是不加密的,它里面会调用解密函数。逆向这个解密函数,就能拿到密钥和算法。我有个项目,就是通过逆向 U-Boot,找到了一个简单的 XOR 密钥,成功解开了整个固件。

对于简单的 XOR 加密,可以用 xorsearch 工具暴力破解。比如:xorsearch -s firmware.bin -t 0xFF,尝试用 0xFF 做密钥解密。有时候,厂商偷懒,用的就是单字节 XOR。

嗯,这里要注意。有些厂商会把加密和压缩结合起来。先加密,再压缩,或者反过来。这时候,binwalk 可能识别不出来。你需要手动分析,先尝试解压,再尝试解密,或者反过来。没有固定套路,全靠经验积累。

好了,这一章的内容就这些。从硬件提取到格式识别,再到加密压缩的初步判断,每一步都有它的门道。多动手,多踩坑,你也能成为固件提取的老手。


专注资料整理