원시 16 비트 x86 기계어 코드를 어떻게 분해합니까?


91

내가 가지고있는 부팅 가능한 x86 디스크의 MBR (처음 512 바이트)을 분해하고 싶습니다. 다음을 사용하여 MBR을 파일에 복사했습니다.

dd if=/dev/my-device of=mbr bs=512 count=1

파일을 분해 할 수있는 Linux 유틸리티에 대한 제안 사항이 mbr있습니까?

답변:


109

objdump를 사용할 수 있습니다. 이 기사 에 따르면 구문은 다음과 같습니다.

objdump -D -b binary -mi386 -Maddr16,data16 mbr

지정한 옵션의 기능을 설명해 주시겠습니까?
Hawken 2011

11
또는 --target대신 -b. -D"모든 섹션의 내용을 분해"입니다. -b bfdname또는 --target=bfdname지정된 개체 코드 형식 (우리의 경우 elf가 아니라 원시 바이너리)으로 강제로 읽습니다. -m machine사용할 아키텍처를 지정합니다 (파일에는 아치 정보가있는 헤더가 없습니다). -M options디스어셈블러의 옵션입니다. addr16,data16"기본 주소 크기와 피연산자 크기를 지정"하는 데 사용됩니다 (범용 x86 disasm 엔진에서 코드를 i8086으로 처리)
osgx

29

GNU 도구는 objdump 라고 합니다. 예를 들면 다음과 같습니다.

objdump -D -b binary -m i8086 <file>

아키텍처 및 구문에 대해 다른 옵션을 설정할 수도 있습니다. 예를 들어, -m i386또는 -Mintel,x86-64. i8086은 오래된 아키텍처이며 최신 코드에 사용하면 예기치 않은 결과가 발생할 수 있습니다. 또한 많은 컴퓨터가 64 비트이기 때문에 오늘날에는 x86-64to를 지정 -M하는 것이 좋습니다. 에 전달 하면 기본 AT & T 스타일 대신 Intel 스타일로 구문 intel-M변경됩니다.
GDP2

24

나는 ndisasm이 목적을 좋아한다 . 무료이며 오픈 소스이며 대부분의 Linux 배포판의 패키지 저장소에 포함 된 NASM 어셈블러와 함께 제공됩니다.


이 답변이 더 좋습니다. 사용하기 쉽고 OS X에 nasm을 설치할 수 있습니다. objdump가 없었고 소스에서 빌드하고 싶지 않습니다.

23
ndisasm -b16 -o7c00h -a -s7c3eh mbr

설명 -ndisasm 맨 페이지에서

  • -b= 16 비트, 32 비트 또는 64 비트 모드를 지정합니다. 기본값은 16 비트 모드입니다.
  • -o= 파일의 명목상로드 주소를 지정합니다. 이 옵션을 사용하면 ndisasm이 왼쪽 여백 아래에 나열된 주소를 가져오고 PC 상대 점프 및 호출의 대상 주소를 오른쪽으로 가져옵니다.
  • -a = 자동 (또는 지능형) 동기화 모드를 활성화합니다. ndisasm은 상대 점프의 대상 주소를 검사하고 디스 어셈블을 호출하여 동기화를 수행해야하는 위치를 추측합니다.
  • -s= 동기화 주소를 수동으로 지정하여 ndisasm이 주소의 양쪽에있는 바이트를 포함하는 기계 명령어를 출력하지 않도록합니다. 따라서 해당 주소에서 시작하는 명령어는 올바르게 분해됩니다.
  • mbr = 분해 할 파일.

이것은 단순한 ndisasm과는 반대로 무엇을합니까? 당신은 옵션을 설명 할 수
Hawken

4
이러한 옵션의 의미와 기능을 설명해 주시겠습니까? 대답을 이해하는 것은 대답을 얻는 것보다 낫습니다.
썰매

-b specifies 16-, 32- or 64-bit mode. The default is 16-bit mode. -o is the notional load address for the file. This option causes ndisasm to get the addresses it lists down the left hand margin, and the target addresses of PC-relative jumps and calls, right. -s specifies a synchronisation address, such that ndisasm will not output any machine instruction which encompasses bytes on both sides of the address. Hence the instruction which starts at that address will be correctly disassembled.
Janus Troelsen

15

starbluehlovdal은 모두 정식 답변의 일부를 가지고 있습니다. 원시 i8086 코드를 분해하려는 경우 일반적으로 AT & T 구문이 아닌 Intel 구문이 필요하므로 다음을 사용하십시오.

objdump -D -Mintel,i8086 -b binary -m i386 mbr.bin
objdump -D -Mintel,i386 -b binary -m i386 foo.bin    # for 32-bit code
objdump -D -Mintel,x86-64 -b binary -m i386 foo.bin  # for 64-bit code

코드가 ELF (또는 a.out (또는 (E) COFF))이면 짧은 형식을 사용할 수 있습니다.

objdump -D -Mintel,i8086 a.out  # disassembles the entire file
objdump -d -Mintel,i8086 a.out  # disassembles only code sections

32 비트 또는 64 비트 코드의 경우 ,8086; ELF 헤더에는 이미이 정보가 포함되어 있습니다.

ndisasmjameslin이 제안 했듯이 jameslin 도 좋은 선택이지만 objdump일반적으로 OS와 함께 제공되며 GNU binutils (GCC에서 지원하는 항목의 상위 집합)에서 지원하는 모든 아키텍처를 처리 할 수 ​​있으며 해당 출력은 일반적으로 GNU에 공급 될 as수 있습니다 (ndisasm의 경우 일반적으로 nasm물론 먹이를 줄 수 있습니다 ).

Peter Cordes 는“ Agner Fog의 objconv 는 매우 훌륭합니다. 분기 대상에 레이블을 지정하여 코드가 수행하는 작업을 훨씬 쉽게 파악할 수 있습니다. NASM, YASM, MASM 또는 AT & T (GNU) 구문으로 분해 할 수 있습니다.”

멀티미디어 Mike는 이미 알게되었습니다 --adjust-vma. ndisasm동등한은입니다 -o옵션을 선택합니다.

분해, 말하자면, sh4코드 (예 :와 86 거의 모든 다른 디셈가 하나 개의 플랫폼으로 제한되며, GNU의 binutils 패키지와 함께 이것을 사용 (I 시험에 대한 데비안에서 하나의 바이너리를 사용) ndisasmobjconv) :

objdump -D -b binary -m sh -EL x

-m기계이며, -EL리틀 엔디안 (수단을 sh4eb사용 -EB하거나 엔디 언에 존재하는 구조와 관련이 대신).


2
Agner Fog의 objconv 는 매우 좋습니다. 브랜치 타겟 에 레이블을 붙여서 코드가 무엇을하는지 훨씬 쉽게 알아낼 수 있습니다. NASM, YASM, MASM 또는 AT & T (GNU) 구문으로 분해 할 수 있습니다.
Peter Cordes 2015

그것은 나를 위해 GNU / Linux에서 바로 사용할 수 있도록 잘 구축되었습니다. 그러나 예, GNU binutils와 달리 x86 / x86-64 전용입니다. 그러나 피연산자 크기 접두사가 Intel CPU의 디코더에서 LCP 중단을 유발할 수있는 경우와 같이 주석으로 추가하는 멋진 x86 관련 힌트가 많이 있습니다. 반드시 답변에 언급하십시오. 댓글의 주요 목적 중 하나는 나중에 시청자가 읽어야 할 내용뿐만 아니라 포스터가 답변을 개선하도록 돕는 것입니다.
Peter Cordes 2015

1
@PeterCordes 예, MirBSD를 기본 OS로 사용하고 있습니다.)
mirabilos dec

@PeterCordes하지만 원시 바이너리를 분해 할 수없는 것 같습니다. 많은 지침을 제공 할 수 있도록 최소한의 ELF 파일을 만들어야했지만 옵션을 놓쳤을 수도 있습니다.
Ruslan

1
@Ruslan : IDK, 흥미로운 질문입니다. 나는 보통 objdump를 사용하거나 분기 레이블을 원할 경우 gcc -O3 -masm=intel -fverbose-asm -S -o- | less일반적으로 C 소스를 조정하여 좋은 asm으로 컴파일하려고하기 때문에 사용합니다.
Peter Cordes

9

다음 명령을 시도하십시오.

sudo dd if=/dev/sda bs=512 count=1 | ndisasm -b16 -o7c00h -
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.