如何解码二进制/原始谷歌protobuf数据

bro*_*oot 15 serialization protocol-buffers

我有一个带有编码的protobuf数据的coredump,我想解码这些数据并查看内容.我有.proto文件,它在原始协议缓冲区中定义此消息.我的proto文件看起来像这样:

$  cat my.proto 
message header {
  required uint32 u1 = 1;
  required uint32 u2 = 2;
  optional uint32 u3 = 3 [default=0];
  optional bool   b1 = 4 [default=true];
  optional string s1 = 5;
  optional uint32 u4 = 6;
  optional uint32 u5 = 7;
  optional string s2 = 9;
  optional string s3   = 10; 
  optional uint32 u6 = 8;
}
Run Code Online (Sandbox Code Playgroud)

和protoc版本:

$  protoc --version
libprotoc 2.3.0
Run Code Online (Sandbox Code Playgroud)

我尝试过以下方法:

  1. 从核心转储原始数据

    (gdb) dump memory b.bin 0x7fd70db7e964 0x7fd70db7e96d

  2. 把它传递给protoc

    //proto file (my.proto) is in the current dir
    $ protoc --decode --proto_path=$pwd my.proto < b.bin
    Missing value for flag: --decode
    To decode an unknown message, use --decode_raw.

    $ protoc --decode_raw < /tmp/b.bin
    Failed to parse input.

有关如何解码的任何想法?文档没有解释如何去做.

编辑:二进制格式的数据(10个字节)

(gdb) x/10xb 0x7fd70db7e964
0x7fd70db7e964: 0x08    0xff    0xff    0x01    0x10    0x08    0x40    0xf7
0x7fd70db7e96c: 0xd4    0x38
Run Code Online (Sandbox Code Playgroud)

Ken*_*rda 20

你使用--decode_raw得当,但你的输入似乎不是一个protobuf.

对于--decode,您需要指定类型名称,例如:

protoc --decode header my.proto < b.bin
Run Code Online (Sandbox Code Playgroud)

但是,如果--decode_raw报告解析错误--decode也会比此过.

看起来你通过gdb提取的字节不是有效的protobuf.也许您的地址不完全正确:如果您在任一端添加或删除了一个字节,它可能无法解析.

我注意到,根据您指定的地址,protobuf只有9个字节长,只有足够的空间可以设置三个或四个字段.这是你期待的吗?也许你可以在这里发布字节.

编辑:

您添加到问题中的10个字节似乎使用--decode_raw以下方法成功解码:

$ echo 08ffff01100840f7d438 | xxd -r -p | protoc --decode_raw
1: 32767
2: 8
8: 928375
Run Code Online (Sandbox Code Playgroud)

交叉引用字段编号,我们得到:

u1: 32767
u2: 8
u6: 928375
Run Code Online (Sandbox Code Playgroud)

  • @Arya 不,但是 unix 命令 `xxd -r -p` 将十六进制解码为二进制,因此您可以在管道中使用它,如我的答案所示。如果你没有从 unix 命令行运行 protoc 那么你将不得不想出一些其他的解决方案...... (2认同)

Hem*_*lle 9

protoc --decode [message_name] [.proto_file_path] < [binary_file_path],

哪里

  • [message_name]是.proto文件中消息对象的名称.如果消息位于.proto文件中的包内,请使用package_name.message_name.
  • [.proto_file_path]是定义消息的.proto文件的路径.
  • [binary_file_path]是要解码的文件的路径.

问题中的情况示例(假设my.proto并且b.bin在您当前的工作目录中):

protoc --decode header my.proto < b.bin

  • 谢谢`package_name.message_name` 是我的关键! (3认同)

小智 9

原型文件:

syntax = "proto3";
package response;

// protoc --gofast_out=. response.proto

message Response {
  int64 UID        
  ....
}

use protoc:
protoc --decode=response.Response response.proto < response.bin
protoc --decode=[package].[Message type] proto.file < protobuf.response
Run Code Online (Sandbox Code Playgroud)