3 个版本
0.2.2 | 2022年6月21日 |
---|---|
0.2.1 | 2022年6月21日 |
0.2.0 | 2021年7月25日 |
#710 in 调试
55KB
691 行
bao - PDB 编译器
bao 允许您从 C 代码生成 CodeView 格式的调试信息,这种格式最常用于 PDBs。使用 JSON 将类型和函数分配给二进制中的地址。
展示
为了展示 bao 的工作原理,我将使用来自 Valve 的反作弊“解决方案”VAC 的一个模块。这是一个理想的测试样本,因为模块相对较小,因此可以非常容易地完全分析。不同模块之间相似的条件是,我分析的模块都包含 ICE 密码。
之前
应用 Bao 生成的 PDB 之后
代码
int ice_sboxes_initialised;
struct IceKey {
int _size;
int _rounds;
struct IceSubkey *_keysched;
};
struct IceKey* __thiscall IceKey__IceKey(struct IceKey*, int nRounds);
void* __fastcall VAC_malloc(size_t dwBytes);
void ice_sboxes_init(void);
配置
{
"functions": [
{
"name": "IceKey__IceKey",
"pattern": "56 57 33 FF"
},
{
"name": "VAC_malloc",
"pattern": "E8 ? ? ? ? 89 7E 04",
"extra": 1,
"rip_relative": true,
"rip_offset": 4
},
{
"name": "ice_sboxes_init",
"pattern": "75 0B E8 ? ? ? ?",
"extra": 3,
"rip_relative": true,
"rip_offset": 4
}
],
"globals": [
{
"name": "ice_sboxes_initialised",
"pattern": "47 83 3D ? ? ? ? ?",
"offsets": [
3
],
"relative": true
}
]
}
依赖
- LLVM 10 用于生成结果 PDB 文件。这由附带的 pdb_wrapper 处理。
- Clang 10 用于解析 C 文件。这使我们能够使用功能强大的预处理器。
已知问题
- 枚举 不支持(目前?)。
- 联合 不支持(目前?)。
- C++ 支持是实验性的且未经测试。
- 没有参数的函数不会被 IDA Pro 分配类型。这可能是在 IDA Pro 中的错误。
- 原始二进制中的 GUID 和年龄没有被应用到生成的 PDB 中。这意味着在 IDA Pro 中加载 PDB 时,您需要确认额外的警告对话框。
- 内存模型是 LLP64 (
sizeof(long) == 4
),无论目标平台如何。
使用方法
如示例中所示,生成 PDB 的方法非常简单,只需运行 bao -c config.json -- vac.dll src/structs.c
即可。在本例中,生成的 PDB 将保存为 vac.dll.pdb
。您可以使用 -o
选项将结果 PDB 保存到其他位置。
设置
运行bao的最简单方法就是使用Docker
~$ git clone https://github.com/not-wlan/bao.git
~$ cd bao
~$ docker build . -t bao:latest
~$ docker run -v /path/to/project:/project -it bao:latest
#$ cd /project
#$ bao-pdb -o vac.pdb -c vac.json vac.dll structs.c
前三个命令仅在您首次运行或更新bao后才是必需的。
或者您可以在自己的机器上安装依赖项。但请注意,不建议在Windows机器上这样做!
用例
您可以使用bao来
- 将您的逆向工程努力从二进制的某个版本转移到另一个版本
- 通过构建函数指针的结构来模拟虚拟方法表
- 从不会完整构建的泄露源代码中生成PDB
- 将您的逆向工程努力从一种工具转移到另一种工具
感谢
- FakePDB为本项目提供灵感,并在一些LLVM API调用上帮助我。
- hazedumper-rs提供了模式格式。
- 所有一路上帮助过我的人。
依赖
~7–17MB
~234K SLoC