Linux'ta ikili dosyaları nasıl karşılaştırabilirim?


303

İkili ikili dosyayı karşılaştırmam ve çıktıyı formda almam gerekiyor:

<fileoffset-hex> <file1-byte-hex> <file2-byte-hex>

Her farklı bayt için. Yani eğer file1.binolduğunu

  00 90 00 11

İkili biçimde ve file2.binbir

  00 91 00 10

Gibi bir şey almak istiyorum

  00000001 90 91
  00000003 11 10

Bunu Linux'ta yapmanın bir yolu var mı? Biliyorum cmp -lama ofsetler için ondalık sistemi ve kaçınmak istediğim baytlar için sekizlik sistemi kullanıyor.


9
temelde "ikili fark" ı arıyorsunuz. Reeeally çirkin bir komut satırı ile bir liner hayal edebiliyorum od...
quack quixote

2
@quack quixote: Tek astarla ilgili çirkin olan ne? ;)
Bobby

xdelta.org oldukça iyi çalışıyor. Belki de bir göz atmaya değer.
juan,

Eğer cevap veremez çünkü bu soruyu (bir kullanıcı değilseniz gibi), ben kapatmak için oy veriyorum. Burada açıkça talep edilen bir ikili fark hiç de kullanışlı değil ve yararlı bir şey istediğinizi düşünmeye meyilliyim , dosyanın başına bir bayt eklerseniz tüm baytlar farklı olarak işaretlenmeli mi? Bunu bilmeden, bu sadece çok belirsiz.
Evan Carroll,

2
@EvanCarroll Sorunun konu dışı olduğunu düşünüyorsanız neden cevaplıyorsunuz?
DavidPostill

Yanıtlar:


174

Bu, ofset ve baytları hex olarak basar:

cmp -l file1.bin file2.bin | gawk '{printf "%08X %02X %02X\n", $1, strtonum(0$2), strtonum(0$3)}'

Veya $1-1ilk yazdırılan ofsetin 0'dan başlaması için yapın.

cmp -l file1.bin file2.bin | gawk '{printf "%08X %02X %02X\n", $1-1, strtonum(0$2), strtonum(0$3)}'

Maalesef, strtonum()GAWK’ya özgüdür, bu nedenle awk’ın diğer sürümleri (örneğin, mawk) için sekizli-ondalık dönüşüm işlevi kullanmanız gerekir. Örneğin,

cmp -l file1.bin file2.bin | mawk 'function oct2dec(oct,     dec) {for (i = 1; i <= length(oct); i++) {dec *= 8; dec += substr(oct, i, 1)}; return dec} {printf "%08X %02X %02X\n", $1, oct2dec($2), oct2dec($3)}'

Okunabilirlik için ayrılmış:

cmp -l file1.bin file2.bin |
    mawk 'function oct2dec(oct,    dec) {
              for (i = 1; i <= length(oct); i++) {
                  dec *= 8;
                  dec += substr(oct, i, 1)
              };
              return dec
          }
          {
              printf "%08X %02X %02X\n", $1, oct2dec($2), oct2dec($3)
          }'

3
@gertvdijk: GAWK'ya strtonumözgüdür. Ubuntu'nun daha önce GAWK'yı varsayılan olarak kullandığını, ancak bir noktada değiştirildiğini düşünüyorum mawk. Her durumda, GAWK kurulabilir ve varsayılan olarak ayarlanabilir (ayrıca bakınız man update-alternatives). Gerektirmeyen bir çözüm için güncellenmiş cevabımı görün strtonum.
Dennis Williamson,

Neden sadece her iki dosyanın sha256sum'unu karşılaştırmıyorsunuz?
Rodrigo,

1
@Rodrigo: Bu ve diğer çeşitli yöntemler sadece dosyaların farklılık gösterip göstermediğini gösterecektir. Cevabım, OP'nin aslında farklılıkların ne olduğunu gösterme şartını yerine getiriyor.
Dennis Williamson,

Tabii ki! Üzgünüm, benim sorunum hakkında endişelenmiştim, OP'leri zar zor okudum. Teşekkür ederim.
Rodrigo,

165

Quack'in belirttiği gibi :

 % xxd b1 > b1.hex
 % xxd b2 > b2.hex

Ve sonra

 % diff b1.hex b2.hex

veya

 % vimdiff b1.hex b2.hex

70
Bash'de: diff <(xxd b1) <(xxd b2)ancak bunun (ya da sizinkilerin) çıktı biçimi OP'nin istediği yere yakın değil.
Dennis Williamson,

6
vimdiff ile, iki 'dosyanın' farklı olduğu satırlardaki baytları renklendirir
akira

Aww, neden bunu düşünmedim? Ve eminim ki bu tekniği geçmişte de kullandım.
njd

1
Bu benim için harika oldu ( opendiffyerine OS X’de vimdiff) - varsayılan görünüm xxd, farklı motoru bayt bayt karşılaştırırken yolunda tutar. Sadece sütun uygun olan düz (ham) hex ile fold, diffbir karşılaştırma yapıldı dosyalarında / grup rastgele şeyler kat çalışacaktı.
natevw

1
Bu komut, bayt eklemesi kaldırma işlemi için iyi çalışmaz, çünkü izleyen her satır yanlış hizalanmış ve tarafından değiştirilmiş olarak görülecektir diff. Çözüm, her satıra 1 bayt koymak ve John Lawrence Aspden ve benim tarafımdan önerilen adres sütununu kaldırmak .
Ciro Santilli 事件 38 事件 法轮功 六四 事件

98

diff + xxd

diffAşağıdaki zsh / bash işlem ikame kombinasyonunu deneyin :

diff -y <(xxd foo1.bin) <(xxd foo2.bin)

Nerede:

  • -y yan yana farklılıkları gösterir (isteğe bağlı).
  • xxd İkili dosyanın bir hexdump çıktısını oluşturmak için CLI aracıdır.
  • Ekle -W200için diffdaha geniş çıkış için (her satıra 200 karakter).
  • Renkler için, colordiffaşağıda gösterildiği şekilde kullanın .

colordiff + xxd

Eğer varsa colordiff, diffçıktıyı renklendirebilir , örneğin:

colordiff -y <(xxd foo1.bin) <(xxd foo2.bin)

Aksi takdirde: ile yükleyin sudo apt-get install colordiff.

Örnek çıktı:

terminalindeki ikili dosya çıktısı - diff -y <(xxd foo1.bin) <(xxd foo2.bin) |  colordiff

vimdiff + xxd

Ayrıca vimdiff, örneğin

vimdiff <(xxd foo1.bin) <(xxd foo2.bin)

İpuçları:

  • dosyalar çok büyükse, -l1000her biri için sınır ekleyin (örn. ).xxd

11
Komut olarak basitleştirilebilir colordiff -y <(xxd foo1.bin) <(xxd foo2.bin).
golem

3
Colordiff'iniz yoksa, bu renk olmadan aynı şeyi yapar:diff -y <(xxd foo1.bin) <(xxd foo2.bin)
Rock Lee 15

5
Her iki dosyanın da aynı olup olmadığını bilmek istiyorsanız , yalnızca dosyalar farklı olduğunda çıktıyı gösterecek olan -qveya --briefanahtarını kullanabilirsiniz .
Stefan van den Akker

1
bunun için bir fonksiyon oluşturmak xxddiff:xxddiff() ( f() ( xxd "$1" ; ); diff -y <(f "$1") <(f "$2") | colordiff; )
rubo77

2
harika! hala, diff -u <(xxd tinga.tgz) <(xxd dec.out.tinga.tgz) | vim - iyi bir iş yapacak
enoug

56

DHEX adlı bir işi yapabilecek bir araç var ve VBinDiff adında başka bir araç var .

Kesinlikle komut satırı yaklaşımı için jojodiff'i deneyin .


8
DHEX harikadır, ikili dosyaları karşılaştırmak, yapmak istediğiniz şeydir. İki dosyaya besleyin ve farklılıkları vurgulayarak, bir sonraki farklılığa kolayca taşınabilmenizi sağlayan karşılaştırmalı bir görünüm elde edin. Ayrıca geniş ekranlı monitörlerde çok faydalı olan büyük terminallerle de çalışabilir.
Marcin

7
VBinDiff'i tercih ederim. DHEX, boşta çalışırken bile CPU kullanıyor, sanırım her zaman yeniden çiziyor. VBinDiff olsa geniş terminalleri ile çalışmaz. Ancak, adresler yine de geniş terminallerle garipleşir, çünkü satır başına 16 bayttan daha fazlasına sahipsiniz.
Janus Troelsen 17:12

1
vbindiff dosyayı gerçekten düzenlememize izin veriyor, thx!
Kova Gücü

2
@DanielBeauyat sıkıştırılmış dosyalar, ilk farklı baytla karşılaştığınızda tamamen farklı olacaktır. Çıktının kullanışlı olması muhtemel değildir.
Mark Ransom,

2
Jdiff, jdiff tarafından bulunan farkları senkronize etmek ve yamalamak için kullanılan bir "programlar" programının bir parçasıdır. Ancak, Mark Ransom'un dediği gibi, bu genellikle sıkıştırılmış dosyalarda akıllıca olmaz; Bunun istisnası, sıkıştırılmamış dosyalardaki küçük farklılıkların sıkıştırılmış dosya üzerinde sınırlı bir etkiye sahip olması gereken "senkronize edilebilir" sıkıştırılmış formatlardır (gzip --rsyncable tarafından üretilenler gibi).
hmijail

27

Bayt ekleme / silme için çalışan yöntem

diff <(od -An -tx1 -w1 -v file1) \
     <(od -An -tx1 -w1 -v file2)

Tek bir bayt 64 kaldırma ile bir test durumu oluşturun:

for i in `seq 128`; do printf "%02x" "$i"; done | xxd -r -p > file1
for i in `seq 128`; do if [ "$i" -ne 64 ]; then printf "%02x" $i; fi; done | xxd -r -p > file2

Çıktı:

64d63
<  40

Ayrıca karakterin ASCII versiyonunu da görmek istiyorsanız:

bdiff() (
  f() (
    od -An -tx1c -w1 -v "$1" | paste -d '' - -
  )
  diff <(f "$1") <(f "$2")
)

bdiff file1 file2

Çıktı:

64d63
<   40   @

Ubuntu 16.04'te test edilmiştir.

Tercihim odüzerinde xxdçünkü:

  • o POSIX , xxddeğil (Vim ile gelir) olduğu
  • sahip -Anolmadan adres sütunu kaldırmak için awk.

Komut açıklaması:

  • -Anadres sütununu kaldırır. Bu önemlidir, aksi takdirde tüm satırlar bir bayt ekleme / kaldırma işleminden sonra farklılık gösterir.
  • -w1Her satıra bir bayt koyar, böylece diff onu tüketebilir. Satır başına bir bayt olması veya silme işleminden sonraki her satırın faz dışı kalması ve farklı olması çok önemlidir. Ne yazık ki, bu POSIX değil, GNU’da var.
  • -tx1 İstediğiniz gösterim, satır başına 1 baytı tuttuğunuz sürece olası herhangi bir değere değiştirin.
  • -v*diff ile karışabilecek yıldız tekrarı kısaltmasını önler
  • paste -d '' - -her iki çizgiye katılır. İhtiyacımız var çünkü hex ve ASCII ayrı bitişik çizgilere gidiyor. Alındığı yer: https://stackoverflow.com/questions/8987257/concatenating-every-other-line-with-the-next
  • Biz parantez kullanımı ()tanımlamak bdiffyerine {}, iç fonksiyon kapsamını sınırlandırmak için f: bakınız https://stackoverflow.com/questions/8426077/how-to-define-a-function-inside-another-function-in-bash

Ayrıca bakınız:


13

Kısa cevap

vimdiff <(xxd -c1 -p first.bin) <(xxd -c1 -p second.bin)

İkili dosyaları karşılaştırmak için hexdumps ve text diff kullanıldığında, özellikle xxdbaytların eklenmesi ve kaldırılması adreslemede değişmeyi zorlaştırabilir. Bu yöntem, xxd'ye adresleri çıkarmamasını ve satır başına yalnızca bir bayt çıktısını söyler; bu da tam olarak hangi baytların değiştirildiğini, eklendiğini veya kaldırıldığını gösterir. Daha sonra "normal" bir hexdump (çıktısı xxd first.bin) içindeki baytların ilginç dizilerini arayarak adresleri daha sonra bulabilirsiniz .


(Tabii ki, biri diffyerine kullanabilirsiniz vimdiff.)
VasyaNovikov

11

İkili dosyaları metinsel biçime dökmek için hexdump'ı ve farklı görüntüleme için kdiff3'ü öneririm.

hexdump myfile1.bin > myfile1.hex
hexdump myfile2.bin > myfile2.hex
kdiff3 myfile1.hex myfile2.hex

2
Burada bile bash kdiff3 <(hexdump myfile1.bin) <(hexdump myfile2.bin)hiçbir dosyaları oluşturmak için ihtiyacı olan myfile1.hexve myfile2.hex.
Hastur,

5

hexdiffAradığınız tam olarak ne yapmak için tasarlanmış bir programdır.

Kullanımı:

hexdiff file1 file2

İki dosyanın üst üste (ve 7 bit ASCII) üst üste, farklılıkları vurgulanmış olarak görüntüler. man hexdiffDosyada dolaşmak için komutları arayın ve basit bir qçıkacaktır.


4
Ancak karşılaştırma kısmına gelince oldukça kötü bir iş çıkarıyor. Bir dosyaya bazı baytlar eklerseniz, daha sonra tüm baytları değişiklik olarak işaretler
Murmel

ve hexdiff Ubuntu
16.4'deki

1
@Melmel katılıyorum, burada sorulan bu değil mi?
Evan Carroll,

@EvanCarroll true ve bu yüzden bir yorum bıraktım (sadece) ve not düşürmedim
Murmel

Ayrıca Mick'i oylamadım, ama sizinle aynı fikirdeyim ve burada cevap verdim: superuser.com/a/1373977/11116 çünkü bu kötü sorunun düzeltilmesi veya kapatılması muhtemel görünüyor.
Evan Carroll,

3

Soruyu kesin olarak cevaplamayabilir, ancak bunu farklı ikili dosyalar için kullanıyorum:

gvim -d <(xxd -c 1 ~/file1.bin | awk '{print $2, $3}') <(xxd -c 1 ~/file2.bin | awk '{print $2, $3}')

Her iki dosyayı da onaltılık ve ASCII değerleri olarak yazdırır , her satırda bir bayt ve daha sonra görselleştirmek için Vim'in diff özelliğini kullanır.


0

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

DHEX başka bir hex editörden daha fazlasıdır: İki ikili dosyayı kolayca ve rahatça karşılaştırmak için kullanılabilen bir diff modu içerir. Hemşirelere dayalı ve tematik olduğu için, herhangi bir sayıda sistem ve senaryo üzerinde çalışabilir. Arama günlüklerinin kullanımıyla, farklı dosya yinelemelerindeki değişiklikleri kolayca izlemek mümkündür.


SuperUser'a Hoşgeldiniz! Neye bu yazılım görünse de olabilir OP'ın sorunu çözmek, saf reklam şiddetle Stack Exchange ağda hoş karşılanmaz. Bu yazılımın editörüne bağlıysanız, lütfen bu durumu açıklayın. Ve reklamınızı daha az ticari görünecek şekilde yeniden yazmayı deneyin. Teşekkür ederim.
Nathan.Eilisha Shiraini

Hiçbir şekilde dhex ile bağlı değilim. Yazarın açıklamasını yazıya kopyaladım çünkü minimum yazı uzunluğu sınırı var
Vincent Vega


0

Vim-gui-common paketinde bulunan gvimdiff aracını kullanabilirsiniz

sudo apt-get update

sudo apt-get install vim-gui-common

Ardından, aşağıdaki komutları kullanarak 2 hex dosyasını karşılaştırabilirsiniz:

ubuntu> gvimdiff <hex-file1> <hex-file2>

Hepsi bu kadar. Umarım yardım eder!


0

Ürün yazılımı analiz aracı binwalkayrıca, yalnızca farklı baytları göstermek gibi seçenekler sunan -W/ --hexdumpkomut satırı seçeneği sayesinde bir özellik olarak da vardır :

    -W, --hexdump                Perform a hexdump / diff of a file or files
    -G, --green                  Only show lines containing bytes that are the same among all files
    -i, --red                    Only show lines containing bytes that are different among all files
    -U, --blue                   Only show lines containing bytes that are different among some files
    -w, --terse                  Diff all files, but only display a hex dump of the first file

OP'nin örneğinde binwalk -W file1.bin file2.binşunları yaparken :

binwalk -W file1.bin file2.bin



-2

Linux'ta (ve diğer her şeyde) açık kaynaklı ürüne gitmek , açıkça bu amaca hizmet eden Radare'dirradiff2 . Bunu kapatmak için oy kullandım çünkü sorduğum soruda kendim ve başkalarının aynı soruyu aldım.

her farklı bayt için

Bu delilik. Çünkü istendiği gibi, dosyadaki ilk bayta bir bayt eklerseniz, izleyen her baytın farklı olduğunu göreceksiniz ve böylece fark bir bayt için gerçek bir fark için bütün dosyayı tekrar edecektir.

Biraz daha pratik radiff -O. -O" "Yerine sabit işlemkodu bayt tüm bayt ile diffing kodu yapın"" içindir

0x000000a4 0c01 => 3802 0x000000a4
0x000000a8 1401 => 3802 0x000000a8
0x000000ac 06 => 05 0x000000ac
0x000000b4 02 => 01 0x000000b4
0x000000b8 4c05 => 0020 0x000000b8
0x000000bc 4c95 => 00a0 0x000000bc
0x000000c0 4c95 => 00a0 0x000000c0

IDA Pro gibi, Radare ikili analiz için birincil olan bir araçtır, ayrıca onlarla farklılık gösteren deltaları gösterebilir -dveya hex yerine demonte baytları gösterebilirsiniz -D.

Bu tür sorular soruyorsanız, kontrol edin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.