二进制文件格式:ELF、PE、BIN、IMG 等常见格式介绍
做固件逆向分析,第一关就是认文件。你拿到一个二进制文件,连它是什么格式都搞不清,后面的分析根本无从下手。我早年刚入行时,就吃过这个亏——对着一个 BIN 文件硬拆,拆了半天才发现它其实是带偏移的 IMG 镜像。嗯,今天咱们就把这几种常见格式彻底捋清楚。
ELF:Linux 世界的通用语言
ELF(Executable and Linkable Format)是 Linux 下最常见的二进制格式。说白了,它就是个带“目录”的文件。这个目录叫节头表(Section Header Table),里面记录了代码段、数据段、符号表等的位置。
我个人习惯,拿到 ELF 文件第一件事就是跑 readelf -h 看文件头。为什么?因为文件头里藏着关键信息:
- 魔数:前4个字节是
7f 45 4c 46(即.ELF),一眼就能认出来 - 位数:32位还是64位,决定了后续解析的指针宽度
- 字节序:小端还是大端,MIPS 路由器固件里经常遇到大端
- 入口点:程序开始执行的地址,逆向时重点关注
核心要点:ELF 文件分为三种类型——可重定位文件(.o)、可执行文件、共享对象文件(.so)。思科固件里最常见的是可执行 ELF,通常就是那个 linux.bin 或 kernel。
我记得有一次分析思科 ISR 系列的路由器固件,解包后发现一个 ELF 文件,用 readelf -S 查看节头,发现 .text 段居然被加密了。嗯,这种情况在商业固件里并不少见,厂商会做代码混淆或加密保护。
PE:Windows 的遗产
PE(Portable Executable)是 Windows 下的标准格式。虽然思科主要用 Linux,但有些管理工具或旧版软件会跑在 Windows 上。PE 格式和 ELF 类似,也有文件头和节表,但结构更复杂一些。
PE 文件头以 4d 5a(即 MZ)开头,这是 DOS 时代的遗产。你想想看,都2025年了,Windows 可执行文件还得兼容40年前的 DOS 头。偏移 0x3c 处有个指针,指向真正的 PE 头(50 45 00 00,即 PE\0\0)。
做逆向时,PE 文件有几个关键结构:
- 导入表(Import Table):记录了程序调用了哪些 DLL 函数。我经常通过导入表快速判断程序的功能
- 导出表(Export Table):DLL 文件向外暴露的函数列表
- 资源段(.rsrc):图标、字符串、对话框等资源,有时会藏敏感信息
小技巧:用 file 命令识别 PE 文件时,输出会显示 PE32 executable (GUI) Intel 80386。GUI 表示图形界面程序,CUI 表示控制台程序。这个细节能帮你判断固件里的工具是后台服务还是管理界面。
BIN:最原始也最坑的格式
BIN 文件,说白了就是“裸二进制”。没有文件头,没有节表,没有符号信息。它就是一段连续的内存转储。你拿到一个 BIN 文件,连它从哪里开始、到哪里结束都不知道。
我曾经踩过一个坑:分析某款思科交换机的固件升级包,解压后得到一个 8MB 的 BIN 文件。我直接用 IDA 加载,结果全是乱码。后来才发现,这个 BIN 文件前面 256 字节是引导加载器的头部,真正的代码从 0x100 开始。嗯,从那以后,我拿到 BIN 文件都会先做几件事:
- 看大小:8MB、16MB 通常是 Flash 芯片的容量,暗示了内存映射的起始地址
- 搜字符串:用
strings命令找版本号、错误信息,判断是什么系统 - 找魔数:在文件里搜索
7f 45 4c 46(ELF)或1f 8b(gzip),看里面是否嵌了其他格式 - 分析偏移:如果文件开头是连续的
ff或00,很可能是填充数据,真正的代码在后面
避坑指南:我曾经分析一个 BIN 文件,用 binwalk 扫描发现里面嵌了三个 ELF 文件。但直接提取出来运行都报错。后来发现,这些 ELF 文件是位置无关的,加载地址需要根据 BIN 文件在 Flash 中的偏移重新计算。所以,BIN 文件里的代码地址,往往不是它实际运行时的地址。
IMG:带偏移的镜像文件
IMG 文件通常是对 Flash 芯片或存储介质的完整镜像。它和 BIN 很像,但多了一层结构——文件系统。常见的 IMG 格式包括:
- SquashFS:思科路由器固件最常用的只读文件系统,压缩率高
- JFFS2:早期的 Flash 文件系统,支持磨损均衡
- UBIFS:较新的 Flash 文件系统,思科新设备上开始出现
识别 IMG 文件的关键是找文件系统魔数。比如 SquashFS 的魔数是 hsqs(小端为 73 68 73 71),JFFS2 的魔数是 19 85。我习惯用 binwalk -Me 自动扫描和提取,但有时候也会手动用 dd 命令切分。
举个例子,思科 IOS 固件通常是一个 IMG 文件,里面包含了:
| 偏移 | 内容 | 说明 |
|---|---|---|
| 0x0000 - 0x00FF | 引导加载器头部 | 包含硬件平台 ID、校验和 |
| 0x0100 - 0x1FFFF | 压缩的内核 | 通常是 gzip 压缩的 ELF |
| 0x20000 - 结束 | SquashFS 文件系统 | 包含 Web 界面、配置文件等 |
其他常见格式
除了上面几种,还有几个格式你可能会遇到:
- COFF:ELF 的前身,老 Unix 系统用。思科早期固件里偶尔能看到
- Mach-O:macOS 和 iOS 的格式。如果你分析思科的 Mac 版管理工具,会碰到
- SREC/Intel HEX:文本格式的二进制文件,用于烧录单片机。思科某些低端设备用
我的经验:遇到不认识的格式,先试 file 命令。它内置了上千种魔数识别规则,能解决80%的问题。剩下的20%,就得靠 hexdump 和搜索引擎了。
知识体系总览
下面这张图,是我自己总结的二进制文件格式识别流程。你跟着这个思路走,基本不会迷路。
这张图的核心逻辑很简单:先用 file 命令快速识别,识别不出来就手动分析魔数和特征。ELF 和 PE 有标准工具,BIN 和 IMG 需要更多经验判断。你多练几次,看到文件头的前几个字节,基本就能猜个八九不离十。
总结一下:ELF 看节头,PE 看导入表,BIN 看偏移,IMG 看文件系统。这四种格式覆盖了思科固件 95% 以上的场景。剩下的 5%,要么是厂商自定义的变种,要么是加密后的伪装。遇到那种情况,就得靠耐心和 hexdump 了。
公众号:蓝海资料掘金营,微信deep3321