一种源代码与二进制代码间的语义比对方法和装置与流程

文档序号:18475071发布日期:2019-08-20 20:54阅读:321来源:国知局
本发明属于程序分析领域,关注代码语义静态分析方向,具体检查二进制代码是否复用目标源代码,如是否重用未修补漏洞的源代码,这是一种基于语义比对的静态分析技术。
背景技术
::语义比对常用于从特定应用角度比对源代码、二进制代码在执行逻辑上的相似性。例如,语义比对常用于比对代码间在某一个功能上的相似性,如是否包含同一恶意功能、是否使用相似的加解密算法等。从研究实现的现状来看,语义比对的应用范围较广,且通常需针对特定的问题来设计具体的语义比对方案。本发明重点关注如何从源代码、二进制代码同时提取相同的语义,该语义需尽可能消减因编译优化和符号信息去除而带来源代码与二进制代码间的差异,以此对源代码和二进制代码进行语义比对,以判断二进制代码是否复用给定的目标源代码。在比对粒度上,本发明着重从函数级比对的角度,提取函数内语句和变量间的语义关系并形成抽象语法树进行比对,以确定源代码函数是否在二进制代码中存在。与本发明最相似的技术有抽象语法树(abstractsyntaxtree,以下简称ast),数据流分析,控制流分析技术。针对特定应用(如语义比对),需对这几类技术进行方案定制,以达到应用预期目标,如可利用clang和antlr等工具的ast技术对整个源代码项目做语法分析。本发明着重关注给定关键语句的相关变量集合,在控制流分析条件的限制下,经数据流分析生成变量的ast,并比对源代码和二进制同时生成的ast。从代码比对的角度来说,类似的方法通常将源代码项目编译为二进制可执行文件,再与其它二进制文件进行比对(“二进制-二进制”比对)。而这种方法需完整的源代码项目,且通常需人工设置多个编译参数并预安装依赖库才能编译成功。故而,本发明直接采用“源代码-二进制”比对的方式,不依赖于人工设置和编译的过程,能直接提高比对成功率和效率。当前,也有少数公开工作部分采用了“源代码-二进制”比对的方式,但其或者依赖于编译过程中输出的调试信息(或符号信息),或者通过字符串、数组等常量进行比对,均未对语义信息进行深入分析,与本发明采用的语义比对方法有明显区别。相比较而言,本发明的方法更为通用,例如并不是每一个二进制代码函数都存在对字符串、数组等常量的引用,但实现了具体功能的代码一定具有相应的语义信息;发布版软件通常会去掉调试信息和大部分符号信息。综上,对于给定关键比对语句,本发明提出一种通用式源代码与二进制代码语义比对的方法。相比现有的工作,着重关注非编译场景下,自动完成源代码与二进制代码函数内语句的语义特征提取比对。技术实现要素:为了实现源代码与二进制代码函数内语句级的语义特征自动比对,克服现有方法依赖编译过程或要求函数内存在对常量的引用的局限性,本发明对于给定关键语句,在控制流约束的情况下,提供一种通过数据流分析产生ast的方法,用于实现源代码与二进制代码的比对,以下称之为“语义比对”方法。为简化描述复杂度,本发明考虑这样的比对过程:从给定源代码中指定一条语句stsrc和其中的关键变量vsrc,同时从二进制代码也指定一条候选语句stbin和中间的关键变量vbin,针对vsrc和vbin生成数据流分析后的ast进行比对,即不涉及如何选定语句和关键变量的过程描述,以聚焦于语义特征提取和比对技术。本发明解决其技术问题所采用的技术方案是:一种源代码与二进制代码间的语义比对方法,包括以下步骤:1)从给定源代码中指定一条语句stsrc和其中的关键变量vsrc,从二进制代码中指定一条语句stbin和其中的关键变量vbin;2)分别对vsrc和vbin进行数据流分析,生成vsrc的抽象语法树和vbin的抽象语法树;3)对vsrc的抽象语法树和vbin的抽象语法树进行比对,判断vsrc和vbin是否语义一致;4)根据关键变量vsrc和vbin的语义一致判断结果,判定源代码与二进制代码间的语义相似性。进一步地,步骤2)包括:(1)对于关键变量v(包括vsrc和vbin),提取其所在语句st的基本块b至函数入口基本块be的最长路径p。该步骤提取变量v的控制流约束,其含义如下:令b1<b2表示基本块b1中存在语句在执行顺序上优先于基本块b2中的语句;令sete表示函数入口基本块be的集合:对于be∈sete,不存在任何基本块bi<be;令b-be表示从基本块b至入口基本块be的所经过的基本块数量(含基本块b和be),则最长路径的长度可表示为max{b-be},be∈sete,其中max{}表示最大值。对于最长路径p上的基本块,以b为起点回溯,采用先遇见先加入的方式放入路径中,且每个基本块不受循环影响而仅加入一次,一直到入口基本块be为止。(2)对于关键变量v,沿最长路径p通过赋值和计算语句追溯其数据组成来源,其原则为“追溯到函数内不能再追溯为止”,经提取抽象最终形成ast。该原则的含义为,在最长路径的约束下,以变量v为根节点,以赋值操作符或计算操作符为中间节点,以最终在函数内无法追溯的数据为叶节点。从来源来说,叶节点可包含以下4类数据(分类1):1.1函数内定义的局部变量:如源代码unsignedlen,x86架构二进制机器码反汇编后ebp-0x1c或ebp+var_1c等形式;1.2函数的传入参数:如源代码intzexportinflateback(strm,in,in_desc,out,out_desc)中的strm,in,in_desc,out和out_desc,x86架构二进制机器码反汇编后ebp+0x8或ebp+arg_0等形式;1.3函数内调用其它函数的返回值:如源代码ret=inflate_table(...)中的ret,x86架构二进制机器码反汇编后callsub_62e8b2f0;testeax,eax中eax寄存器所表示的值等形式;1.4常量(立即数、字符串、地址等):如源代码state->lenbits=7,x86架构二进制机器码反汇编后movdwordptr[ecx+54h],7中的数字7等形式。从表达形式上来说,叶节点可包含以下2类数据(分类2):2.1指针量(变量或常量):源代码中的指针量定义或引用时会用*,&或->等表示,二进制反汇编代码则会包括dwordptr以及中括号[…],如dwordptr[ecx+54h];2.2非指针量:其与指针量相反,源代码中不会出现*,&或->等定义或引用该类量,反汇编代码中也不会出现dwordptr以及中括号[…]等形式。组合分类1(1.1-1.4)和分类2(2.1-2.2),叶节点共包含4×2=8类数据。(3)比对指定关键变量vsrc和vbin的ast树。对中间节点和叶节点所表示的赋值语句或计算语句进行标记,检查该语句所在基本块是否位于循环之中:模糊比对标记:满足条件i)或ii)。条件i):基本块处于循环之中,则标记为进行模糊比对。条件ii):如该节点的祖先节点包含模糊比对标记,则将该中间节点标记为进行模糊比对;精确比对标记:满足条件iii)。条件iii):基本块不在循环之中,且该节点不包含具有模糊比对标记的祖先节点,则标记为采用精确比对。具体比对方法如下:a)从vsrc和vbin提取ast的根节点开始比对;b)对ast的节点进行合并,如树路径上存在相邻的父子节点包含赋值操作符,或者同一的运算操作符,则合并成同一节点,将合并前节点的子节点作为合并后新节点的子节点;c)判断1:对于vsrc的ast中间节点nsrc,如果其内容为赋值操作符,则不进行比较,深度遍历其子节点;如果其内容为运算操作符,则从vbin的ast深度遍历找到具有同样的运算操作符进的节点nbin,形成匹配对(nsrc,nbin)。一旦找不到同样的运算操作符,或者在ast的路径上间隔其它运算操作符,则认为vsrc和vbin提取ast并不一致;d)判断2:对于vsrc的ast叶子节点nsrc,如果其具有精确比对标记,且为分类1中的常量类型和分类2中的非指针量类型,则需能在vbin的ast深度遍历找到具有相同常量值的叶子节点nbin;如果为其它情况,则仅在vbin的ast深度遍历找到属于分类1和分类2中相同分类的叶子节点nbin。一旦找不到这样的节点,则认为vsrc和vbin提取ast并不一致;e)判断3:对于vsrc的ast节点n’src,如果其内容为运算操作符,搜索到vbin的ast中同样的运算操作符节点nbin,已与另一个节点nsrc形成匹配对(nsrc,nbin),且无法协调,则认为vsrc和vbin提取ast并不一致;此处的无法协调指不存在n’bin,使得匹配对组{(nsrc,nbin),(n’src,n’bin)},或者{(n’src,nbin),(nsrc,n’bin)}成立;f)当vsrc和vbin提取ast比对之后无上述不一致的情况,则认为两者为语义一致的变量。在源代码和二进制代码比对中,可根据多组关键变量的语义一致判定来判断目标比对代码的语义相似性。如果多组关键变量一致,则认为源代码和二进制代码在语义上相似。与上面方法对应地,本发明还提供一种源代码与二进制代码间的语义比对装置,其包括:抽象语法树生成模块,用于从给定源代码中指定一条语句stsrc和其中的关键变量vsrc,从二进制代码中指定一条语句stbin和其中的关键变量vbin,分别对vsrc和vbin进行数据流分析,生成vsrc的抽象语法树和vbin的抽象语法树;比对模块,用于对vsrc的抽象语法树和vbin的抽象语法树进行比对,判断vsrc和vbin是否语义一致;相似性判定模块,用于根据关键变量vsrc和vbin的语义一致判断结果,判定源代码与二进制代码间的语义相似性。进一步地,所述抽象语法树生成模块包括:最长路径提取模块,负责对于关键变量v,提取其所在语句st的基本块b至函数入口基本块be的最长路径p,其中v包括vsrc和vbin;数据依赖分析模块,负责对于关键变量v,沿最长路径p通过赋值和计算语句追溯其数据组成来源,经提取抽象最终形成抽象语法树。本发明还提供一种计算机,包括存储器和处理器,所述存储器存储计算机程序,所述计算机程序被配置为由所述处理器执行,所述计算机程序包括用于执行上面所述方法中各步骤的指令。本发明还提供一种软件代码的安全检测方法,包括以下步骤:a)收集二进制软件样本;b)采用上面所述的方法,将收集的二进制软件样本与存在安全漏洞的开源库中的源代码进行关键变量的比对;c)根据步骤b)的比对结果确定二进制软件样本中是否含有所述安全漏洞。本发明的有益效果是:本发明设计了一种面向源代码和二进制代码的语义提取和比对方式,能根据关键变量是否语义一致来判定推断源代码与二进制代码间的语义相似程度。该发明的语义设计是对ast构建、控制流分析和数据流分析等程序分析方法的方案定制。(1)相比公开工作中常见的将源代码项目编译为二进制可执行文件,并进行“二进制-二进制”比对的方法,本发明的方案不依赖人工干预和编译的过程,能提高比对成功率和效率。(2)相比少数公开工作中的“源代码-二进制”比对方法,本发明的方案不依赖于编译过程中输出的调试信息(或符号信息),也不要求函数中存在字符串等常量,能指定任意源代码和二进制代码函数中的关键变量进行比对。附图说明图1是本发明的实施流程图。图2是源代码和二进制文件的反汇编代码、反编译代码示例。图3是图2的示例中关键变量ast的提取示意图。图4是图3中关键变量ast经比对处理后的示意图。具体实施方式为使本发明的上述目的、特征和优点能够更加明显易懂,下面通过具体实施例和附图,对本发明做进一步详细说明。本发明的实施方式如图1所示。给定源代码src和二进制代码bin,指定其中的关键变量vsrc和vbin,(1)第一步,分别提取vsrc和vbin所在语句的基本块至函数入口基本块的最长路径(即经过基本块数量最多的路径);(2)第二步,以
发明内容中所述的追溯和分类方式,分别分析vsrc和vbin最长路径上的数据依赖,形成ast;(3)第三步,以
发明内容中所述的比对方式,判断vsrc和vbin的语义是否一致,进而根据关键变量是否语义一致来判定推断源代码与二进制代码间的语义相似程度。为了更好地说明本发明的工作流程,下面以被众多软件所复用的基础库zlib为例,图2所示为其1.2.8版本中inflateback函数的部分源代码((a)图)和二进制可执行文件中的部分反汇编代码((b)图)、反编译代码((c)图)。为了便于理解,此处主要以源代码和反编译代码为例进行比对,设定关键变量为图2中源代码中语句ret=inflate_table(codes,state->lens,19,&(state->next),&(state->lenbits),state->work);中的state->lens(即vsrc),反编译代码中if(sub_62e8b2f0(0,v179+112,19,v146,v145,v147))中的v179+112(即vbin)。对于指定的关键变量vsrc=state->lens和vbin=v179+112,本发明实施方式阐述如下:第一步:提取最长路径。对于源代码,可以用clang或antlr等工具提取基本块;对于反编译代码,可以用idapro或antlr等工具提取基本块;如inflateback函数在使用idapro解析之后共提取出224个基本块及其后继关系。在提取出基本块之后,对于每一对有后继关系的基本块建立连接边,设置权值为-1,使用floyd-warshall算法得出的最小值即为最长路径。第二步:分析数据依赖。图3中(a)图和(b)图分别表示vsrc和vbin所提取的ast。需要注意的是此处将v179+112视为一个变量,而不是变量v179与常量112相加,这是由于v179定义或被赋值时为指针型变量,如v179=*(_dword*)(a1+28);加号在此处仅用来取出指定偏移处内存中的数据,不对应源代码中的实际运算,因此将不被视为运算符。如
发明内容中所述,可以看到,经过对赋值或计算语句追溯来源之后,vsrc和vbin所提取的ast均包含3个叶节点。vsrc的追溯过程为:√vsrc=state->lens,即由state->lens赋值;√赋值语句state->lens[order[state->have++]]=0,即state->lens中的元素可能等于0;√赋值语句state->lens[order[state->have++]]=(unsignedshort)bits(3),即state->lens中的元素可能等于bits(3),宏展开后bits(3)为数字7;√赋值语句state=(structinflate_statefar*)strm->state,表示state来源于指针strm->state;√前述赋值语句可追踪到3个叶节点,常数-非指针0,常数-非指针bits(3),以及传入参数-指针z_streampstrm。vbin的追溯过程为:√vbin=v179+112,即由v179+112赋值;√赋值语句*(_word*)(v179+2*v38+112)=7中v38的值可能为0,因此变量v179+112可受v179+2*v38+112影响,被赋值为数字7;√变量v38可追溯赋值语句v38=(unsigned__int16)word_62e98520[v34++]→v34=*(_dword*)(v179+104)→*(_dword*)(v179+104)=0,直至被赋值为0;√变量v179可追溯赋值语句v179=*(_dword*)(a1+28),而a1来源于传入参数a1;√前述赋值语句可追踪到3个叶节点,常数-非指针0,常数-非指针7,以及传入参数-指针a1。第三步:比对。如
发明内容中所述,图4中(a)图和(b)图分别是vsrc和vbin经过标记和合并的ast,经过判断1,2和3比对之后,可以形成{(传入参数-指针z_streampstrm,传入参数-指针a1),(常数-非指针0,常数-非指针0),(常数-非指针bits(3),常数-非指针7)}的匹配对组。图4的(a)图、(b)图中,第二个文本框中只含有一个等号“=”,其表示第一个文本框中“=”右边的state->lens或v179+112的来源。√通过检查节点语句所属基本块是否属于循环之中,对节点进行模糊比对或精确比对的标记,如图4中(a)图和(b)图的叶节点标记;√进行节点合并:如树中相邻的父子节点同为赋值语句,或者同为具有同一运算操作符,则合并成同一节点。√经过对判断1,2和3对中间和叶节点的比对之后,得到(传入参数-指针z_streampstrm,传入参数-指针a1)精确匹配,(常数-非指针0,常数-非指针0),(常数-非指针bits(3),常数-非指针7)或(常数-非指针0,常数-非指针7),(常数-非指针bits(3),常数-非指针0)模糊匹配,未出现判断1,2和3所述的语义不一致情况。经比对,可以认为vsrc=state->lens和vbin=v179+112的语义一致。进一步,可以指定更多诸如vsrc和vbin的关键变量进行比对,判断代码的语义相似性。具体方法是:对于待比对的源代码和二进制代码,先在源代码中指定的多个关键变量,如果这些变量均能在二进制代码中对应找到语义相似的关键变量,则认为源代码和二进制代码具有语义相似性。本发明另一实施例提供一种源代码与二进制代码间的语义比对装置,其包括:抽象语法树生成模块,用于从给定源代码中指定一条语句stsrc和其中的关键变量vsrc,从二进制代码中指定一条语句stbin和其中的关键变量vbin,分别对vsrc和vbin进行数据流分析,生成vsrc的抽象语法树和vbin的抽象语法树;比对模块,用于对vsrc的抽象语法树和vbin的抽象语法树进行比对,判断vsrc和vbin是否语义一致;相似性判定模块,用于根据关键变量vsrc和vbin的语义一致判断结果,判定源代码与二进制代码间的语义相似性。其中,所述抽象语法树生成模块包括:最长路径提取模块,负责对于关键变量v,提取其所在语句st的基本块b至函数入口基本块be的最长路径p,其中v包括vsrc和vbin;数据依赖分析模块,负责对于关键变量v,沿最长路径p通过赋值和计算语句追溯其数据组成来源,经提取抽象最终形成抽象语法树。本发明另一实施例提供一种计算机,包括存储器和处理器,所述存储器存储计算机程序,所述计算机程序被配置为由所述处理器执行,所述计算机程序包括用于执行上面所述方法中各步骤的指令。在通过比对得到源代码与二进制代码间的语义相似性之后,可以进一步用于发现代码中的安全问题。例如,一旦某版本的开源库被报告存在安全漏洞,可进一步收集二进制软件样本并进行多个关键变量比对,发现存在该开源库漏洞的软件样本。以上实施例仅用以说明本发明的技术方案而非对其进行限制,本领域的普通技术人员可以对本发明的技术方案进行修改或者等同替换,而不脱离本发明的原理和范围,本发明的保护范围应以权利要求书所述为准。当前第1页12当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1