Assembly IDA pro如何从二进制文件创建汇编代码? 如何从已编译的二进制文件创建程序集?

Assembly IDA pro如何从二进制文件创建汇编代码? 如何从已编译的二进制文件创建程序集?,assembly,binaryfiles,ida,Assembly,Binaryfiles,Ida,我正在学习x86汇编编程。所以我开始了解gdb、objdump和IDA pro,这些程序都是从二进制文件创建程序集的。我想知道它们是如何从二进制文件创建程序集的?当我在记事本中打开二进制文件时,它会显示很多符号、数字和字母。我的疑问是,他们如何从编译的二进制文件创建程序集 汇编与机器代码1(大致)有1:1的对应关系,因此根据原则,反汇编没有什么太复杂的事情:一旦你有了一块机器代码和它必须加载的地址,你就从第一条指令开始并开始解码 在RISC体系结构上,这项工作通常更容易,因为机器指令通常具有固定

我正在学习x86汇编编程。所以我开始了解gdb、objdump和IDA pro,这些程序都是从二进制文件创建程序集的。我想知道它们是如何从二进制文件创建程序集的?当我在记事本中打开二进制文件时,它会显示很多符号、数字和字母。我的疑问是,他们如何从编译的二进制文件创建程序集

汇编与机器代码1(大致)有1:1的对应关系,因此根据原则,反汇编没有什么太复杂的事情:一旦你有了一块机器代码和它必须加载的地址,你就从第一条指令开始并开始解码

在RISC体系结构上,这项工作通常更容易,因为机器指令通常具有固定大小,通常非常规则——“经典”ARM和PowerPC,例如,使用固定大小的32位指令,其中部分位指定汇编指令、参数等。在x86上,情况更为复杂,这既因为它是一个可变长度的指令集,也因为它随时间不规则地发展

通常,汇编指令由一个或多个前缀字节组成(可转换回汇编前缀,如
rep
lock
,指定指令操作的数据段或大小与默认值不同,或选择一个不同的子指令集-参见例如VEX前缀),一个操作码(一个字节,指定指令加上可能的部分参数),然后是参数(有一种规则的编码,用于指定立即数、寄存器或内存操作数及其各种寻址模式)。有关通用x86指令格式的更详细说明,请参阅(通常指该站点)

一旦对指令进行解码,反汇编程序就必须解析相对地址/跳转(将它们应用于代码中的当前位置)并发出相应的程序集,可能会为跳转目标生成标签名(或者只是将跳转目标保留为普通地址)

现在,这只是低级部分,“原始”反汇编程序(如
ndisam
)可以做的。但是,除了特殊情况(如MS-DOS中的COM文件)外,可执行文件不仅仅是CPU要执行的原始代码,而是更结构化的二进制格式

通常,一个可执行文件包含多个部分,这些部分可以包含不同类型的数据。通常有一个部分用于汇编代码(通常称为
.text
),另外还有几个部分用于程序数据(可变和不可变、零初始化、合并资源等)加之加载程序的其他附件信息,如来自动态链接库的依赖项和重新定位信息。更复杂的可执行检查工具(如objdump、nm或dumpbin)可以解析可执行格式,解码其结构,并在需要时反汇编在代码部分找到的代码

除此之外,诸如IDA之类的工具还添加了相当多的智能—它们解析可执行格式,部分执行加载程序的工作(对代码应用重定位),反汇编代码并对其执行大量分析—它尝试跟踪代码流,传播类型信息(如果可用)(通常从OS API开始,其入口点众所周知),检查对全局数据的访问模式以推断其类型


  • 也就是说,减去注释和“高级”功能,例如宏、标签名和跳转,将计算目标地址的最佳方法留给汇编程序。此外,还有同义指令之间的区别(例如,
    je
    /
    jz
    )显然丢失了-在解码操作码时,反汇编程序通常只会发出一个可能的同义词

  • 更简洁的回答是,IDA Pro是一个“递归下降”工具。这意味着,在识别二进制头和节之后,它开始从文本段开始(更具体地说,在入口点)反汇编代码。然后,它将开始跟随分支,在代码中递归递减,尝试识别和跟随这些分支,而不是简单地假设代码从文本段开始按顺序对齐


    这非常好用,不像线性分解那样容易混淆,但它仍然不能通过跳转表和其他动态计算的分支跟踪分支。

    用记事本打开非文本文件没有用。这些文件都是字节,但一些恰好在ASCII范围内,而另一些不在ASCII范围内。这只是一种错误有些字节显示为数字和字母。IDA所做的事情非常复杂,这就是为什么程序如此昂贵的原因。