还剩1页未读,继续阅读
文本内容:
一种识别白噪声的方法off icessh1逆向工程中的应用随着网络普及,恶意软件的危害越来越大防病毒者使用各种方法来分析和检测程序是否恶意,逆向工程已成为一个重要的方面当前逆向工程的研究已取得长足的进展,但在某些方面还存在一些难题静态反汇编是逆向工程中对恶意程序进行静态分析的第一步,而病毒等恶意程序也往往使用各种方法来干扰、阻碍静态反汇编,比如使用各种代码混淆技术在代码混淆中call指令后插入数据便是一种常见的并且十分有效的迷惑反汇编器的方法目前流行的反汇编工具如Windbg,IDA pro都不能解决该问题2基于指令的反汇编在保留源程序语义和功能的条件下,所使用的一些使提取和理解逆向过程中得到的高级语言结构表示的结果更为困难的方法称为混淆本文所提到的call指令后插入混淆数据的情况在利用上述2种技术的同时综合了其他方法,主要采用如下2种形式1call指令后跟有用数据典型的如call指令后插入一段字符串由于call指令可以分解为压栈和无条件跳转2个动作,因此它后面的字符串的起始地址被压入堆栈,该字符串可被用来作为函数调用的参数,如图1的代码片断所示图1展示了常见的字符串定义方式与call指令后定义字符串的情况对于前者,一般的静态反汇编器都能够得到准确无误的反汇编结果;而大部分的反汇编器在对后者进行反汇编时,都将字符串错误地解码成指令,典型的如采用线性扫描算法的Windbg和采用递归分析算法的IDA,它们的反汇编结果见图2*表示反汇编出错此外,还可以对上述情况进行扩展,如可以使用几条连续这样的call指令来传递参数,也可以在定义字符串后进行出栈动作从而把字符串的首地址传递给寄存器或变量,示例代码片段见图32call指令后跟垃圾代码这种情况是在can指令后定义一些垃圾字节数据,见图4a o在程序运行过程中,call指令所调用的子过程在返回时使用push等指令修改栈顶的值从而修改返回地址使过程返回到了其他位置,而并不返回到call指令的下条指令执行此时是数据,但是这种方法却造成了反汇编的错误,IDA的反汇编结果见图4b o目前市场上的大部分反汇编器基本基于2种静态反汇编算法,即线性扫描算法和递归分析算法3算法1:生成补全、优解码为解决call指令后插入混淆数据带来的反汇编出错的问题,本文设计了统一的识别算法来解决该问题并识别出混淆数据首先,针对现有反汇编算法的缺陷并为了缩小问题的规模,本文采用了一种改进的递归分析算法,它与一般的递归分析算法的区别在于当遇到call指令时,对其进行分析,如需要则产生新的子过程,对子过程做标记,但并不立即对子过程进行解码,随后从call指令的下一条指令的地址继续解码;对其他控制转移指令的处理方法与一般的递归分析方法相同,这样直到整个程序解码结束最后对子过程依次再进行解码,并在解码过程中逐步建立起控制流图(CFG)该算法分为2个阶段,第1阶段是对call指令是否满足第1种形式的混淆做判断,第2阶段是在整个程序初步解码完成后对call指令是否满足第2种形式的混淆做判断具体流程如下第1阶段
(1)对call指令进行解码
(2)设call指令的目标地址为addr2,call指令的下一条指令(数据)的地址为addrl进行如下判断:若addr2-addrl的结果大于0且小于当前代码的长度C,转
(3),否则转
(7)
(3)取出addrl到addr2T范围内的每一个字节判断其是否为ASCH字符,是则转
(4),否则转
(7)
(4)add「2T地址处的字节是否为0(ASCII字符串以0结束),是则转
(5),否则转
(7)
(5)判断addr2后的指令是否是call指令或者非控制转移指令是则转
(6),否则转
(7)
(6)提取字符串,处理基本块信息从addr2继续解码
(7)从addrl继续解码图5给出了上述算法的流程第2阶段
(1)对子过程解码
(2)判断子过程是否是通过push压栈和ret返回的动作完成过程调用返回是则转
(3),否则转
(5)
(3)找到调用该子过程的call指令,设其下一条指令的地址为addr3,从全局常量地址表中寻找比addr3大的最小地址addr4进行判断:o若addr4-addr3的值大于0且小于一个常量值(插入的混淆数据应有限制,此处设为30),转
(4),否则转
(5)
(4)提取混淆数据,即为addr3到addr4范围内的数据清除解码错误的指令产生的基本块及控制流图信息
(5)继续对下一子过程解码,转
(1),直至所有的子过程解码结束图6给出了上述算法对应的流程算法依据如下
(1)算法第1阶段对call指令后字符串的识别主要依靠字符串的特征以0结尾并且每一个字节都是ASCII码字符,在长期的反汇编实践中,尚未发现满足上述条件并且可以解码为一段有意义的指令序列的情况,因此,该算法具有较强的适用性,另外在算法的第
(5)步又添加了一些附加条件(判断指令类型)来确保该方法对于识别call指令后保存有用字符串这种类型混淆的有效性
(2)算法第2阶段1)考虑常量地址表的构造,该地址表是在解码的同时对指令中涉及到的常量地址记录而得到的,恶意代码经常使用一些方法把标号或变量传递给寄存器,再对寄存器操作从而增加反汇编时数据分析的难度,因此,这个常量地址表的构造可以将这些地址记录下来,以便于判断是否存在混淆2)考虑子过程异常返回,即算法的第
(2)步所做的判断,大多数的病毒通常采用的技术是通过push和ret指令使控制流到达栈顶的值确定的地址,而一些高级的技术可以通过对这2条指令变形来达到同样的目的3)考虑call指令后混淆数据的确定,从常量地址表中确定了大于addr3的最小地址addr4后,并不能就此确定2个地址间就是混淆数据,必须要判断addr4-addr3的值,若为0表明call指令的下一条指令是正常的指令,若大于设定的范围,则表明call指令后是大量数据定义或者这条call指令本身是解码错误的经过对大量病毒的分析确定该值范围值为30Byte,这样可以保证该算法的准确性,减少误报的可能4)混淆数据的提取与错误解码指令的清除,解码错误的指令会导致基本块的划分以及控制流图的构造出错,因此,需要对它们产生的错误结果进行清除此时需要注意一种情况,解码错误的指令可能会涉及到后面的部分正常指令,这时候要对解错的指令重新进行解码4混合病毒的混淆情况本文所设计的算法在课题组设计的原形系统Radux(Reverse analysisfor detectingunsafeexecutables)中得到了应用,对几个知名病毒进行测试后,对call指令后混淆数据的识别情况如表1所示注:此处的混淆次数表示病毒使用的call指令后插入有用或垃圾数据的次数结果显示本算法在对call指令后混淆数据的识别方面是令人满意的5下一步研究内容混淆与反混淆的斗争有愈演愈烈的趋势,病毒制作者总是不断利用各种新的技术方法来对源程序进行混淆以增加静态分析的难度,而反病毒工作者也针锋相对,积极寻求新思路来应对新问题本文提出的算法对call指令后插入数据这一类的混淆能够很好的解决,可以应用在静态反汇编过程中,提高反汇编的正确率混淆手段是多种多样的,本文提出的算法也仅能解决一部分问题,而call指令后是非字符串或编码后的字符串以及子函数不以ret指令返回时的情况,将是下一步重点研究的内容总之,为了得到更好的反汇编结果,必须考虑使用多种方法来对抗混淆。