从去符号的二进制文件中自动提取 protobuf 定义,还原 .proto 文件。
支持 C / C++ / Go / Rust 编译的程序,支持 ELF (Linux) 和 PE (Windows),32/64 位。
| 语言 | 库 | 识别方式 | 支持情况 |
|---|---|---|---|
| C | protobuf-c | magic 0x28AAEEF9 结构体扫描 |
✅ 完整支持 |
| C++ | Google protobuf | 序列化 FileDescriptorProto 搜索 |
✅ 完整支持 |
| Go | google.golang.org/protobuf | gzip 压缩描述符搜索 | ✅ 完整支持 |
| Rust | prost / rust-protobuf | 通用原始描述符扫描 | ✅ 基础支持 |
pip install protobuf# 自动检测并提取所有 protobuf 定义
python main.py ./pwn
# 指定输出目录
python main.py ./pwn -o output/
# 只使用特定扫描器
python main.py ./pwn -s protobuf-c # 仅扫描 protobuf-c (C)
python main.py ./pwn -s cpp -s go # 扫描 C++ 和 Go
# 提取后自动编译 .proto 为 _pb2.py
python main.py ./pwn --compile
# 指定 protoc 路径
python main.py ./pwn --compile --protoc /path/to/protoc扫描二进制中的 ProtobufCMessageDescriptor 结构体 (magic: 0x28AAEEF9),
解析字段名、类型、标签等信息,还原 .proto 文件。支持嵌套 message 和 enum 引用。
C++ protobuf 生成的代码会将 FileDescriptorProto 序列化后以字节数组形式嵌入二进制中。
工具搜索 .proto 文件名编码模式 (0x0A + length + filename),提取并反序列化描述符。
Go protobuf 将描述符以 gzip 压缩 的 FileDescriptorProto 形式嵌入。
工具搜索 gzip magic (\x1f\x8b\x08),解压并解析描述符。
通用扫描器搜索所有可能的序列化 FileDescriptorProto 和 FileDescriptorSet,
同时搜索 gzip 压缩的描述符。适用于任何嵌入了 protobuf 描述符的程序。
main.py # 入口 + CLI
binary_reader.py # 二进制文件抽象 (ELF/PE, 32/64-bit)
proto_generator.py # .proto 文件生成器
scanner_protobuf_c.py # protobuf-c 扫描器 (C)
scanner_cpp.py # C++ protobuf 扫描器
scanner_go.py # Go protobuf 扫描器
scanner_raw.py # 通用原始 protobuf 扫描器
requirements.txt # Python 依赖
╔═══════════════════════════════════════════════╗
║ protobuf_rev - Protobuf 逆向工具 ║
║ C / C++ / Go / Rust ➜ .proto 文件 ║
╚═══════════════════════════════════════════════╝
[*] 加载文件: ./pwn
[*] 格式: ELF 64-bit little-endian, 12345 bytes, 28 sections
🔍 扫描 protobuf-c (C 语言)
[+] 发现 1 个 ProtobufCMessageDescriptor
├─ ctf.Msg (3 fields)
│ uint32 size = 1
│ int32 idx = 2
│ bytes content = 3
📝 生成 .proto 文件
[+] 生成: protobuf_c_extracted.proto
syntax = "proto3";
package ctf;
message Msg {
uint32 size = 1;
int32 idx = 2;
bytes content = 3;
}