Programme simple qui peut analyser les blobs codés par Google Protobuf (version 2 ou 3) sans connaître la définition qui les accompagne. Il imprimera une belle représentation colorée de leur contenu. Exemple:
Comme vous pouvez le constater, les noms de champs sont évidemment perdus, ainsi que certains détails de haut niveau tels que :
Mais protobuf-inspector est capable de deviner correctement la structure du message la plupart du temps. Lorsqu'il trouve des données binaires intégrées dans un champ, il essaie d'abord de les analyser sous forme de message. Si cela échoue, il affichera les données sous forme de chaîne ou de vidage hexadécimal. Il peut faire des erreurs, surtout avec de petits morceaux.
Il affiche les champs dans l'ordre dans lequel ils sont codés dans le fil, il peut donc être utile pour ceux qui souhaitent se familiariser avec le format filaire ou les développeurs d'analyseurs, en plus de l'ingénierie inverse.
Vous pouvez installer avec pip :
pip install protobuf-inspector
Cela installe la commande protobuf_inspector
. Exécutez-le en alimentant le blob protobuf sur stdin :
protobuf_inspector < my-protobuf-blob
Après avoir lu la première analyse (aveugle) du blob, vous commencez généralement à définir certains champs afin que protobuf-inspector puisse mieux analyser vos blobs, jusqu'à ce que vous arriviez à un point où vous avez une définition complète de protobuf et où l'analyseur n'a plus à le faire. devinez n'importe quoi.
Apprenez-en davantage sur la définition des champs ici.
Si une erreur d'analyse est trouvée, l'analyse s'arrêtera dans ce champ , mais continuera sans être affectée à l'extérieur de la hiérarchie. La trace de la pile sera imprimée là où le contenu du champ serait placé, ainsi qu'un vidage hexadécimal indiquant où l'analyse a été arrêtée dans ce morceau, le cas échéant.
Ainsi, si vous spécifiez un uint32
et qu'une variante plus grande est trouvée, vous obtiendrez quelque chose comme :
Si vous spécifiez qu'un champ contient un message intégré, mais que des données non valides y sont trouvées, vous obtiendrez :
Veuillez noter que main.py
se terminera avec un statut différent de zéro si une ou plusieurs erreurs d'analyse se produisent.
Il existe quelques astuces que vous pouvez utiliser pour gagner du temps lorsque vous approchez d’un blob :
Si vous êtes certain qu'un varint n'utilise pas le codage en zigzag, mais que vous n'êtes toujours pas sûr de la signature, laissez-le comme varint
. S'il utilise le codage en zigzag, utilisez sint64
sauf si vous êtes sûr qu'il s'agit d'un format 32 bits et non 64 bits.
Si un fragment est reconnu à tort comme un packed chunk
ou un message intégré, ou si vous voyez quelque chose de bizarre avec le message analysé et que vous souhaitez voir les octets bruts, spécifiez un type de bytes
. À l'inverse, si pour une raison quelconque, il n'est pas détecté comme un message intégré alors qu'il devrait le faire, forcez-le à message
pour en voir la raison.
Si vous souhaitez extraire les données brutes d'un morceau dans un fichier pour mieux l'analyser, spécifiez un type de dump
et protobuf-inspector créera dump.0
, dump.1
, etc. chaque fois qu'il trouvera un blob correspondant.
protobuf-inspector analyse le blob comme un message de type root
, mais ce n'est qu'une valeur par défaut. Si de nombreux types de messages sont définis, vous pouvez transmettre un nom de type comme argument facultatif, et protobuf-inspector l'utilisera à la place de root
:
protobuf_inspector request < my-protobuf-blob
Exemple simple :
from protobuf_inspector . types import StandardParser
parser = StandardParser ()
with open ( 'my-blob' , 'rb' ) as fh :
output = parser . parse_message ( fh , "message" )
print ( output )
Ce projet n'a cependant pas été initialement conçu pour être utilisé comme bibliothèque et son API pourrait changer. Pour un exemple plus complexe, voir protobuf_inspector/__main__.py
.