繁体   English   中英

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

[英]Using ndisasm in files of different architectures

我想将ndisasm用于大量不同体系结构( x86x64 )的文件。 我不知道-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)提供了相当不错的输出,但是它使用了.intel_syntax noprefix MASM的GNU .intel_syntax noprefix (有关MASM样式与NASM样式的更多信息,请参见intel-syntax标签wiki 。)

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

    (但是没有保留特殊的编码,例如.plt通常使用push imm32进行填充,即使在立即数较小的情况下,也可以使用,但是当NASM汇编push 0x1时,您将获得push imm8形式,因为objconv不会反汇编它来push strict dword 0x1 。)尽管如此,在大多数情况下它还是很好的,甚至将标签放在分支目标上,因此您可以轻松地找到循环的顶部。


如果您的某些二进制文件不是全部​​而是平坦的 ,则可以使用file查找不是二进制文件的二进制 file ,并将其提供给objconv 对于平坦的二进制文件,您可能必须尝试以多种方式分解并使用人工判断来确定代码是否看起来“合理”。

32位代码被分解为16的一个主要标志是,当32位立即数或寻址模式位移的结尾被解码为新指令的开始时。 通常这是一条add指令(操作码00 )。

对于64位和32位代码,最大的区别是REX前缀与单字节dec / inc指令。 如果您在32位反汇编中看到奇怪的dec / inc指令,则可能实际上是64位机器代码。 如果您看到奇怪的REX前缀(尤其是当反汇编程序显示rex add eax, ecx或其他内容以显示给您一个无用的REX前缀),则可能是32位机器代码中的单独的inc指令。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM