Como comparar arquivos binários no Linux

Laptop Linux mostrando um prompt do bash

Como você pode verificar se dois binários do Linux são iguais? Se forem arquivos executáveis, quaisquer diferenças podem significar comportamento indesejado ou malicioso. Esta é a maneira mais fácil de verificar se eles diferem.

Comparando arquivos binários

O Linux é rico em maneiras de comparar e analisar arquivos de texto. O diffcomando comparará dois arquivos para você  e destacará as diferenças . Ele pode até fornecer algumas linhas em ambos os lados das alterações para fornecer algum contexto em torno das linhas alteradas. E a

 colordiff 

O comando adiciona cor para tornar a análise visual das diferenças ainda mais fácil.

Desenvolvedores e autores costumam diffdestacar as diferenças entre diferentes versões de arquivos de código-fonte de programas ou rascunhos de textos. É rápido e fácil, e você não precisa de nenhum conhecimento técnico para ver as diferenças entre sequências de texto.

No mundo dos arquivos binários, as coisas não são tão simples. Os arquivos binários não são compostos de texto simples. Eles são compostos de muitos bytes contendo valores numéricos. Se for um arquivo compactado, como um  arquivo TAR  ou um  arquivo ZIP , esses valores representam os arquivos compactados armazenados dentro do arquivo compactado, junto com as tabelas de símbolos necessárias para a descompactação e extração dos arquivos.

Se o arquivo binário for um arquivo executável, os valores numéricos dos bytes do arquivo serão interpretados como instruções de código de máquina para a CPU, metadados, rótulos ou dados codificados. Alterações em um arquivo binário ou em um arquivo de biblioteca provavelmente levarão a diferenças de comportamento quando o binário for executado ou usado por outro aplicativo.

É fácil falsificar a data e hora de criação ou modificação de um arquivo. Isso significa que pode haver duas versões de um arquivo com o mesmo nome, tamanho do arquivo — se as alterações substituirem o conteúdo existente, byte por byte — e carimbos de data. E ainda assim, um dos arquivos pode ter sido alterado.

Algoritmos Hash Seguros

Um algoritmo hash seguro é um algoritmo baseado em matemática. Ele cria um valor de 64 bits verificando todos os bytes em um arquivo e aplicando uma transformação matemática a eles para gerar o valor hash. Em qualquer dia, o mesmo arquivo sempre produzirá o mesmo hash. Mesmo uma diferença de um byte resultará em um hash radicalmente diferente.

Recomendado:  Você deve pagar se for atingido por um ransomware?

Freqüentemente, você verá o hash de um arquivo exibido em sua página de download. Você deve gerar um hash para o arquivo depois de baixá-lo. Se for diferente do hash exibido na página da web, você sabe que o arquivo está comprometido. Ele foi adulterado e substituído pelo arquivo original — para fazer com que as pessoas baixem o arquivo contaminado — ou foi corrompido em trânsito.

Em nosso computador de teste, temos duas cópias do mesmo arquivo, uma biblioteca compartilhada. Os arquivos foram renomeados para que possam ficar no mesmo diretório. Em teoria, esses arquivos deveriam ser iguais. Afinal, eles deveriam ser a mesma versão da biblioteca compartilhada.

ls -l *.so

Dois arquivos binários que parecem iguais

Os arquivos têm o mesmo tamanho, os mesmos carimbos de data e de hora. Para o observador casual, eles parecerão iguais. Vamos usar o sha256sumcomando e gerar um hash para cada arquivo.

sha256sum arquivo_binário1.so

sha256sum arquivo_binário2.so

Gerando hashes para os dois arquivos binários

Os hashes são completamente diferentes, indicando claramente que existem diferenças entre os dois arquivos. Se o site mostrar o hash do arquivo original, você poderá descartar o arquivo que não corresponde.

Encontrando as diferenças

Se você quiser observar as mudanças, também existem maneiras de fazer isso. Você não precisa ser capaz de descompilar o arquivo, nem entender assembly ou código de máquina apenas para ver as modificações. Compreender o que essas mudanças significam e qual é o seu propósito exigiria, obviamente, um conhecimento técnico mais profundo. Mas simplesmente saber quão substanciais são as alterações pode ser um indicativo do que aconteceu com o arquivo.

Se usarmos diffos dois arquivos binários, obteremos uma resposta um pouco desanimadora.

diff arquivo_binário1.so arquivo_binário2.so

Usar diff com dois arquivos binários fornece muito pouca informação

Já sabíamos que os arquivos eram diferentes. Vamos tentar cmp.

cmp arquivo_binário1.so arquivo_binário2.so

Usar cmp com dois arquivos binários fornece um pouco mais de informação, mas não muito

Isso nos diz um pouco mais. O primeiro byte que difere entre os dois arquivos é o byte número 13451. Ou seja, contado a partir do início do arquivo binário, o byte 13451 é diferente nos dois arquivos binários. Portanto, 13451 é o deslocamento da primeira diferença, desde o início do arquivo.

Por acaso, ao longo do arquivo, haverá bytes que contêm o valor hexadecimal 0x10. Este é o valor que o Linux usa em arquivos de texto como caractere de fim de linha. O cmpcomando encontrou 131 bytes com este valor entre o início do arquivo binário e o local da primeira diferença. Então pensa que está na linha 132. Realmente não significa nada neste contexto.

Recomendado:  Como ver os aplicativos usando sua rede no Windows 10

Se adicionarmos a -lopção (detalhada) começaremos a obter informações úteis.

cmp -l arquivo_binário1.so arquivo_binário2.so

Usando a opção -l com cmp para listar os bytes alterados

Todos os bytes diferentes são listados. O número ou deslocamento do byte, o valor do primeiro arquivo e o valor do segundo arquivo são mostrados, com um byte por linha de saída.

Os valores de bytes são mostrados em octal , em vez do formato hexadecimal usual usado com arquivos binários. No entanto, aprendemos outra coisa. Todos os bytes alterados estão em uma sequência contínua. Seus deslocamentos são incrementados em um para cada byte.

A hexdumpferramenta irá despejar um arquivo binário na janela do terminal. Se usarmos a -Copção (canônica), a saída listará em cada linha o deslocamento, os valores de 16 bytes nesse deslocamento e – se houver – a representação ASCII dos valores de bytes.

hexdump -C arquivo_binário1.so

A saída canônica hexdump de um arquivo binário

Podemos usar a saída de hexdumpcomo entrada para diff, deixando difffuncionar como se estivéssemos lendo dois arquivos de texto.

diff <(hexdump arquivo_binário1.so) <(hexdump arquivo_binário2.so)

Usando diff e hexdump para obter as diferenças entre dois arquivos

difflocaliza as linhas que são diferentes e mostra os valores de bytes hexadecimais do primeiro arquivo acima dos valores do segundo arquivo. O deslocamento da primeira linha é 0x3480 ou 13440 em decimal. Anteriormente, cmpnos disse que a primeira alteração ocorreu no byte 13451, que é 0x348B. Isso realmente corresponde ao que vemos aqui.

A saída de diffestá em blocos de dois bytes. O primeiro par de bytes são os bytes 0 e 1 do deslocamento de 0x3480, o segundo bloco contém os bytes 2 e 3 do deslocamento. O bloco 6 conterá os bytes 0xA e 0xB, ou 10 e 11 em decimal. Esses são os bytes 13450 e 13451. E podemos ver que são os primeiros bytes que diferem. Os primeiros cinco pares de bytes são iguais em ambos os arquivos.

Porém, como diffestá contando da base zero, o que cmpchama 13451 será o byte 13540 para diff. E para tornar as coisas ainda mais confusas, a ordem dos bytes em cada bloco de dois bytes é invertida por diff. Na verdade, os bytes são listados nesta ordem: 1 e 0, 3 e 2, 5 e 4, 7 e 6 e assim por diante.

Recomendado:  Como marcar com estrela suas mensagens de texto favoritas no Android

O comando também é computacionalmente caro – dois hexdumpse um diffde uma só vez – especialmente se os arquivos que estão sendo comparados forem grandes.

Mas se hexdump -Cpodemos enviar uma versão ASCII do arquivo binário para a janela do terminal, por que não redirecionamos a saída para arquivos de texto e depois comparamos esses dois arquivos de texto com diff?

hexdump -C arquivo_binário1.so > binário1.txt

hexdump -C arquivo_binário2.so > binário2.txt

diferença binário1.txt binário2.txt

Redirecionando hexdump para criar dois arquivos de texto e usando diff para comparar os arquivos de texto

A diferença entre os dois arquivos é exibida em dois pequenos trechos. Há uma representação ASCII ao lado deles. Haverá um par de extratos para cada diferença entre os arquivos. Neste exemplo, há apenas uma diferença.

Está tudo muito bem, mas não seria ótimo se houvesse algo que fizesse tudo isso por você?

VBinDiff

O programa VBinDiff pode ser instalado a partir dos repositórios usuais de todas as principais distribuições. Para instalá-lo no Ubuntu, use este comando:

sudo apt instalar vbindiff

Instalando VBinDiff no Ubuntu

No Fedora, você precisa digitar:

sudo dnf instalar vbindiff

Instalando VBinDiff no Fedora

Os usuários do Manjaro precisam usar o pacman.

sudo pacman -Sy vbindiff

Instalando VBinDiff no Fedora

Para utilizar o programa, passe o nome dos dois arquivos binários na linha de comando.

vbindiff arquivo_binário1.so arquivo_binário2.so

Passando dois arquivos binários para VBinDiff na linha de comando

O aplicativo baseado em terminal é aberto, mostrando os dois arquivos em uma visualização de rolagem.

VBinDiff exibindo dois arquivos binários

Você pode usar a roda de rolagem do mouse ou as teclas “UpArrow”, “DownArrow”, “Home”, “End”, “PageUp” e “PageDown” para percorrer os arquivos. Ambos os arquivos irão rolar.

Pressione a tecla “Enter” para pular para a primeira diferença. A diferença é destacada em ambos os arquivos.

VBinDiff destacando diferenças entre dois arquivos binários

Se houvesse mais diferenças, pressionar “Enter” exibiria a próxima diferença. Pressionar “q” ou “Esc” sairá do programa.

Qual é a diferença?

Se você estiver trabalhando em um computador que pertence a outra pessoa e não tiver permissão para instalar nenhum pacote, poderá usar cmp, diff, e hexdump. Se você precisar capturar a saída para processamento posterior, essas também são as ferramentas a serem usadas.

Mas se você tiver permissão para instalar pacotes, o VBinDiff torna seu fluxo de trabalho mais fácil e rápido. E, de fato, usar VBinDiff com um único arquivo binário é uma maneira fácil e conveniente de navegar pelos arquivos binários , o que é um ótimo bônus.