一种基于树优化的程序依赖关系分析方法及系统的制作方法

文档序号:6538058阅读:210来源:国知局
一种基于树优化的程序依赖关系分析方法及系统的制作方法
【专利摘要】本发明涉及一种基于树优化的程序依赖关系分析方法及系统,该方法包括:步骤1,将函数中的连续指令划分为多个基本块,每个基本块仅有单一入口和单一出口;步骤2,针对每个基本块构建相应的指令依赖树和指令依赖森林;步骤3,分析指令依赖树和指令依赖森林,去除未改变原状态的指令,去除依赖于特殊寄存器的指令依赖树;步骤4,从前一基本块中去除在其后续各基本块中有重复定义但未被使用的变量对应的指令依赖树;步骤5,选取内存索引中不能静态计算寄存器值的指令所在的位置,将该指令位置之前的位置作为动态插装位置;步骤6,在所有动态插装位置上插装统一化的影子指令。本发明无需对每条指令进行插装,有效提高了程序动态分析的效率。
【专利说明】一种基于树优化的程序依赖关系分析方法及系统【技术领域】
[0001]本发明涉及程序分析【技术领域】,特别是涉及一种基于树优化的程序依赖关系分析方法及系统。
【背景技术】
[0002]程序依赖关系分析通常被用来检测变量是否受输入数据影响,也可以用来跟踪输入数据的传播过程。这个方法在检测攻击和漏洞方面应用非常广泛,已经成为软件分析领域的重要方法。
[0003]程序依赖关系分析支持静态和动态分析。静态分析方法效率较高,但是精确度不足,因为需要估计间接内存地址和间接跳转/调用的值。动态分析方法在二进制代码分析中较为流行,通常是通过插装指令来实现分析,但通过这种方法每个插装的指令执行都要消耗额外的执行时间,这个时间通常是正常执行的数倍。
[0004]分析人员尝试很多方法来提高程序依赖关系分析的效率,主要是基于硬件的方法和基于编译器的方法。
[0005]一、对于基于硬件的方法,虽然可极大提高分析的运行性能,但是并不是所有的系统都支持这类硬件。而且,在硬件中修改传播规则也不容易。
[0006]二、对于基于编译器的方法,通常依据一些策略从源程序中选择部分语句进行程序依赖关系分析。通过减少需要分析语句的数量,来提高传播速度。但是,这些方法通常会遭遇一个或多个如下的缺陷:a)只有其中一部分与某些预定策略相关的指令会被选择进行依赖关系分析。一旦这些策略发生改变,这类方法需要重新分析整个程序来找到合适的分析语句,缺乏灵活性。b)这些方法通常需要源代码,但是软件提供商,尤其商业的软件提供商,不会公开源代码。c)一些方法需要改变目标程序的原始代码,这是在一些应用程序中是不被允许的。
[0007]因此,针对上述问题,本发明提出了一种基于树优化的程序依赖关系分析方法及系统。

【发明内容】

[0008]本发明所要解决的技术问题是提供一种基于树优化的程序依赖关系分析方法及系统,用于解决现有程序依赖关系分析方法效率不高、精度度不足等问题。
[0009]本发明解决上述技术问题的技术方案如下:一种基于树优化的程序依赖关系分析方法,包括:
[0010]步骤1,以函数为基本单位进行程序依赖关系分析,将函数中的连续指令划分为多个基本块,且保证每个基本块有单一入口和单一出口;
[0011 ] 步骤2,针对每个基本块构建相应的指令依赖树和指令依赖森林;
[0012]步骤3,分析各基本块的指令依赖树和指令依赖森林,去除未改变原状态的指令,去除依赖于特殊寄存器的指令依赖树;[0013]步骤4,分析各基本块的指令依赖树和指令依赖森林,从前一基本块中去除在其后续各基本块中有重复定义但未被使用的变量对应的指令依赖树;
[0014]步骤5,根据步骤3和步骤4的处理结果,选取内存索引中不能静态计算寄存器值的指令所在的位置,将该指令位置之前的位置作为动态插装位置;
[0015]步骤6,在所有动态插装位置上插装统一化的影子指令,通过影子指令分析指令依赖树和指令依赖森林。
[0016]在上述技术方案的基础上,本发明还可以做如下改进。
[0017]进一步,所述步骤2中,若指令中定义的一个变量i没出现在指令依赖树的节点集合V中,则将该变量i增加到指令依赖树的节点集合V中,并增加从该节点i到指令所用到的变量相应的边。
[0018]进一步,所述步骤2中,若指令中定义的一个变量i出现在指令依赖树的节点集合V中,且其是指令依赖森林的根节点,则删除从节点i到其孩子节点的边,并增加从i到指令所用到的变量集合相应的边;若i是指令依赖森林的叶子节点,则i没有在基本块中重复定义,增加新的节点I1,作为块入口 i的初始状态,并用I1取代i,增加从i到相应指令中使用变量的边;否则,增加i的父节点到i的孩子节点的边,并去掉i的父节点到i的边及i到其孩子节点的边。
[0019]进一步,所述步骤4具体包括:
[0020]步骤41,定义一个记录 在一个基本块中被定义但未被使用的变量的集合S ;
[0021]步骤42,分析函数的最后一个基本块B,如果该基本块的最后一个指令是一个函数调用指令,则清空S ;
[0022]步骤43,若最后一个基本块是一个分支块,则重新定义S集合为两个分支的定义集合的交集,若存在一个分支未被分析过,则返回分析该分支;
[0023]步骤44,如果基本块的非叶节点存在于步骤43执行后的S中,则删除该非叶节
占.[0024]步骤45,更新集合S,重复执行步骤41至步骤44,优化基本块B前面的基本块。
[0025]进一步,所述步骤5中,若在指令依赖森林中没有间接内存地址,则动态插装位置为基本块中的任意位置。
[0026]进一步,所述步骤6中通过影子指令分析指令依赖森林具体包括:影子指令对指令依赖森林中每个根节点η和其孩子节点Ci,执行操作T (n) = Ui = KlnjT(Ci),其中T (χ)表示返回χ的依赖关系状态,且孩子节点Ci中i=0, --?,m。
[0027]对应上述方法,本发明的技术方案还包括一种基于树优化的程序依赖关系分析系统,包括依次连接的基本块划分模块、依赖关系构建模块、基本块内优化模块、基本块间优化模块、插装位置获取模块和影子指令生成模块:
[0028]基本块划分模块,其用于以函数为基本单位进行程序依赖关系分析,将函数中的连续指令划分为多个基本块,且保证每个基本块有单一入口和单一出口 ;
[0029]依赖关系构建模块,其用于针对每个基本块构建相应的指令依赖树和指令依赖森林;
[0030]基本块内优化模块,其用于分析各基本块的指令依赖树和指令依赖森林,去除未改变原状态的指令,去除依赖于特殊寄存器的指令依赖树;[0031]基本块间优化模块,其用于分析各基本块的指令依赖树和指令依赖森林,从前一基本块中去除在其后续各基本块中有重复定义但未被使用的变量对应的指令依赖树;
[0032]插装位置获取模块,其用于根据基本块内优化模块和基本块间优化模块的处理结果,选取内存索引中不能静态计算寄存器值的指令所在的位置,将该指令位置之前的位置作为动态插装位置;
[0033]影子指令生成模块,其用于在所有动态插装位置上生成统一化的影子指令,通过影子指令分析指令依赖树和指令依赖森林。
[0034]进一步,所述依赖关系构建模块中,若指令中定义的一个变量i没出现在指令依赖树的节点集合V中,则将该变量i增加到指令依赖树的节点集合V中,并增加从该节点i到指令所用到的变量相应的边。
[0035]进一步,所述依赖关系构建模块中,若指令中定义的一个变量i出现在指令依赖树的节点集合V中,且其是指令依赖森林的根节点,则删除从节点i到其孩子节点的边,并增加从i到指令所用到的变量集合相应的边;若i是指令依赖森林的叶子节点,则i没有在基本块中重复定义,增加新的节点I1,作为块入口 i的初始状态,并用I1取代i,增加从i到相应指令中使用变量的边;否则,增加i的父节点到i的孩子节点的边,并去掉i父节点到i的边及i到其孩子节点的边。
[0036]进一步,若在指令依赖森林中没有间接内存地址,则所述插装位置获取模块将基本块中的任意位置作为动态插装位置。
[0037]本发明的有益效果是:本发明一方面采用树优化方法,不需要对二进制程序的每一条指令进行动态插装;另一方面采用程序动态分析,避免了单独使用静态树优化分析不准确的问题,提高了整体程序分析效率。该方法无需对每条指令进行插装,节省了时间和空间。同时,使用基本块为一个单元,通过构建指令依赖树与指令依赖森林对基本块内和基本块间进行分析,有效识别无用的依赖关系传递操作并进行优化,有效提高了程序动态分析过程的效率。最后通过选取合适的位置并产生影子指令来对目标二进制程序进行插装,极大地提高了分析的效率。
【专利附图】

【附图说明】
[0038]图1为本发明的程序依赖关系分析方法的流程示意图;
[0039]图2为本发明的程序依赖关系分析系统的结构示意图;
[0040]图3为本发明实施例中含4个基本块的函数示例图;
[0041]图4为本发明实施例中对如图3所示的函数进行基本块优化的示例图。
【具体实施方式】
[0042]以下结合附图对本发明的原理和特征进行描述,所举实例只用于解释本发明,并非用于限定本发明的范围。
[0043]如图1所示,实施例一是一种基于树优化的程序依赖关系分析方法,具体包括以下步骤:
[0044]步骤1,以函数为基本单位进行程序依赖关系分析,将函数中的连续指令划分为多个基本块,且保证每个基本块有单一入口和单一出口 ;[0045]步骤2,针对每个基本块构建相应的指令依赖树和指令依赖森林;
[0046]步骤3,分析各基本块的指令依赖树和指令依赖森林,去除未改变原状态的指令,去除依赖于特殊寄存器的指令依赖树;
[0047]步骤4,分析各基本块的指令依赖树和指令依赖森林,从前一基本块中去除在其后续各基本块中有重复定义但未被使用的变量对应的指令依赖树;
[0048]步骤5,根据步骤3和步骤4的处理结果,选取内存索引中不能静态计算寄存器值的指令所在的位置,将该指令位置之前的位置作为动态插装位置;
[0049]步骤6,在所有动态插装位置上插装统一化的影子指令,通过影子指令分析指令依赖树和指令依赖森林。
[0050]对应地,如图2所示,本实施例还给出了一种基于树优化的程序依赖关系分析系统,包括依次连接的基本块划分模块、依赖关系构建模块、基本块内优化模块、基本块间优化模块、插装位置获取模块和影子指令生成模块:
[0051]基本块划分模块,其用于以函数为基本单位进行程序依赖关系分析,将函数中的连续指令划分为多个基本块,且保证每个基本块有单一入口和单一出口 ;
[0052]依赖关系构建模块,其用于针对每个基本块构建相应的指令依赖树和指令依赖森林;
[0053]基本块内优化模块,其用于分析各基本块的指令依赖树和指令依赖森林,去除未改变原状态的指令,去除依赖于特殊寄存器的指令依赖树;
[0054]基本块间优化模块,其用于分析各基本块的指令依赖树和指令依赖森林,从前一基本块中去除在其后续各基本块中有重复定义但未被使用的变量对应的指令依赖树;
[0055]插装位置获取模块,其用于根据基本块内优化模块和基本块间优化模块的处理结果,选取内存索引中不能静态计算寄存器值的指令所在的位置,将该指令位置之前的位置作为动态插装位置;
[0056]影子指令生成模块,其用于在所有动态插装位置上生成统一化的影子指令,通过影子指令分析指令依赖树和指令依赖森林。
[0057]对于上述六个步骤及六个处理模块,其实施的具体过程分为以下几个部分。
[0058]一、基本块划分
[0059]基本块划分原则依据通用的方法,将函数中的连续指令划分为多个基本块,且保证每个基本块有单一入口和单一出口。如图3所示,示意了一段分为4个基本块的函数,图中push指令是将寄存器edi中的内容放入内存“栈”中,“栈”由esp指针表示,[esp]表示该指针指向的位置;call指令表示程序调用,在调用前需要保存现在程序的位置(由eip表示)到栈中,具体位置是当前栈偏移4个字节的内存(由[esp-4]表示)。
[0060]基本块中的指令无需逐一进行分析,这里定义T(X)表示返回χ是否依赖于外部输入的状态,其中X可以是一块内存或寄存器。如图3中第一个基本块中对应指令可知“T([esp]) —T (edi)”,“T (edi)—T (ecx)”,“T ([esp-4] ) — T (eip)”(call 指令操作)。其中,“T([esp_4]) — T (eip)”表示如果eip依赖于外部输入,则寄存器esp-4指向的内存也依赖于外部输入;“T (edi)—T (ecx)”表不如果ecx依赖于外部输入,贝U寄存器edi也依赖于外部输入。这个过程中,无需分析指令“lea ecx, [edi+04h] ”,因为它没有改变ecx的状态。[0061]二、指令依赖树与指令依赖森林构建
[0062]在每个基本块中构建指令依赖树T (V, E)或指令依赖森林Fb,,其中V表示指令依赖树的节点集合,E表示指令依赖树中的各边。构建指令依赖树的过程主要依据如下规则:
[0063]I)如果指令中定义的一个变量i没出现在指令依赖树T的节点集合V中,则将其增加到节点集合V中,并增加从该节点i到指令所用到的变量u相应的边e。
[0064]2)如果指令中定义的一个变量i出现在指令依赖树T的节点集合V中,如果i是Fb的根节点,则删除从i到其孩子节点的边,并增加从i到指令所用到的变量集合相应的边;如果i是叶子节点,即i没有在块中重复定义,则增加新的节点I1,作为块入口 i的初始状态,并用I1取代i,增加从i到相应指令中使用变量的边;否则,对于指令依赖树中非根、非叶的其他节点,增加i的父节点到i的孩子节点的边,并去掉i的父节点到i的边及i到其孩子节点的边。
[0065]举例说明,如图4所示,对于图4中的基本块I,首先根据push edi指令,建立依赖树[esp] —edi,然后指令mov edi, ecx将ecx的值赋给edi,即重新定义了 edi,此时将[esp] — edi中的edi改变为edi I,便于区分edi在基本块入口的时候的值(采用edi I表示)和指令mov edi, ecx执行后edi的值(采用edi表示)。
[0066]3)指令依赖森林Fb是指令依赖树的联合,其中包含多个根节点。
[0067]三、基本块内优化
[0068]优化包括两部分:一是舍弃未改变原状态的指令,如基本块I中Ieaecx, [edi+04h]的依赖关系分析过程可以舍弃(详见第一部分基本块划分);二是特殊寄存器优化,如程序指针寄存器eip和栈寄存器esp,实际中并不关注从寄存器eip和esp流出的数据,而是关注eip和esp是否依赖于外部输入,因为一旦eip或esp依赖于外部输入,程序即进入错误状态。如图4所示,基本块3中即进行了优化,优化部分用虚线圆圈表示。
[0069]四、基本块间优化
[0070]这一部分主要是通过在基本块之间进行分析,减少指令依赖森林中节点的数量。例如,图4中基本块2中T(ebx)=T ( [esp])并不是必须的,因为ebx在后续基本块3和4中会被重新定义,从而可进行优化。
[0071]举例说明,基本块间优化的具体程序流程如下:
[0072]
【权利要求】
1.一种基于树优化的程序依赖关系分析方法,其特征在于,包括: 步骤1,以函数为基本单位进行程序依赖关系分析,将函数中的连续指令划分为多个基本块,且保证每个基本块有单一入口和单一出口; 步骤2,针对每个基本块构建相应的指令依赖树和指令依赖森林; 步骤3,分析各基本块的指令依赖树和指令依赖森林,去除未改变原状态的指令,去除依赖于特殊寄存器的指令依赖树; 步骤4,分析各基本块的指令依赖树和指令依赖森林,从前一基本块中去除在其后续各基本块中有重复定义但未被使用的变量对应的指令依赖树; 步骤5,根据步骤3和步骤4的处理结果,选取内存索引中不能静态计算寄存器值的指令所在的位置,将该指令位置之前的位置作为动态插装位置; 步骤6,在所有动态插装位置上插装统一化的影子指令,通过影子指令分析指令依赖树和指令依赖森林。
2.根据权利要求1所述的程序依赖关系分析方法,其特征在于,所述步骤2中,若指令中定义的一个变量i没出现在指令依赖树的节点集合V中,则将该变量i增加到指令依赖树的节点集合V中,并增加从该节点i到指令所用到的变量相应的边。
3.根据权利要求1或2所述的程序依赖关系分析方法,其特征在于,所述步骤2中,若指令中定义的一个变 量i出现在指令依赖树的节点集合V中,且其是指令依赖森林的根节点,则删除从节点i到其孩子节点的边,并增加从i到指令所用到的变量集合相应的边;若i是指令依赖森林的叶子节点,则i没有在基本块中重复定义,增加新的节点I1,作为块入口 i的初始状态,并用I1取代i,增加从i到相应指令中使用变量的边;否则,增加i的父节点到i的孩子节点的边,并去掉i的父节点到i的边及i到其孩子节点的边。
4.根据权利要求1所述的程序依赖关系分析方法,其特征在于,所述步骤4具体包括: 步骤41,定义一个记录在一个基本块中被定义但未被使用的变量的集合S ; 步骤42,分析函数的最后一个基本块B,如果该基本块的最后一个指令是一个函数调用指令,则清空S ; 步骤43,若最后一个基本块是一个分支块,则重新定义S集合为两个分支的定义集合的交集,若存在一个分支未被分析过,则返回分析该分支; 步骤44,如果基本块的非叶节点存在于步骤43执行后的S中,则删除该非叶节点; 步骤45,更新集合S,重复执行步骤41至步骤44,优化基本块B前面的基本块。
5.根据权利要求1所述的程序依赖关系分析方法,其特征在于,所述步骤5中,若在指令依赖森林中没有间接内存地址,则动态插装位置为基本块中的任意位置。
6.根据权利要求1所述的程序依赖关系分析方法,其特征在于,所述步骤6中通过影子指令分析指令依赖森林具体包括:影子指令对指令依赖森林中每个根节点η和其孩子节Aci,执行操作T(n) =Ui = K^T(Ci),其中T (X)表示返回X的依赖关系状态,且孩子节点Ci 中 i=0,..., m。
7.一种基于树优化的程序依赖关系分析系统,其特征在于,包括依次连接的基本块划分模块、依赖关系构建模块、基本块内优化模块、基本块间优化模块、插装位置获取模块和影子指令生成模块: 基本块划分模块,其用于以函数为基本单位进行程序依赖关系分析,将函数中的连续指令划分为多个基本块,且保证每个基本块有单一入口和单一出口 ; 依赖关系构建模块,其用于针对每个基本块构建相应的指令依赖树和指令依赖森林;基本块内优化模块,其用于分析各基本块的指令依赖树和指令依赖森林,去除未改变原状态的指令,去除依赖于特殊寄存器的指令依赖树; 基本块间优化模块,其用于分析各基本块的指令依赖树和指令依赖森林,从前一基本块中去除在其后续各基本块中有重复定义但未被使用的变量对应的指令依赖树; 插装位置获取模块,其用于根据基本块内优化模块和基本块间优化模块的处理结果,选取内存索引中不能静态计算寄存器值的指令所在的位置,将该指令位置之前的位置作为动态插装位置; 影子指令生成模块,其用于在所有动态插装位置上生成统一化的影子指令,通过影子指令分析指令依赖树和指令依赖森林。
8.根据权利要求7所述的程序依赖关系分析系统,其特征在于,所述依赖关系构建模块中,若指令中定义的一个变量i没出现在指令依赖树的节点集合V中,则将该变量i增加到指令依赖树的节点集合V中,并增加从该节点i到指令所用到的变量相应的边。
9.根据权利要求7或8所述的程序依赖关系分析方法,其特征在于,所述依赖关系构建模块中,若指令中定义的一个变量i出现在指令依赖树的节点集合V中,且其是指令依赖森林的根节点,则删除从节点i到其孩子节点的边,并增加从i到指令所用到的变量集合相应的边;若i是指令依赖森林的叶子节点,则i没有在基本块中重复定义,增加新的节点ip作为块入口 i的初始状态,并用I1取代i,增加从i到相应指令中使用变量的边;否则,增加i的父节点到i的孩子节点 的边,并去掉i父节点到i的边及i到其孩子节点的边。
10.根据权利要求7所述的程序依赖关系分析系统,其特征在于,若在指令依赖森林中没有间接内存地址,则所述插装位置获取模块将基本块中的任意位置作为动态插装位置。
【文档编号】G06F21/57GK103793653SQ201410055841
【公开日】2014年5月14日 申请日期:2014年2月19日 优先权日:2014年2月19日
【发明者】陈恺, 赵险峰, 张颖君 申请人:中国科学院信息工程研究所
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1