固件解包与文件系统分析: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 -W对比多个固件版本找差异。 - 自定义压缩:我遇到过用LZMA但魔数被改过的squashfs。用
7z x或者lzma -d试试,有时候能直接解压。 - 大小端问题:ARM和MIPS的大小端不同。挂载ubifs时如果报错,检查一下是不是大小端搞反了。
- 大模型不是万能的:它给出的建议要验证。我习惯先在大模型建议的偏移量处手动hexdump确认,再执行解包命令。
总结一下:固件解包的核心是三步走——binwalk扫描、类型识别、挂载提取。大模型能帮你加速识别过程,但最终还是要靠自己的经验和工具验证。多练几次,你就能一眼看出固件里藏着什么文件系统。
公众号:蓝海资料掘金营,微信deep3321