2009년 1월 21일 수요일

od와 xxd

윈도우 환경에서 사용 가능한 몇가지 hex editor가 존재하듯 유닉스/리눅스 환경에서도 몇가지 방법으로 바이너리 파일을 hex 모드로 읽고 편집할 수 있다. emacs가 이를 지원하는 대표적인 유닉스 환경에서의 에디터이지만, 여기서는 다른 방법을 소개한다.

먼저 바이너리 파일을 hex 모드로 읽기만 하는 경우에는 xdd나 od를 사용하면 된다.

xxd -g1 filename
  or
od -tx1 -Ax filename

두 프로그램은 거의 동일한 포맷으로 출력을 보여주지만 od가 좀 더 포맷을 자유롭게 지정할 수 있다. -tx1는 type을 16진수로 해서 1바이트 단위로 표시하라는 뜻이며, -Ax는 Address표시를 16진수로 지정하는 옵션으로 위 예와같이 데이터와 어드레스의 표시 형식을 서로 다르게 지정할 수도 있다. od는 octal dump의 약자로 옵션을 주지 않을 경우 8진수로 출력된다.

od가 여러가지 타입으로 출력을 지원하는 것과 달리 xxd는 오직 16진수 형식만 지원한다. -g옵션으로 출력 바이트 단위를 지정해줄 수 있으며 기본값은 2바이트 단위이다.

바이너리 파일을 수정하기 위해서는 vi와 xxd를 함께 사용하면 된다. xxd는 -r 옵션을 제공하는데 이는 reverse 기능으로, 원래 xxd가 바이너리 파일을 16진수 텍스트 형태로 변경해주는 프로그램인데 -r옵션을 사용하여 실행하면 16진수 텍스트를 그대로 다시 바이너리로 변경해 주게 된다. 따라서 바이너리 파일을 헥사 에디팅하려면 vi에서 xxd를 사용하여 바이너리를 16진수 텍스트 형태로 바꾸에 표시하여 주고, 이를 수정한 후 xxd -r을 사용하여 다시 바이너리 형태로 바꾸어준 다음 저장하면 된다.

먼저 vi 실행 시 -b옵션을 사용하여 수정하고자 하는 바이너리 파일은 연다. 이 옵션을 사용하게 되면 vi에서 binary 파일을 열 때 문제를 야기할 수 있는 여러가지 vi 기능들이 모두 turn off 된다.

vi -b filename

이후 아래와 같이 파일을 hex 포맷으로 변환한다.

:%!xxd

이제 헥사 포맷으로 변환된 텍스트를 수정한다. 수정시에는 데이터를 insert나 delete하면 안된다. (아쉬운 제약 사항이지만 어쩔 수 없다.) 따라서 r 명령을 사용하여 데이터를 원하는 값으로 한자씩 수정하는 것이 좋다. 수정이 끝나면 아래 명령으로 이를 다시 바이너리 데이터로 바꾸면 된다.

:%!xxd -r

-r 옵션으로 xxd를 실행시에는 16진수로 표시되는 데이터 영역의 값들만 참조되기 때문에 vi에서 16진수 데이터영역 외에 주소 영역이나 아스키로 표시되는 영역을 수정하더라도 이는 무시된다.

이제 데이터를 저장하고 나가면 된다.

:wq

수정사항을 xxd나 od로 확인해 볼 수 있다.

od -tx1 -Ax filename more +20 -10

댓글 없음: