Protocol buffers protobufs格式的原始解码器

Protocol buffers protobufs格式的原始解码器,protocol-buffers,Protocol Buffers,我想找到一种方法,将二进制protobuf消息转换为所包含数据的可读描述,而不使用.proto文件 背景是我有一条.proto消息,Android上的解析器拒绝了它,但原因还不完全清楚。我可以用手把这封信通读一遍,但它相当乏味 我尝试了protoc--decode_raw,但它只给出了错误“解析输入失败”。我希望/期待有人会做一个很好的网络工具,可以做到这一点,但没有发现任何明显的 我只是希望得到一些输出,比如: field 1: varint: 128 field 4: string: "fo

我想找到一种方法,将二进制protobuf消息转换为所包含数据的可读描述,而不使用.proto文件

背景是我有一条.proto消息,Android上的解析器拒绝了它,但原因还不完全清楚。我可以用手把这封信通读一遍,但它相当乏味

我尝试了
protoc--decode_raw
,但它只给出了错误“解析输入失败”。我希望/期待有人会做一个很好的网络工具,可以做到这一点,但没有发现任何明显的

我只是希望得到一些输出,比如:

field 1: varint: 128
field 4: string: "foo"

任何指向正确方向的指针都是最受欢迎的

您可以尝试通过wireshark插件强制执行,或者您也可以借用一些实现的“reader”部分(例如,我知道如何在C#中执行此操作,但我怀疑您的意思是什么)

但是,要小心-协议缓冲区中的字符串实际上并不意味着“字符串”-它可能是:

  • UTF-8字符串
  • 任意数据的原始块
  • 子消息
  • “压缩”数组
  • (可能还有什么我忘了)
为子孙后代: 谷歌的协议缓冲区能够解码原始缓冲区

只需将未知缓冲区发送给它,并传递
--decode_raw
标志

$ cat has_no_proto.buff | protoc --decode_raw
2 {
  2: "Error retrieving information from server. [RH-02]"
}
这里有一条消息,字段2被设置为一条嵌入的消息,而嵌入的消息 它的第二个字段设置为一个字符串,告诉我我对Google Play很生气


类型信息是不确定的(看起来它会尝试将所有二进制数据显示为字符串——但满足了您对变量/字符串/子消息区分的要求)。

如果您碰巧有一个二进制文件,其中包含(多个?)长度前缀的protobuf消息,
protoc‒decode‒raw 0;){
int bytesRead=fs.Read(buffer,0,Math.Min(bytesToRead,buffer.Length));
bytesToRead-=字节读取;
如果(bytesRead如中所述,您的protobuf消息可能有一个。假设有,这个答案应该会有所帮助

(注意:对于下面的大多数命令,我假设protobuf消息存储在名为
input
的文件中)

protoc——对单个消息进行原始解码
+
dd
: 如果它只是一条消息,那么您确实可以利用
protoc--decode_raw
,但是您需要先去掉长度前缀头。假设头长4字节,您可以使用
dd
去掉
输入的头,然后将输出馈送到
protoc

dd bs=1 skip=4 if=input 2>/dev/null | protoc --decode_raw
protoc decode lenprefix——对单个消息进行原始解码
: 我还编写了一个自动处理标题剥离的程序:

protoc-decode-lenprefix --decode_raw < input
protoc decode lenprefix——对消息流进行解码…foo.proto
此脚本还可用于完全解码长度前缀消息(而不仅仅是“原始解码”消息)。它假定您可以访问定义protobuf消息的
.proto
文件,就像包装的
protoc
命令一样。调用语法与
protoc--decode
相同。例如,使用
dd
技巧和
protoc--decode
,以及作为文件的输入,语法看起来很简单这样做:

dd bs=1 skip=4 if=task.info 2>/dev/null | \
protoc --decode mesos.internal.Task \
                      -I MESOS_CODE/src -I MESOS_CODE/include \
                      MESOS_CODE/src/messages/messages.proto
使用
protoc decode lenprefix

cat task.info | \
protoc-decode-lenprefix --decode mesos.internal.Task \
                      -I MESOS_CODE/src -I MESOS_CODE/include \
                      MESOS_CODE/src/messages/messages.proto

消息是否有可能包含附加到其上的某些标头?请在跳过前1,2,3,4…字节后尝试对其进行解码。其中一条有问题的消息实际上只有4个字节:18,4,48,0(十进制)。(可能它实际上被截断了?)18=“字段2,长度前缀”(可能意味着:子消息),4=4(下一个片段的长度,以字节为单位),48=“field 6,varint”,0=0。因此您至少缺少2个字节(广告的子消息大小不满足),这肯定可以解释我遇到问题的原因-谢谢Marc!有一个(使用已知的
.proto
).谢谢Marc!我不知道如果没有.proto,字符串和子消息等是无法区分的(尽管我想你可以基于启发式进行猜测)@Joseph是的,你可以试试UTF-8-如果它有效的话,你会得到非常接近的结果;但是其他的比较复杂…buff文件的格式是什么?我有一个二进制文件,其中只包含原始协议缓冲区字节,但不断得到“无法解析输入”。在这种情况下,它是原始协议缓冲区字节输出。你确定你的文件是正确的吗?(请注意编辑器添加的神奇字节)@DeepSpace101也许您在一个文件中有多条消息?请参阅
dd bs=1 skip=4 if=task.info 2>/dev/null | \
protoc --decode mesos.internal.Task \
                      -I MESOS_CODE/src -I MESOS_CODE/include \
                      MESOS_CODE/src/messages/messages.proto
cat task.info | \
protoc-decode-lenprefix --decode mesos.internal.Task \
                      -I MESOS_CODE/src -I MESOS_CODE/include \
                      MESOS_CODE/src/messages/messages.proto