2009-11-15 148 views
74

我想反汇编我有的可启动x86磁盘的MBR(前512字节)。我抄了MBR到使用Linux的实用工具,可以拆卸文件mbr如何反汇编原始x86代码?

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

任何建议文件?

回答

89

您可以使用objdump。据this article语法是:

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

你能解释一下你指定的选项吗? – Hawken 2012-11-17 14:18:13

+10

或'--target'而不是'-b'。 '-D'是“反汇编所有部分的内容”; '-b bfdname'或'--target = bfdname'会强制读取指定的目标代码格式(在我们的例子中不是精灵,而是原始二进制); '-m machine'将指定要使用的体系结构(在我们的文件中没有包含arch info的标题)。 '-M options'是反汇编的选项; 'addr16,data16'用于“指定默认地址大小和操作数大小”(在通用x86 disasm引擎中将代码视为i8086) – osgx 2012-11-28 16:41:25

18

我喜欢ndisasm用于这一目的。它带有NASM汇编程序,它是免费的,开源的,并且包含在大多数Linux发行版的软件包仓库中。

+0

我更喜欢这个答案。更容易使用,我可以在OS X上安装nasm - objdump不在那里,我不想从源代码构建它。 – 2012-10-28 13:12:40

+0

@ H2CO3 NASM通常预装在OS-X上... – Hawken 2012-11-17 03:42:19

26

GNU工具被称为objdump的,例如:

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

您还可以为体系结构和语法设置不同的选项。例如,'-m i386'或'-Mintel,x86-64'。 'i8086'是一种古老的架构,将其用于现代代码可能会产生意想不到的结果。此外,现在指定'x86-64'为'-M'可能是一个好主意,因为许多机器都是64位的。将'intel'传递给'-M'会将语法更改为Intel风格,而不是默认的AT&T风格,您可能会也可能不想要。 – GDP2 2018-03-05 03:04:50

7

须藤DD如果=/dev/sda上BS = 512计数= 1 | ndisasm -b16 -o7c00h -

16
ndisasm -b16 -o7c00h -a -s7c3eh mbr 

说明 - 从ndisasm手册页

  • -b =指定16,32或64位模式。默认值是16位模式。
  • -o =指定文件的名义加载地址。这个选项会导致ndisasm得到它在左边空白处列出的地址,以及PC相对跳转和调用的目标地址。
  • -a =启用自动(或智能)同步模式,其中ndisasm将尝试通过检查相对跳转的目标地址并调用它进行反汇编来猜测应执行同步的位置。
  • -s =手动指定一个同步地址,这样ndisasm将不会输出包含地址两边字节的任何机器指令。因此,从该地址开始的指令将被正确拆卸。
  • mbr =需要反汇编的文件。
+0

与简单的ndisasm相比,这是做什么用的?你能解释一下选项吗 – Hawken 2012-11-17 14:16:12

+4

你能解释一下这些选项的含义吗?理解答案比只取得答案要好。 – ArtB 2012-11-17 17:33:04

+0

'-b指定16,32或64位模式。缺省值是16位模式。“-o是文件的名义加载地址。这个选项 导致ndisasm得到它在左边 余量中列出的地址,以及PC相对跳转和调用的目标地址, right。“-s指定同步地址,使得ndisasm 将不输出任何机器指令包含地址两侧的字节 。因此,在该地址开始 的指令将被正确拆卸。' – 2013-05-06 18:49:59

8

starblue and hlovdal都有部分规范的答案。如果要拆卸的原始i8086代码,通常希望英特尔的语法,而不是在& 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's通常可以输入到nasm中)。

Peter Cordes表明“Agner Fog's objconv是非常好的。它将标签放在分支目标上,使得更容易弄清代码的作用。它可以反汇编为NASM,YASM,MASM或T(GNU)语法。“

Multimedia Mike已经发现约--adjust-vma;等效的ndisasm-o选项。

为了拆卸,比方说,sh4代码(I使用的一个二进制从Debian的测试),使用此具有GNU binutils的(几乎所有其他反汇编限于一个平台,例如x86与ndisasmobjconv):

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

-m是机器,并-EL意味着小端(对于sh4eb使用-EB代替),这是相关的存在于任一端序架构。

+2

[Agner Fog's objconv](http://agner.org/optimize/)非常好。它将标签放在分支*目标*上,使得更容易弄清楚代码的作用。它可以反汇编成NASM,YASM,MASM或AT&T(GNU)语法。 – 2015-12-23 04:05:54

+0

它在GNU/Linux上为我开箱即可使用。但是,是的,它只是x86/x86-64,不像GNU binutils。但是,它有很多很好的x86特有提示,它们会作为注释添加,比如操作数大小的前缀会导致英特尔CPU解码器中的LCP停顿。通过一切手段,在你的答案中提及它。评论的主要目的之一是帮助海报改善他们的答案,而不仅仅是后来观众需要阅读的内容。 – 2015-12-23 11:11:03

+1

@PeterCordes是的,我有MirBSD作为主要操作系统;) – mirabilos 2015-12-23 11:35:23