Einfaches Programm, das Google Protobuf-codierte Blobs (Version 2 oder 3) analysieren kann, ohne die zugehörige Definition zu kennen. Es wird eine schöne, farbige Darstellung ihres Inhalts gedruckt. Beispiel:
Wie Sie sehen, gehen die Feldnamen offensichtlich verloren, zusammen mit einigen übergeordneten Details wie:
Aber Protobuf-Inspector ist in den meisten Fällen in der Lage, die Nachrichtenstruktur richtig zu erraten. Wenn eingebettete Binärdaten in einem Feld gefunden werden, versucht es zunächst, diese als Nachricht zu analysieren. Wenn dies fehlschlägt, werden die Daten als String oder Hexdump angezeigt. Insbesondere bei kleinen Stücken kann es zu Fehlern kommen.
Es zeigt die Felder nur in der Reihenfolge an, in der sie im Wire codiert sind, sodass es neben dem Reverse Engineering auch für diejenigen nützlich sein kann, die sich mit dem Wire-Format oder Parser-Entwicklern vertraut machen möchten.
Sie können mit pip installieren:
pip install protobuf-inspector
Dadurch wird der Befehl protobuf_inspector
installiert. Führen Sie es aus und füttern Sie den Protobuf-Blob auf stdin:
protobuf_inspector < my-protobuf-blob
Nachdem Sie die erste (blinde) Analyse des Blobs gelesen haben, beginnen Sie normalerweise mit der Definition einiger Felder, damit der Protobuf-Inspektor Ihre Blobs besser analysieren kann, bis Sie an einem Punkt angelangt sind, an dem Sie eine vollständige Protobuf-Definition haben und der Parser dies nicht mehr tun muss erraten Sie alles.
Lesen Sie hier, wie Sie Felder definieren.
Wenn ein Parsing-Fehler gefunden wird, wird das Parsen innerhalb dieses Felds angehalten, außerhalb der Hierarchie jedoch unbeeinträchtigt fortgesetzt. Der Stack-Trace wird dort ausgegeben, wo der Feldinhalt hingehört, zusammen mit einem Hexdump, der gegebenenfalls angibt, wo das Parsen in diesem Block gestoppt wurde.
Wenn Sie also uint32
angegeben haben und eine größere Variante gefunden wird, erhalten Sie etwa Folgendes:
Wenn Sie angegeben haben, dass ein Feld eine eingebettete Nachricht enthielt, dort jedoch ungültige Daten gefunden wurden, erhalten Sie Folgendes:
Bitte beachten Sie, dass main.py
mit einem Status ungleich Null beendet wird, wenn ein oder mehrere Parsing-Fehler aufgetreten sind.
Es gibt einige Tricks, mit denen Sie bei der Annäherung an einen Blob Zeit sparen können:
Wenn Sie sicher sind, dass ein varint keine Zick-Zack-Codierung verwendet, sich aber immer noch nicht sicher sind, ob die Vorzeichen vorliegen, belassen Sie es bei varint
. Wenn Zick-Zack-Kodierung verwendet wird, verwenden Sie sint64
es sei denn, Sie sind sicher, dass es 32-Bit und nicht 64-Bit ist.
Wenn ein Block fälschlicherweise als packed chunk
oder eingebettete Nachricht erkannt wird oder wenn Sie bei der analysierten Nachricht etwas Seltsames sehen und die Rohbytes sehen möchten, geben Sie einen bytes
an. Wenn umgekehrt die Nachricht aus irgendeinem Grund nicht als eingebettete Nachricht erkannt wird, und dies sollte der Fall sein, erzwingen Sie die message
um den Grund herauszufinden.
Wenn Sie die Rohdaten eines Blocks in eine Datei extrahieren möchten, um sie besser zu analysieren, geben Sie einen dump
-Typ an. Protobuf-Inspector erstellt jedes Mal dump.0
, dump.1
usw., wenn ein passender Blob gefunden wird.
protobuf-inspector analysiert den Blob als Nachricht vom Typ root
, aber das ist nur eine Standardeinstellung. Wenn Sie viele Nachrichtentypen definiert haben, können Sie einen Typnamen als optionales Argument übergeben, und protobuf-inspector verwendet diesen anstelle von root
:
protobuf_inspector request < my-protobuf-blob
Einfaches Beispiel:
from protobuf_inspector . types import StandardParser
parser = StandardParser ()
with open ( 'my-blob' , 'rb' ) as fh :
output = parser . parse_message ( fh , "message" )
print ( output )
Dieses Projekt war jedoch ursprünglich nicht für die Verwendung als Bibliothek konzipiert und seine API könnte sich ändern. Ein komplexeres Beispiel finden Sie unter protobuf_inspector/__main__.py
.