【发布时间】:2010-12-16 18:19:52
【问题描述】:
我想反汇编我拥有的可引导 x86 磁盘的 MBR(前 512 个字节)。我已将 MBR 复制到一个文件中使用
dd if=/dev/my-device of=mbr bs=512 count=1
对可以反汇编文件mbr的Linux实用程序有什么建议吗?
【问题讨论】:
标签: linux assembly x86 x86-16 mbr
我想反汇编我拥有的可引导 x86 磁盘的 MBR(前 512 个字节)。我已将 MBR 复制到一个文件中使用
dd if=/dev/my-device of=mbr bs=512 count=1
对可以反汇编文件mbr的Linux实用程序有什么建议吗?
【问题讨论】:
标签: linux assembly x86 x86-16 mbr
您可以使用 objdump。根据this article,语法是:
objdump -D -b binary -mi386 -Maddr16,data16 mbr
【讨论】:
--target 而不是 -b。 -D是“反汇编所有节的内容”; -b bfdname 或 --target=bfdname 将强制读取为指定的目标代码格式(在我们的例子中不是精灵,而是原始二进制文件); -m machine 将指定要使用的架构(在我们的文件中,没有包含拱信息的标题)。 -M options 是反汇编器的选项; addr16,data16 用于“指定默认地址大小和操作数大小”(在通用 x86 disasm 引擎中将代码视为 i8086 之一)
GNU 工具名为objdump,例如:
objdump -D -b binary -m i8086 <file>
【讨论】:
-m i386 或 -Mintel,x86-64。 i8086 是一种旧架构,将其用于现代代码可能会产生意想不到的结果。此外,现在将x86-64 指定为-M 可能是一个好主意,因为许多机器都是64 位的。将 intel 传递给 -M 会将语法更改为 Intel 样式,而不是您可能想要也可能不想要的默认 AT&T 样式。
为此,我喜欢ndisasm。它带有 NASM 汇编器,它是免费和开源的,并且包含在大多数 linux 发行版的软件包存储库中。
【讨论】:
ndisasm -b16 -o7c00h -a -s7c3eh mbr
解释 - 来自 ndisasm 手册页
-b = 指定 16、32 或 64 位模式。默认为 16 位模式。-o = 指定文件的名义加载地址。此选项使 ndisasm 获取它在左边距下列出的地址,以及与 PC 相关的跳转和调用的目标地址,右边。-a = 启用自动(或智能)同步模式,在这种模式下,ndisasm 将通过检查相对跳转的目标地址并调用它反汇编来尝试猜测应该在哪里执行同步。-s = 手动指定同步地址,这样 ndisasm 将不会输出包含地址两侧字节的任何机器指令。因此,从该地址开始的指令将被正确反汇编。mbr = 要反汇编的文件。【讨论】:
-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 和 hlovdal 都有部分规范答案。如果你想反汇编原始 i8086 代码,你通常需要 Intel 语法,而不是 AT&T 语法,所以使用:
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 标头已包含此信息。
ndisasm,正如jameslin 所建议的,也是一个不错的选择,但objdump 通常是操作系统自带的,可以处理GNU binutils 支持的所有架构(GCC 支持的超集),以及它的输出通常可以输入到 GNU as(当然,ndisasm 通常可以输入到nasm)。
Peter Cordes 建议“Agner Fog's objconv 非常好。它将标签放在分支目标上,从而更容易弄清楚代码的作用。它可以反汇编成 NASM、YASM、MASM 或 AT&T (GNU) 语法。”
Multimedia Mike 已经发现了--adjust-vma; ndisasm 等效项是 -o 选项。
要反汇编,比如说,sh4 代码(我使用 Debian 的一个二进制文件进行测试),将其与 GNU binutils 一起使用(几乎所有其他反汇编程序都仅限于一个平台,例如 x86 与 ndisasm 和 objconv ):
objdump -D -b binary -m sh -EL x
-m 是机器,-EL 表示 Little Endian(sh4eb 使用 -EB 代替),这与存在于任一字节序中的架构相关。
【讨论】:
gcc -O3 -masm=intel -fverbose-asm -S -o- | less,因为我通常会尝试将 C 源代码调整为编译为好的 asm。
试试这个命令:
sudo dd if=/dev/sda bs=512 count=1 | ndisasm -b16 -o7c00h -
【讨论】: