固件解包与文件系统分析:binwalk深度使用、文件系统挂载、大模型辅助识别

固件解包,说白了就是拆礼物。你拿到一个二进制文件,里面可能藏着文件系统、内核、引导程序。我刚开始干这行时,以为解包就是跑个binwalk完事。结果有一次,一个IoT设备的固件死活解不开,折腾了两天才发现是文件系统类型判断错了。嗯,从那以后,我对这步再也不敢马虎。

binwalk深度使用:不只是跑个命令

binwalk是固件逆向的瑞士军刀。但很多人只用它的默认扫描,其实浪费了。

核心用法:

  • binwalk firmware.bin — 扫描固件中的文件签名
  • binwalk -Me firmware.bin — 自动提取所有文件
  • binwalk -D 'squashfs:rootfs.sqsh' firmware.bin — 只提取特定类型

我个人习惯先用 binwalk -Me 跑一遍,看看能解出什么。但注意,binwalk不是万能的。我曾经遇到一个固件,binwalk扫描显示有squashfs,但提取出来全是乱码。后来发现是固件头部有自定义偏移,binwalk没识别出来。

我的经验:遇到binwalk解不出来的情况,试试 binwalk -R "\x68\x73\x71\x73" firmware.bin 手动搜索squashfs魔数。hsqs就是squashfs的签名,很多厂商会把它藏在固件中间。

文件系统挂载:squashfs、jffs2、ubifs

解包只是第一步。拿到文件系统镜像后,你得挂载它才能看到里面的文件结构。三种最常见的嵌入式文件系统,我分别说说。

squashfs:只读文件系统

squashfs是最常见的。它只读、压缩率高。挂载命令很简单:

# 先查看文件系统信息
unsquashfs -s rootfs.sqsh

# 挂载到本地目录
sudo mount -t squashfs rootfs.sqsh /mnt/firmware

# 或者直接用unsquashfs解压
unsquashfs -d ./extracted rootfs.sqsh

这里有个坑:有些固件用了LZMA压缩的squashfs,老版本的unsquashfs可能不支持。我建议用最新版的squashfs-tools,或者用 sasquatch 这个补丁版工具。

避坑指南:我曾经遇到一个固件,unsquashfs报错说"Filesystem is corrupt"。后来发现是固件头部有4字节的校验和,去掉后才能正常解压。所以,遇到报错先别慌,用hexdump看看文件头是不是有多余数据。

jffs2:闪存专用文件系统

jffs2是专门为NAND Flash设计的。挂载它需要模拟一个MTD设备:

# 加载内核模块
sudo modprobe mtdblock
sudo modprobe jffs2

# 创建MTD设备
sudo modprobe mtdram total_size=65536 erase_size=256
sudo flash_erase /dev/mtd0 0 0
sudo nandwrite -p /dev/mtd0 rootfs.jffs2

# 挂载
sudo mount -t jffs2 /dev/mtdblock0 /mnt/firmware

说实话,jffs2挂载比squashfs麻烦多了。我建议直接用 jefferson 这个工具,它不需要内核模块:

# 安装jefferson
pip install jefferson

# 解压jffs2镜像
jefferson rootfs.jffs2 -d ./extracted

ubifs:UBI文件系统

ubifs是较新的闪存文件系统,常见于Linux 3.x以上内核的设备。挂载它需要模拟UBI设备:

# 加载模块
sudo modprobe nandsim
sudo modprobe ubi
sudo modprobe ubifs

# 创建模拟NAND设备
sudo modprobe nandsim first_id_byte=0x2c second_id_byte=0xda \
                     third_id_byte=0x90 fourth_id_byte=0x95

# 烧录UBI镜像
sudo ubiattach -m 0 -d 0
sudo ubiformat /dev/mtd0 -f rootfs.ubi
sudo ubiattach -m 0 -d 0

# 挂载
sudo mount -t ubifs ubi0:rootfs /mnt/firmware

嗯,这里要注意:ubifs的挂载参数很敏感。我遇到过因为页大小不对导致挂载失败的情况。用 ubinfo -a 可以查看UBI设备信息,帮你排查问题。

大模型辅助识别文件系统类型

你想想看,有时候拿到一个固件,binwalk扫描结果模棱两可。这时候大模型能帮上忙。

我的做法是:把固件头部的hexdump发给大模型,让它分析可能的文件系统类型。比如:

# 提取固件前1KB的hex
head -c 1024 firmware.bin | xxd | pbcopy

# 然后问大模型:
# "这个hex dump来自一个嵌入式固件,请分析可能的文件系统类型。
#  特征:偏移0x100处有'hsqs'签名,但后面跟着非标准数据。"

大模型会给出分析建议,比如:

  • 签名匹配squashfs,但偏移量异常
  • 可能是自定义头部 + squashfs的组合
  • 建议跳过前N字节再尝试解包

我的技巧:把binwalk的扫描结果直接贴给大模型,让它帮你解读。比如binwalk显示多个文件系统签名,大模型能根据偏移量和大小判断哪个是真正的根文件系统。我试过几次,准确率还挺高。

另外,大模型还能帮你写解包脚本。比如遇到自定义加密的固件,你可以描述加密特征,让大模型生成解密代码。我曾经遇到一个固件,头部有XOR加密,大模型帮我写了个Python脚本,几分钟就搞定了。

知识体系结构图

下面这张图展示了固件解包与文件系统分析的核心流程:

固件解包与文件系统分析流程 固件二进制文件 binwalk扫描与提取 文件系统类型识别(binwalk + 大模型) squashfs unsquashfs / mount jffs2 jefferson / MTD模拟 ubifs UBI模拟 / mount 文件系统挂载 / 文件提取

实战中的避坑指南

最后,分享几个我踩过的坑:

  • 文件系统碎片化:有些固件把文件系统分成了多个块。binwalk可能只提取到一部分。这时候需要手动拼接,或者用 binwalk -W 对比多个固件版本找差异。
  • 自定义压缩:我遇到过用LZMA但魔数被改过的squashfs。用 7z x 或者 lzma -d 试试,有时候能直接解压。
  • 大小端问题:ARM和MIPS的大小端不同。挂载ubifs时如果报错,检查一下是不是大小端搞反了。
  • 大模型不是万能的:它给出的建议要验证。我习惯先在大模型建议的偏移量处手动hexdump确认,再执行解包命令。

总结一下:固件解包的核心是三步走——binwalk扫描、类型识别、挂载提取。大模型能帮你加速识别过程,但最终还是要靠自己的经验和工具验证。多练几次,你就能一眼看出固件里藏着什么文件系统。


公众号:蓝海资料掘金营,微信deep3321