Respostas:
Você pode usar objdump. De acordo com este artigo, a sintaxe é:
objdump -D -b binary -mi386 -Maddr16,data16 mbr
--target
vez de -b
. -D
é "desmontar o conteúdo de todas as seções"; -b bfdname
ou --target=bfdname
forçará a leitura como formato de código-objeto especificado (não elf, mas binário bruto em nosso caso); -m machine
irá especificar a arquitetura a ser usada (em nosso arquivo não há cabeçalho com informações de arquitetura). -M options
são opções de desmontador; addr16,data16
sã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)
A ferramenta GNU é chamada de objdump , por exemplo:
objdump -D -b binary -m i8086 <file>
-m i386
ou -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-64
de -M
pode ser uma boa ideia hoje em dia, já que muitas máquinas são de 64 bits. Passar intel
para -M
muda a sintaxe para o estilo Intel em vez do estilo AT&T padrão, que você pode ou não querer.
Eu gosto ndisasm
para 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.
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.-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.
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 objdump
geralmente 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 nasm
embora, 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 ndisasm
equivalente é a -o
opção.
Para desmontar, digamos, sh4
có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 ndisasm
e objconv
):
objdump -D -b binary -m sh -EL x
O -m
é a máquina e -EL
significa Little Endian (para sh4eb
uso em -EB
vez disso), o que é relevante para arquiteturas que existem em qualquer endianness.
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.