在不同体系结构的文件中使用ndisasm

时间:2017-11-21 19:04:21

标签: linux assembly cpu-architecture disassembly

我想将 ndisasm 用于大量不同架构的文件( x86 x64 )。我不知道 -b16 是否会为所有文件提供正确的输出,或者我是否必须为每个文件指定正确的选项,例如 -b32 -b64 即可。我正在运行的是从命令行知道的:

for file in *; do ndisasm -b16 -07c00h -a -s7c3eh "$file" > "/my-path/$file"; done

1 个答案:

答案 0 :(得分:0)

我建议使用ndisasm,除非你确实有平的二进制文件。它将整个文件(包括元数据)视为指令。

x86机器代码是可变长度的,需要从正确的起始地址解码为“同步”。例如如果元数据的最后几个字节解码为长指令的开始,那就是ndisasm将解码它们的方式。这将占用对象或可执行文件中应该是机器代码的第一条指令的前几个字节。之后,当前位置可能在另一条指令的中间。

解码通常会很快恢复同步,并与指令的实际执行方式保持一致,但是如果您要运行大批量反汇编,您也可以使用能够正确执行此操作的工具。

以下两个反汇编程序都了解目标文件格式,并根据文件类型选择了一种模式。 (例如,对于x86-64 ELF或PE-COFF对象/可执行文件的x86-64模式)。

  • objdump -drwC -Mintel(来自GNU binutils)输出相当不错,但它使用类似MASM的GNU .intel_syntax noprefix。 (有关MASM风格与NASM风格的更多信息,请参阅the intel-syntax tag wiki。)

  • Agner Fog's objconv disassembler非常好,可以反汇编为NASM / YASM语法,MASM或AT& T. Example of using it。输出包含所有额外信息作为注释,因此您可以将其提供给汇编程序并获得类似于您开始使用的二进制文件,包括不同的部分。

    (但是不保留特殊编码,例如.plt通常使用push imm32进行填充,即使是小的立即数,但是当NASM汇编{{1}时,您将获得push imm8形式因为push 0x1没有将它反汇编到objconv。)但是,它在大多数情况下都非常好,甚至可以在分支目标上放置标签,这样您就可以轻松找到循环的顶部。 / p>

如果您的某些二进制文件不是很平常,可以使用push strict dword 0x1查找不符合条件的文件<{1}}。对于平面二进制文件,您可能必须尝试拆分多种方式并使用人为判断来判断代码是否看起来“合理”。

将32位代码反汇编为16的一个主要标志是当32位立即或寻址模式位移的结束被解码为新指令的开始时。通常这是file指令(操作码objconv)。

对于64位与32位代码,一个很大的区别是REX前缀与单字节add / 00指令。如果您在32位反汇编中看到奇怪的dec / inc指令,那么它实际上可能是64位机器代码。如果您看到奇怪的REX前缀(特别是当反汇编程序说dec或某些东西向您显示有无用的REX前缀时),它可能是32位机器代码中的单独inc指令。