GrammaTech/gtirb-pprinter
GitHub: GrammaTech/gtirb-pprinter
将 GTIRB 中间表示转换为可重新汇编的汇编代码或直接生成二进制文件的反汇编输出工具。
Stars: 50 | Forks: 13
# GTIRB Pretty Printer
一个基于 [GTIRB](https://github.com/grammatech/gtirb) 的 pretty printer
二进制分析和逆向工程的中间表示
转换为 gas 语法的汇编代码。
## 构建
pretty-printer 使用 C++17,需要支持的编译器,例如
gcc 7、clang 6 或 MSVC 2017。
要构建和安装 pretty printer,应预先安装以下依赖:
* [GTIRB](https://github.com/grammatech/gtirb)。
* [Capstone](http://www.capstone-engine.org/)。我们使用
自己的 fork 分支 https://github.com/GrammaTech/capstone/tree/v5
目前它与官方发布版本等效。
* [Boost](https://www.boost.org/),版本 1.67.0 或更高。
* 需要以下库:
* filesystem
* program_options
* system
请注意,这些版本可能比您的包管理器默认提供的版本要新:
在 Ubuntu 18、Debian 10 及其他系统上确实如此。建议从源码构建
这些依赖项,以避免版本问题。
使用以下选项配置 cmake:
- 您可以通过
`-DCMAKE_CXX_COMPILER=` 告诉 CMake 使用哪个编译器。
- 通常 CMake 会自动查找 GTIRB,但如果没有,您
可以传入 `-Dgtirb_DIR=`。
- 如果您使用标志
`-DGTIRB_PPRINTER_BUILD_SHARED_LIBS=OFF`,gtirb-pprinter 可以使用静态库形式的 GTIRB(而不是
默认的共享库形式)。
- 此外,如果您想生成静态链接的
`gtirb-pprinter` 可执行文件,请指定 `-DGTIRB_PPRINTER_STATIC_DRIVERS=ON`。
- 您可以通过指定
`-DCMAKE_LIBRARY_PATH=` 来配置 CMake 使用自定义的 Capstone 位置。
- 在 Windows 上,您可以通过传入
`-DCMAKE_TOOLCHAIN_FILE=` 来使用 vcpkg 提供部分依赖项。
安装完依赖项后,您可以按如下方式进行配置和构建:
```
cmake ./ -Bbuild
cd build
make
```
## 安装
请参阅 [GTIRB readme](https://github.com/GrammaTech/gtirb/#installing)。
## 用法
### 生成可重新汇编的汇编代码
将一个简单的 hello world 可执行文件的 GTIRB pretty print 为
名为 `hello.S` 的汇编文件,使用 GNU 汇编器将该文件汇编为名为 `hello.o` 的目标文件,并将该目标文件
链接为可执行文件。
```
gtirb-pprinter hello.gtirb --asm hello.S
as hello.S -o hello.o
ld hello.o -o hello
./hello
```
### 生成新的二进制文件
传给 gtirb-pprinter 的 `--binary` 标志会通过
直接调用 `gcc` 来生成新的二进制文件。
```
gtirb-pprinter hello.gtirb --binary hello
```
此选项接受一个参数 `--library-paths` 或 `-L`,
用于指定库可能所在的额外路径。
例如:
```
gtirb-pprinter hello.gtirb --binary hello -L . -L /usr/local/lib
```
### 伪 .so
在某些情况下,最好在重建动态链接的 ELF 可执行文件时,
不依赖于它所链接的任何库(例如,从另一个系统重建可执行文件时)。
通常,链接器需要具备这些库才能与它们链接。
然而,`--dummy-so` 选项会生成包含
该二进制文件所需符号的假库,这足以让
链接器运行。示例如下:
```
gtirb-pprinter hello.gtirb --binary hello --dummy-so=yes
```
## Pretty Printer 使用的 AuxData
生成汇编不仅依赖于 IR 中的符号和指令/数据字节,还需要一些额外的信息。
pretty printer 期望这些信息能存储在随 IR 一起保存的多个
[AuxData](https://github.com/GrammaTech/gtirb/blob/master/README.md#auxiliary-data)
对象中。我们在下表中记录了预期的键以及相关的类型和内容。
| 键 | 类型 | 用途 |
|------------------|------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|
| comments | `std::map` | 每条指令或数据元素的注释。 |
| functionEntries | `std::map>` | 作为函数入口点的块的 UUID。 |
| symbolForwarding | `std::map` | 从符号到其他符号的映射。此表用于因重定位或因使用 plt 和 got 表而进行符号转发。 |
| encodings | `std::map` | 从(类型化的)数据对象到数据编码的映射,以包含汇编编码说明符的 std::string 表示:“string”、“uleb128”或“sleb128”。 |
| sectionProperties | `std::map>` | 从节 UUID 到包含节类型和标志的元组的映射。 |
| cfiDirectives | `std::map, gtirb::UUID>>>` | 从 Offset 到 cfi 指令向量的映射。一条 cfi 指令包含:一个描述指令的字符串,一个数值参数向量,以及一个可选的符号参数(用符号的 UUID 表示)。 |
| elfSymbolInfo | `std::map>` | 仅适用于 ELF 目标:从符号到其类型、绑定和可见性类别的映射。 |
## Binary Printer 使用的 AuxData
为了生成新的二进制文件,gtirb-binary-printer 还使用以下表:
| 键 | 类型 | 用途 |
|------------------|----------------------------------|----------------------------------------------------------------------------------|
| libraries | `std::vector` | 所需库的名称。 |
| libraryPaths | `std::vector` | 包含在二进制文件 rpath 中的路径 |
| elfStackExec | `bool` | 由 ELF 文件中 PT_GNU_STACK 段指定的栈可执行标志。使用 `-Wl,-z,stack,[no]execstack` 进行二进制打印 |
| elfStackSize | `uint64_t` | 由 ELF 文件中 PT_GNU_STACK 段指定的栈大小。使用 `-Wl,-z,stack-size=value` 进行二进制打印。 |
标签:Bash脚本, C++, CMake, Wayback Machine, 二进制分析, 云安全运维, 云资产清单, 代码生成, 反汇编, 数据擦除, 渗透测试工具, 逆向工程