Como diferenciar três arquivos binários para mostrar apenas o que mudou entre 1 e 2 e depois voltou entre 2 e 3?

Como diferenciar três arquivos binários para mostrar apenas o que mudou entre 1 e 2 e depois voltou entre 2 e 3?

Eu tenho três arquivos binários (despejos de memória). Chame-os file1, file2, file3. Estou tentando depurar algum software e estou alternando uma opção.

  • file1= desligar

  • file2= ligar

  • file3= desligar

Preciso saber quais bytes foram alterados entre file1e file2, que também voltaram para os mesmos valores (como file1) em file3.

Há muitas mudanças não relacionadas entre file1, file2então isso diffpor si só não é suficiente para eu determinar o que está mudando quando eu alterno essa opção, estou tentando identificar os bytes únicos de entropia que mudam de file1, 2, 3,…

Eu sei que existem ferramentas como xxd, diff, vimdiff, colordiff. Só não tenho certeza da melhor forma de usá-los para esse problema.

Responder1

Para saber os bytes que mudaram entre file1e file2e seus respectivos valores, use cmp -l:

cmp -l file1 file2 > changes12

Da mesma forma para file3e file2. O truque é investigar sempre na mesma direção (aqui: desligue para ligar), por isso coloquei file2no final:

cmp -l file3 file2 > changes32

Agora você pode encontrar alterações idênticas:

comm -12 changes12 changes32

e a saída será como (exemplo):

     1629 152 112

o que significa que o byte 1629(decimal, a numeração começa com 1) mudou de 152(octal) para 112(octal).


Notas:

  • cmp -lno meu Ubuntu "coluna" sua saída. Isso significa que pode imprimir linhas com espaços à esquerda, a largura da primeira coluna depende do tamanho da entrada. Acho que algumas implementações podem não fazer isso. Existem algumas preocupações:
    • Se os arquivos originais forem de tamanhos diferentes (provavelmente não é o seu caso), um cmppoderá gerar uma primeira coluna mais larga que a outra. No contexto posterior, commisso é inaceitável. Você pode "descolunar" a saída canalizando para awk '{print $1" "$2" "$3}'.
    • Se a saída não estiver "colunada" (ou tiver sido "descolunada"), commpode reclamar que os arquivos não estão classificados. Você precisa sort(não sort -n) antes de salvar em changesAB. Isto poderá gerar uma ordem algo inesperada (por exemplo, 23aparecerão bytes diferentesdepoisbyte diferente 100453) que pode ser corrigido canalizando a saída de commto sort -n.
  • changes*os arquivos podem ser enormes. Eles são intermediários e temporários, portanto a substituição de processos pode ser uma boa abordagem. Porém, isso não é POSIX:

    # Korn shell syntax example
    comm -12 <(cmp -l file1 file2) <(cmp -l file3 file2)
    
  • A saída from commpode ser usada com outra e outra saída of cmppara filtrar melhor as alterações não relacionadas:

    comm -12 changes12 changes32 > result1
    cmp -l file4 file5 | comm -12 - result1 > result2
    cmp -l file6 file5 | comm -12 - result2 > result3
    

    Mas lembre-se:


Documentação:

Responder2

Sou usuário do Windows e uso o Beyond Compare há muitos anos para comparar arquivos, incluindo comparar 3 arquivos (2 de cada vez) entre si.

Parece que o Beyond Compare também tem uma distribuição Linux, então você pode querer dar uma olhada.

https://www.scootersoftware.com/download.php?zz=kb_linux_install

Eu sei que a versão para Windows tem opções para mostrar apenas diferenças, além de muitos outros recursos que podem ajudá-lo. Não me lembro se eles têm uma comparação de 3 vias ou não.

Não sou desenvolvedor nem vendedor deles, apenas gosto muito do software.

Responder3

Com base na resposta de Kamil, usei isto para conseguir o que precisava:

cmp -l arquivo1 arquivo2 | awk '{imprimir $1" "$2" "$3}' | classificar > alterações_12

cmp -l arquivo3 arquivo2 | awk '{imprimir $1" "$2" "$3}' | classificar > alterações_32

comm -12 alterações_12 alterações_32 > alterações_comuns

informação relacionada