反汇编引擎初探

Posted on 2021-08-31  23 Views


反汇编引擎简介

反汇编引擎的作用是将机器码解析成汇编指令,在逆向工程中起着巨大的作用。目前主流的开源x86-64引擎有ODDisasm、BeaEngine、Udis86、Capstone,汇编引擎有ODAssembler、Keystone、AsmJit。

ODDisasm

ODDisasm是著名动态调试软件od所使用的反汇编引擎,优点是可以将文本字符串解析并编码成二进制值。但他的缺点很多,例如因为已经停止更新所以支持的指令集不全,解码得到的结构也不够详细,最重要的是他不支持使用64伪指令的汇编和反汇编。所以,这是一款优秀但已经落后时代的反汇编引擎 源码下载地址:http://www.ollydbg.de/disasm.zip

BeaEngine

这款引擎没有明显的缺点,能解析的拓展指令集有

FPU、MMX、SSE、SSE2、SSE3、SSSE3、SSE4.1、SSE4.2、VMX、CLMUL、AES、MPX。

BeaEngine对指令进行了分类,以便判断不同的指令。他还有一个特点是可以解码每一条指令所使用和影响的寄存器,包括标志位寄存器,甚至能精确解码标志位寄存器的所有位置,这个功能用来做优化器和混淆器是很有优势的。BeaEngine除了支持X86,也支持x64反汇编。 该项目开源地址github :https://github.com/BeaEngine/beaengine

Udis86

这是一款广受欢迎的汇编引擎,支持的x86扩展指令集包括

MMX、FPU(x87)、AMD3DNow!、SSE、SSE2、SSE3、SSSE3、SSE4.1、SSE4.2、AES、AMD-V、INTEL-VMX、SMX。他同时支持x86与x64的反汇编。

Udis86的优点是接口灵活,可以使用ud_decode函数对一条指令只进行解码操作,再对解码后的结构使用ud_translate_intel函数转换成文本格式,也可以直接使用ud_disassemble函数一次性完成所有操作,这些接口都只要一行代码就能实现。 他的这种设计理念使其在拥有强大适应能力的同时兼顾了性能。再解码细节和能力相近的情况下Udis86是解码速度最快的反汇编引擎。 开源地址:https://github.com/vmt/udis86

Capstone

Capstone被称为如今世界上最优秀的反汇编引擎,被许多著名的项目使用,例如ida。 它支持CPU构架有: Arm, Arm64 (Armv8), M68K, Mips, PowerPC, Sparc, SystemZ, XCore & X86 (包括 X86_64) 而且Capstone对X86构架的指令集支持是最全的,这一点是其他引擎都比不上的,其支持的X86扩展指令集有:

3dnow, 3dnowa, x86_64, adx, aes, atom, avx, avx2, avx512cd, avx512er, avx512f, avx512pf, bmi, bmi2, fma, fma4, fsgsbase, lzcnt, mmx, sha, slm, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, xop.

无论是解码能力还是指令集支持,Capstone都是非常强大的,但因为解码过程的复杂,对性能造成了一定的影响,内存消耗也比较大。 官方网站:http://www.capstone-engine.org/

Udis86、BeaEngine、Capstone 比较分析

性能:udis86 > BeaEngine > capstone 解码能力 :capstone > BeaEngine > udis86 (udis86不支持寄存器分析,其余解码能力是相近的) 平台支持:capstone > (udis86 = BeaEngine) X86扩展指令集:capstone > (udis86 ≈BeaEngine)

浅析反汇编引擎工作原理

反汇编,顾名思义就是将机器码翻译为对应的汇编指令,翻译的过程需要参考CPU的指令集,还需要根据不同的可执行文件找到对应的格式标准,找到代码段和数据段

x86平台下的汇编指令对应的机器码为inter指令集,可以通过他进行了解反汇编引擎大致的工作原理

Inter指令手册中个描述的指令由6部分组成

有些不太理解具体的工作流程,先记下来以后再看

INSTRUCTION PREFIXESOPCODEMODE R/MSIB DISPLACEMENTIMMEDIATE
指令前缀指令操作码操作数类型辅助Mode R/M,计算地址偏移立即数
  • instruction prefixes:指令前缀 这是一个可选的参数,是作为指令的补助说明存在,主要用于以下四种情况。 重复指令:如REP、REPE\REPZ 跨段指令: 如 mov dword ptr fs:[ ] ,0 将操作数从32位转为16位:如 mov ax,word ptr ds:[ eax ] 将地址从16位转为32位
  • opcode :指令操作码 opcode为机器码中操作符的部分,用来说明指令语句执行什么样的操作,如某条指令是mov,jmp还是call。opcode是唯一必不可少的参数。 汇编指令与opcode是一一对应的关系。 因为操作数的不同,所占长度也不同,因此对于非单字节指令来说,解析一条汇编指令还需要mode r\m、sib、dislacement的帮助
  • Mode R/M:操作数类型mode r/m 是辅助opcode解析汇编指令助记符后的操作数类型,R表示寄存器,M表示内存单元,
  • SIB:辅助Mode R/M ,计算地址偏移sib的寻址方式为基址+变址,如mov eax,dword ptr ds:[ ebx + ecx * 2 ],其中的ecx、乘数2都是由sib来指定的
  • displacement:辅助Mode R/M ,计算地址偏移displacement用于辅助sib,如mov eax,dword ptr ds:[ ebx + ecx * 2 + 3 ]这条指令中的 “ + 3 ” 就是由displacement来指定的
  • immediate :立即数 用于结束指令语句中操作数为一个常量值的情况

反汇编引擎通过查表将由以上6种方案组合而成的机器指令编码,解释为对应的汇编指令,从而完成了机器码的转换工作。


欢迎来到parafish的个人博客,这里是一个正在努力的ctfer

路虽远,行则必至