jbirby/binary-format-reverser

GitHub: jbirby/binary-format-reverser

专注于反编译未记录固定记录二进制文件,自动生成 Python 解析器与格式规范的逆向工具。

Stars: 0 | Forks: 0

# binary-format-reverser 一个用于反编译未记录固定记录二进制文件格式的工具包。从任何示例文件(可参考已解码数据的导出文件)生成可运行的 Python 解析器和 README 风格的格式规范。 基于以下观察构建:大多数设备日志格式(GPS 追踪器、传感器记录器、遥测转储、游戏存档、行车记录仪元数据)具有相同的形状:一系列大小相同的记录,可选地带有一个小型头部。给定这种形状,一组暴力技巧可以在几分钟而不是几天内识别出大部分字段。 ## 适用场景 **适合使用的情况** - 来自设备的专有 `.bin`、`.dat`、`.log`、`.gpl` 等文件,其 PC 软件提供了 CSV、GPX、JSON 或 KML 格式的导出文件作为参考。 - 上述情况但没有参考导出文件——黑盒模式也适用,只是速度较慢。 - 任何看起来像“均匀的小记录流”的格式:健身追踪器、潜水计算机、OBD/CAN 日志记录器、气象站、无人机飞行日志、实验室仪器、老式游戏存档等。 **不适合使用的情况** - 容器格式(PNG、ZIP、WAV、ELF 可执行文件)——这些格式包含嵌套的报头和块,本工具不建模此类结构。 - 可变长度记录(Protobuf、长度前缀定界)。 - 压缩或加密的有效载荷——熵探测会标记它们,但本工具无法解码。 - 文本密集型格式(JSON、伪造成二进制的 XML)。 ## 安装 ``` git clone https://github.com//binary-format-reverser.git cd binary-format-reverser ``` 除 Python 3 标准库外无依赖。每个脚本均支持 `--help`。 ## 四阶段工作流程 1. **侦察**(Reconnaissance)——记录大小和整体形状是什么? 2. **假设**(Hypothesis)——每个字节可能代表什么? 3. **确认**(Confirmation)——假设是否在所有记录中成立? 4. **编码**(Codification)——编写小型字段映射 JSON 并生成解析器与规范。 阶段对应脚本;阶段 1-3 是迭代过程,阶段 4 是一次性操作。 ## 使用参考 CSV 的快速路径 快速路径。你拥有 `mystery.bin` 以及一份它应解码成的 CSV 参考文件。 ``` # 1. Figure out the record size python scripts/structure_probe.py mystery.bin # 2. Brute-force find the fields python scripts/csv_correlate.py mystery.bin --record-size 28 --csv reference.csv # 3. Write a fieldmap.json describing the layout # (see references/dg388_fieldmap.json for a complete example) # 4. Generate the parser and spec document python scripts/gen_parser.py fieldmap.json -o parser.py python scripts/gen_docs.py fieldmap.json -o FORMAT.md # 5. Run the parser python parser.py mystery.bin decoded.csv ``` `csv_correlate` 为每个识别出的字段输出一行,例如: ``` --- Latitude --- 100.0% offset=0x08 (8) i32 LE scale=1/10000000 ``` 说明:字节 8-11 为小端有符号 32 位整数,除以 10,000,000 后与参考文件中的 `Latitude` 列在 100% 记录中匹配。将这四个事实带入字段映射并继续下一步。 标注为 `transform=ddmm` 的匹配表示二进制以 NMEA 风格的 `DDMM.MMMM` 格式存储坐标,而非十进制度——生成解析器时会自动处理转换。标注为 `unordered (values match but row order differs)` 的匹配表示两个文件中的值相同但顺序不同——当参考工具将航点排在轨迹点之前而二进制文件交错存储时常见。 ## 无参考(黑盒)的快速开始 ``` python scripts/structure_probe.py mystery.bin python scripts/field_probe.py mystery.bin --record-size 28 --scan ``` 扫描会输出每个偏移量及其通过合理性检查的字段类型解释:`YYYYMMDD`、`HHMMSS`、`unix_ts`、`coord/1e7`、`coord_deg (float)`、`coord_ddmm (float NMEA)`、`altitude_m`、`speed_kmh`、`heading_deg`、`monotonic↑`、`enum(N)`。每个标签均为提示而非确认。 对有希望的偏移量进行有针对性的后续扫描: ``` python scripts/field_probe.py mystery.bin --record-size 28 --offset 8 --type i32 --endian LE ``` 你将获得每个记录的最小值、最大值、均值与标准差,以及相同的启发式标签,以便你肉眼判断分布是否符合预期(例如海拔 0–9000 米、速度 0–300 公里/小时、航向 0–360°)。 ## 脚本说明 | 脚本 | 用途 | | --- | --- | | `scripts/structure_probe.py` | 按列熵对候选记录大小进行排名;提取 ASCII/UTF-16 字符串;报告字节频率峰值(填充模式、已擦除闪存、压缩区域)。 | | `scripts/multi_file_diff.py` | 比较多份同类样本文件;查找魔数、常量标志与可变字段。 | | `scripts/csv_correlate.py` | 在(偏移量 × 类型 × 字节序 × 缩放因子 × 变换)空间中对参考 CSV 进行暴力搜索。包含 NMEA `DDMM` 变换以及针对顺序错开参考的排序值回退。 | | `scripts/field_probe.py` | 黑盒假设测试器。靶向模式(单个偏移量与单个类型)或扫描模式(所有偏移量与所有类型)。 | | `scripts/gen_parser.py` | 从字段映射 JSON 生成仅依赖标准库的 Python 解析器。处理缩放因子、`YYYYMMDD`、`HHMMSS`、`unix_seconds`、`ddmm` 以及跳过空白规则。 | | `scripts/gen_docs.py` | 从同一字段映射 JSON 生成 README 风格的格式规范。 | ## 字段映射模式 请参阅 `references/fieldmap_schema.md` 获取完整模式,`references/dg388_fieldmap.json` 为实际示例。简言之: ``` { "format_name": "My Device GPS Log", "endianness": "little", "record_size": 28, "file_header_size": 0, "fields": [ {"name": "latitude", "offset": 8, "size": 4, "type": "i32", "encoding": "degrees", "scale": 10000000, "unit": "°"} ] } ``` 支持的字段类型:`u8`、`i8`、`u16`、`i16`、`u32`、`i32`、`u64`、`i64`、`f32`、`f64`、`bytes`、`utf8`、`pad`。 支持的编码:`YYYYMMDD`、`HHMMSS`、`unix_seconds`、`ddmm`、`degrees`、`meters`、`kmh`、`enum`,以及用于文档的自由形式标签。 ## 实际示例 `references/dg388_fieldmap.json` 是 GlobalSat DG-388 GPS 数据记录器的完整字段映射——一种 28 字节固定记录格式,携带日期、时间、坐标(i32 × 1e-7 度)、海拔、速度、航向和记录类型标志。阅读该字段映射并结合 `references/fieldmap_schema.md` 是理解本工具期望输出的最快方式。 ## 常见陷阱 - **选取真实记录大小的倍数**。`structure_probe` 按列熵对候选大小进行排名,真实记录大小的倍数得分同样高。优先选择得分高且尺寸最小的候选。 - **信任常量列的 100% 匹配**。任意字节解释都可能匹配 `[34.400, 34.400, 34.400, ...]`。务必结合具有真实方差的列进行验证。 - **预分配空白记录**。许多设备会预先格式化 N 条记录并在记录时逐步填充。可使用 `--skip-zero-records` 或在字段映射中添加 `skip_blank` 规则。 - **参考数据被重排序或过滤**。PC 工具常按时间戳排序或丢弃无效记录。`unordered` 回退可自动处理排序情况;过滤情况需要手动对齐。 - **宽字段内的压缩字段**。一个解码后无意义的大 `uint32` 可能是两个背靠背的 `uint16`。`field_probe --scan` 会分别标记这些窄解释。 ## 范围与限制 本工具处理固定记录二进制格式。它不支持可变长度记录、容器/块格式(PNG、WAV、ZIP、ELF)、压缩或加密有效载荷、混合文本格式或位级字段。`structure_probe` 中的熵探测会正确标记看起来被压缩或加密的区域;解码这些区域不在本工具范围内。 它也无法识别校验和或 CRC——它们看起来像随机字节,会被报告为未知。 ## 贡献 可拓展本工具适用范围的扩展包括: - 支持可变长度记录(长度前缀或定界符分帧)。 - 子字节字段提取。 - 容器格式检测(LEN-TYPE-DATA 块遍历)。 - 更多编码变换(六十进制坐标、非十进制比例的固定点数)。 - Python 以外的语言解析器生成器。 ## 许可证 根据 MIT 许可证授权。详见 [`LICENSE`](LICENSE)。
标签:GPS追踪, GPX导出, JSON导出, KML导出, OBD/CAN记录, Python, README规格说明, 二进制文件逆向, 云资产清单, 传感器日志, 健身追踪器, 固定记录格式, 字段推断, 字段映射, 实验室仪器, 嵌入式日志, 工具集, 快速逆向, 批量解析, 探针分析, 数据解码, 文件格式规范, 文件格式解析, 无人机飞行日志, 无依赖, 无后门, 旧游戏存档, 格式规范生成, 气象站, 游戏存档, 潜水计算机, 熵检测, 网络连接监控, 记录结构分析, 设备固件, 设备日志, 逆向工具, 逆向工程, 遥测数据, 黑盒分析