4. 固件头部解析

任务说明

本案例以典型的 TRX 固件格式为对象,手动解析其头部结构,识别固件格式并提取关键字段。TRX 是 Broadcom 平台路由器常用的固件封装格式,结构紧凑,适合作为头部解析的入门样本。完成本案例后,你将能够不依赖专用工具,仅通过十六进制查看与简单脚本即可识别 TRX 固件并读取关键元数据。

TRX 头部结构

TRX 头部固定为 28 字节,定义如下:

偏移大小字段说明
0x004magic固定为 0x30524448(字符串 "HDR0")
0x044len整个固件文件长度(含头部),小端序
0x084crc32从偏移 0x0C 开始到文件末尾的 CRC32 校验值
0x0C2flags标志位(如是否包含 DNI 扩展头)
0x0E2version版本号,通常为 1
0x104offs[0]第一个分区(内核)相对文件头的偏移
0x144offs[1]第二个分区(文件系统)相对文件头的偏移
0x184offs[2]第三个分区偏移(通常为 0)

解析脚本实现

以下 Python 脚本读取固件文件,验证 magic,解析头部字段,并打印分区偏移与长度:

```python import struct import sys import os def parse_trx_header(filepath): with open(filepath, 'rb') as f: header = f.read(28) if len(header) < 28: print(f"文件过小,不足 28 字节头部") return False magic, length, crc, flags, version, off0, off1, off2 = struct.unpack(' offsets[i]: next_off = min(next_off, offsets[j]) part_len = next_off - offsets[i] print(f"分区{i}长度: {part_len} 字节 (0x{part_len:X})") # 检查头部声明长度与实际文件大小是否一致 if length != file_size: print(f"警告: 头部长度字段({length})与实际文件大小({file_size})不一致") return True if __name__ == '__main__': if len(sys.argv) != 2: print(f"用法: python {sys.argv[0]} <固件文件路径>") sys.exit(1) parse_trx_header(sys.argv[1]) ```

运行与验证

运行方式:

python parse_trx.py firmware.bin

验证方法:

  1. 准备一个已知的 TRX 固件样本(可从开源路由器固件中提取,或使用 trx 工具自行构造测试文件)。
  2. 运行脚本,观察输出:
    • 若文件是 TRX 格式,应打印 magic=0x30524448 及完整字段信息;
    • 若文件不是 TRX 格式,脚本输出 不是 TRX 固件 并退出。
  3. 使用 hexdump -C firmware.bin | head -2 人工核对前 4 字节是否为 48 44 52 30(即 "HDR0"),验证脚本解析正确。
  4. 对照头部长度字段与实际文件大小,若一致则说明头部解析正确。

通过条件:脚本能正确识别 TRX 格式、打印所有头部字段,且分区偏移与十六进制人工核对结果一致。

常见问题

  • magic 校验失败:文件可能不是 TRX 格式,或文件头被篡改/加密。
  • 长度不一致:部分固件在头部长度字段中不包含尾部填充字节,属正常现象,可忽略警告。
  • 分区偏移为 0:表示该分区不存在,脚本自动跳过长度计算。