web-dev-qa-db-fra.com

Comment décoder les données binaires / brutes de Google Protobuf

J'ai un coredump avec des données protobuf encodées et je veux décoder ces données et voir le contenu. J'ai le fichier .proto qui définit ce message dans le tampon de protocole brut. Mon fichier proto ressemble à ceci:

$  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;
}

Et la version de protocole:

$  protoc --version
libprotoc 2.3.0

J'ai essayé ce qui suit:

  1. Vider les données brutes du noyau

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

  2. Passez-le au protocole

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

Des réflexions sur la façon de le décoder? La documentation n’explique pas grand-chose sur la façon de procéder.

Modifier : données au format binaire (10 octets)

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

Vous avez utilisé --decode_raw correctement, mais votre saisie ne semble pas être un protobuf.

Pour --decode, vous devez spécifier le nom du type, comme:

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

Toutefois, si --decode_raw signale une erreur d'analyse que --decode le sera aussi.

Il semblerait que les octets que vous avez extraits via gdb ne soient pas un protobuf valide. Peut-être que vos adresses ne sont pas tout à fait exactes: si vous avez ajouté ou supprimé un octet à l'une ou l'autre extrémité, il ne sera probablement pas analysé.

Je note que selon les adresses que vous avez spécifiées, le protobuf ne fait que 9 octets de long, ce qui n'est que suffisamment d'espace pour que trois ou quatre des champs soient définis. C'est ce que vous attendez? Vous pourriez peut-être publier les octets ici.

ÉDITER:

Les 10 octets que vous avez ajoutés à votre question semblent décoder avec succès en utilisant --decode_raw:

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

En croisant les numéros de champ, nous obtenons:

u1: 32767
u2: 8
u6: 928375
20
Kenton Varda

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

  • [nom_message] est le nom de l'objet message dans le fichier .proto. Si le message se trouve dans un package du fichier .proto, utilisez package_name.message_name.
  • [.proto_file_path] est le chemin d'accès au fichier .proto où le message est défini.
  • [chemin_fichier_binaire] est le chemin d'accès au fichier que vous souhaitez décoder.

Exemple pour la situation dans la question (en supposant que my.proto et b.bin se trouvent dans votre répertoire de travail actuel):

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

7
Hemaolle

fichier proto:

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
0
Иван Дуюн