Wie zerlege ich rohen 16-Bit-x86-Maschinencode?

90

Ich möchte den MBR (die ersten 512 Bytes) einer bootfähigen x86-Festplatte, die ich habe, zerlegen. Ich habe den MBR mit in eine Datei kopiert

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

Irgendwelche Vorschläge für ein Linux-Dienstprogramm, das die Datei zerlegen kann mbr?

Sigjuice
quelle

Antworten:

107

Sie können objdump verwenden. Nach diesem Artikel lautet die Syntax:

objdump -D -b binary -mi386 -Maddr16,data16 mbr
hlovdal
quelle
Können Sie erklären, was die von Ihnen angegebenen Optionen bewirken?
Hawken
11
oder --targetstatt -b. -Dist "den Inhalt aller Abschnitte zerlegen"; -b bfdnameoder --target=bfdnameerzwingt das Lesen als angegebenes Objektcode-Format (in unserem Fall nicht elf, sondern rohe Binärdatei); -m machinegibt die zu verwendende Architektur an (in unserer Datei gibt es keinen Header mit Arch-Informationen). -M optionssind Optionen des Disassemblers; addr16,data16werden verwendet, um "die Standardadressgröße und die Operandengröße anzugeben" (behandeln Sie den Code als i8086 in der universellen x86-Disasm-Engine)
osgx
28

Das GNU-Tool heißt beispielsweise objdump :

objdump -D -b binary -m i8086 <file>
Sternenblau
quelle
Sie können auch verschiedene Optionen für die Architektur und die Syntax festlegen. Zum Beispiel -m i386oder -Mintel,x86-64. i8086ist eine alte Architektur und die Verwendung für modernen Code kann zu unerwarteten Ergebnissen führen. Darüber hinaus ist es heutzutage möglicherweise eine gute Idee , auf anzugeben x86-64, -Mda viele Computer 64-Bit-Computer sind. Vorbei intelan -MÄnderungen der Syntax zu Intel-Stil anstelle der Standard - AT & T - Stil, die Sie kann oder auch nicht.
GDP2
23

Ich mag ndisasmzu diesem Zweck. Es wird mit dem NASM-Assembler geliefert, der kostenlos und Open Source ist und in den Paket-Repositorys der meisten Linux-Distributionen enthalten ist.

asveikau
quelle
Diese Antwort gefällt mir besser. Einfacher zu bedienen und ich könnte nasm unter OS X installieren - objdump war nicht da und ich möchte es nicht aus dem Quellcode erstellen.
21
ndisasm -b16 -o7c00h -a -s7c3eh mbr

Erklärung - von der ndisasm-Manpage

  • -b= Gibt den 16-, 32- oder 64-Bit-Modus an. Der Standardwert ist der 16-Bit-Modus.
  • -o= Gibt die fiktive Ladeadresse für die Datei an. Diese Option bewirkt, dass ndisasm die aufgelisteten Adressen am linken Rand und die Zieladressen von PC-relativen Sprüngen und Aufrufen rechts abruft.
  • -a = Aktiviert den automatischen (oder intelligenten) Synchronisationsmodus, in dem ndisasm versucht, zu erraten, wo die Synchronisation durchgeführt werden soll, indem die Zieladressen der relativen Sprünge untersucht und zerlegt werden.
  • -s= Gibt manuell eine Synchronisationsadresse an, sodass ndisasm keinen Maschinenbefehl ausgibt, der Bytes auf beiden Seiten der Adresse umfasst. Daher wird der Befehl, der an dieser Adresse beginnt, korrekt zerlegt.
  • mbr = Die zu zerlegende Datei.
Jameslin
quelle
Was bedeutet dies im Gegensatz zu einfachem Ndisasmus? Können Sie die Optionen erklären
Hawken
4
Können Sie erklären, was diese Optionen bedeuten und bewirken? Eine Antwort zu verstehen ist besser als nur eine zu bekommen.
Schlitten
-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
14

starblue und hlovdal haben beide Teile der kanonischen Antwort. Wenn Sie rohen i8086-Code zerlegen möchten, möchten Sie normalerweise die Intel-Syntax und nicht auch die AT & T-Syntax. Verwenden Sie daher:

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

Wenn Ihr Code ELF (oder a.out (oder (E) COFF)) ist, können Sie die Kurzform verwenden:

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

Lassen Sie für 32-Bit- oder 64-Bit-Code das ,8086; Der ELF-Header enthält diese Informationen bereits.

ndisasm, wie von jameslin vorgeschlagen , ist ebenfalls eine gute Wahl, wird jedoch objdumpnormalerweise mit dem Betriebssystem geliefert und kann mit allen Architekturen umgehen, die von GNU-Binutils unterstützt werden (Obermenge der von GCC unterstützten Architekturen), und seine Ausgabe kann normalerweise in GNU eingespeist werden as(ndisasm's können normalerweise nasmnatürlich eingespeist werden ).

Peter Cordes schlägt vor: „ Das Objekt von Agner Fog ist sehr schön. Es bringt Beschriftungen auf Verzweigungsziele, wodurch es viel einfacher wird, herauszufinden, was der Code tut. Es kann in NASM-, YASM-, MASM- oder AT & T-Syntax (GNU) zerlegt werden. “

Multimedia Mike hat bereits davon erfahren --adjust-vma; das ndisasmÄquivalent ist das-o Option.

sh4Verwenden Sie dies zum Zerlegen von Code (ich habe zum Testen eine Binärdatei von Debian verwendet) mit GNU-Binutils (fast alle anderen Disassembler sind auf eine Plattform beschränkt, z. B. x86 mit ndisasmund objconv):

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

Das -mist die Maschine, und -ELbedeutet Little Endian (für den sh4ebEinsatz -EBstatt), die für die Architekturen von Bedeutung ist , die in beiden endianness existieren.

Mirabilos
quelle
2
Agner Fogs Objekt ist sehr schön. Es setzt Etiketten auf Zweig Ziele , viel einfacher zu Figur zu machen, was der Code tut. Es kann in NASM-, YASM-, MASM- oder AT & T-Syntax (GNU) zerlegt werden.
Peter Cordes
Für mich hat es unter GNU / Linux sofort einwandfrei funktioniert. Aber ja, im Gegensatz zu GNU-Binutils ist es nur x86 / x86-64. Es enthält jedoch viele nette x86-spezifische Hinweise, die als Kommentare hinzugefügt werden, z. B. wenn ein Präfix in Operandengröße einen LCP-Stillstand in den Decodern einer Intel-CPU verursachen kann. Erwähnen Sie es auf jeden Fall in Ihrer Antwort. Einer der Hauptzwecke von Kommentaren ist es, dem Poster zu helfen, seine Antwort zu verbessern, nicht nur als etwas, das spätere Zuschauer auch lesen müssen.
Peter Cordes
1
@ PeterCordes Ja gut, ich habe MirBSD als Hauptbetriebssystem;)
Mirabilos
@PeterCordes, aber es scheint, dass es keine rohen Binärdateien zerlegen kann, oder? Ich musste nur minimale ELF-Dateien erstellen, um eine Reihe von Anweisungen einspeisen zu können, aber vielleicht habe ich gerade eine Option verpasst?
Ruslan
1
@ Ruslan: IDK, interessante Frage. Normalerweise verwende ich nur objdump oder wenn ich Verzweigungsbezeichnungen möchte gcc -O3 -masm=intel -fverbose-asm -S -o- | less, da ich normalerweise versuche, die C-Quelle so zu optimieren, dass sie zu einem guten asm kompiliert.
Peter Cordes
8

Versuchen Sie diesen Befehl:

sudo dd if=/dev/sda bs=512 count=1 | ndisasm -b16 -o7c00h -
Jason
quelle