我想将 ndisasm 用于大量不同架构(x86 或 x64)的文件。我不知道 -b16 是否会为我提供所有文件的正确输出,或者我是否必须为每个文件指定正确的选项,例如 -b32 或 -b64强>。我正在运行的是从命令行知道的:
for file in *; do ndisasm -b16 -07c00h -a -s7c3eh "$file" > "/my-path/$file"; done
最佳答案
我建议不要使用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
进行填充,即使是小立即数,但你会得到push imm8
在 NASM 汇编push 0x1
时形成,因为objconv
不会将其反汇编为push strict dword 0x1
。)不过,它是大多数时候都很好,甚至在分支目标上贴上标签,这样您就可以轻松找到循环的顶部。
如果您的一些但不是所有二进制文件都是平面的,可以使用 file
找到不是的二进制文件并将它们提供给 objconv
。对于平面二进制文件,您可能必须尝试以多种方式反汇编并使用人为判断来确定代码是否看起来“正常”。
32 位代码被反汇编为 16 的一个主要标志是 32 位立即数或寻址模式位移的末尾被解码为新指令的开始。这通常是一个add
指令(操作码00
)。
对于 64 位代码和 32 位代码,一个很大的区别是 REX 前缀与单字节 dec
/inc
指令。如果您在 32 位反汇编中看到奇怪的 dec
/inc
指令,它可能实际上是 64 位机器代码。如果您看到奇怪的 REX 前缀(特别是当反汇编器说 rex add eax, ecx
或其他东西来告诉您有一个无用的 REX 前缀),它可能是一个单独的 inc
指令在 32 位机器代码中。
关于linux - 在不同架构的文件中使用 ndisasm,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47420776/