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 )
  • 더하다 -W200diff 더 넓은 출력 (한 줄당 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.hexmyfile2.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.