基于最小分支路径函数胎记的软件局部抄袭证据生成方法与流程

文档序号:14279571阅读:135来源:国知局
基于最小分支路径函数胎记的软件局部抄袭证据生成方法与流程
本发明涉及程序特征发现及软件抄袭检测领域,特别涉及一种软件局部抄袭证据生成的方法。
背景技术
:随着计算机软件产业迅速发展,软件的安全问题得到了越来越多的研究人员、教育人员及软件企业的重视。而开源软件的出现,更是将软件抄袭问题推到了风头浪尖。近年来,各类软件侵权案件时有发生,verizon、ebay、apple等公司都曾卷入相关案件当中。为了对抗软件抄袭,保护软件知识产权,国内外的研究人员提出了大量的软件抄袭检测技术。以应用场景和技术手段作为基准,可将现有的软件抄袭检测技术归为三类:源码抄袭检测技术,基于软件水印的抄袭检测技术,以及基于软件胎记的抄袭检测技术。但是,目前的软件抄袭检测技术存在一系列的局限性:1)目前大部分具有权威性的软件抄袭检测方法是针对源代码的,而在现实中,软件所有者通常是以二进制文件的形式发布软件,软件源代码在未取得一定的证据之前是很难获取;2)抄袭者为了躲避软件抄袭检测,通常使用成熟、强力的代码混淆技术和工具,使得抄袭程序与原程序在表面上呈现很大的不同,使得一部分软件抄袭检测方法失效;3)相较于整体抄袭,局部抄袭更为普遍,一方面是因为局部抄袭更容易符合抄袭者的要求,更加灵活,另一方面也因为使得计算出的软件与原版本之间的整体相似度较低,从而导致许多整体检测方法失效。4)现有的抄袭检测都只是提供一个简单的结果,没有具体且有力的抄袭证据作为佐证。技术实现要素:本发明的目的在于提出一种基于最小分支路径函数胎记的软件局部抄袭证据生成方法,以应对当前的软件抄袭检测的需要。本发明通过对程序进行逆向分析,提取出程序的静态信息;基于函数的控制流图、基本块、指令序列等,提取基于最小分支路径的函数胎记,以表征函数的行为特征;计算函数胎记之间的相似度,从而得到函数之间的相似性;基于函数间的相似度,结合函数调用图,构建出最优相似子图集,将其作为程序间局部抄袭的判断依据和有力的抄袭证据,为真实的软件侵权案件提供初步证据。为了实现上述目的,本发明采用以下技术方案:基于最小分支路径函数胎记的软件局部抄袭证据生成方法,包括如下步骤:步骤s101:基于反汇编技术,对原告程序p及被告程序q对应的可执行二进制文件进行反汇编,记录并分析生成的汇编代码,对于其包含的静态信息进行预处理并以数据表的形式存储;步骤s102:基于程序的函数内静态控制流图,将一个分支的起始基本块到下一个分支的起始基本块之间的基本块所包含的指令序列作为函数的一条最小分支路径,一个函数fid的函数胎记fbid是其所有最小分支路径构成的集合path={pathid,i|i=0,1,…n},提取原告程序p与被告程序q内所有函数对应的函数胎记pb={fbi|i=0,1,…,m1}以及qb={fbj'|j=0,1,…,m2};n为函数胎记fbid的所有最小分支路径的个数,m1和m2分别为原告程序p与被告程序q中所有函数胎记的个数;步骤s103:基于原告程序p内的所有函数胎记,计算其对于被告程序q内的所有函数的函数胎记相似度sim(fbi,fbj'),fbi∈pb&&fbj'∈qb;步骤s104:基于函数间的相似度以及函数间调用图,发现相似子图集,构建最优相似子图集;步骤s105:基于最优相似子图集,进行抄袭判定,如存在抄袭,生成抄袭证据。根据最优相似子图集的规模大小,并与原程序规模作比较从而判断程序是否存在抄袭,而生成的最优相似子图集则可作为被告程序q抄袭原告程序p的抄袭证据。如果存在抄袭,将步骤s104获得的最优相似子图集输出作为抄袭证据。进一步的,所述步骤s101具体为使用逆向分析工具来撤除编译和汇编过程,输入为机器语言,输出结果为汇编语言;对原告及被告程序p,q对应的二进制可执行文件进行反汇编,对反汇编后输出的汇编代码进行分析,对程序包含的静态信息进行预处理,删除库函数以及过小的函数,得到有效的函数信息,以数据表的形式记录存储,存储方式如下表所示;表名表结构functionsaddress#name#typebasicblocksid#parent_function#adressbasicblocks_instructionsbasicblock_id#instruction_addressinstructionsaddress#mnemonicoperandsaddress#expression_tree_idexpression_tree_nodesexpression_tree_id#expression_node_idexpression_nodesid#type#symbol#immediate#parent_idcontrol_flow_graphsid#parent_function#source#destinationcallgraphid#source#destination所述静态信息具体包括:基本块,函数,指令,助记符,操作数,函数内静态控制流图以及函数间调用图;所述过小的函数为指令数小于3的函数。进一步的,步骤s102中基于最小分支路径的函数胎记fbid即最小分支路径集合path的提取方法是基于函数的静态控制流图,对函数内的每一个基本块bid进行分析,如果该基本块的分支大于等于2或该基本块为所属函数的起始基本块,则提取以该基本块为起点的所有最小分支路径集合pathid={pathid,i|i=0,1,…,m},并将该集合加入所属函数胎记集合,path=path∪pathid,m为以基本块bid为起点的所有最小分支路径的个数。进一步的,步骤s102中提取基本块bid的最小分支路径的方法是为其每一个分支创建一条以bid为起点的路径pathid,i,对于每一条路径,将其后继基本块不断加入该路径中,直至遇到下一个分支,则该路径经过的基本块内的汇编指令构成了该最小分支路径,这些路径的集合pathid即为以该基本块为起点的所有最小分支路径。进一步的,步骤s102中提取基本块中汇编指令的方法是:首先读取汇编指令的助记符,接着读取该汇编指令对应的操作数的表达树id,根据表达树id读取对应的节点id,从而读取节点id对应的符号或立即数,遍历该表达树的各个节点,得到操作数,最后将助记符与操作数组合,得到该汇编指令的表达形式。进一步的,步骤s103中函数胎记之间相似度的计算方法是:令原告程序p中的函数fun_1的胎记fb1与被告程序q中函数fun_2的胎记fb2'分别表示为path1={path1,i|i=0,1,…,a},path2={path2,j|j=0,1,…,b},a为函数fun_1的函数胎记的所有最小分支路径的个数;b为函数fun_2的函数胎记的所有最小分支路径的个数;对于path1中的每一条路径path1,i,计算其与path2中每一条路径path2,j的相似度,基于这些相似度,寻找与path1,i最匹配的路径path2,match,并记录其相似度sim(path1,i,path2,match);基于fun_1的静态信息,以路径中包含的汇编指令个数li为权值,进行加权计算,从而得到函数胎记fb1与函数胎记fb2之间的相似度,计算公式为:式中:li——函数fun_1中第i条最小分支路径包含的汇编指令的个数;则函数之间的相似度sim(fun_1,fun_2)=sim(fb1,fb2')。进一步的,步骤s103中路径path1,i与path2,j之间相似度的计算方法分为四个步骤,分别是预处理,校准路径,基于助记符和操作数关联的汇编指令相似值计算,以及路径相似度计算;具体如下:a)预处理:预处理的方法是首先删除路径中所包含的跳转指令,接着将操作数抽象化;操作数抽象化是指将构成路径的指令中的具体操作数抽象为三类:寄存器,存储单元以及变量名,分别用reg,mem,val来表示;b)校准路径:校准路径的方法是使用lcs算法,以相同的助记符作为基准,对要进行相似性计算的两条路径path1,i,path2,j进行校准;校准后的两条路径为path1,i',path2,j',这两条路径汇编指令的数目是相同的,同时对应位置上的汇编指令的助记符也是相同的;c)基于助记符和操作数关联的汇编指令相似值计算:令校准后的路径path1,i',path2,j'表示为path1,i'=<ins1,ins2,…,insn>,path2,j'=<ins1',ins2',…,insn'>,其中,n为每条路径的汇编指令的数目。计算path1,i',path2,j'之间的相似值,首先计算对应位置的汇编指令inspos,inspos'之间的相似值,计算方法为对应位置的相同操作数的个数:sim_ins(inspos,inspos')=|{i|args(inspos)[i]=args(inspos')[i]}|式中:inspos,inspos'——两条汇编指令;args(inspos)[i]——汇编指令inspos的第i个操作数;d)路径相似度计算:将path1,i'中汇编指令的相似值相加,得到path1,i',path2,j'之间的相似值score(path1,i',path2,j');采用相同的方法,得到path1,i,path2,j与其自身的相似值score(path1,i,path1,i)与score(path2,j,path2,j);最后,进行标准化,得到路径path1,i,path2,j之间的相似度;进一步的,步骤s104中,相似子图是指以函数为节点,函数的调用关系为边,对应节点相似度较高且对相似的函数有相同的调用关系的子图;最优相似子图是指,对每个子图基于节点数目、对应节点相似值和节点权重赋予一个分数,分数最高的子图为该子图的最优相似子图;最优相似子图集是指每次加入一个最优相似子图所得到的集合{g1→g1',g2→g2',...,gn→gn'},g1,g2,...gn属于原告程序p,g1',g2',...gn'属于被告程序q,且g1,g2,...gn不相交,g1',g2',...gn'不相交;gi→gi'为一个相似子图,其中i=1,2,…n。进一步的,步骤s104中最优相似子图集发现的方法是:1)筛选出相似度大于阈值ε1的相似函数对:ff={(fun_i,fun_j)|fun_i∈p&&fun_j∈q&&sim(fun_i,fun_j)>ε1};2)基于函数间调用图,生成ff的相似子图集g,并计算每个子图的分数s;子图分数s是指子图中所有函数对的相似度的和,计算公式为:式中,n为子图中所有函数对的数目;3)提取最优相似子图gb,记录其分数sb,并入最优相似子图集;4)如果最优相似子图的分数大于ε2,更新ff,将目前最优相似子图集中包含的函数对从ff中移除,ff=ff-{(fun_i,fun_j)|fun_i∈gb||fun_j∈gb},并跳转至步骤2);否则,结束,并输出当前的最优相似子图集;其中阈值ε1的取值为0.5~1;ε2的取值大于1小于第一个提取的最优相似子图gb的分数sb。进一步的,步骤s104中生成ff的相似子图集g的方法是:2.1)将ff={ffi|i=0,1,…,n}中的第一个函数对ff0作为一个子图加入子图集g中;g={{ff0}};n为ff中函数对的个数;2.2)从ffi,i=1开始,遍历ff,对于ffi:a)遍历子图集g={gj|j=0,1,…,m};m为子图集g中的子图个数;b)如果ffi与gj不冲突,且基于函数调用图,对于ffi,存在gj中的函数对与其符合调用关系,则g=g∪{gj∪{ffi}};2.3)将函数对ffi作为一个子图加入子图集g中,g=g∪{{ffi}};2.4)输出相似子图集g;步骤s104中判断一个函数对ffi=(fun_i,fun_i')是否与子图gj冲突的方法是:如果存在ff=(fun,fun')∈gj,使得fun_i=fun且fun_i'≠fun',或fun_i'=fun'且fun_i≠fun,则函数对ffi与子图gj冲突。本发明的进一步改进在于:步骤s102具体包括以下步骤:步骤s201:初始化最小分支路径的集合以及计数器id=0;步骤s202:从函数内静态控制流图中读取基本块bid的内容;步骤s203:判断是否计数器id==0或bid的分支数目大于等于2,若是,则转入步骤s204,否则转入步骤s206;步骤s204:提取以基本块bid为起点的所有最小分支路径集合pathid={pathid,i|i=0,1,…,m},并将该集合加入所属函数胎记集合,path=path∪pathid;m为以基本块bid为起点的所有最小分支路径的个数;步骤s205:判断是否计数器id==n,若是,则转入步骤s207,否则转入步骤s206;步骤s206:计数器id++,并转入步骤s202进行下一轮的分析;步骤s207:输出最小分支路径的集合path作为函数f的函数胎记fb。本发明的进一步改进在于:步骤s102具体包括以下步骤:步骤s301:输入基本块bid及其m+1个后继基本块bid,0,bid,1,...bid,m;步骤s302:初始化bid的最小分支路径的集合以及计数器i=0;步骤s303:为其后继基本块bid,i创建一条以bid为起点的路径pathid,i,pathid,i=bid+bid,i;步骤s304:创建指针pt指向当前后继基本块bid,i,pt→bid,i;步骤s305:判断指针pt指向的基本块是否有且只有一个后继基本块pt.bs,若是,则转入步骤s306,否则转入步骤s307;步骤s306:将后继基本块pt.bs加入路径pathid,i中,pathid,i=pathid,i+pt.bs,指针pt指向其后继基本块pt.bs,pt→pt.bs,并转入步骤s305进行下一轮的分析;步骤s307:将当前路径pathid,i并入bid的最小分支路径的集合pathid来,pathid=pathid∪{pathid,i},计数器i++;步骤s308:判断是否计数器i>m,若是,则转入步骤s309,否则转入步骤s303进行下一轮的分析;步骤s309:输出基本块bid的所有最小分支路径集合pathid。本发明的进一步改进在于:步骤s103具体包括以下步骤:步骤s401:初始化计数器i=0;步骤s402:从函数fun_1的函数胎记path1={path1,i|i=0,1,…,a}中读取最小分支路径path1,i;a为函数fun_1的函数胎记的所有最小分支路径的个数;步骤s403:读取函数fun_2的函数胎记path2={path2,j|j=0,1,…,b},计算path1,i与path2中每一条路径path2,j的相似度;b为函数fun_2的函数胎记的所有最小分支路径的个数;步骤s404:寻找与path1,i最匹配的路径path2,match,并记录其相似度sim(path1,i,path2,match),存入路径间相似度矩阵sim_path中,sim_path=[sim(path1,i,path2,match)],i=0,1,…,a;步骤s405:判断是否计数器i==a,若是,则转入步骤s407,否则转入步骤s406;步骤s406:计数器i++,并转入步骤s402进行下一轮的分析;步骤s407:基于路径间相似度矩阵sim_path以及从函数胎记path1中读取的fun_1的静态信息,以路径中包含的汇编指令个数li为权值,进行加权计算,计算公式为:式中:li——函数fun_1中第i条最小分支路径包含的汇编指令的个数;步骤s408:输出函数fun_1与函数fun_2之间的相似度sim(fun_1,fun_2)=sim(fb1,fb2'),并存入函数间相似度矩阵sim_fun中,sim_fun=[sim(fun_i,fun_j)],i=0,1,…,m1,j=0,1,…,m2。本发明的进一步改进在于:步骤s103中路径path1,i与path2,j之间相似度的计算方法可分为四个步骤,分别是预处理,校准路径,基于助记符和操作数关联的汇编指令相似值计算,以及路径相似度计算。具体包括以下步骤:步骤s501:输入最小分支路径path1,i与path2,j;步骤s502:对路径path1,i和path2,j进行预处理,首先删除路径中所包含的跳转指令(包括je、jne、jz、jnz、js、jns、jc、jnc、jo、jno、ja、jna、jae、jnae、jg、jng、jge、jnge、jb、jnb、jbe、jnbe、jl、jnl、jle、jnle、jp、jnp、jpe、jpo等跳转指令);接着抽象化操作数,将构成路径的指令中的具体操作数抽象为三类:寄存器,存储单元以及变量名,分别用reg,mem,val来表示;步骤s503:使用lcs算法校准路径,以相同的助记符作为基准,对要进行相似性计算的两条路径path1,i,path2,j进行校准。校准后的两条路径为path1,i',path2,j',这两条路径汇编指令的数目是相同的,同时对应位置上的汇编指令的助记符也是相同的;步骤s504:基于助记符和操作数关联的汇编指令相似值计算,令校准后的路径path1,i',path2,j'表示为path1,i'=<ins1,ins2,…,insn>,path2,j'=<ins1',ins2',…,insn'>,其中,n为每条路径的汇编指令的数目。计算path1,i',path2,j'之间的相似值,首先计算对应位置的汇编指令inspos,inspos'之间的相似值,计算方法为取对应位置的相同操作数的个数,令inspos,inspos'表示两条汇编指令,args(inspos)[i]表示汇编指令inspos的第i个操作数,计算公式为:sim(inspos,inspos')=|{i|args(inspos)[i]=args(inspos')[i]}|式中:inspos,inspos'——两条汇编指令;args(inspos)[i]——汇编指令inspos的第i个操作数;步骤s505:进行路径相似度计算,将path1,i'中汇编指令的相似值相加,得到path1,i',path2,j'之间的相似值score(path1,i',path2,j'),计算公式为采用相同的方法,得到path1,i,path2,j与其自身的相似值score(path1,i,path1,i)与score(path2,j,path2,j)。最后,进行标准化,得到路径path1,i,path2,j之间的相似度:步骤s506:输出最小分支路径path1,i与path2,j间的相似度sim(path1,i,path2,j)。本发明的进一步改进在于:步骤s104中最优相似子图集发现的方法具体包括以下步骤:步骤s601:输入阈值ε1和ε2,ε1用于筛选相似函数对,ε2用于判断是否可以结束循环;其中阈值ε1的取值为0.5~1;ε2的取值大于1小于第一个提取的最优相似子图gb的分数sb;步骤s602:基于函数间相似度矩阵sim_fun,筛选出相似度大于一定阈值ε1的相似函数对ff:ff={(fun_i,fun_j)|fun_i∈p&&fun_j∈q&&sim(fun_i,fun_j)>ε1};步骤s603:基于函数间调用图,生成ff的相似子图集g,并计算子图分数s;子图分数s是指子图中所有函数对的相似度的和,计算公式为:式中,n为子图中所有函数对的数目;步骤s604:提取最优相似子图gb,记录其分数sb,将其并入最优相似子图集;步骤s605:判断是否当前最优相似子图集的分数sb>ε2,若是,则转入步骤s606,否则转入步骤s607;步骤s606:更新ff,将目前最优相似子图集中包含的函数对从ff中移除,ff=ff-{(fun_i,fun_j)|fun_i∈gb||fun_j∈gb},并跳转至步骤s603进行下一轮的分析;步骤s607:输出当前的最优相似子图集。本发明的进一步改进在于:步骤s104中生成ff的相似子图集g的方法具体包括以下步骤:步骤s701:输入相似函数对集合ff={ffi|i=0,1,…,n};n为ff中函数对的个数;步骤s702:将ff={ffi|i=0,1,…,n}中的第一个函数对ff0作为第一个子图加入子图集,初始化相似子图集g={{ff0}}和计数器i=1;步骤s703:遍历子图集g={gj|j=0,1,…,m},初始化计数器j=1;m为子图集g中的子图个数;步骤s704:判断ffi是否与gj冲突,若是,则转入步骤s707,否则转入步骤s705;步骤s705:基于函数调用图,判断对于ffi,是否存在gj中的函数对与其符合调用关系,若是,则转入步骤s706,否则转入步骤s707;步骤s706:将ffi加入图gj组成的子图加入子图集g中,g=g∪{gj∪{ffi}};步骤s707:判断是否计数器j==m,若是,则转入步骤s709,否则转入步骤s708;步骤s708:计数器j++,并转入步骤s704进行下一轮的分析;步骤s709:将函数对ffi作为一个子图加入子图集g中,g=g∪{{ffi}};步骤s710:判断是否计数器i==n,若是,则转入步骤s712,否则转入步骤s711;步骤s711:计数器i++,并转入步骤s703进行下一轮的分析;步骤s712:输出当前相似子图集g。本发明的进一步改进在于:步骤s104中判断一个函数对ffi=(fun_i,fun_i')是否与子图gj冲突的方法是:如果存在ff=(fun,fun')∈gj,使得fun_i=fun且fun_i'≠fun',或fun_i'=fun'且fun_i≠fun,则函数对ffi与子图gj冲突。相对于现有技术,本发明具有以下有益效果:1)本发明方法能够直接针对二进制代码,不依赖于源代码,不依赖特定的编程语言或平台,具有更好的适用性;2)本发明的检测手段可以应对各种各样的成熟、强力的代码混淆技术和工具,提高对深度混淆的检测能力;3)本发明方法不仅能够应用于整体抄袭的情况,还能够应对局部抄袭的场景;4)不同于现有的抄袭检测技术,本方法不仅可以提供是否存在抄袭的结果,并且对抄袭情况,可以提供具体且有力的抄袭证据。附图说明图1为本发明基于最小分支路径函数胎记的软件局部抄袭证据生成方法整体流程图;图2为基于最小分支路径的函数胎记提取过程流程图;图3为基本块的最小分支路径提取过程流程图;图4为函数间相似度计算方法流程图;图5为路径间相似度计算方法流程图;图6为最优相似子图集发现方法流程图;图7为相似子图集生成过程流程图;图8为函数的控制流图及其最小分支路径的示意图;其中图8(a)为函数f的控制流图;图8(b)为函数f的所有最小分支路径图;图9为程序的函数调用图及最优相似子图的示意图;其中图9(a)为程序p函数调用图示意图;图9(b)为程序q函数调用图示意图;图9(c)为程序p、q最优相似子图示意图。具体实施方式以下结合附图详细说明本发明基于最小分支路径函数胎记的软件局部抄袭证据生成方法的具体实施方式。图1为基于最小分支路径函数胎记的软件局部抄袭证据生成方法整体处理流程。本发明一种基于最小分支路径函数胎记的软件局部抄袭证据生成方法,包括以下步骤:步骤s101:使用逆向分析工具如idapro、binnavi等,实现对原告程序p及被告程序q对应的可执行二进制代码的反汇编,提取出其包含的静态信息,进行预处理并以数据表的形式存储。具体而言,提取并分析与基本块,函数,指令,助记符,操作数,函数内静态控制流图以及函数间调用图的有关的静态信息,删除库函数以及指令数小于3的函数,得到有效的函数信息,并对其进行整理与分析,按照下表所示,以数据表的形式记录存储所有数据。表1:数据表表名及结构表名表结构functionsaddress#name#typebasicblocksid#parent_function#adressbasicblocks_instructionsbasicblock_id#instruction_addressinstructionsaddress#mnemonicoperandsaddress#expression_tree_idexpression_tree_nodesexpression_tree_id#expression_node_idexpression_nodesid#type#symbol#immediate#parent_idcontrol_flow_graphsid#parent_function#source#destinationcallgraphid#source#destination步骤s102:基于程序的函数内静态控制流图构建函数胎记,一个函数fid的函数胎记fbid是其所有最小分支路径构成的集合path={pathid,i|i=0,1,…n},提取原告程序p与被告程序q内所有函数对应的函数胎记pb={fbi|i=0,1,…,m1}以及qb={fbj'|j=0,1,…,m2};n为函数胎记fbid的所有最小分支路径的个数,m1和m2分别为原告程序p与被告程序q中所有函数胎记的个数。结合图2,具体而言,将一个分支的起始基本块到下一个分支的起始基本块之间的基本块所包含的指令序列作为函数的一条最小分支路径,基于最小分支路径的函数胎记提取具体包括以下步骤:步骤s201:初始化最小分支路径的集合以及计数器id=0;步骤s202:从函数内静态控制流图中读取基本块bid的内容;步骤s203:判断是否计数器id==0或bid的分支数目大于等于2,若是,则转入步骤s204,否则转入步骤s206;步骤s204:提取以基本块bid为起点的所有最小分支路径集合pathid={pathid,i|i=0,1,…,m},并将该集合加入所属函数胎记集合,path=path∪pathid;m为以基本块bid为起点的所有最小分支路径的个数;步骤s205:判断是否计数器id==n,若是,则转入步骤s207,否则转入步骤s206;步骤s206:计数器id++,并转入步骤s202进行下一轮的分析;步骤s207:输出最小分支路径的集合path作为函数f的函数胎记fb。其中,提取基本块bid的最小分支路径的方法具体包括以下步骤:步骤s301:输入基本块bid及其m+1个后继基本块bid,0,bid,1,...bid,m;步骤s302:初始化bid的最小分支路径的集合以及计数器i=0;步骤s303:为其后继基本块bid,i创建一条以bid为起点的路径pathid,i,pathid,i=bid+bid,i;步骤s304:创建指针pt指向当前后继基本块bid,i,pt→bid,i;步骤s305:判断指针pt指向的基本块是否有且只有一个后继基本块pt.bs,若是,则转入步骤s306,否则转入步骤s307;步骤s306:将后继基本块pt.bs加入路径pathid,i中,pathid,i=pathid,i+pt.bs,指针pt指向其后继基本块pt.bs,pt→pt.bs,并转入步骤s305进行下一轮的分析;步骤s307:将当前路径pathid,i并入bid的最小分支路径的集合pathid来,pathid=pathid∪{pathid,i},计数器i++;步骤s308:判断是否计数器i>m,若是,则转入步骤s309,否则转入步骤s303进行下一轮的分析;步骤s309:输出基本块bid的所有最小分支路径集合pathid。例如函数f的控制流图如图8(a)所示,则按照以上步骤可提取出最小分支路径4条如图8(b)所示,构成该函数的函数胎记。步骤s103:基于原告程序p内的所有函数胎记,计算其对于被告程序q内的所有函数的函数胎记相似度sim(fbi,fbj'),fbi∈pb&&fbj'∈qb。其中函数胎记之间相似度的计算方法是:令函数fun_1的胎记fb1与函数fun_2的胎记fb2分别表示为path1={path1,i|i=0,1,…,a},path2={path2,j|j=0,1,…,b},a为函数fun_1的函数胎记的所有最小分支路径的个数;b为函数fun_2的函数胎记的所有最小分支路径的个数;对于path1中的每一条路径path1,i,计算其与path2中每一条路径path2,j的相似度,基于这些相似度,寻找与path1,i最匹配的路径path2,match,并记录其相似度sim(path1,i,path2,match)。基于fun_1的静态信息,以路径中包含的汇编指令个数li为权值,进行加权计算,从而得到函数胎记fb1与函数胎记fb2之间的相似度sim(fbi,fbj')。具体包括以下步骤:步骤s401:初始化计数器i=0;步骤s402:从函数fun_1的函数胎记path1={path1,i|i=0,1,…,a}中读取最小分支路径path1,i;步骤s403:读取函数fun_2的函数胎记path2={path2,j|j=0,1,…,b},计算path1,i与path2中每一条路径path2,j的相似度;步骤s404:寻找与path1,i最匹配的路径path2,match,并记录其相似度sim(path1,i,path2,match),存入路径间相似度矩阵sim_path中,sim_path=[sim(path1,i,path2,match)],i=0,1,…,a;步骤s405:判断是否计数器i==a,若是,则转入步骤s407,否则转入步骤s406;步骤s406:计数器i++,并转入步骤s402进行下一轮的分析;步骤s407:基于路径间相似度矩阵sim_path以及从函数胎记path1中读取的fun_1的静态信息,以路径中包含的汇编指令个数li为权值,进行加权计算,计算公式为:式中:li——函数fun_1中第i条最小分支路径包含的汇编指令的个数;步骤s408:输出函数fun_1与函数fun_2之间的相似度sim(fun_1,fun_2)=sim(fb1,fb2'),并存入函数间相似度矩阵sim_fun中,sim_fun=[sim(fun_i,fun_j)],i=0,1,…,m1,j=0,1,…,m2。例如函数fun_1包含路径path1、path2、path3,函数fun_2包含路径patha、pathb、pathc,它们两两之间的相似度如下表所示,则路径间相似度矩阵sim_path=[0.990.870.86]。表2:路径相似度举例示意图相似度pathapathbpathcpath10.760.860.99path20.540.870.18path30.860.150.47如果路径path1、path2、path3中包含的汇编指令个数分别为19、25、8,则函数fun_1与函数fun_2之间的相似度其中路径path1,i与path2,j之间相似度的计算方法可分为四个步骤,分别是预处理,校准路径,基于助记符和操作数关联的汇编指令相似值计算,以及路径相似度计算。具体包括以下步骤:步骤s501:输入最小分支路径path1,i与path2,j;步骤s502:对路径path1,i和path2,j进行预处理,首先删除路径中所包含的跳转指令(包括je、jne、jz、jnz、js、jns、jc、jnc、jo、jno、ja、jna、jae、jnae、jg、jng、jge、jnge、jb、jnb、jbe、jnbe、jl、jnl、jle、jnle、jp、jnp、jpe、jpo等跳转指令);接着抽象化操作数,将构成路径的指令中的具体操作数抽象为三类:寄存器,存储单元以及变量名,分别用reg,mem,val来表示;步骤s503:使用lcs算法校准路径,以相同的助记符作为基准,对要进行相似性计算的两条路径path1,i,path2,j进行校准。校准后的两条路径为path1,i',path2,j',这两条路径汇编指令的数目是相同的,同时对应位置上的汇编指令的助记符也是相同的;步骤s504:基于助记符和操作数关联的汇编指令相似值计算,令校准后的路径path1,i',path2,j'表示为path1,i'=<ins1,ins2,…,insn>,path2,j'=<ins1',ins2',…,insn'>,其中,n为每条路径的汇编指令的数目。计算path1,i',path2,j'之间的相似值,首先计算对应位置的汇编指令inspos,inspos'之间的相似值,计算方法为取对应位置的相同操作数的个数,令inspos,inspos'表示两条汇编指令,args(inspos)[i]表示汇编指令inspos的第i个操作数,计算公式为:sim_ins(inspos,inspos')=|{i|args(inspos)[i]=args(inspos')[i]}|式中:inspos,inspos'——两条汇编指令;args(inspos)[i]——汇编指令inspos的第i个操作数;步骤s505:进行路径相似度计算,将path1,i'中汇编指令的相似值相加,得到path1,i',path2,j'之间的相似值score(path1,i',path2,j'),计算公式为采用相同的方法,得到path1,i,path2,j与其自身的相似值score(path1,i,path1,i)与score(path2,j,path2,j)。最后,进行标准化,得到路径path1,i,path2,j之间的相似度步骤s506:输出最小分支路径path1,i与path2,j间的相似度sim(path1,i,path2,j)。例如路径path1=<(push,ebp),(mov,ebp,esp),(push,ebx),(sub,esp,4h),(cmp,byteds:[completed.6159],byte0h),(jnz,loc_8049f6f),(mov,byteds:[completed.6159],byte1h)>,path2=(mov,eax,ds:[dtor_idx.6161]),(mov,ebx,__dtor_end__),(sub,ebx,__dtor_list__),(sar,ebx,byte2h),(sub,ebx,1h),(cmp,eax,ebx),(jnb,loc_8049f68),(lea,esi,ds:[esi+0h])>,经过预处理可抽象为path1=<(push,reg),(mov,reg,reg),(push,reg),(sub,reg,val),(cmp,mem,val),(mov,mem,val)>,path2=(mov,reg,mem),(mov,reg,val),(sub,reg,val),(sar,reg,val),(sub,reg,val),(cmp,reg,reg),(lea,reg,mem)>,采用lcs算法,以相同的助记符作为基准,校准后的两条路径为path1’=<(mov,reg,reg),(sub,reg,val),(cmp,mem,val)>,path2’=(mov,reg,mem),(sub,reg,val),(cmp,reg,reg)>,两条路径对应的指令之间的相似值依次为1、2、0,则校准后路径的相似值为score(path1',path2')=3,最后通过标准化得到路径间的相似值为步骤s104:基于函数间的相似度以及函数间调用图,发现相似子图集,构建最优相似子图集。首先基于给定的阈值以及函数间的相似度,进行相似函数对的筛选;生成所有相似函数对的的相似子图集,然后从中提取最优相似子图,构建最优相似子图集。具体描述为:相似子图g1→g1'是指以函数为节点,函数的调用关系为边,对应节点相似度较高且对相似的函数有相同的调用关系的子图。最优相似子图是指,对每个子图基于节点数目、对应节点相似值和节点权重赋予一个分数,分数最高的子图为该子图的最优相似子图。最优相似子图集是指每次加入一个最优相似子图所得到的集合{g1→g1',g2→g2',...,gn→gn'},g1,g2,...gn属于原告程序p,g1',g2',...gn'属于被告程序q,且g1,g2,...gn不相交,g1',g2',...gn'不相交。最优相似子图集发现的方法具体包括以下步骤:步骤s601:输入阈值ε1和ε2,ε1用于筛选相似函数对,ε2用于判断是否可以结束循环;其中阈值ε1的取值为0.5~1;ε2的取值大于1小于第一个提取的最优相似子图gb的分数sb;步骤s602:基于函数间相似度矩阵sim_fun,筛选出相似度大于一定阈值ε1的相似函数对ff:ff={(fun_i,fun_j)|fun_i∈p&&fun_j∈q&&sim(fun_i,fun_j)>ε1};步骤s603:基于函数间调用图,生成ff的相似子图集g,并计算子图分数s;子图分数s是指子图中所有函数对的相似度的和,计算公式为:式中,n为子图中所有函数对的数目;步骤s604:提取最优相似子图gb,记录其分数sb,将其并入最优相似子图集;步骤s605:判断是否当前最优相似子图集的分数sb>ε2,若是,则转入步骤s606,否则转入步骤s607;步骤s606:更新ff,将目前最优相似子图集中包含的函数对从ff中移除,ff=ff-{(fun_i,fun_j)|fun_i∈gb||fun_j∈gb},并跳转至步骤s603进行下一轮的分析;步骤s607:输出当前的最优相似子图集。其中生成ff的相似子图集g的方法具体包括以下步骤:步骤s701:输入相似函数对集合ff={ffi|i=0,1,…,n};n为ff中函数对的个数;步骤s702:将ff={ffi|i=0,1,…,n}中的第一个函数对ff0作为第一个子图加入子图集,初始化相似子图集g={{ff0}}和计数器i=1;步骤s703:遍历子图集g={gj|j=0,1,…,m},初始化计数器j=1;m为子图集g中的子图个数;步骤s704:判断ffi是否与gj冲突(判断方法是:如果存在ff=(fun,fun')∈gj,使得fun_i=fun且fun_i'≠fun',或fun_i'=fun'且fun_i≠fun,则函数对ffi与子图gj冲突),若是,则转入步骤s707,否则转入步骤s705;步骤s705:基于函数调用图,判断对于ffi,是否存在gj中的函数对与其符合调用关系,若是,则转入步骤s706,否则转入步骤s707;步骤s706:将ffi加入图gj组成的子图加入子图集g中,g=g∪{gj∪{ffi}};步骤s707:判断是否计数器j==m,若是,则转入步骤s709,否则转入步骤s708;步骤s708:计数器j++,并转入步骤s704进行下一轮的分析;步骤s709:将函数对ffi作为一个子图加入子图集g中,g=g∪{{ffi}};步骤s710:判断是否计数器i==n,若是,则转入步骤s712,否则转入步骤s711;步骤s711:计数器i++,并转入步骤s703进行下一轮的分析;步骤s712:输出当前相似子图集g。例如原告程序p与被告程序q的函数调用图如图9(a)、(b)所示,其中节点代表函数,有向连接线表示的是函数之间的调用关系,通过最优相似子图的提取可得到如图9(c)所示的最优相似子图,左边的函数均属于原告程序p,右边的属于被告程序q,虚线连接的两个函数就是相似函数对。步骤s105:基于最优相似子图集,进行抄袭判定,如存在抄袭,生成抄袭证据。具体描述为:根据最优相似子图集的规模大小,并与原程序规模作比较从而判断程序是否存在抄袭,而生成的最优相似子图集则可作为被告程序q抄袭原告程序p的抄袭证据。在实际的应用中,还需要考虑最优相似子图集中所包含的模块是否是功能模块亦或是通用模块等具体问题,如果最优相似子图集中全部为通用模块,则判断不存在抄袭;如果最优相似子图集中存在至少一个功能模块相同,则可以认定存在抄袭;如果存在抄袭,将步骤s104获得的最优相似子图集输出作为抄袭证据。其中,功能模块为原告程序所原创的模块。当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1