Linux 如何反汇编原始16位x86机器代码?

Linux 如何反汇编原始16位x86机器代码?,linux,assembly,x86,x86-16,mbr,Linux,Assembly,X86,X86 16,Mbr,我想反汇编我拥有的可引导x86磁盘的MBR(前512字节)。我已使用将MBR复制到一个文件中 dd if=/dev/my-device of=mbr bs=512 count=1 对于可以反汇编文件的Linux实用程序有什么建议吗?您可以使用objdump。根据语法是: objdump -D -b binary -mi386 -Maddr16,data16 mbr 为此,我喜欢NDISAM。它附带NASM汇编程序,它是免费的、开源的,包含在大多数linux发行版的软件包存储库中。GNU工具被

我想反汇编我拥有的可引导x86磁盘的MBR(前512字节)。我已使用将MBR复制到一个文件中

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

对于可以反汇编文件的Linux实用程序有什么建议吗?

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

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

为此,我喜欢NDISAM。它附带NASM汇编程序,它是免费的、开源的,包含在大多数linux发行版的软件包存储库中。

GNU工具被称为objdump,例如:

objdump -D -b binary -m i8086 <file>
objdump-D-b binary-mi8086
试试这个命令:

sudo dd if=/dev/sda bs=512 count=1 | ndisasm -b16 -o7c00h -
解释-来自NDISAM手册页

  • -b
    =指定16位、32位或64位模式。默认为16位模式
  • -o
    =指定文件的名义加载地址。此选项使NDISAM从左边空白处获取其列出的地址,并从右边获取PC相对跳转和呼叫的目标地址
  • -a
    =启用自动(或智能)同步模式,在该模式下,NDISAM将通过检查相对跳转的目标地址和其反汇编的调用,尝试猜测应在何处执行同步
  • -s
    =手动指定同步地址,这样NDISAM将不会输出任何包含地址两侧字节的机器指令。因此,从该地址开始的指令将被正确地反汇编
  • mbr
    =要反汇编的文件
而且两者都有部分标准答案。如果要反汇编原始i8086代码,通常需要英特尔语法,而不是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标头已包含此信息

正如所建议的那样,
ndisam
也是一个不错的选择,但是
objdump
通常随操作系统提供,可以处理GNU-binutils支持的所有架构(GCC支持的架构的超集),其输出通常可以作为
输入GNU
(当然,ndisam通常可以输入到
nasm

建议“非常好。它将标签放在分支目标上,使代码更容易理解。它可以分解为NASM、YASM、MASM或AT&T(GNU)语法。”

已了解
——调整vma
ndisam
等效项是
-o
选项

要反汇编,比如说,
sh4
代码(我使用了Debian的一个二进制代码进行测试),请将其与GNU binutils一起使用(几乎所有其他反汇编程序都限制在一个平台上,例如带有
ndisam
的x86和
objconv
):


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

我更喜欢这个答案。更易于使用,而且我可以在OS X上安装nasm-objdump不在那里,我不想从源代码构建它。与简单的NDISSM相比,这有什么作用?你能解释一下这些选项的含义和用途吗?理解一个答案比只得到一个要好。
-b指定16、32或64位模式。默认为16位模式。
-o是文件的名义加载地址。此选项使NDISSM从左边空白处获取其列出的地址,以及PC相对跳转和呼叫的目标地址(右侧)。
-s指定同步地址,这样NDISAM就不会输出任何包含地址两侧字节的机器指令。因此,从该地址开始的指令将被正确地反汇编。
您能解释一下您指定的选项是做什么的吗?或者
--target
而不是
-b
<代码>-D
是“分解所有章节的内容”
-b bfdname
--target=bfdname
将强制读取指定的目标代码格式(在本例中不是elf而是原始二进制)<代码>-m machine将指定要使用的体系结构(在我们的文件中没有包含arch info的头)
-M选项
是反汇编程序的选项
addr16、data16
用于“指定默认地址大小和操作数大小”(将代码视为通用x86 disasm引擎中的i8086代码)非常好。它将标签放在分支目标上,使了解代码的功能变得更加容易。它可以反汇编成NASM、YASM、MASM或AT&T(GNU)语法。但是是的,它只是x86/x86-64,不同于GNUBinautils。但是,它有许多特定于x86的提示,可以作为注释添加,比如操作数大小前缀可能导致Intel CPU的解码器出现LCP暂停。无论如何,在你的回答中提到它。评论的主要目的之一是帮助海报改进他们的答案,而不仅仅是后期观众需要阅读的内容。@PeterCordes是的,我将MirBSD作为主要操作系统;)@但它似乎不能反汇编原始二进制文件,不是吗?我必须创建最小的ELF文件,以便能够向其中输入大量指令,但也许我错过了一些选择?@Ruslan:IDK,有趣的问题。我通常只使用objdump,或者如果我想要分支标签,
gcc-O3-masm=intel-fverbose asm-S-o-| less
,因为我通常试图调整C源代码以编译成好的asm。您还可以为架构和语法设置不同的选项。例如,
-mi386
-Mintel,x86-64
i8086是一种古老的体系结构,将其用于现代代码可能会产生意想不到的结果。进一步的
objdump -D -Mintel,i8086 a.out  # disassembles the entire file
objdump -d -Mintel,i8086 a.out  # disassembles only code sections
objdump -D -b binary -m sh -EL x