前言
在之前写的《利用机器学习分析vmp的思路》中,把读写内存的操作数直接替换成了绝对地址的形式,这就产生了大量赋值语句,阅读起来也不是很友好。写这篇文章的主要目的是如何做进一步的优化,本篇文章用到了程序切片技术和编译原理中的一些优化算法,复制传播、死代码删除和有向无环图DAG的局部优化。
trace的处理
在之前写的文章基础上对trace增加了eflags寄存器的记录。利用程序切片技术提取了handle与写内存相关的指令后,通过一些简单的特征就可以处理该样本trace中所有的handle,所以本篇没有使用深度学习的方法对handle进行分类处理,深度学习也只是通过有标签的handle数据集代替了人工提取特征的过程。
trace处理后会得到以下文件:
NormalCode表示正常的代码,不需要对其优化处理,VmProcedureCode表示虚拟机中执行的代码,后面的数字表示执行的顺序。handle的识别和处理参考相应的代码
复制传播
复制传播(Copy Propagation)的思想:对于给定的关于某个变量v和s的赋值v=s,在没有出现其他关于v定值的程序范围内,可以用s来替代出现的v的引用。
handle处理后,trace中含有大量的mov语句,可以利用复制传播配合死代码消除处理掉冗余的mov语句。
比如有以下指令序列:
b=a
c=b
d=c
按照复制传播的思想,c可以用a代替,即d=a。如果c是不活跃的,那么c=b是可以删除的。
复制传播可以通过ud链(Use-Definition Chains)实现,ud链描述的是指令或语句中引用的变量可能定值点的位置。因为在很多情况下,一个定值是否能实际到达某一特定程序点是不可判定的,有时候需要依赖于特定的外部输入。当然,在trace中可以直接认为都是可到达的。ud链的构造可以通过到达定值分析实现,但是在trace中,可以认为语句之间是顺序执行的,ud链的构造只要向上遍历找到最后出现的对当前变量定值的语句即可。代码实现在VmProcedureCode类中的CopyPropagation和DeadCodeEliminatioin部分
在虚拟机的代码中,设定的活跃变量如下:
eax、ebx、ecx、edx、esi、edi、esp、eip、eflags寄存器
esp+4,对应虚拟机退出后的跳转地址,去执行正常函数
esp+8,正常函数执行完后的跳转地址,通常是虚拟机的入口
esp+12,可能是正常函数的参数一
esp+16,可能是正常函数的参数二
esp+20,可能是正常函数的参数三
esp+24,可能是正常函数的参数四
esp+28,可能是正常函数的参数五
esp+32,可能是正常函数的参数六
以VmProcedureCode0.txt中的最后几行代码为例
0x0076591d: mov eax, dword ptr [zxsq-anti
支付4UD,阅读全文
还有更多的精彩内容,作者设置为付费后可见