
🕵️ Herramienta para realizar ingeniería inversa de Protocol Buffers con definición desconocida
Programa simple que puede analizar blobs codificados en Google Protobuf (versión 2 o 3) sin conocer su definición acompañante. Imprimirá una representación agradable y coloreada de su contenido. Ejemplo:

Como puede ver, los nombres de los campos se pierden obviamente, junto con algunos detalles de alto nivel como:
Pero protobuf-inspector es capaz de adivinar correctamente la estructura del mensaje la mayoría de las veces. Cuando encuentra datos binarios incrustados en un campo, primero intenta analizarlos como un mensaje. Si eso falla, muestra los datos como una cadena o volcado hexadecimal. Puede cometer errores, especialmente con fragmentos pequeños.
Muestra los campos en el orden en que están codificados en el cable, por lo que puede ser útil para quienes deseen familiarizarse con el [formato de cable][] o para desarrolladores de analizadores, además de para la ingeniería inversa.
Puede instalarlo con pip:
pip install protobuf-inspector
Esto instala el comando protobuf_inspector. Ejecútelo, alimentando el blob de protobuf en la entrada estándar:
protobuf_inspector < my-protobuf-blob
Después de leer el primer análisis (ciego) del blob, normalmente comienza a definir algunos de los campos para que protobuf-inspector pueda analizar mejor sus blobs, hasta llegar a un punto en el que tenga una definición completa de protobuf y el analizador ya no tenga que adivinar nada.
Lea sobre cómo definir campos aquí.
Si se encuentra un error de análisis, el análisis se detendrá dentro de ese campo, pero continuará sin verse afectado fuera de la jerarquía. El rastreo de la pila se imprimirá donde irían los contenidos del campo, junto con un volcado hexadecimal que indica dónde se detuvo el análisis en ese fragmento, si corresponde.
Por lo tanto, si especificó un uint32 y se encuentra un varint más grande, obtendría algo como:

Si especificó que algún campo contenía un mensaje incrustado, pero se encontraron datos no válidos allí, obtendría:

Tenga en cuenta que main.py saldrá con un estado distinto de cero si ocurrieron uno o más errores de análisis.
Hay algunos trucos que puede utilizar para ahorrar tiempo al abordar un blob:
Si está seguro de que un varint no utiliza codificación zig-zag, pero aún no está seguro del signo, déjelo como varint. Si utiliza codificación zig-zag, use sint64 a menos que esté seguro de que es de 32 bits y no de 64 bits.
Si un fragmento se reconoce incorrectamente como un fragmento empaquetado o un mensaje incrustado, o si ve algo extraño con el mensaje analizado y desea ver los bytes sin procesar, especifique un tipo bytes. Por el contrario, si por alguna razón no se detecta como un mensaje incrustado y debería serlo, fórcelo a message para ver el motivo.
Si desea extraer los datos sin procesar de un fragmento a un archivo para analizarlo mejor, especifique un tipo dump y protobuf-inspector creará dump.0, dump.1, etc. cada vez que encuentre un blob coincidente.
protobuf-inspector analiza el blob como un mensaje de tipo root, pero eso es solo un valor predeterminado. Si tiene muchos tipos de mensajes definidos, puede pasar un nombre de tipo como argumento opcional, y protobuf-inspector lo usará en lugar de root:
Ejemplo simple:
from protobuf_inspector.types import StandardParser
parser = StandardParser()
with open('my-blob', 'rb') as fh:
output = parser.parse_message(fh, "message")
print(output)
Este proyecto no fue diseñado inicialmente para usarse como biblioteca, y su API podría cambiar. Para un ejemplo más complejo, consulte protobuf_inspector/__main__.py.
protobuf_inspector request < my-protobuf-blob