Como faço para desmontar código de máquina x86 de 16 bits bruto?

90

Gostaria de desmontar o MBR (primeiros 512 bytes) de um disco x86 inicializável que tenho. Copiei o MBR para um arquivo usando

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

Alguma sugestão de um utilitário Linux que pode desmontar o arquivo mbr?

Sigjuice
fonte

Respostas:

107

Você pode usar objdump. De acordo com este artigo, a sintaxe é:

objdump -D -b binary -mi386 -Maddr16,data16 mbr
Hlovdal
fonte
você pode explicar o que as opções especificadas fazem?
Hawken
11
ou em --targetvez de -b. -Dé "desmontar o conteúdo de todas as seções"; -b bfdnameou --target=bfdnameforçará a leitura como formato de código-objeto especificado (não elf, mas binário bruto em nosso caso); -m machineirá especificar a arquitetura a ser usada (em nosso arquivo não há cabeçalho com informações de arquitetura). -M optionssão opções de desmontador; addr16,data16são usados ​​para "especificar o tamanho do endereço padrão e o tamanho do operando" (trate o código como um i8086 no mecanismo universal x86 disasm)
osgx
28

A ferramenta GNU é chamada de objdump , por exemplo:

objdump -D -b binary -m i8086 <file>
azul da estrela
fonte
Você também pode definir opções diferentes para a arquitetura e a sintaxe. Por exemplo, -m i386ou -Mintel,x86-64. i8086é uma arquitetura antiga e usá-la para códigos modernos pode gerar resultados inesperados. Além disso, a especificação x86-64de -Mpode ser uma boa ideia hoje em dia, já que muitas máquinas são de 64 bits. Passar intelpara -Mmuda a sintaxe para o estilo Intel em vez do estilo AT&T padrão, que você pode ou não querer.
GDP2
23

Eu gosto ndisasmpara esse propósito. Ele vem com o NASM assembler, que é gratuito e de código aberto e incluído nos repositórios de pacotes da maioria das distros Linux.

Asveikau
fonte
Eu gosto mais dessa resposta. Mais fácil de usar e poderia instalar o nasm no OS X - objdump não estava lá, e não quero compilá-lo a partir do código-fonte.
21
ndisasm -b16 -o7c00h -a -s7c3eh mbr

Explicação - da página de manual do ndisasm

  • -b= Especifica o modo de 16, 32 ou 64 bits. O padrão é o modo de 16 bits.
  • -o= Especifica o endereço de carregamento nocional para o arquivo. Esta opção faz com que o ndisasm obtenha os endereços que lista na margem esquerda e os endereços de destino das chamadas e saltos relativos ao PC, à direita.
  • -a = Habilita o modo de sincronização automática (ou inteligente), no qual o ndisasm tentará adivinhar onde a sincronização deve ser realizada, por meio do exame dos endereços de destino dos saltos relativos e chama isso de desmontagem.
  • -s= Especifica manualmente um endereço de sincronização, de forma que ndisasm não produza nenhuma instrução de máquina que inclua bytes em ambos os lados do endereço. Portanto, a instrução que começa naquele endereço será desmontada corretamente.
  • mbr = O arquivo a ser desmontado.
Jameslin
fonte
o que isso faz em oposição ao simples ndisasm? Você pode explicar as opções
Hawken
4
Você poderia explicar o que essas opções significam e significam? Compreender uma resposta é melhor do que apenas obter uma.
Trenó de
-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 e hlovdal têm partes da resposta canônica. Se você deseja desmontar o código i8086 bruto, geralmente deseja a sintaxe Intel, não a sintaxe AT&T também, então use:

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

Se o seu código for ELF (ou a.out (ou (E) COFF)), você pode usar a forma abreviada:

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

Para código de 32 ou 64 bits, omita o ,8086; o cabeçalho ELF já inclui essas informações.

ndisasm, como sugerido por jameslin , também é uma boa escolha, mas objdumpgeralmente vem com o sistema operacional e pode lidar com todas as arquiteturas suportadas pelo GNU binutils (superconjunto daquelas suportadas pelo GCC), e sua saída geralmente pode ser alimentada no GNU as(ndisasm's geralmente podem ser alimentados em nasmembora, naturalmente).

Peter Cordes sugere que “ o objconv de Agner Fog é muito bom. Ele coloca rótulos em alvos de branch, tornando muito mais fácil descobrir o que o código faz. Ele pode ser desmontado em sintaxe NASM, YASM, MASM ou AT&T (GNU). ”

Multimídia que Mike já descobriu --adjust-vma; o ndisasmequivalente é a -oopção.

Para desmontar, digamos, sh4código (usei um binário do Debian para testar), use-o com binutils GNU (quase todos os outros desmontadores são limitados a uma plataforma, como x86 com ndisasme objconv):

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

O -mé a máquina e -ELsignifica Little Endian (para sh4ebuso em -EBvez disso), o que é relevante para arquiteturas que existem em qualquer endianness.

mirabilos
fonte
2
O objconv de Agner Fog é muito bom. Ele coloca rótulos em alvos de branch , tornando muito mais fácil descobrir o que o código faz. Ele pode ser desmontado em sintaxe NASM, YASM, MASM ou AT&T (GNU).
Peter Cordes
Para mim, ele foi criado bem fora da caixa no GNU / Linux. Mas sim, é apenas x86 / x86-64, ao contrário do GNU binutils. No entanto, ele tem muitas dicas específicas para x86 que adiciona como comentários, como quando um prefixo de tamanho de operando pode causar um travamento de LCP nos decodificadores de uma CPU Intel. Certamente, mencione-o em sua resposta. Um dos principais objetivos dos comentários é ajudar o autor da postagem a melhorar sua resposta, não apenas como algo que os espectadores posteriores também precisam ler.
Peter Cordes
1
@PeterCordes Sim, bem, tenho MirBSD como sistema operacional principal;)
mirabilos
@PeterCordes mas parece que não pode desmontar binários brutos, pode? Tive de criar arquivos ELF mínimos apenas para poder inserir um monte de instruções neles, mas talvez tenha esquecido alguma opção?
Ruslan
1
@Ruslan: IDK, pergunta interessante. Eu geralmente uso apenas objdump, ou se eu quiser rótulos de ramificação gcc -O3 -masm=intel -fverbose-asm -S -o- | less, já que normalmente estou tentando ajustar o código-fonte C para compilar em conjunto bom.
Peter Cordes
8

Tente este comando:

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