一种利用图同构验证编译器的方法

文档序号:6516667阅读:182来源:国知局
一种利用图同构验证编译器的方法
【专利摘要】本发明公开一种利用图同构验证编译器的方法,包括待处理的源程序和将源程序生成目标程序的编译器,在选定环境下建立一个反编译器,通过反编译器将目标程序反编译成对比程序,验证对比程序和源程序之间的语义一致性,并在此基础上,分别建立源程序和对比程序的控制流图相关结点信息后进行同构判定,从而得到编译器是否安全的结论。本发明通过判断对比程序与源程序的控制流图是否同构,来验证编译器的安全性。该方法直接将反编译后的代码与源代码进行语义比较,避免了验证过程中由于源代码信息丢失导致验证不全面的问题,该算法不需要再次遍历控制流图,使得图同构判断算法简单,易于实现。
【专利说明】—种利用图同构验证编译器的方法
【技术领域】
[0001]本发明涉及核电领域,具体涉及核电中用于生成安全级代码的编译器的安全性验证方法。
【背景技术】
[0002]编译器作为软件的生成工具,在那些对软件安全性要求十分高的特殊环境里面,其安全性至关重要,特别是用于核安全级保护系统的软件。在核安全级系统中,一方面为了保证软件运行的安全性,程序员经常会引入查错程序或者防御性的程序,而经过编译后的目标代码为了保持源代码的安全性,要求编译器不能在无警告或提示下删除程序员引入的防御程序或查错程序,从而导致目标程序不符合安全级软件的要求;另一方面,由于编译器的漏洞以及人为的后门程序可能会对整个软件造成根本性的破坏,所以,要求编译器在编译的过程中不会人为的插入恶意代码。由此,在验证编译正确性的基础上必须从以上两个方面验证编译器的安全性。
[0003]目前对于编译器的验证技术主要有形式化验证技术以及测试验证技术,其中,形式化验证技术是从编译器本身的正确性或者是从保证被编译对象的正确性入手进行证明,但是这个方法实现难度较大,成功案例也仅限应用于某个语言子集的证明,很难推广到现有的工程应用上来。而测试验证技术由于无法对其输入进行全覆盖,以及编译器的复杂性所带来的巨大工作量,使得仅靠测试验证技术难以完成对编译器的完整的验证。
[0004]此外,这些验证技术仅基于编译器逻辑正确性的验证,即对源代码和目标代码行为是否一致的验证,且都没有很好的解决编译器对恶意代码注入的问题,以及编译器对那些不影响动态语义的防御程序的删除的问题。故除了依赖对编译器的逻辑正确性验证之夕卜,还需要多遍交叉编译、目标文件结构化比较、目标文件反编译逻辑比较等理论和方法完成对安全性的验证。
[0005]在现有技术中验证代表包括:(I)、ISTec利用反编译技术由独立的小组开发从目标程序翻译到源程序的反编译器,比较源代码与目标代码反编译后的代码的一致性,来实现对编译器的正确性验证的方式。
[0006](2)、Xavier Leroy带领的CompCert项目组利用定理证明的形式化方法首次完成了从C light到PowerPC转换过程的正确性形式化验证。但是,这种针对编译器本身的形式化验证方法一般较难实现,且证明整个编译器的正确性也比较困难,即使是CompCert小组也只是针对编译器的后端进行了证明。
[0007](3)、俞甲子基于GCC编译器提出了一种除了能够验证编译器逻辑正确性之外,还可对编译器的安全性进行验证的方法。该方法结合了编译器代码分析及对比验证方案和源代码与目标代码控制流图同构比较方案。其中编译器代码分析及对比验证方案首先对编译器的设计及源代码进行分析,针对每个函数进行分类,对能够改变输入数据的函数进行重新编写,对比原始版本的数据结构和重新设计的数据结构;控制流图同构比较方案是采用对源代码和目标代码抽取控制流图,并判断控制流图是否同构来排除编译时是否人为的插入恶意代码。

【发明内容】

[0008]为解决现有技术中无法验证编译器安全性的问题,本发明提供一种利用源程序和对比程序的控制流图是否同构的方法来检测编译器的安全性。具体方案如下:一种利用图同构验证编译器的方法,包括待处理的源程序和将源程序生成目标程序的编译器,在选定环境下建立一个反编译器,通过反编译器将目标程序反编译成对比程序,验证对比程序和源程序之间的语义一致性,其特征在于,在此基础上分别建立源程序和对比程序的控制流图相关结点信息后进行同构判定,从而得到编译器是否安全的结论,具体步骤如下:
[0009]步骤1、首先对源程序和对比程序的语句按顺序进行扫描,并利用带序号的结点进行标识,同时标明各结点的出边信息;
[0010]步骤2、同时建立一个辅助栈表,并将当前结点及相关结点信息压入辅助栈表;
[0011]步骤3、对条件结构的所有结点进行简化并用简化结点替代,然后将简化结点压入辅助栈表原条件结构的结点位置处形成简化栈表,并且在程序中所有结点被扫描完成之后,将栈表中的结点依次出栈,在上述简化过程中,建立该结点的邻接链表,同时建立一个记录简化结点信息的简化信息表;
[0012]步骤4、根据结点的邻接链表和简化信息表建立源程序和对比程序的出入度信息,并生成相应的η点连通子图的出入度序列;
[0013]步骤5、根据出入度序列判断源程序和对比程序的控制流图是否同构;其中,当两个控制流图中的任意η点连通子图的出入度序列相同时,则表明两个控制流图是同构的,进而表明源程序与目标程序是相同的,并得到编译器是安全的结果;反之,则证明编译器是不安全的。
[0014]为根据不同的结构设置相应的结点:所述步骤I中,结点的添加标准如下:
[0015]步骤11、首先在源程序和对比程序的开始和结尾分别增加一个开始结点和终止结
占.[0016]步骤12、顺序执行的语句(程序)用一个结点标识;
[0017]步骤13、条件语句的起始句用一个条件起始结点标识,中间的各条件表达式分别用一个中间结点标识,同时增加一个条件语句的条件结束结点;
[0018]步骤14、循环语句的起始句用一个执行结点标记,结尾语句用一个判断结点标记;
[0019]步骤15、在分析时遇到RETURN语句则单独添加一个返回结点。
[0020]为建立出入度信息:各结点的出边连接方法如下:
[0021]步骤31、按各结点排列顺序依次连接;
[0022]步骤32、遇到条件语句的结点时,条件起始结点与各中间条件表达式的中间结点按顺序连接,如遇到返回结点时,则返回结点的出边直接与终止结点连接,否则按顺序连接条件结束结点;
[0023]步骤33、遇到循环语句的结点时,执行语句结点指向判断结点,判断结点分别指向执行语句结点和顺序排列的下一个结点。
[0024]为方便后续检索:所述辅助栈表的基本信息包括如下内容:[0025]A、按分析顺序生成的各结点的类型,包括顺序类型、条件类型和循环类型,各类型以相应结构的起始句为标识进行区分;
[0026]B、各结点对应的排列序号;
[0027]C、每个结点所包含的结点数量;
[0028]D、所包含的return语句数量。
[0029]为方便查找各结点:所述步骤3中,邻接链表记录每个结点的出边信息,并记录所有邻接链表的表头指针信息以作为检索信息。
[0030]为方便查找简化结点的信息:所述步骤3中,简化信息表的内容包括结点名、被简化结构包含的结点个数、起始结点和终止结点名,以及所涉及的return分支数量。
[0031]为方便源程序和对比程序的对比:所述步骤4中,出入度序列的建立方法如下:
[0032]步骤41、根据邻接链表中的结点信息统计出各结点的出度和入度信息;
[0033]步骤42、然后依次读取简化栈表中各结点的信息,遇到简化结点时,并用简化结点及其出度、入度信息去更换被简化结构相应位置结点的出度、入度信息,同时更新该被简化块的出入度信息,并且连同该简化块的结点总数一起记录下来;
[0034]步骤43、分别统计更新后源程序和对比程序的η点连接子图的出入度序列,并对其中的出度和入度按大小进行排序。
[0035]本发明在利用反编译技术的基础上,将目标代码反编译之后的对比程序与源程序利用常规手段进行语义一致性比较,验证编译器的正确性;然后判断反编译之后的对比程序与源程序的控制流图是否同构,来验证编译器的安全性。该方法直接将反编译后的代码与源代码进行语义比较,避免了验证过程中由于源代码信息丢失导致验证不全面的问题,并且在进行安全性验证时,提出了在同一语言下进行程序控制流图同构判定算法,该算法只需要实现一种语言下程序的信息提取,并借此信息进行控制流图同构的判定,不需要再次遍历控制流图,使得控制流图同构判断算法简单,易于实现。另外,由于恶意代码和防御程序以及查错程序一般包含一定的条件判断语句,能够改变程序的控制流图,因此,通过验证程序的控制流图是否同构来判断编译器在编译的过程中是否改变了程序的结构,从而达到验证编译器的安全性的目的。
【专利附图】

【附图说明】
[0036]图1源程序和对比程序正确性和安全性验证的示意图;
[0037]图2本发明中顺序结构的结点标识示意图;
[0038]图3本发明中条件结构的结点标识示意图;
[0039]图4本发明中do_while循环结构的结点标识示意图;
[0040]图5本发明中while_do循环结构的结点标识示意图;
[0041 ]图6本发明的流程示意图。
【具体实施方式】
[0042]本发明利用图同构验证编译器的方法,包括待处理的源程序和将源程序生成目标程序的编译器,在选定环境下建立一个反编译器,通过反编译器将目标程序反编译成对比程序,验证对比程序和源程序之间的语义一致性,在此基础上分别建立源程序和对比程序的控制流图相关结点信息后进行同构判定,本发明的验证环境是C语言。
[0043]如图1所示,例:首先用待验证编译器Generator将源程序programA转换成目标程序 programB ;
[0044]新开发一个针对目标程序programB的反编译器Generator_verify ;
[0045]将目标程序programB利用反编译器Generator_verify编译生成对比程序programA,;
[0046]如果想验证编译器Generator的正确性,可以通过静态分析、模型检验或者自动定理证明等方式来验证programA和programA’的语义一致性来达到目的。
[0047]而为检测编译器Generator的安全性则需要首先建立源程序programA和对比程序programA’控制流图信息,然后进行同构判定。
[0048]本发明的实现原理是:控制流图可以由邻接链表表示法来存储,并且这种方法便于计算每个结点的出入度,因此本发明采取邻接链表的存储方式记录结点的出边信息;为获得程序的控制流图结点信息,并且便于后续图同构的判定,只需要计算每个连通子图的出入度,所以,在搜集程序控制流图信息的过程中重点记录图中每个结点的出入度,以及连通子图的出入度信息;然后根据记录的结点信息建立连通子图的出入度序列并进行比较,以判断源程序和对比程序的控制流图是否同构的结论。
[0049]程序控制流图是描述程序控制逻辑的一种有向图,图中的每个结点对应于一个顺序流程的程序代码块或者谓词,弧对应程序的转移。对于程序来说,其控制流图比较特殊,只有循环结构块的部分存在强连通子图,其余的结构只存在单向连通子图,所以在对程序结构进行归约的过程中重点记录每个被简化结构块的结点个数,以及该结构与图中其余结点相联系的连接点。
[0050]在符合结构化程序设计思想这一前提下,一个程序的控制流图可由下述三种基本
结构组合而成:顺序结构、if-elseif-----else和switch代表的分支结构、while-do和
do-while代表的循环结构,其中顺序结构中的语句可以扩展,可以是分支结构或循环结构。
[0051]如图6所示,本发明的具体步骤如下:
[0052]101、首先对源程序和对比程序的语句按顺序进行扫描,并利用带序号的结点进行标识,同时标明各结点的出边信息;
[0053]1、首先在源程序和对比程序的开始和结尾分别增加一个开始结点和终止结点,如:START和END分别表示起始和结束结点。
[0054]2、然后对整个程序进行分析并增加相应结点,在出入边的连接上,基本原则是按各结点排列顺序依次连接,遇到条件语句的结点时,条件起始结点与各中间条件表达式的中间结点按顺序连接,如遇到返回结点时,则返回结点的出边直接与终止结点连接,否则按顺序连接条件结束结点;如:
[0055]如图2所示,顺序执行的语句作为一个基本块,如果最后的语句不是return语句,由一个结点代替;否 则,除return之外的语句由一个结点代替,而return单独一个结点。
[0056]如图3所示,对于条件语句的选择结构块,起始句用一个条件起始结点标识,中间的各条件表达式分别用一个中间结点标识,同时增加一个条件语句的条件结束结点;如:是if-elseif——else,则增加一个中间结点IFELSE_END1,并将所有的条件表达式作为谓词结点,顺次连接,所有的条件语句按照顺序结构处理,该结构块的入边连接点为对应的条件表达式,出边连接点为IFELSE_END1。但选择结构块中如果含有return语句,则出边连接
END结点。
[0057]是switch时,将表达式及其对应的case值都作为谓词结点顺次连接,case语句的处理和if 一致,记增加的中间结点为SWITCH_END1。结点之间的连接关系和if-elseif—..-else结构一致。
[0058]遇到循环语句的结点时,执行语句结点向判断结点出边,判断结点分别向执行语句结点和顺序排列的下一个结点出边。如图4、5所示,分别是do_while和while_do两种循环结构的结点标识示意。
[0059]102、同时建立一个辅助栈表,并将当前结点及相关结点信息压入辅助框;
[0060]其中辅助栈表用于压入顺序扫描时标识的结点及相关结点信息,这些结点信息与生成的后继结点有关,为结点的连接提供信息,其中的结点信息包括结点类型、结点序号和当前结点的数量以及return语句数量,当是条件结构时,结点的数量则为此结构所包含的结点个数,上述信息为判定控制流图同构时提供信息,
[0061]1、其中的结点类型记录每条语句的类型,如:是return语句记为RETURN,其余顺序结构的语句记为STATEMENT,如果是do_while循环结构的第一条语句序号,其类型记为DOWHILE_STATEMENT ;每个块结构的开始谓词则记为IFELSE_PREDICATE、SffITCH_PREDICATE、WHILEDO_PREDICATE,其余谓词的均为 PREDICATE ;
[0062]2、结点序号为每条语句或者块的序号;
[0063]3、结点数目num,记录每个结点的个数,如果是简化结点,则记录的是被简化结构块所包含的结点个数;
[0064]4、Retrun语句数目retun_num,记录return语句的数目,主要是为了在简化条件结构时,统计该结构与其它结点的连接信息。
[0065]辅助栈表的内容如下表所示:
[0066]
【权利要求】
1.一种利用图同构验证编译器的方法,包括待处理的源程序和将源程序生成目标程序的编译器,在选定环境下建立一个反编译器,通过反编译器将目标程序反编译成对比程序,验证对比程序和源程序之间的语义一致性,其特征在于,在此基础上分别建立源程序和对比程序的控制流图相关结点信息后进行同构判定,从而得到编译器是否安全的结论,具体步骤如下: 步骤1、首先对源程序和对比程序的语句按顺序进行扫描,并利用带序号的结点进行标识; 步骤2、同时建立一个辅助栈表,并将当前结点及相关结点信息压入辅助栈表框; 步骤3、对条件结构的所有结点进行简化并用简化结点替代,然后将简化结点压入辅助栈表原条件结构的结点位置处形成简化栈表,并且在程序中所有结点被扫描完成之后,将栈表中的结点依次出栈,在上述简化过程中,建立该结点的邻接链表,同时建立一个记录简化结点信息的简化信息表; 步骤4、根据结点的邻接链表和简化信息表建立源程序和对比程序的出入度信息,并生成相应的η点连通子图的出入度序列; 步骤5、根据出入度序列判断源程序和对比程序的控制流图是否同构;其中,当两个控制流图中的任意η点连通子图的出入度序列相同时,则表明两个控制流图是同构的,进而表明源程序与目标程序是相同的,并得到编译器是安全的结果;反之,则证明编译器是不安全的。
2.如权利要求1所述的一种利用图同构验证编译器的方法,其特征在于,所述步骤I中,结点的添加标准如下: 步骤11、首先在源程序和对比程序的开始和结尾分别增加一个开始结点和终止结点; 步骤12、顺序执行的语句(程序)用一个结点标识; 步骤13、条件语句的起始句用一个条件起始结点标识,中间的各条件表达式分别用一个中间结点标识,同时增加一个条件语句的条件结束结点; 步骤14、循环语句的起始句用一个执行结点标记,结尾语句用一个判断结点标记; 步骤15、在分析时遇到RETURN语句则单独添加一个返回结点。
3.如权利要求1所述的一种利用图同构验证编译器的方法,其特征在于,各结点的出边连接方法如下: 步骤31、按各结点排列顺序依次连接; 步骤32、遇到条件语句的结点时,条件起始结点与各中间条件表达式的中间结点按顺序连接,如遇到返回结点时,则返回结点的出边直接与终止结点连接,否则按顺序连接条件结束结点; 步骤33、遇到循环语句的结点时,执行语句结点指向判断结点,判断结点分别指向执行语句结点和顺序排列的下一个结点。
4.如权利要求1所述的一种利用图同构验证编译器的方法,其特征在于,所述辅助栈表的基本信息包括如下内容: A、按分析顺序生成的各结点的类型,包括顺序类型、条件类型和循环类型,各类型以相应结构的起始句为标识进行区分; B、各结点对应的排列序号;C、每个结点所包含的结点数量; D、所包含的return语句数量。
5.如权利要求1所述的一种利用图同构验证编译器的方法,其特征在于,所述步骤3中,邻接链表记录每个结点的出边信息,并记录所有邻接链表的表头指针信息以作为检索信息。
6.如权利要求1所述的一种利用图同构验证编译器的方法,其特征在于,所述步骤3中,简化信息表的内容包括结点名、被简化结构包含的结点个数、起始结点和终止结点名,以及所涉及的return分支数量。
7.如权利要求1所述的一种利用图同构验证编译器的方法,其特征在于,所述步骤4中,出入度序列的建立方法如下: 步骤41、根据邻接链表中的结点信息统计出各结点的出度和入度信息; 步骤42、然后依次读取简化信息表中各结点的信息,并用简化结点及其出度、入度信息去更换被简化结构相应位置结点的出度、入度信息,同时更新该被简化块的出入度信息,并且连同该简化块的结点总数一起记录下来; 步骤43、分别统计更新后源程序和对比程序的η点连接子图的出入度,并对其中的出度和入度按大小进行排序。`
【文档编号】G06F11/36GK103559125SQ201310512437
【公开日】2014年2月5日 申请日期:2013年10月25日 优先权日:2013年10月25日
【发明者】冯素梅, 刘建龙, 李幼媛, 袁劲涛, 杨晓豫, 赵云飞 申请人:北京广利核系统工程有限公司, 中国广核集团有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1