404 votes

Comment comparer des fichiers binaires sous Linux?

J'ai besoin de comparer deux fichiers binaires et obtenir la sortie sous la forme :

pour chaque octet différent. Donc si file1.bin est

  00 90 00 11

sous forme binaire et file2.bin est

  00 91 00 10

Je veux obtenir quelque chose comme

  00000001 90 91
  00000003 11 10

Y a-t-il un moyen de le faire dans Linux ? Je connais cmp -l mais il utilise un système décimal pour les décalages et octal pour les octets ce que je voudrais éviter.

0 votes

Xdelta.org fonctionne assez bien. Il serait peut-être utile d'y jeter un œil.

0 votes

Parce que vous ne pouvez pas répondre à cette question (car vous n'êtes pas un utilisateur), je vote pour la fermeture. Une différence binaire explicitement demandée ici n'est pas du tout utile, et je suis enclin à penser que vous voulez quelque chose d'utile, si vous insérez un octet au début du fichier, tous les octets doivent-ils être marqués comme étant différents? Sans savoir cela, cela est simplement trop vague.

0 votes

Ne pas mentionner que cela va explicitement à l'encontre des règles sur plusieurs domaines, il s'agit de "programmation et développement de logiciels" et vous demandez un produit ou une recommandation plutôt que comment utiliser un produit spécifique.

1voto

Vincent Vega Points 11

Dhex http://www.dettus.net/dhex/

DHEX est bien plus qu'un simple éditeur hexadécimal : il inclut un mode "diff" qui peut être utilisé pour comparer facilement et commodément deux fichiers binaires. Basé sur ncurses et personnalisable, il peut s'exécuter sur un grand nombre de systèmes et de scénarios. Grâce à son utilisation des journaux de recherche, il est possible de suivre facilement les modifications dans différentes itérations de fichiers.

0 votes

Bienvenue sur SuperUser! Bien que ce logiciel semble pouvoir résoudre le problème de l'OP, la publicité pure est fortement déconseillée sur le réseau Stack Exchange. Si vous êtes affilié à l'éditeur de ce logiciel, veuillez en informer. Et essayez de réécrire votre message de manière à ce qu'il ressemble moins à une publicité. Merci.

0 votes

Je ne suis affilié d'aucune manière avec dhex. J'ai copié la description de l'auteur dans le message car il y a une limite minimale de longueur du message.

1 votes

Déjà mentionné ici : superuser.com/a/125390/128124

1voto

craken Points 119

Vous pouvez utiliser l'outil gvimdiff qui est inclus dans le package vim-gui-common

sudo apt-get update

sudo apt-get install vim-gui-common

Ensuite, vous pouvez comparer deux fichiers hexadécimaux en utilisant les commandes suivantes:

ubuntu> gvimdiff

1voto

jjazzboss Points 111

Voici un script Perl, colorbindiff, qui effectue un diff binaire, en prenant en compte les changements d'octets. mais aussi des ajouts/suppressions d'octets (beaucoup des solutions proposées ici ne gèrent que les changements d'octets), comme dans un diff texte. Il est également disponible sur GitHub .

Il affiche les résultats côte à côte avec des couleurs, ce qui facilite grandement l'analyse.

instantané de la sortie de colorbindiff

Pour l'utiliser :

perl colorbindiff.pl FILE1 FILE2

Le script :

#!/usr/bin/perl
#########################################################################
#
# VBINDIFF.PL : A side-by-side visual diff for binary files.
#               Consult usage subroutine below for help.
#
# Copyright (C) 2020 Jerome Lelasseux jl@jjazzlab.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#
#########################################################################

use warnings;
use strict;
use Term::ANSIColor qw(colorstrip colored);
use Getopt::Long qw(GetOptions);
use File::Temp qw(tempfile);
use constant BLANK => "..";
use constant BUFSIZE =>  64 * 1024;     # 64kB

sub usage
{
    print "USAGE: $0 [OPTIONS] FILE1 FILE2\n";
    print "Show a side-by-side binary comparison of FILE1 and FILE2. Show byte modifications but also additions and deletions, whatever the number of changed bytes. Rely on the 'diff' external command such as found on Linux or Cygwin. The algorithm is not suited for large and very different files.\n";
    print "Author: Jerome Lelasseux \@2021\n";
    print "OPTIONS: \n";
    print " --cols=N       : display N columns of bytes.diff Default is 16.\n";
    print " --no-color     : don't colorize output. Needed if you view the output in an editor.\n";
    print " --no-marker    : don't use the change markers (+ for addition, - for deletion, * for modified).\n";
    print " --no-ascii     : don't show the ascii columns.\n";
    print " --only-changes : only display lines with changes.\n";
    exit;
}

# Command line arguments
my $maxCols = 16;
my $noColor = 0;
my $noMarker = 0;
my $noAscii = 0;
my $noCommon = 0;
GetOptions(
    'cols=i'       => \$maxCols,
    'no-ascii'     => \$noAscii,
    'no-color'     => \$noColor,
    'no-marker'    => \$noMarker,
    'only-changes' => \$noCommon
) or usage();
usage() unless ($#ARGV == 1);
my ($file1, $file2) = (@ARGV);

# Convert input files into hex lists
my $fileHex1 = createHexListFile($file1);
my $fileHex2 = createHexListFile($file2);

# Process diff -y output to get an easy-to-read side-by-side view
my $colIndex = 0;
my $oldPtr = 0;
my $newPtr = 0;
my $oldLineBuffer = sprintf("0x%04X ", 0);
my $newLineBuffer = sprintf("0x%04X ", 0);
my $oldCharBuffer;
my $newCharBuffer;
my $isDeleting = 0;
my $isAdding = 0;
my $isUnchangedLine = 1;

open(my $fh, '-|', qq(diff -y $fileHex1 $fileHex2)) or die $!;
while (<$fh>)
{
    # Parse line by line the output of the 'diff -y' on the 2 hex list files.
    # We expect:
    # "xx      | yy" for a modified byte
    # "        > yy" for an added byte
    # "xx      <"    for a deleted byte
    # "xx        xx" for identicial bytes

   my ($oldByte, $newByte);
   my ($oldChar, $newChar);
   if (/\|/)
   {
        # Changed
        if ($isDeleting || $isAdding)
        {
            printLine($colIndex);
        }
        $isAdding = 0;
        $isDeleting = 0;
        $isUnchangedLine = 0;

        /([a-fA-F0-9]+)([^a-fA-F0-9]+)([a-fA-F0-9]+)/;
        $oldByte = formatByte($1, 3);
        $oldChar = toPrintableChar($1, 3);
        $newByte = formatByte($3, 3);
        $newChar = toPrintableChar($3, 3);
        $oldPtr++;
        $newPtr++;
   }
   elsif (/</)
   {
        # Deleted in new
        if ($isAdding)
        {
            printLine($colIndex);
        }
        $isAdding = 0;
        $isDeleting = 1;
        $isUnchangedLine = 0;

        /([a-fA-F0-9]+)/;
        $oldByte=formatByte($1, 2);
        $oldChar=toPrintableChar($1, 2);
        $newByte=formatByte(BLANK, 2);
        $newChar=colorize(".", 2);
        $oldPtr++;
   }
   elsif (/>/)
   {
        # Added in new
        if ($isDeleting)
        {
            printLine($colIndex);
        }
        $isAdding = 1;
        $isDeleting = 0;
        $isUnchangedLine = 0;

        /([a-fA-F0-9]+)/;
        $oldByte=formatByte(BLANK, 1);
        $oldChar=colorize(".", 1);
        $newByte=formatByte($1, 1);
        $newChar=toPrintableChar($1, 1);
        $newPtr++;
   }
   else
   {
        # Unchanged
        if ($isDeleting || $isAdding)
        {
            printLine($colIndex);
        }
        $isDeleting = 0;
        $isAdding = 0;

        /([a-fA-F0-9]+)([^a-fA-F0-9]+)([a-fA-F0-9]+)/;
        $oldByte=formatByte($1, 0);
        $oldChar=toPrintableChar($1, 0);
        $newByte=formatByte($3, 0);
        $newChar=toPrintableChar($3, 0);
        $oldPtr++;
        $newPtr++;
   }

   # Append the bytes to the old and new buffers
    $oldLineBuffer .= $oldByte;
    $oldCharBuffer .= $oldChar;
    $newLineBuffer .= $newByte;
    $newCharBuffer .= $newChar;
    $colIndex++;
    if ($colIndex == $maxCols)
    {
        printLine();
    }
}

printLine($colIndex);    # Possible remaining line

#================================================================
# subroutines
#================================================================

# $1 a string representing a data byte
# $2 0=unchanged, 1=added, 2=deleted, 3=changed
# return the formatted string (color/maker)
sub formatByte
{
    my ($byte, $type) = @_;
    my $res;
    if (!$noMarker)
    {
        if    ($type == 0  || $byte eq BLANK)     { $res = "  " . $byte; }    # Unchanged or blank
        elsif ($type == 1)     { $res = " +" . $byte; }    # Added
        elsif ($type == 2)     { $res = " -" . $byte; }    # Deleted
        elsif ($type == 3)     { $res = " *" . $byte; }    # Changed
        else  { die "Error"; }
    } else
    {
        $res = " " . $byte;
    }
    $res = colorize($res, $type);
    return $res;
}

# $1 a string
# $2 0=unchanged, 1=added, 2=deleted, 3=changed
# return the colorized string according to $2
sub colorize
{
    my ($res, $type) = @_;
    if (!$noColor)
    {
        if ($type == 0)     {  }        # Unchanged
        elsif ($type == 1)     { $res = colored($res, 'bright_green'); }  # Added
        elsif ($type == 2)     { $res = colored($res, 'bright_red'); }    # Deleted
        elsif ($type == 3)     { $res = colored($res, 'bright_cyan'); }   # Changed
        else   { die "Error"; }
    }
    return $res;
}

# Print the buffered line
sub printLine
{
    if (length($oldLineBuffer) <=10)
    {
        return;        # No data to display
    }

    if (!$isUnchangedLine)
    {
        # Colorize and add a marker to the address of each line if some bytes are changed/added/deleted
        my $prefix = substr($oldLineBuffer, 0, 6) . ($noMarker ? " " : "*");
        $prefix = colored($prefix, 'magenta') unless $noColor;
        $oldLineBuffer =~ s/^......./$prefix/;
        $prefix = substr($newLineBuffer, 0, 6) . ($noMarker ? " " : "*");
        $prefix = colored($prefix, 'magenta') unless $noColor;
        $newLineBuffer =~ s/^......./$prefix/;
    }

    my $oldCBuf = $noAscii ? "" : $oldCharBuffer;
    my $newCBuf = $noAscii ? "" : $newCharBuffer;
    my $spacerChars = $noAscii ? "" : (" " x ($maxCols - $colIndex));
    my $spacerData = ($noMarker ? "   " : "    ") x ($maxCols - $colIndex);
    if (!($noCommon && $isUnchangedLine))
    {
        print "${oldLineBuffer}${spacerData} ${oldCBuf}${spacerChars}  ${newLineBuffer}${spacerData} ${newCBuf}\n";
    }

    # Reset buffers and counters
    $oldLineBuffer = sprintf("0x%04X ", $oldPtr);
    $newLineBuffer = sprintf("0x%04X ", $newPtr);
    $oldCharBuffer = "";
    $newCharBuffer = "";
    $colIndex = 0;
    $isUnchangedLine = 1;
}

# Convert a hex byte string into a printable char, or '.'.
# $1 = hex str such as A0
# $2 0=unchanged, 1=added, 2=deleted, 3=changed
# Return the corresponding char, possibly colorized
sub toPrintableChar
{
    my ($hexByte, $type) = @_;
    my $char = chr(hex($hexByte));
    $char = ($char =~ /[[:print:]]/) ? $char : ".";
    return colorize($char, $type);
}

# Convert file $1 into a text file with 1 hex byte per line.
# $1=input file name
# Return the output file name
sub createHexListFile
{
    my ($inFileName) = @_;
    my $buffer;
    my $in_fh;
    open($in_fh,  "<:raw", $inFileName) || die "$0: cannot open $inFileName for reading: $!";
    my ($out_fh, $filename) = tempfile();

    while (my $nbReadBytes = read($in_fh, $buffer, BUFSIZE))
    {
        my @hexBytes = unpack("H2" x $nbReadBytes, $buffer);
        foreach my $hexByte (@hexBytes)
        {
            print $out_fh "$hexByte\n" || die "couldn't write to $out_fh: $!";
        }
    }
    close($in_fh);
    return $filename;
}

0voto

guyskk Points 101

J'ai écrit un script simple pour différencier un fichier binaire. Il affichera le premier groupe différent (40 octets) et le décalage :

https://gist.github.com/guyskk/98621a9785bd88cf2b4e804978950122

$ bindiff fichier1 fichier2
8880> 442408E868330300488D05825337004889042448C744240802000000E84F330300E88A2A0300488B
                      ^^^^^^^^^ ^^
      442408E868330300E59388E59388004889042448C744240802000000E84F330300E88A2A0300488B

-2voto

Evgeny Points 894

https://security.googleblog.com/2016/03/bindiff-now-available-for-free.html

BinDiff est un excellent outil d'interface utilisateur pour comparer des fichiers binaires qui a été récemment ouvert en open source.

4 votes

Peut-il être utilisé sur des fichiers binaires arbitraires, cependant? Cette page semble indiquer qu'il n'est utile que pour comparer des exécutables qui ont été désassemblés par Hex-Rays IDA Pro.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X