
🕵️ Strumento per fare reverse engineering di Protocol Buffers con definizione sconosciuta
Programma semplice in grado di analizzare blob codificati Google Protobuf (versione 2 o 3) senza conoscerne la definizione. Mostrerà una rappresentazione colorata e chiara del loro contenuto. Esempio:

Come puoi vedere, i nomi dei campi vengono ovviamente persi, insieme ad alcuni dettagli di alto livello come:
Ma protobuf-inspector è in grado di indovinare correttamente la struttura del messaggio nella maggior parte dei casi. Quando trova dati binari incorporati in un campo, proverà prima a interpretarli come messaggio. Se fallisce, mostrerà i dati come stringa o esadecimale. Può commettere errori, specialmente con piccoli frammenti.
Mostra i campi nell'ordine in cui sono codificati nel flusso, quindi può essere utile sia per chi vuole familiarizzare con il [formato wire][], sia per sviluppatori di parser, oltre che per il reverse engineering.
Puoi installarlo con pip:
pip install protobuf-inspector
Questo installa il comando protobuf_inspector. Eseguilo, fornendo il blob protobuf su stdin:
protobuf_inspector < my-protobuf-blob
Dopo aver letto la prima analisi (cieca) del blob, di solito si iniziano a definire alcuni dei campi in modo che protobuf-inspector possa analizzare meglio i tuoi blob, fino ad arrivare a un punto in cui hai una definizione completa di protobuf e il parser non deve più indovinare nulla.
Leggi come definire i campi qui.
Se viene rilevato un errore di parsing, l'analisi si fermerà all'interno di quel campo, ma proseguirà inalterata all'esterno della gerarchia. Verrà stampata la traccia dello stack dove sarebbero dovuti andare i contenuti del campo, insieme a un esadecimale che indica dove l'analisi è stata interrotta in quel blocco, se applicabile.
Quindi, se hai specificato un uint32 e viene trovato un varint più grande, otterrai qualcosa del genere:

Se hai specificato che un campo conteneva un messaggio incorporato, ma sono stati trovati dati non validi, otterrai:

Nota che main.py uscirà con un codice di errore se si è verificato uno o più errori di parsing.
Ci sono alcuni trucchi che puoi usare per risparmiare tempo quando analizzi un blob:
Se sei certo che un varint non utilizzi la codifica zig-zag, ma non sei ancora sicuro del segno, lascialo come varint. Se invece utilizza la codifica zig-zag, usa sint64 a meno che tu non sia sicuro che sia a 32 bit e non a 64 bit.
Se un blocco viene erroneamente riconosciuto come packed chunk o messaggio incorporato, o se vedi qualcosa di strano nel messaggio analizzato e vuoi vedere i byte grezzi, specifica il tipo bytes. Al contrario, se per qualche motivo non viene rilevato come messaggio incorporato e dovrebbe esserlo, forza message per vedere il motivo.
Se vuoi estrarre i dati grezzi di un blocco in un file per analizzarlo meglio, specifica il tipo dump e protobuf-inspector creerà dump.0, dump.1, ecc. ogni volta che trova un blob corrispondente.
protobuf-inspector analizza il blob come messaggio di tipo root, ma è solo un'impostazione predefinita. Se hai molti tipi di messaggio definiti, puoi passare un nome di tipo come argomento opzionale e protobuf-inspector userà quello al posto di root:
protobuf_inspector request < my-protobuf-blob
Esempio semplice:
from protobuf_inspector.types import StandardParser
parser = StandardParser()
with open('my-blob', 'rb') as fh:
output = parser.parse_message(fh, "message")
print(output)
Questo progetto non è stato inizialmente progettato per essere usato come libreria, quindi la sua API potrebbe cambiare. Per un esempio più complesso, vedi protobuf_inspector/__main__.py.