Comment désassembler le code machine x86 16 bits brut?


91

Je voudrais démonter le MBR (512 premiers octets) d'un disque x86 amorçable que j'ai. J'ai copié le MBR dans un fichier en utilisant

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

Des suggestions pour un utilitaire Linux qui peut désassembler le fichier mbr?

Réponses:


109

Vous pouvez utiliser objdump. Selon cet article, la syntaxe est:

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

pouvez-vous expliquer ce que font les options que vous spécifiez?
Hawken

11
ou --targetau lieu de -b. -Dest "démonter le contenu de toutes les sections"; -b bfdnameou --target=bfdnameforcera la lecture au format de code objet spécifié (pas elf mais binaire brut dans notre cas); -m machinespécifiera l'architecture à utiliser (dans notre fichier il n'y a pas d'en-tête avec des informations sur l'archive). -M optionssont des options de désassembleur; addr16,data16sont utilisés pour "spécifier la taille de l'adresse par défaut et la taille de l'opérande" (traiter le code comme i8086 dans le moteur de désasme universel x86)
osgx

29

L'outil GNU s'appelle objdump , par exemple:

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

Vous pouvez également définir différentes options pour l'architecture et la syntaxe. Par exemple, -m i386ou -Mintel,x86-64. i8086est une architecture ancienne et son utilisation pour du code moderne peut donner des résultats inattendus. De plus, spécifier x86-64à -Mpourrait être une bonne idée de nos jours, car de nombreuses machines sont 64 bits. Passer intelà -Mmodifie la syntaxe en style Intel au lieu du style AT&T par défaut, ce que vous pouvez ou non vouloir.
GDP2

24

J'aime à ndisasmcet effet. Il est livré avec l'assembleur NASM, qui est gratuit et open source et inclus dans les référentiels de packages de la plupart des distributions Linux.


J'aime mieux cette réponse. Plus facile à utiliser, et j'ai pu installer nasm sur OS X - objdump n'était pas là, et je ne veux pas le construire à partir des sources.

22
ndisasm -b16 -o7c00h -a -s7c3eh mbr

Explication - de la page de manuel ndisasm

  • -b= Spécifie le mode 16, 32 ou 64 bits. La valeur par défaut est le mode 16 bits.
  • -o= Spécifie l'adresse de chargement fictive du fichier. Cette option permet à ndisasm d'obtenir les adresses qu'il répertorie dans la marge de gauche et les adresses cibles des sauts et des appels relatifs au PC, à droite.
  • -a = Active le mode de synchronisation automatique (ou intelligente), dans lequel ndisasm tentera de deviner où la synchronisation doit être effectuée, en examinant les adresses cibles des sauts relatifs et en l'appelant à la désassemblage.
  • -s= Spécifie manuellement une adresse de synchronisation, de sorte que ndisasm ne sortira aucune instruction machine englobant des octets des deux côtés de l'adresse. Par conséquent, l'instruction qui commence à cette adresse sera correctement démontée.
  • mbr = Le fichier à désassembler.

qu'est-ce que cela fait par opposition au simple ndisasme? Pouvez-vous expliquer les options
Hawken

4
Pourriez-vous expliquer ce que signifient et font ces options? Il vaut mieux comprendre une réponse que simplement en obtenir une.
Traîneau du

-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

starblue et hlovdal ont tous deux des parties de la réponse canonique. Si vous souhaitez démonter du code i8086 brut, vous voulez généralement la syntaxe Intel, pas la syntaxe AT&T, alors utilisez:

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

Si votre code est ELF (ou a.out (ou (E) COFF)), vous pouvez utiliser la forme courte:

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

Pour le code 32 bits ou 64 bits, omettez le ,8086; l'en-tête ELF contient déjà ces informations.

ndisasm, comme suggéré par jameslin , est également un bon choix, mais il objdumpest généralement fourni avec le système d'exploitation et peut gérer toutes les architectures prises en charge par GNU binutils (un sur-ensemble de celles prises en charge par GCC), et sa sortie peut généralement être introduite dans GNU as(ndisasm peut généralement être introduit nasmcependant, bien sûr).

Peter Cordes suggère que « l'objconv d'Agner Fog est très gentil. Il met des étiquettes sur les cibles de branche, ce qui facilite beaucoup la compréhension de ce que fait le code. Il peut être désassemblé dans la syntaxe NASM, YASM, MASM ou AT&T (GNU). »

Multimédia Mike a déjà découvert --adjust-vma; l' ndisasméquivalent est l' -ooption.

Pour désassembler, disons, du sh4code (j'ai utilisé un binaire de Debian pour tester), utilisez ceci avec les binutils GNU (presque tous les autres désassembleurs sont limités à une plate-forme, comme x86 avec ndisasmet objconv):

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

Le -mest la machine, et -ELsignifie Little Endian (à sh4ebutiliser à la -EBplace), ce qui est pertinent pour les architectures qui existent dans les deux endianness.


2
L'objconv d'Agner Fog est très gentil. Il met des étiquettes sur les cibles de branche , ce qui facilite beaucoup la compréhension de ce que fait le code. Il peut se désassembler en syntaxe NASM, YASM, MASM ou AT&T (GNU).
Peter Cordes

Il s'est bien construit dès sa sortie de la boîte sur GNU / Linux, pour moi. Mais oui, c'est uniquement x86 / x86-64, contrairement aux binutils GNU. Cependant, il a beaucoup de jolis indices spécifiques à x86 qu'il ajoute en tant que commentaires, comme lorsqu'un préfixe de taille d'opérande peut provoquer un blocage LCP dans les décodeurs d'un processeur Intel. Par tous les moyens, mentionnez-le dans votre réponse. L'un des principaux objectifs des commentaires est d'aider l'affiche à améliorer sa réponse, pas seulement comme quelque chose que les téléspectateurs ultérieurs doivent également lire.
Peter Cordes

1
@PeterCordes Oui, j'ai MirBSD comme système d'exploitation principal;)
mirabilos

@PeterCordes mais il semble qu'il ne peut pas démonter les binaires bruts, n'est-ce pas? J'ai dû créer des fichiers ELF minimaux juste pour pouvoir y insérer un tas d'instructions, mais peut-être ai-je simplement manqué une option?
Ruslan

1
@Ruslan: IDK, question intéressante. J'utilise généralement simplement objdump, ou si je veux des étiquettes de branche gcc -O3 -masm=intel -fverbose-asm -S -o- | less, car j'essaie généralement de modifier la source C pour la compiler en un bon asm.
Peter Cordes

9

Essayez cette commande:

sudo dd if=/dev/sda bs=512 count=1 | ndisasm -b16 -o7c00h -
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.