Linux에서 이진 파일을 비교하려면 어떻게합니까?


272

두 바이너리 파일을 비교하고 출력을 다음과 같은 형식으로 얻어야합니다.

& lt; fileoffset-hex & gt; & lt; file1-byte-hex & gt; & lt; file2-byte-hex & gt;

모든 다른 바이트마다. 그래서 만약 file1.bin ~이다.

  00 90 00 11

이진 형태로 file2.bin ~이다.

  00 91 00 10

나는 뭔가를 사고 싶다.

  00000001 90 91
  00000003 11 10

Linux에서이 작업을 수행 할 수있는 방법이 있습니까? 나도 알아. cmp -l 하지만 오프셋을위한 10 진수 체계와 피하고자하는 바이트의 8 진수를 사용합니다.


9
기본적으로 "binary diff"를 찾고 있습니다. 나는 지독하게 명령 라인이 한줄짜리로 추측 할 수있다. od...
— quack quixote

2
@quack quixote : 하나의 라이너에 대해보기 흉한 것은 무엇입니까? ;)
— Bobby

xdelta.org는 꽤 잘 작동합니다. 아마 그것을 볼 가치가있을 것입니다.
— thatjuan

네가 대답 할 수 없기 때문에 이 질문 (당신이 사용자가 아니기 때문에), 나는 투표를 끝내고 있습니다. 여기에 명시 적으로 요청 된 바이너리 diff는 전혀 유용하지 않으며 여러분이 유용하다고 생각하는 경향이 있습니다. 파일의 시작 부분에 1 바이트를 삽입하면 모든 바이트가 다르게 표시되어야합니까? 그것을 모른 채, 이것은 너무 애매합니다.
— Evan Carroll

1
@EvanCarroll 질문이 주제를 벗어난다고 생각한다면 왜 대답하고 있습니까?
— DavidPostill

답변:


162

offset과 bytes를 16 진수로 출력합니다 :

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

또는 $1-1 첫 번째 인쇄 오프셋을 0에서 시작합니다.

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

운수 나쁘게, strtonum() GAWK에만 해당하므로 awk의 다른 버전 (예 : mawk)에서는 8 진수 - 10 진수 변환 함수를 사용해야합니다. 예를 들어,

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)}'

가독성을 위해 깨진 :

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 : strtonum GAWK에만 해당됩니다. 우분투는 이전에 GAWK를 기본값으로 사용했지만 어떤 시점에서는 mawk. 어떤 경우에도 GAWK를 설치하고 기본값으로 설정할 수 있습니다 ( man update-alternatives ). 필요하지 않은 솔루션에 대한 업데이트 된 답변보기 strtonum.
— Dennis Williamson

149

같이 ~ 돌팔매 지적했다 :

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

그리고

 % diff b1.hex b2.hex

또는

 % vimdiff b1.hex b2.hex

62
배쉬에서 : diff <(xxd b1) <(xxd b2) 그러나이 형식 (또는 당신의 것)의 출력 형식은 OP가 요구 한 것 근처에 없습니다.
— Dennis Williamson

6
vimdiff를 사용하면 두 개의 '파일'이 다른 행의 바이트에 색상이 지정됩니다.
— akira

왜 그런 생각을하지 않았을까요? 그리고 나는이 기술을 과거에도 사용 했었다고 확신합니다.
— njd

1
이것은 나를 위해 위대한 일을했다. opendiff OS X 대신 vimdiff ) - 기본보기 xxd diff 엔진을 바이트 단위로 비교하여 트랙에 보관합니다. 평범한 (날것의) 헥스와 fold, diff 비교하고 있던 파일에서 무작위로 그룹화 / 그룹화를 시도합니다.
— natevw

1
이 명령은 바이트 추가 제거에서 잘 작동하지 않습니다. 그 다음에 오는 모든 라인은 정렬되지 않고 diff. 해결 방법은 한 줄에 1 바이트를 넣고 다음과 같이 제안 된 주소 열을 제거하는 것입니다. 존 로렌스 아스펜 과 나를 .
— Ciro Santilli 新疆改造中心 六四事件 法轮功

70

시험 diff 다음 zsh / bash 프로세스 대체 조합 및 colordiff CLI에서 :

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

어디에:

  • -y 차이점을 나란히 표시합니다 (선택 사항).
  • xxd 이진 파일의 hexdump 출력을 만드는 CLI 도구입니다
  • colordiff 색을 칠 것이다 diff 출력 (통해 설치 : sudo apt-get install colordiff )
  • 더하다 -W200 에 diff 더 넓은 출력 (한 줄당 200 자)

힌트 :

  • 파일이 너무 큰 경우 제한을 추가하십시오 (예 : -l1000 ) 각각 xxd

샘플 출력 :

binary file output in terminal - diff -y <(xxd foo1.bin) <(xxd foo2.bin) | colordiff


8
명령을 다음과 같이 단순화 할 수 있습니다. colordiff -y <(xxd foo1.bin) <(xxd foo2.bin).
— golem

3
당신이 colordiff를 가지고 있지 않다면, 이것은 색깔없이 같은 일을 할 것입니다 : diff -y <(xxd foo1.bin) <(xxd foo2.bin)
— Rock Lee

4
두 파일이 실제로 동일한 지 여부를 알고 싶다면 -q 또는 --brief 스위치는 파일이 다를 때만 출력을 표시합니다.
— Stefan van den Akker

1
함수를 만든다. xxddiff 이것을 위해 : xxddiff() ( f() ( xxd "$1" ; ); diff -y <(f "$1") <(f "$2") | colordiff; )
— rubo77

1
큰! 아직도, diff -u <(xxd tinga.tgz) <(xxd dec.out.tinga.tgz) | vim - 충분히 잘할 수있다.
— ribamar

50

다음과 같은 도구가 있습니다. DHEX 어떤 일을 할 수 있는지, 그리고 다른 도구가 있습니다. VBinDiff .

엄밀히 말하면 명령 줄 방식으로 시도해보십시오. JDIFF .


8
DHEX는 바이너리를 비교하는 것이 당신이하고 싶은 일이라는 것이 굉장합니다. 두 개의 파일을 제공하면 비교보기로 이동하여 차이점을 강조 표시하고 다음 차이로 쉽게 이동할 수 있습니다. 또한 대형 터미널에서 작동 할 수있어 와이드 스크린 모니터에서 매우 유용합니다.
— Marcin

6
나는 VBinDiff를 선호한다. DHEX는 공회전 상태 일 때도 CPU를 사용하고 있습니다. 항상 재연하고 있다고 생각합니다. VBinDiff는 넓은 터미널에서 작동하지 않습니다. 그러나 행 당 16 바이트 이상을 가지고 있기 때문에 어쨌든 넓은 터미널에서 주소가 이상하게 보입니다.
— Janus Troelsen

vbindiff는 우리가 실제로 파일을 편집하게합니다!
— Aquarius Power

2
@DanielBeauyat 압축 파일은 첫 번째 다른 바이트를 만나면 완전히 다른 것입니다. 출력물이 유용하지 않을 수 있습니다.
— Mark Ransom

2
@ 1111161171159459134 jdiff는 jdiff에서 찾은 차이점을 동기화하고 패치하는 프로그램의 "suite"의 일부입니다. 그러나 마크 랜섬 (Mark Ransom)이 말했듯이, 일반적으로 압축 파일에는 현명하지 않을 것입니다. 예외적으로 압축되지 않은 파일의 작은 차이가 압축 된 파일에 미치는 영향이 제한되는 "동기화가 가능한"압축 된 형식 (gzip --rsyncable에 의해 생성 된 것과 같은)입니다.
— hmijail

26

바이트 추가 / 삭제에 작동하는 메소드

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

바이트 64를 한 번만 제거하여 테스트 케이스 생성 :

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

산출:

64d63
<  40

문자의 ASCII 버전을보고 싶다면 다음을 수행하십시오.

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

bdiff file1 file2

산출:

64d63
<   40   @

우분투 16.04에서 테스트되었습니다.

나는 선호한다 od 위에 xxd 때문에:

  • 그것 POSIX이다. , xxd 그렇지 않다 (Vim과 함께).
  • ~을 가지고있다. -An 없이 주소 열을 제거하려면 awk.

명령 설명 :

  • -An 주소 열을 제거합니다. 이것은 중요합니다. 그렇지 않으면 모든 행은 바이트 추가 / 제거 후에 달라집니다.
  • -w1 diff가 그것을 소비 할 수 있도록 한 줄에 한 바이트 씩 넣는다. 한 줄에 한 바이트 씩 넣는 것이 중요합니다. 그렇지 않으면 삭제 후 모든 줄이 서로 다르고 다르게됩니다. 불행하게도 이것은 POSIX가 아니고 GNU에있다.
  • -tx1 한 줄에 1 바이트를 유지하는 한 원하는 표현으로, 가능한 모든 값으로 변경하십시오.
  • -v 별표 반복 생략 방지 * diff를 방해 할 수있는
  • paste -d '' - - 두 줄마다 조인합니다. 16 진수와 ASCII가 서로 인접한 라인으로 들어가기 때문에 필요합니다. 취한 것 : https://stackoverflow.com/questions/8987257/concatenating-every-other-line-with-the-next
  • 괄호를 사용한다. () 정의하기 bdiff 대신에 {} 내부 기능의 범위를 제한하는 것 f, 또한보십시오 : https://stackoverflow.com/questions/8426077/how-to-define-a-function-inside-another-function-in-bash

참조 :


13

짧은 답변

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

hexdumps와 text diff를 사용하여 이진 파일을 비교할 때, 특히 xxd, 바이트의 추가 및 제거가 어드레싱에서 변경되어보기 어려울 수 있습니다. 이 방법은 xxd가 주소를 출력하지 않고 줄마다 한 바이트 만 출력하도록 지시합니다.이 바이트는 변경, 추가 또는 제거 된 바이트를 정확하게 보여줍니다. 나중에 "정상적인"16 진수 덤프에서 흥미로운 바이트 시퀀스를 검색하여 주소를 찾을 수 있습니다 ( xxd first.bin ).


(물론, diff 대신에 vimdiff.)
— VasyaNovikov

11

바이너리 파일을 텍스트 형식으로 덤프하고 diff보기를 위해 kdiff3을 사용하도록 hexdump를 권합니다.

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

2
심지어 여기 bash에서 kdiff3 <(hexdump myfile1.bin) <(hexdump myfile2.bin) 파일을 만들 필요가 없다. myfile1.hex 과 myfile2.hex.
— Hastur

4

그만큼 hexdiff 당신이 찾고있는 것을 정확하게하기 위해 고안된 프로그램입니다.

용법:

hexdiff file1 file2

두 파일의 16 진수 (및 7 비트 ASCII)를 서로 위에 표시하고 차이점을 강조 표시합니다. 보다 man hexdiff 명령이 파일에서 돌아 다니고, 간단한 q 그만 둘거야.


4
그러나 그것은 비교 부분에 관해서는 꽤 나쁜 일을합니다. 파일에 몇 바이트를 삽입하면 변경 후의 모든 바이트가 표시됩니다
— Murmel

그리고 hexdiff는 apt-get을 통해 Ubuntu에서 구할 수 없습니다. 16.4
— rubo77

@Murmel 내가 동의하는 동안 여기에 무엇이 묻히고있는 것이 아닌가?
— Evan Carroll

@EvanCarroll true이고, 따라서 주석을 남기고 (오직), downvote하지 않았다.
— Murmel

나는 또한 Mick에게 투표하지 않았다. 그러나 나는 당신과 동의하고, 여기에서 대답했다. superuser.com/a/1373977/11116 왜냐하면이 나쁜 질문이 개혁되거나 닫힐 가능성이 높기 때문입니다.
— Evan Carroll

3

그것은 엄격하게 질문에 대답하지 않을 수도 있지만, 나는 diffing 바이너리에 이것을 사용한다.

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

두 파일을 16 진수로 출력합니다. ASCII 값을 한 줄에 한 바이트 씩 넣은 다음 Vim의 diff 기능을 사용하여 시각적으로 렌더링합니다.


0

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

DHEX는 단지 16 진수 편집기 이외의 다른 편집기입니다 : diff 모드가있어 두 바이너리 파일을 쉽고 편리하게 비교할 수 있습니다. ncurses를 기반으로하고 테마화할 수 있기 때문에 모든 시스템 및 시나리오에서 실행할 수 있습니다. 검색 로그를 사용하여 파일의 여러 반복에서 변경 사항을 쉽게 추적 할 수 있습니다.


수퍼 유저 환영합니다! 이 소프트웨어가 그 것처럼 보일지라도 할 수 있었다 OP의 문제를 해결하면 스택 교환 네트워크에서 순수한 광고가 강하게 싫어하게됩니다. 이 소프트웨어 편집인과 제휴 한 경우이 사실을 공개하십시오. 그리고 광고가 상업 광고처럼 보이지 않도록 게시물을 다시 작성하십시오. 고맙습니다.
— Nathan.Eilisha Shiraini

나는 어떤 방식 으로든 dhex와 제휴하지 않았습니다. 최소 게시물 길이 제한이 있기 때문에 작성자의 설명을 게시물에 복사했습니다.
— Vincent Vega


0

당신이 사용할 수있는 gvimdiff 포함 된 도구 Vim-gui-common 꾸러미

sudo apt-get update

sudo apt-get vim-gui-common을 설치하십시오.

다음 명령을 사용하여 2 개의 16 진수 파일을 비교할 수 있습니다.

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

그게 다야. 그들이 도움이되기를 바랍니다!



-2

Linux에서 오픈 소스 제품으로 이동 (및 기타 모든 것) 방사능 제공하는 radiff2 이 목적을 위해 명시 적으로. 나 자신 때문에 이걸 끝내기로 결심했다. 다른 사람 당신이 묻는 질문에서 같은 질문을하십시오.

매 바이트마다

그건 미친 짓이야. 요청 된대로 파일의 첫 번째 바이트에 1 바이트를 삽입하면 이후의 모든 바이트가 다르기 때문에 diff가 전체 파일을 반복하므로 실제로 1 바이트 차이가 나옵니다.

조금 더 실용적이다. radiff -O. 그만큼 -O ""고정 된 opcode 바이트가 아닌 모든 바이트로 diff를 수행합니다. ""

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와 마찬가지로 Radare는 바이너리 분석을위한 기본 도구이며, 다음과 같이 델타 차이를 표시 할 수도 있습니다. -d, 또는 16 진수 대신에 디스 어셈블 된 바이트 표시 -D.

이런 종류의 질문을하는 경우 체크 아웃하십시오.


-3

나는 추천한다. IDA Pro 바이너리 파일을 분석합니다. 그런 다음 IDA 용 플러그인을 사용하여 비교를 수행 할 수 있습니다. BinDiff .


1
나는 그것을 올바르게 테스트하기 위해 사야 만할까요?
— Aquarius Power

1
@AquariusPower IDA Pro에는 무료 버전
— user3119546

7
하지만 그것은 리눅스가 아닙니다! :(
— Aquarius Power

IDA Pro의 몇 가지 무료 버전을 와인없이 문제없이 사용했습니다. 올바르게 회상하면됩니다.
— doshea

이것은 최근에 오픈 소스가되었습니다. security.googleblog.com/2016/03/...
— Evgeny
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.