GrammaTech/gtirb
GitHub: GrammaTech/gtirb
GTIRB 是一种以 LLVM-IR 为蓝本的二进制中间表示数据结构,旨在为二进制反汇编、分析、转换和重写工具之间提供标准化的 IR 通信与互操作能力。
Stars: 358 | Forks: 39
# GTIRB
GrammaTech Intermediate Representation for Binaries (GTIRB) 是一种
机器码分析与重写的数据结构。它的目的是
促进在执行二进制反汇编、分析、转换和美化打印的程序之间
进行 binary IR 的通信。
GTIRB 以 LLVM-IR 为模型,并力求提供类似的功能,
以鼓励工具之间的通信和互操作性。
本文件的其余部分描述了 GTIRB 的各个方面:
- [结构](#structure)
- [安装](#installing)
- [构建](#building)
- [用法](#usage)
# 结构
GTIRB 具有以下结构。实线表示继承关系。
虚线表示通过 UUID 进行引用。

## IR
GTIRB 的一个实例可以包含多个模块 (`Module`),这些模块
代表可加载对象(例如可执行文件或库)、一个过程间控制流图 (`IPCFG`),以及
辅助数据表 (`AuxData`),该表可以以用户自定义的格式保存任意分析结果,
并且可以轻松引用 IR 的其他元素。每个
模块都包含符号 (`Symbol`) 和节等信息,
而节本身又保存了该模块的实际字节、数据块和代码块。
CFG 由基本块 (`Block`) 以及这些
块之间的控制流边组成。每个数据或代码块都引用
字节区间 (`ByteInterval`) 中的一段字节范围。一个节可以
持有一个包含所有块的大型字节区间——如果该节中块的相对
位置已定义——或者每个块持有一个
字节区间——如果块的相对位置未
定义,例如在程序重写期间 `.text` 节中的代码块。每个
符号都保存着一个指向其引用的块或数据的指针。
## 指令
GTIRB 明确不表示指令或指令
语义,但确实提供符号操作数信息和对
字节的访问。有许多用于表示
指令语义的*中间语言* (IL)(例如,[BAP][] 的 [BIL][]、
[Angr][] 的 [Vex][] 或 [Ghidra][] 的 P-code)。GTIRB 与这些
或任何其他 IL 配合工作,方式是将指令通常且高效地作为
*原始机器码字节* 存储,并单独存储符号和
控制流信息。流行的 [Capstone][]/[Keystone][]
解码器/编码器提供了一个绝佳的选择,用于从 GTIRB 的机器码字节表示中读取和向其写入
指令,
而无需绑定到任何特定的语义 IL。通过支持多种 IL
以及在辅助数据表中单独存储分析结果,
GTIRB 实现了独立的二进制分析和
重写团队及工具之间的协作。
## 辅助数据
GTIRB 以 `AuxData` 对象的形式提供
额外信息(例如分析结果)的共享。这些对象可以
以可移植的方式存储基本 GTIRB 类型的映射和向量。
[GTIRB 手册][]描述了常见类型的辅助数据的结构,
例如函数边界信息、类型信息,或者
[Standard AuxData Schemata][] 中常见分析的结果。
## UUID
GTIRB 的每一个元素——例如,模块 (`Module`)、符号 (`Symbol`)
和块 (`Block`)——都有一个通用的唯一标识符 (UUID)。
UUID 允许一等 IR 组件和 AuxData 表引用
IR 的元素。
指令和符号操作数可以通过类
`Offset` 来寻址,该类封装了一个 UUID(指向指令的
块)和一个偏移量。
# 安装
目前已有可轻松安装 GTIRB(以及包括
[ddisasm][] 反汇编器和 [gtirb-pprinter][]
美化打印器在内的配套工具)的软件包,适用于 Windows 和 Ubuntu 20。相关说明请参见
下文。此外,在
[grammatech/ddisasm][] 有一个安装了所有这些工具的公共 Docker 镜像。GTIRB 使用 Major.Minor.Patch 进行版本控制,其中 Major 版本
升级将需要进行重大的源代码更改,但这种情况应该非常
罕见;Minor 版本升级可能需要少量的源代码更改;而
Patch 版本升级不应破坏任何下游构建。目前我们不
提供任何版本更改之间的 ABI 兼容性。
## Python API
可以使用 pip 从 PyPI 安装最新稳定版的 GTIRB Python API:
```
pip install gtirb
```
可以从预构建的 wheel 安装最新不稳定版本的
Python API:
```
pip install https://download.grammatech.com/gtirb/files/python/gtirb-0.dev-py3-none-any.whl
```
至关重要的一点是,选择的 `stable` 或 `unstable` 软件包必须与已安装的 ddisasm 和 gtirb-pprinter 软件包相匹配。
## Windows
Windows 版本以 .zip 文件打包,可在以下地址获取:
https://download.grammatech.com/gtirb/files/windows-release/
## Ubuntu
适用于 Ubuntu 20 的软件包可在 GTIRB apt 仓库中找到,并可以按照以下说明进行安装。
首先,添加 GrammaTech 的 APT 密钥。
```
wget -O - https://download.grammatech.com/gtirb/files/apt-repo/conf/apt.gpg.key | apt-key add -
```
接下来更新你的 sources.list 文件。
```
echo "deb [arch=amd64] https://download.grammatech.com/gtirb/files/apt-repo [distribution] [component]"| sudo tee -a /etc/apt/sources.list
```
其中:
- `[distribution]` 是 `focal`(目前仅提供 Ubuntu 20 软件包)
- `[component]` 是 `stable`(保存上一个版本化发布)或 `unstable`(保存仓库的 HEAD)。
最后更新你的软件包数据库并安装核心 GTIRB 工具:
```
sudo apt-get update
sudo apt-get install gtirb-pprinter ddisasm
```
**警告**:稳定版本 gtirb-2.0.0、gtirb-pprinter-2.1.0、ddisasm-1.8.0
及更早版本依赖于元软件包,如果你尝试执行 `apt-get upgrade`,这会导致冲突
(参见 https://github.com/GrammaTech/gtirb/issues/63)。在这种情况下,
请卸载并重新安装你从 GTIRB 仓库获取的软件包。你
可能需要使用 `dpkg --remove` 来移除元软件包(例如 `ddisasm`),
然后再移除具体的版本化软件包(例如 `ddisasm-1.5.1`)。
较新的稳定版本不再依赖于元软件包,可以无障碍地进行升级。
# 构建
GTIRB 的 C++ API 应该能够在 64 位环境下,使用至少支持 C++17 的 GCC、Clang
和 Visual Studio 编译器成功构建。GTIRB 使用
CMake,并且必须安装至少 3.10 版本。
常见的构建过程如下所示:
```
mkdir build
cd build
# 注意:你可能希望为下一条命令添加一些 -D 参数。见下文。
cmake
cmake --build .
# 运行测试套件。
ctest
```
要自定义 GTIRB 构建,你可以通过
导航到你的构建目录并运行以下命令来获取自定义选项列表:
```
cmake -LH
```
## 要求
要构建和安装 GTIRB,应安装以下要求:
- [CMake][],版本 3.10.0 或更高。
- Ubuntu 18 通过 APT 软件包 `cmake` 提供此版本。
- Ubuntu 16 及更早版本提供的是过期版本;请在这些版本上从
源码构建。
- [Protobuf][],版本
3.0.0 或更高。
- Ubuntu 18 通过 APT 软件包
`libprotobuf-dev` 和 `protobuf-compiler` 提供此版本。
- Ubuntu 16 及更早版本提供的是过期版本;请在这些版本上从
源码构建。
- Boost [(来自 launchpad.net 的非标准 Ubuntu 软件包)][],版本 1.68 或更高。
- Ubuntu 18 的标准软件库中仅包含 1.65 版本。请参见上文中的 Ubuntu 说明。
# 用法
GTIRB 旨在使用 [Google protocol buffers][](即
[protobuf][])进行序列化,从而[从任何编程语言轻松高效地使用](#using-serialized-gtirb-data)。
GTIRB 也可以通过以多种语言实现的专用 API 来使用。这些 API 提供了适合
二进制分析和重写应用程序使用的高效数据结构;有关详细信息,请参见
[下文](#gtirb-api-implementations)。
## 使用序列化的 GTIRB 数据
GTIRB 使用一种序列化格式,该格式由一个 8 字节的签名组成,
后跟序列化的 [protobuf][] 数据。该 protobuf 数据允许
使用你选择的语言进行探索和操作。
[Google protocol buffers][] 主页列出了可以直接
使用 protocol buffers 的语言;其他语言的用户可以
将 protobuf 格式的数据转换为 JSON 格式,然后在其应用程序中使用该
JSON 数据。
此仓库中的 `proto` 目录包含 GTIRB 的 protocol buffer
消息类型定义。你可以检查这些 `.proto`
文件以确定各种 GTIRB 消息
的结构。顶级消息类型是 `IR`。
有关更多详细信息,请参见[使用序列化的 GTIRB 数据](PROTOBUF.md)。
## GTIRB API 实现
目前 GTIRB API 提供了 C++、Python 和 Common Lisp 版本。
还有一个尚未准备好供外部使用的*部分* Java API。
有关独立于语言的 API 信息,请参见 [GTIRB
组件](doc/general/ComponentsIndex.md)。有关
不同 API 实现的信息,请参见:
- [C++ API](doc/cpp/README.md)
- [Python API](python/README.md)
- [Common Lisp API](cl/README.md)
- Java API **不完整**
标签:Bash脚本, JS文件枚举, 中间表示, 二进制分析, 二进制重写, 云安全运维, 云资产清单, 可配置连接, 程序分析, 编译器基础设施, 逆向工具, 逆向工程