Как декодировать бинарные/необработанные данные google protobuf

У меня есть coredump с закодированными данными protobuf, и я хочу декодировать эти данные и посмотреть содержимое. У меня есть .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;
}

И версия protoc:

$  protoc --version
libprotoc 2.3.0

Я пробовал следующее:

  • Сбросьте необработанные данные из ядра

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

  • Передайте его протоку

    //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.

Любые мысли о том, как его декодировать? Документация не объясняет, как это сделать.

Edit: Данные в двоичном формате (10 байт)

(gdb) x/10xb 0x7fd70db7e964
0x7fd70db7e964: 0x08    0xff    0xff    0x01    0x10    0x08    0x40    0xf7
0x7fd70db7e96c: 0xd4    0x38

Ответ 1

Вы правильно использовали --decode_raw, но ваш ввод не является протобуфом.

Для --decode вам нужно указать имя типа, например:

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

Однако, если --decode_raw сообщает об ошибке синтаксического анализа, кроме --decode.

Казалось бы, байты, которые вы извлекли через gdb, не являются действительными protobuf. Возможно, ваши адреса не совсем правильные: если вы добавили или удалили байт с обоих концов, он, вероятно, не будет разбираться.

Я отмечаю, что в соответствии с указанными вами адресами protobuf имеет длину всего 9 байтов, что достаточно для размещения трех или четырех полей. Это то, чего вы ожидаете? Возможно, вы можете разместить здесь байты.

EDIT:

10 байтов, добавленных в ваш вопрос, будут успешно декодироваться с помощью --decode_raw:

$ echo 08ffff01100840f7d438 | xxd -r -p | protoc --decode_raw
1: 32767
2: 8
8: 928375

Перекрестно ссылаясь на номера полей, получаем:

u1: 32767
u2: 8
u6: 928375

Ответ 2

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

Ответ 3

Можно ли таким же образом декодировать двоичный файл onnx? Я пробовал, но это не сработает

Ответ 4

файл протока:

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