Programa simples que pode analisar blobs codificados pelo Google Protobuf (versão 2 ou 3) sem conhecer a definição que os acompanha. Ele imprimirá uma bela representação colorida de seu conteúdo. Exemplo:
Como você pode ver, os nomes dos campos estão obviamente perdidos, juntamente com alguns detalhes de alto nível, como:
Mas o protobuf-inspector é capaz de adivinhar corretamente a estrutura da mensagem na maioria das vezes. Ao encontrar dados binários incorporados em um campo, ele primeiro tentará analisá-los como uma mensagem. Se isso falhar, os dados serão exibidos como uma string ou hexdump. Pode cometer erros, especialmente com pequenos pedaços.
Ele mostra os campos apenas na ordem em que são codificados na ligação, por isso pode ser útil para quem deseja se familiarizar com o formato da ligação ou desenvolvedores de analisadores, além de engenharia reversa.
Você pode instalar com pip:
pip install protobuf-inspector
Isso instala o comando protobuf_inspector
. Execute-o, alimentando o blob protobuf no stdin:
protobuf_inspector < my-protobuf-blob
Depois de ler a primeira análise (cega) do blob, você normalmente começa a definir alguns dos campos para que o protobuf-inspector possa analisar melhor seus blobs, até chegar a um ponto em que você tenha uma definição completa do protobuf e o analisador não precise mais adivinhe qualquer coisa.
Leia sobre como definir campos aqui.
Se um erro de análise for encontrado, a análise será interrompida nesse campo , mas não será afetada fora da hierarquia. O rastreamento de pilha será impresso onde o conteúdo do campo iria, junto com um hexdump indicando onde a análise foi interrompida naquele pedaço, se aplicável.
Então, se você especificou um uint32
e um varint maior for encontrado, você obterá algo como:
Se você especificou que algum campo continha uma mensagem incorporada, mas dados inválidos foram encontrados lá, você obteria:
Observe que main.py
sairá com status diferente de zero se ocorrer um ou mais erros de análise.
Existem alguns truques que você pode usar para economizar tempo ao se aproximar de um blob:
Se você tem certeza de que um varint não usa codificação zig-zag, mas ainda não tem certeza da assinatura, deixe-o como varint
. Se usar codificação zig-zag, use sint64
a menos que tenha certeza de que é de 32 bits e não de 64 bits.
Se um pedaço estiver sendo reconhecido erroneamente como um packed chunk
ou uma mensagem incorporada, ou se você vir algo estranho com a mensagem analisada e quiser ver os bytes brutos, especifique um tipo de bytes
. Por outro lado, se por algum motivo ela não estiver sendo detectada como uma mensagem incorporada e deveria, force-a a message
para ver o motivo.
Se você deseja extrair os dados brutos de um pedaço para um arquivo para analisá-lo melhor, especifique um tipo de dump
e o protobuf-inspector criará dump.0
, dump.1
, etc. toda vez que encontrar um blob correspondente.
protobuf-inspector analisa o blob como uma mensagem do tipo root
, mas isso é apenas um padrão. Se você tiver muitos tipos de mensagens definidos, poderá passar um nome de tipo como argumento opcional, e o protobuf-inspector usará isso em vez de root
:
protobuf_inspector request < my-protobuf-blob
Exemplo simples:
from protobuf_inspector . types import StandardParser
parser = StandardParser ()
with open ( 'my-blob' , 'rb' ) as fh :
output = parser . parse_message ( fh , "message" )
print ( output )
Este projeto não foi inicialmente projetado para uso como uma biblioteca e sua API pode mudar. Para um exemplo mais complexo, consulte protobuf_inspector/__main__.py
.