如何反汇编原始 16 位 x86 机器代码?
- 2024-10-22 08:29:00
- admin 原创
- 63
问题描述:
我想反汇编我拥有的可启动 x86 磁盘的 MBR(前 512 个字节)。我已使用以下命令将 MBR 复制到一个文件中
dd if=/dev/my-device of=mbr bs=512 count=1
有没有什么可以反汇编该文件的 Linux 实用程序的建议mbr
?
解决方案 1:
您可以使用 objdump。根据这篇文章,语法是:
objdump -D -b binary -mi386 -Maddr16,data16 mbr
解决方案 2:
GNU 工具名为objdump,例如:
objdump -D -b binary -m i8086 <file>
解决方案 3:
我喜欢ndisasm
这个用途。它附带 NASM 汇编程序,它是免费的开源程序,包含在大多数 Linux 发行版的软件包存储库中。
解决方案 4:
ndisasm -b16 -o7c00h -a -s7c3eh mbr
解释- 来自 ndisasm 手册页
-b
= 指定 16 位、32 位或 64 位模式。默认为 16 位模式。-o
= 指定文件的名义加载地址。此选项使 ndisasm 获取其在左侧边缘列出的地址,以及右侧 PC 相关跳转和调用的目标地址。-a
= 启用自动(或智能)同步模式,在该模式下,ndisasm 将尝试通过检查相对跳转的目标地址并调用其反汇编来猜测应该在何处执行同步。-s
= 手动指定同步地址,这样 ndisasm 就不会输出任何包含该地址两侧字节的机器指令。因此,从该地址开始的指令将被正确反汇编。mbr
= 要反汇编的文件。
解决方案 5:
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 的 objconv非常棒。它为分支目标添加标签,使人们更容易理解代码的作用。它可以反汇编为 NASM、YASM、MASM 或 AT&T (GNU) 语法。”
多媒体 Mike已经发现了--adjust-vma
;ndisasm
等效于-o
选项。
例如,为了反汇编sh4
代码(我使用了 Debian 的一个二进制文件进行测试),请将其与 GNU binutils 一起使用(几乎所有其他反汇编程序都仅限于一个平台,例如带有ndisasm
和的x86 objconv
):
objdump -D -b binary -m sh -EL x
是-m
机器,-EL
意味着小端(代替sh4eb
使用-EB
),这与存在于任一字节序的体系结构相关。
解决方案 6:
尝试这个命令:
sudo dd if=/dev/sda bs=512 count=1 | ndisasm -b16 -o7c00h -
解决方案 7:
如果您只是想使用反汇编程序,那么 objdump 是一个选择。nasm 汇编程序附带的反汇编程序是 ndisasm。您也可以在 Linux 上的 DOS Box 中运行“debug.exe”,前提是您获得了该程序的副本。它还可以进行反汇编以及受控执行;即模拟 CPU 本身 - 这也很重要,即使在进行反汇编时也是如此,原因我将在下面描述。
Fake86 有一个 CPU 模拟器。您可以通过以下方式破解它,使其执行反汇编:(a) 让它显示指令而不是模拟指令;(b) 让它不进行条件跳转或调用,而是将地址堆叠为执行反汇编的新入口点(即,实际上同时进行分支和封装子例程);(c) 让它在无条件跳转或返回时停止当前反汇编;(d) 让它接受一个、两个或更多入口点,最好 (e) 让它也接受数据段的基址;(f) 让它对所有未处理为数据或代码段的区域进行十六进制转储(因为这些区域通常是间接跳转或调用或间接访问的数据段进入的地方)。
这涉及到您的查询的另一种含义:“我想制作一个反汇编程序”。ndisasm 的源代码是可用的,它可以处理 8086 的许多后代,而不仅仅是 8086 本身(如果您想要的只是 8086 甚至 80386 反汇编程序,这会严重混乱),但它不是独立的,并且严重依赖于发行版的其余部分。
它的主要论点是它使用八进制数字作为操作码 - 这更适合 80x86 - 正如我在 1995 年的 USENET 上的 comp.lang.asm 中指出的那样... 并且(事实上)nasm 的创建是对此的直接回应。因此,它可能更加透明,如果您正在制作自己的反汇编程序,您可能希望将源代码放在手边以备检查和比较。
您也可以自行运行 debug.exe 程序。
您还可以尝试在 debug.exe 上运行 ndisasm;在删除 0x200 字节的 .EXE 文件头后,使其成为原始二进制文件,然后从中提取入口点地址 CS:IP 和堆栈指针地址 SS:SP(80x86 堆栈向下增长,因此堆栈段名义上是 SS:0 到 SS:(SP-1))。debug.exe 的 EXE 没有重定位,因此您可以将代码视为原始二进制文件。
但是你不会得到任何清晰可辨的东西,因为该程序是自我修改的 - 更准确地说:自我提取。你将得到一个(勉强)压缩的代码映像(压缩率约为 5/6),后面跟着一个加载程序例程。
您必须对其进行模拟,例如通过在 debug.exe 上运行 debug.exe 来模拟其解包例程,使其自行提取,然后转储解包后的程序映像并对其进行反汇编。加载程序例程末尾有一个“重定位表”,因此它确实包含重定位 - 只是它们是在程序自行解包时应用的,而不是在加载 EXE 文件时由操作系统应用的。
然后,您就反汇编了一个反汇编程序,它恰好也能进行 CPU 模拟,就像 Fake86 一样 - 但只适用于 8086。您必须将绝对地址设为相对地址(使用原始重定位表作为指导),才能使其可重新组装。完成此操作后,您就可以处理源代码了。操作码表清晰可见(如果您将其显示为文本)- 无论是在打包版本还是解包版本的 debug.exe 中都可以看到。
GitHub 上还有 DosDebug。它可以处理“80586”(或 Pentium)和“80686”以下的所有内容:它会将某些指令标记为“6”代;例如,它可以处理条件“cmov”操作以及它们的“fcmov”浮点版本。DosDebug 是 8086 汇编语言,最适合用 jwasm 进行编译。您可能可以在其上运行 nasm,我不知道。我从未尝试过。
我可能会将 DAS 反汇编程序移植到 x86,因为项目 (a)-(f) 已经融入 DAS 的设计中。到目前为止,我只将它移植到 8051、6800、6809 和 8080/8085(和 Z80);但从 8085 到 8086 的转变相对较小。为此,我可能会从 Fake86 中破解一些东西。现在,这主要是废弃软件,因为作者用 XTulator 替换了它,因为 Fake86 是在程序员对 C 语言还比较陌生时编写的。您还可以直接从 DosDebug 的操作码表(它们的“instr.*”文件)中破解一些东西。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件