嵌入式开发必看:手把手教你读懂Hex文件里的地址与数据(附STM32实例)

张开发
2026/4/19 11:36:04 15 分钟阅读

分享文章

嵌入式开发必看:手把手教你读懂Hex文件里的地址与数据(附STM32实例)
嵌入式开发实战Hex文件地址解析与STM32逆向调试指南当你面对一个程序崩溃的嵌入式系统手头只有编译生成的Hex文件时能否像侦探一样从这些十六进制代码中找出问题所在本文将带你深入Hex文件的结构迷宫掌握地址计算的密钥并通过真实的STM32案例演示如何定位内存中的关键数据。1. Hex文件结构与地址体系解析Hex文件本质上是一张内存地图用ASCII字符记录二进制数据及其存储位置。每行记录由六个关键部分组成就像快递单号包含收件人地址一样精确:LLAAAATTDD...DDCCLL数据长度如0x04表示4字节数据AAAA偏移地址相当于快递的楼层号TT记录类型决定地址计算规则DD...DD实际数据包裹内容CC校验和防错机制地址计算的核心在于理解三种记录类型类型码名称地址影响计算公式示例02扩展段地址记录后续地址段地址4 偏移地址0x12FF - 0x12FF004扩展线性地址记录后续地址线性地址16 偏移地址0x0108 - 0x0108000000数据记录直接使用当前基址偏移地址0x003D0000 0x8010实际项目中80%的地址异常都源于对04/02类型记录的忽略。建议在分析时先用文本编辑器搜索:02和:04定位所有基址变更点。2. STM32实战从Hex到物理地址的完整追踪让我们解剖一个真实的STM32F103工程Hex片段:02000004003DBD :04801000007DF9A155 :20801200FF5A8EA4C5A492ABEC079CFF88A992859687000EFFFE92AB88A9A9A90FA6EC10AE步骤解析基址确定第一行:02000004003DBD是04类型记录计算基址base_addr 0x003D 16 # 得到0x003D0000数据定位第二行:04801000007DF9A155包含偏移地址0x8010数据长度0x04数据内容0x007DF9A155物理地址计算physical_addr base_addr 0x8010; // 0x003D8010连续地址验证第三行偏移地址为0x8012与上一行相差2字节正好对应前一行4字节数据的存储位置0x003D8010: 00 7D F9 A1 0x003D8014: 55 ?? ?? ?? // 下一行数据从0x8012开始常见陷阱大端/小端模式混淆STM32为小端未考虑多个基址记录交替出现的情况校验和验证失败导致数据误读3. 高级调试技巧Hex与Map文件联合分析当程序跑飞时结合Map文件可以快速定位异常地址对应的代码段在Map文件中搜索异常地址.text 0x003d8010 0x200 0x003d8010 main 0x003d8120 timer_interrupt反向查找Hex数据若崩溃地址为0x003D8123对应Map文件中的timer_interrupt3位置此时在Hex中查找grep -n :..8120 firmware.hex机器码反汇编获取对应位置的Hex数据后使用arm-none-eabi-objdump反汇编echo FF5A8EA4 | xxd -r -p temp.bin arm-none-eabi-objdump -D -b binary -marm temp.bin4. 工程化工具链Hex处理自动化方案手动解析适合学习原理实际项目推荐自动化工具组合工具对比表工具名称功能典型命令示例适用场景objcopyHex/Bin格式转换arm-none-eabi-objcopy -O binary firmware.elf firmware.bin生产固件生成hexdump十六进制查看hexdump -C firmware.bin | less快速验证数据pyhexedit可视化编辑pyhexedit firmware.hex紧急补丁修改Custom Python地址范围提取extract_hex_range.py 0x8000000-0x8004000批量数据分析Python解析示例def parse_hex_line(line): if line[0] ! :: return None byte_count int(line[1:3], 16) address int(line[3:7], 16) record_type int(line[7:9], 16) data [int(line[i:i2],16) for i in range(9,9byte_count*2,2)] checksum int(line[-2:],16) return (byte_count, address, record_type, data, checksum)5. 逆向分析实战从崩溃地址反推问题根源假设调试器显示程序在0x20001000处发生HardFault按照以下流程诊断确定内存区域0x200xxxxx对应STM32的SRAM区域检查是否为堆栈溢出或野指针访问查找Hex中的相关数据# 搜索可能的数据记录 grep -E :..[01][0-9a-f]{3}00 firmware.hex | head -20交叉验证Map文件.data 0x20000000 0x1000 0x20000ff0 sensor_buffer发现0x20001000紧邻sensor_buffer末端疑似数组越界修复验证修改代码后对比新旧Hex文件差异-:10200000 A5C3F18E 523B00FF # 旧数据 :10200000 A5C3F18E 523B0000 # 修复后的数据掌握Hex文件解析能力后你会发现自己拥有了X光透视眼——不仅能快速定位故障还能在没有源码的情况下理解第三方固件的内存布局。这种技能在IoT设备安全分析、驱动逆向等场景中尤为珍贵。

更多文章