8个版本 (5个破坏性更新)

0.6.0 2024年1月4日
0.5.0 2022年11月21日
0.4.1 2022年9月24日
0.4.0 2022年6月5日
0.1.0 2022年1月29日

命令行工具中排名第1106

每月下载量:26

GPL-3.0-only

415KB
9K SLoC

resymgen,一个逆向工程符号表生成器

resymgen是一个命令行工具,它根据YAML配置文件生成各种格式的符号表。输出符号表旨在直接导入到不同的逆向工程工具中,而YAML配置文件旨在通用、灵活,并支持文档。

动机

resymgen是一个旨在简化以下约束条件下的逆向工程协作工作的工具:

  • 被逆向的二进制文件有多个版本,所有这些版本都很有趣,并且符号偏移量随版本而变化。
  • 被逆向的二进制文件涉及覆盖,这意味着一个地址可以根据上下文对应不同的符号。
  • 不同的合作者使用不同的逆向工程工具集。
  • 合作尚未建立一种简单、标准化的方式来全面共享调试信息。
  • 共享正在被逆向的二进制文件的注释版本可能存在潜在的法律问题。

上述约束在视频游戏逆向工程等领域尤为常见。在这些约束下,共享信息可能非常困难。使用resymgen,一个团队可以在版本和覆盖的基础上共享地址到符号的关联,并以人类可读的YAML格式进行,这种格式还可以作为文档。然后可以将通用的YAML格式转换为不同的符号表格式,以便直接与不同的逆向工程工具一起使用,而无需共享二进制文件本身。

注意事项

《resymgen》的功能可能对大多数逆向工程项目来说并不普遍有用,这是因为它本意就不是这样的。如果你的逆向工程问题不适用上述任何限制,那么使用《resymgen》与合作伙伴共享信息可能不是最佳选择。例如,如果所有合作伙伴都统一使用一个逆向工程工具(例如Ghidra或IDA),那么使用该工具的内置导入/导出和协作功能可能更容易、更有效,尤其是如果可以合法地共享完整项目的导出。如果感兴趣的二进制文件只有一个版本(或只关注一个版本)并且没有覆盖,那么通过行业标准的格式(如PDB、DWARF、链接器映射等)共享调试信息可能更简单。

用法

本包提供了《resymgen》的二进制文件。运行 resymgen --help 以获取详细用法信息。每个子命令都有自己的 --help 标志,用于打印详细用法信息。以下列表提供了《resymgen》不同子命令的概述。

  • gen:根据给定的《resymgen》YAML文件生成指定版本和输出格式的符号表。
  • fmt:《resymgen》YAML文件的格式化工具。
  • check:《resymgen》YAML文件的验证器。提供了一组不同的检查,可以运行在文件的內容上以确保正确性。
  • merge:将来自各种结构化输入格式的符号合并到另一个《resymgen》YAML文件中。这在某种程度上是 gen 子命令的相反。

《resymgen》YAML规范

《resymgen》YAML文件由一个或多个命名 组成。

每个块都带有一些元数据,包括起始内存地址、长度、可选的版本列表和可选的描述。地址和长度允许版本相关。每个块还包含两个 符号 列表,一个用于函数,一个用于数据,并且可选地包含一个 子区域 列表。

符号 代表一个或多个包含可识别指令或数据的内存区域。每个符号有以下字段

  • 名称(必需)
  • 零个或多个 别名(可选),这是符号的备用名称
  • 地址(必需)和长度(可选)。与块类似,地址和长度字段允许版本相关。
    • 此外,地址(或每个地址,如果版本相关)可以是单个值或值列表。这对于数据符号被定义为常量或在行内定义,并由编译器放置在多个不同位置(通常在数据池中)的情况很有用。这对于在C头文件中定义为静态链接并在多个源文件中宏包含的函数也很有用,因为这会导致相同的功能在编译的二进制文件中的多个位置存在。
  • 描述(可选)

子区域 代表一个嵌套的《resymgen》YAML文件,它有一个或多个自己的命名块,这些块包含在父块中。在《resymgen》YAML文件中,子区域表示为文件名(注意,它 不应 是具有多个组件的文件路径)。如果父文件具有文件路径 /path/to/parent.yml,并且其中一个块具有名为 sub.yml 的子区域,那么这个子区域名称引用的相应子区域文件具有文件路径 /path/to/parent/sub.yml

子区域对于分割大型 resymgen YAML 文件很有用。如果一个父文件有一个或多个子区域文件,父文件中的块仍然可以包含描述整个区域的元数据,并且父文件可以由 resymgen 子命令处理为一个聚合实体。

快速参考

<block1_name>:
  versions (optional):
    - <string>
    ...
  address: MaybeVersionDep[number]
  length: MaybeVersionDep[number]
  description (optional): <string>
  subregions (optional):
    - <file name>
    ...
  functions:
    - name: <string>
      aliases (optional):
        - <string>
        ...
      address: MaybeVersionDep[ScalarOrList[number]]
      length (optional): MaybeVersionDep[number]
      description (optional): <string>
    ...
  data:
    - name: <string>
      aliases (optional):
        - <string>
        ...
      address: MaybeVersionDep[ScalarOrList[number]]
      length (optional): MaybeVersionDep[number]
      description (optional): <string>
    ...
...

假设以下类型定义

MaybeVersionDep[T] = <T> OR {<string>: <T>, ...}
ScalarOrList[T] = <T> OR [<T>, ...]

示例

main:
  versions:
    - v1
    - v2
  address:
    v1: 0x2000000
    v2: 0x2010000
  length:
    v1: 0x100000
    v2: 0x100000
  description: The main memory region
  subregions:
    - sub1.yml
    - sub2.yml
  functions:
    - name: function1
      aliases:
        - function1_alias1
        - function1_alias2
      address:
        v1: 0x2001000
        v2: 0x2012000
      description: |-
        multi
        line
        description
    - name: function2
      address:
        v1:
          - 0x2002000
          - 0x2003000
        v2: 0x2013000
      description: simple description
  data:
    - name: SOME_DATA
      address:
        v1: 0x2000000
        v2: 0x2010000
      length:
        v1: 0x1000
        v2: 0x1600
other:
  address: 0x2400000
  length: 0x100000
  functions: []
  data:
    - name: OTHER_DATA
      address: 0x2400000

当前支持的输出格式(《code》gen

  • Ghidra 兼容的符号表(通过《code》ImportSymbolsScript.py 脚本导入)
  • JSON
  • No$GBA SYM 格式

当前支持的输入格式(《code》merge

  • resymgen YAML
  • Ghidra 导出的 CSV 格式,包含“名称”、“位置”和“类型”列,以换行符分隔记录

依赖项

~8–18MB
~244K SLoC