Skip to content

InkeyP/protobuf_rev

Repository files navigation

protobuf_rev - Protobuf 逆向工具

从去符号的二进制文件中自动提取 protobuf 定义,还原 .proto 文件。

支持 C / C++ / Go / Rust 编译的程序,支持 ELF (Linux) 和 PE (Windows),32/64 位。

支持的 protobuf 实现

语言 识别方式 支持情况
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

工作原理

C (protobuf-c)

扫描二进制中的 ProtobufCMessageDescriptor 结构体 (magic: 0x28AAEEF9), 解析字段名、类型、标签等信息,还原 .proto 文件。支持嵌套 message 和 enum 引用。

C++ (Google protobuf)

C++ protobuf 生成的代码会将 FileDescriptorProto 序列化后以字节数组形式嵌入二进制中。 工具搜索 .proto 文件名编码模式 (0x0A + length + filename),提取并反序列化描述符。

Go

Go protobuf 将描述符以 gzip 压缩FileDescriptorProto 形式嵌入。 工具搜索 gzip magic (\x1f\x8b\x08),解压并解析描述符。

Rust / 通用

通用扫描器搜索所有可能的序列化 FileDescriptorProtoFileDescriptorSet, 同时搜索 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;
      }

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Contributors

Languages