← 返回目录课程:《ARM Cortex-M处理器固件逆向核心技术实战》
02

02 ELF/HEX固件解析与Cortex-M向量表手动恢复

形成bin
章节导航 难度:入门类型:排障定位
本页抓手

把ELF落到Bootloader升级链路的触发条件、可观察状态和复查材料上,先判断问题从哪里收窄。

判断线索
接口配置流程状态日志
复用位置
代码片段排障表检查清单架构图

查看现场信号与复查材料

  1. 核对Bootloader升级链路的输入条件、变化信号和结果材料
  2. 再把命令、配置、日志和状态结果对应到同一个操作结果
  3. 最后用启动成功率验证结果是否可复现

代码阅读线索

ELF涉及源码、函数、脚本或 API 时,应先确认代码对象、调用条件和结果信号是否对应。

本节用Bootloader升级链路的真实调用点说明代码变化会影响哪一个操作结果。

固件格式差异与向量表恢复:从二进制到执行入口

ELF对象、步骤、结果对齐01格式差异区分ELF/HEX/B…02向量表定位从0地址读取前64字节03复位入口确认Entrypoin…04栈顶指针验证SP初始值有效性05手动恢复核对中断向量表顺序06对象边界先定义适用范围

ELF架构示意

Boot ROM
→
Bootloader
→
App分区
→
回滚记录

在固件逆向工程中,拿到一个未经处理的二进制文件(Binary Image)或十六进制文件(HEX File)时,你面对的不是可读的符号表,而是一段原始的机器码。与包含丰富调试信息的 ELF(Executable and Linkable Format)文件不同,BIN/HEX 格式剥离了所有结构信息,仅保留程序在 Flash 中的绝对布局。这意味着,手动恢复 Cortex-M 处理器的中断向量表(Vector Table)——尤其是定位复位入口(Reset Handler)——成为逆向分析的第一步,也是判断固件是否可执行的关键检查点

实操步骤

拿到固件后,优先使用 readelf -h firmware.elf 确认入口点(Entry point address),再通过 hexdump -C firmware.bin | head -64 观察前 64 字节的向量表原始数据。这是区分“有符号的 ELF”与“裸二进制”的最快方法

ELF/HEX/BIN 格式差异与向量表定位机制

Cortex-M 处理器上电后,硬件自动从地址 0x00000000(或 VTOR 寄存器指定的地址)加载栈顶指针(MSP),并从 0x00000004 加载复位向量(Reset Vector)。这一机制决定了向量表必须位于 Flash 起始位置,且前 8 字节固定为 MSP 和 Reset Handler 地址。在 ELF 文件中,这些信息通过符号表(Symbol Table)和段(Section)描述;而在 BIN/HEX 中,你必须手动解析原始字节

以下对比表总结了三种格式在向量表恢复场景下的关键差异:

HEX固件解析 相关检查
维度方案A方案B判断建议
符号信息完整保留函数名、地址无符号,仅地址+数据无任何元数据
向量表可见性通过 .isr_vector 段直接查看需按记录类型 (00) 提取数据从偏移 0 开始直接读取
地址连续性连续,由链接脚本控制可能分段,需拼接连续,按加载地址排列
逆向难度低(有符号辅助)中(需解析记录格式)高(完全依赖人工识别)

实际工程中,大部分量产固件以 BIN 或 HEX 形式交付。因此,手动定位并验证中断向量表(ARM手动定位并验证中断向)的能力,直接决定了能否从裸二进制中恢复出可执行的固件入口

手动恢复向量表:工序、检查点与判定条件

恢复过程分为三个核心工序:定位向量表基址、解析复位向量、验证入口合法性。每个工序都包含明确的检查点和判定条件

工序一:定位向量表基址

对于 Cortex-M 处理器,向量表默认位于 Flash 起始地址(通常为 0x08000000 或 0x00000000)。在 BIN 文件中,前 4 字节为 MSP 初始值,后 4 字节为复位向量地址。关键检查点:MSP 值必须指向 RAM 区域(如 0x20000000 至 0x20020000),且对齐到 4 字节。若 MSP 值落在 Flash 区域或未对齐,则说明向量表可能被加密、偏移或固件格式异常

关键判断

使用 xxd -l 16 firmware.bin 查看前 16 字节。若前 4 字节(MSP)在 0x20000000 范围内,且第 5-8 字节(Reset Vector)为奇数(表示 Thumb 指令集),则初步判定向量表有效。否则,需检查固件是否包含 Bootloader 头部或加密段

工序二:解析复位向量与验证入口

复位向量值必须为奇数(Cortex-M 强制 Thumb 模式),且指向 Flash 区域内的可执行代码。例如,若读取到 0x08000101,则实际入口地址为 0x08000100(忽略最低位)。验证动作:使用反汇编工具(如 arm-none-eabi-objdump -d -b binary -m armv7m firmware.bin)从该地址开始反汇编,检查前几条指令是否为栈初始化、系统时钟配置或跳转到 main 的典型序列

以下是一个典型的向量表手动恢复流程日志表,记录了从原始 BIN 到入口验证的完整过程:

关键摘要
步骤输入动作输出

真实项目场景

某 IoT 设备固件升级后无法启动,仅提供 BIN 文件。通过上述流程,发现复位向量指向 0x08000005(最低位为 1,但地址落在 Flash 起始处,而非代码区)。进一步反汇编发现该地址为中断向量表自身,导致死循环。最终定位为 Bootloader 未正确跳转至应用程序,属于分区表配置错误

风险复查

项目收束要把HEX固件解析落到下一步可执行材料上:入口在哪里、输出是什么、HEX固件解析能否证明当前实现已经达到目标。如果继续扩展,应先判断ELF/HEX哪一个会影响结果,再决定是补配置、补测试,还是补一份更清晰的Cortex-M向量表手动恢复。这样的尾部不重复资产清单,而是让后续协作能从具体材料判断项目能否继续推进。本节留下的复查锚点是ELF:HEX固件解析是否还能解释HEX固件解析,再用Cortex-M向量表手动恢复核对源码结构到项目成果的变化。第02节的交接重点是源码结构,它决定HEX固件解析是短暂波动还是可复现证据。