能够解析 Google Protobuf 编码的二进制数据(版本 2 或 3)的简单程序,无需事先知道其对应的定义。它会打印出内容之美观的彩色表示。示例:

如你所见,字段名称显然丢失了,同时一些高层细节也丢失了,例如:
但 protobuf-inspector 大多数时候能够正确猜测消息结构。当它在某个字段中发现嵌入的二进制数据时,会先尝试将其解析为消息。如果失败,则会以字符串或十六进制转储形式显示数据。它可能会出错,尤其是在处理小数据块时。
它以字段在线缆上的编码顺序显示,因此除了逆向工程之外,对于那些希望熟悉线缆格式或解析器开发者也很有用。
你可以通过 pip 安装:
pip install protobuf-inspector
这将安装 protobuf_inspector 命令。运行它,将 protobuf 二进制数据通过标准输入传入:
protobuf_inspector < my-protobuf-blob
在对二进制数据进行首次(盲)分析后,你通常开始定义一些字段,以便 protobuf-inspector 能更好地解析你的二进制数据,直到你获得完整的 protobuf 定义并且解析器不再需要猜测任何内容。
如果发现解析错误,解析将在该字段内部停止,但会在层次结构外层继续不受影响。如果适用,将在该字段内容本应出现的位置打印堆栈跟踪,以及一个指示该块中解析停止位置的十六进制转储。
因此,如果你指定了一个 uint32 但发现了一个更大的 varint,你会看到类似这样的内容:

如果你指定某个字段包含嵌入消息,但其中发现了无效数据,你会看到:

请注意,如果发生一个或多个解析错误,main.py 将以非零状态退出。
在分析二进制数据时,可以使用一些技巧来节省时间:
如果你确定某个 varint 不使用 zig-zag 编码,但仍不确定其有符号性,请将其保留为 varint。如果它确实使用 zig-zag 编码,则使用 sint64,除非你确定它是 32 位而不是 64 位。
如果一个数据块被错误地识别为 packed chunk 或嵌入消息,或者你看到解析后的消息有异常并想查看原始字节,请指定类型为 bytes。相反,如果由于某种原因它未被检测为嵌入消息但本应是,请强制指定为 message 以查看原因。
如果你想要提取某个数据块的原始数据到文件中以更好地分析,请指定类型为 dump,protobuf-inspector 会在每次找到匹配的二进制数据时创建 dump.0、dump.1 等文件。
protobuf-inspector 默认将二进制数据解析为类型为 root 的消息,但这只是默认值。如果你定义了很多消息类型,可以传递一个类型名称作为可选参数,protobuf-inspector 将使用该类型而不是 root:
protobuf_inspector request < my-protobuf-blob
简单示例:
from protobuf_inspector.types import StandardParser
parser = StandardParser()
with open('my-blob', 'rb') as fh:
output = parser.parse_message(fh, "message")
print(output)
本项目最初并非作为库来设计,因此其 API 可能会变化。如需更复杂的示例,请参见 protobuf_inspector/__main__.py。