CN114780103B - 一种基于图匹配网络的语义类代码克隆检测方法 - Google Patents
一种基于图匹配网络的语义类代码克隆检测方法 Download PDFInfo
- Publication number
- CN114780103B CN114780103B CN202210450356.XA CN202210450356A CN114780103B CN 114780103 B CN114780103 B CN 114780103B CN 202210450356 A CN202210450356 A CN 202210450356A CN 114780103 B CN114780103 B CN 114780103B
- Authority
- CN
- China
- Prior art keywords
- code
- node
- var
- data
- operator
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/43—Checking; Contextual analysis
- G06F8/436—Semantic checking
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/70—Software maintenance or management
- G06F8/75—Structural analysis for program understanding
- G06F8/751—Code clone detection
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06N—COMPUTING ARRANGEMENTS BASED ON SPECIFIC COMPUTATIONAL MODELS
- G06N3/00—Computing arrangements based on biological models
- G06N3/02—Neural networks
- G06N3/04—Architecture, e.g. interconnection topology
- G06N3/044—Recurrent networks, e.g. Hopfield networks
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06N—COMPUTING ARRANGEMENTS BASED ON SPECIFIC COMPUTATIONAL MODELS
- G06N3/00—Computing arrangements based on biological models
- G06N3/02—Neural networks
- G06N3/08—Learning methods
- G06N3/084—Backpropagation, e.g. using gradient descent
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Physics & Mathematics (AREA)
- Software Systems (AREA)
- General Physics & Mathematics (AREA)
- Computational Linguistics (AREA)
- Data Mining & Analysis (AREA)
- Biophysics (AREA)
- Evolutionary Computation (AREA)
- General Health & Medical Sciences (AREA)
- Molecular Biology (AREA)
- Computing Systems (AREA)
- Biomedical Technology (AREA)
- Artificial Intelligence (AREA)
- Mathematical Physics (AREA)
- Life Sciences & Earth Sciences (AREA)
- Health & Medical Sciences (AREA)
- Machine Translation (AREA)
Abstract
本发明公开了一种基于图匹配网络的语义类代码克隆检测方法,目的是解决语义类克隆检测结果不准确的问题。技术方案是:构建由代码补全模块、代码中间表示提取模块、语义图构建模块、代码向量生成模块和向量相似度计算器构成的代码克隆检测系统;使用语义类代码克隆数据集对代码向量生成模块中的深度学习模型进行训练;使用代码克隆检测系统对待检测代码进行代码补全、提取代码中间表示、构建代码语义图,训练后的代码向量生成模块将代码语义图转化为高维向量,再使用向量相似度计算器判断向量的相似度是否超过阈值以判断待检测代码是否是克隆代码。采用本发明可完整获取代码语义信息,有效检测语义类代码克隆,且在代码不可编译时仍能进行检测。
Description
技术领域
本发明涉及大型软件维护中的克隆检测技术,具体涉及一种基于图匹配网络的代码克隆检测方法。
背景技术
随着计算机的发展,计算机软件已经在社会各个领域得到了广泛的应用,在现代社会中扮演着举足轻重的角色,发挥了重要的作用。随着各行各业对软件系统的需求日益扩增,现代软件系统的代码规模逐渐扩大,导致现代软件系统的开发往往需要耗费大量的人力以及时间。为了提高现代软件系统开发人员在软件开发中的效率,开发人员在开发软件过程中往往会复用一些已有的代码。复用代码的方法主要包括从代码仓库中搜索满足需求的代码,对代码简要修改和复制到目标软件系统中、使用成熟的开发框架例如Spring、Tensorflow等、针对具体任务使用前人总结的设计模式。上述方法虽然提高了开发人员的软件开发效率,但也催生了代码克隆现象。代码克隆是指代码仓库中两段相同或相似的代码。根据已有的研究工作显示,代码克隆已经广泛的存在于现代软件系统之中。在Linux操作系统内核中包含27%-35%的代码存在代码克隆,在当前最大的代码仓库Github中,超过70%的代码都存在代码克隆。虽然重复使用已有的代码可以显著提升软件开发人员的开发效率,但是重复使用已有代码也有可能引入潜藏的漏洞,如在复用代码时,为根据上下文对代码进行更改,使得引入预期外的控制流或数据流。因此代码克隆检测尤为重要。利用代码克隆检测,软件维护人员可以根据已知的恶意程序代码或含有漏洞的代码检测在软件中其他可能潜藏的恶意软件代码和含有漏洞的代码。
根据两段代码的相似程度的不同,一般将代码克隆分为四类。第一类代码克隆指除了注释和空格不同,其他都相同的两段代码。第二类代码克隆指仅仅函数名或变量名不同的两段代码。第三类代码克隆指在保持语法结构不变的基础上,在代码语句上略有增删的两段代码。第四类代码克隆也叫做语义类代码克隆,指语法结构不同,但是代码语义相同的两段代码。针对代码克隆的种类不同,现有主要有基于匹配和基于深度学习的方法检测代码克隆。基于匹配的代码克隆检测方法,主要通过将代码进行一些转换,再根据代码转换之后的表示形式,利用对应的相似比较算法,判断两段代码是否相似。例如Zu Yue等人在ASE2020会议上发表的文章“CCGraph:a PDG-based code clone detector withapproximate graph matching(一种利用相似图匹配算法的基于程序依赖图的克隆检测方法,简称CCGRAPH)”,将代码转化为包含其数据流信息和控制流信息的程序依赖图。为了比较两段代码的程序依赖图的相似性,他们使用Weisfeiler-Lehman图核算法来比较两个图的相似性,最后根据两个图的相似性是否超过既定阈值来判断两段代码是否是克隆代码。基于匹配的克隆检测方法速度较快,不需要前期准备工作,并且在前三种类型的代码克隆检测中可以取得较好的准确率和召回率。但是在解决语义类代码克隆问题时,基于匹配的克隆检测方法的准确率和召回率都有显著下降,导致开发人员在查找语义类克隆检测时,仍然需要花费大量的人力物力检查匹配的克隆检测方法的输出结果。基于深度学习的代码克隆检测方法是使用深度学习模型将代码转化为可以表示其含义的高维向量,通过训练深度学习模型,可以使克隆代码的向量在高维空间之中更近似。在判断一对代码是否是克隆代码时,使用训练好的深度学习模型将他们转化为高维向量,根据代码向量距离判断两段代码是否是克隆代码。例如Hao Yu等人在ICPC2019会议上发表的文章“Neural detectionof semantic code clones via tree-based convolution(基于树型卷积的语义代码克隆检测方法,简称TBCCD)”,将代码转化为抽象语法树,然后利用树型卷积模型将代码的抽象语法树转化为向量,最后比较代码向量的相似度判断代码是否为克隆代码。基于深度学习的代码克隆方法可以更有效的理解代码的语义,因此可以有效检测出语义类代码克隆。但是目前的基于深度学习的代码克隆检测方法主要使用以LSTM网络为代表的基于文本的深度学习模型,只学习了代码的文本和语法信息,在准确率和召回率仍有待提高。
综上,如何提供一种检测语义类代码克隆的方法,更好地挖掘代码中的信息,更好地使用深度学习模型学习代码语义,使得代码克隆检测更准确,是本领域技术人员正在探讨的热点问题。
发明内容
本发明要解决的技术问题是针对语义类克隆检测结果不准确,代码语义信息获取不全面问题,提供一种基于图匹配网络的代码克隆检测方法。此方法基于深度学习检测代码克隆的方法框架,抽取代码的数据流控制流信息构建代码语义图,更完整的提取代码语义信息。使用图匹配网络,可以更有效地学习代码语义图的语义信息,进而更准更全地查找语义类代码克隆。
为解决上述问题,本发明的技术方案是:首先构建由代码补全模块、代码中间表示提取模块、语义图构建模块、代码向量生成模块和向量相似度计算器构成的代码克隆检测系统。然后使用语义类代码克隆数据集对代码向量生成模块中的深度学习模型进行训练,调整深度学习网络模型参数。最后使用代码克隆检测系统对用户输入的待检测代码进行代码补全、提取代码中间表示、构建代码语义图,训练后的代码向量生成模块将代码语义图转化为对应的高维向量V1和V2,再使用向量相似度计算器判断向量的相似度是否超过既定阈值。
本发明包含以下步骤:
第一步,构建代码克隆检测系统。代码克隆检测系统由代码补全模块、代码中间表示提取模块、语义图构建模块、代码向量生成模块和向量相似度计算器构成。
代码补全模块与代码中间表示提取模块相连,使用JCoffee-1.0工具(见P Gupta等人在ICSME会议上发表的文献“JCoffee:Using Compiler Feedback to Make PartialCode Snippets Compilable”使用编译器反馈来使代码片段可编译,下载地址:https://github.com/piyush69/JCoffee)对输入的代码对C1,C2分别进行补全,得到补全后的代码对C‘1,C‘2,使C‘1,C‘2可以进行编译,将C‘1,C‘2发送给代码中间表示提取模块。
代码中间表示提取模块与代码补全模块、语义图构建模块相连,将从代码补全模块接收的C‘1,C‘2分别进行编译,提取C‘1,C‘2编译过程中的代码中间表示,构成代码中间表示对R1,R2。将R1,R2发送给语义图构建模块。
语义图构建模块与代码中间表示提取模块、代码向量生成模块相连,从代码中间表示提取模块接收R1,R2,从R1,R2中提取代码的常量、变量、操作符、API、数据流和控制流信息,分别构建可以表示代码语义的语义图,得到语义图对G1,G2,将G1,G2发送给代码向量生成模块。
代码向量生成模块与语义图构建模块、向量相似度计算器相连,从代码向量生成模块接收G1,G2,使用图匹配网络(见Y Li等人在PMLR2019的文献“Graph matchingnetworks for learning the similarity of graph structured objects”:使用图匹配网络来学习图结构目标的相似性)将G1,G2分别映射为高层向量空间中的两个代码向量V1,V2,将V1,V2发送给向量相似度计算器。
向量相似度计算器与代码向量生成模块相连,计算V1,V2的向量相似度SIM,根据SIM是否超过设定的阈值来判断V1,V2所表示的代码对C1,C2是否属于语义类代码克隆。
第二步,代码补全模块采用代码补全方法补全数据集中的代码。方法为:
2.1使用BigCloneBench数据集作为训练代码,BigCloneBench数据集来自JSvajlenko等人发表在ICSME2015会议上的文献“Evaluating clone detection toolswith bigclonebench”:使用Bigclonebench检验代码克隆检测工具。其中BigCloneBench数据集包含44种功能的代码,共8961段代码。在构建克隆代码对时,从BigCloneBench数据集中任意抽取两段代码可以构成一个代码对,若抽取的两段代码功能相同,则为克隆代码对,否则为非克隆代码对。从BigCloneBench数据集中总共可以构建11,241,933对克隆代码以及69,057,588对非克隆代码。由于从BigCloneBench数据集中构建的代码对数量庞大,使用全部的代码对讲消耗过多的时间和资源,因此在使用时仅仅从所有代码对中选择N(80299521=11,241,933+69,057,588≥N≥10,000)对代码以及对应的标注作为训练集用于模型训练。由于BigCloneBench数据集中存在代码不可编译,无法提取其代码中间表示,因此需要对代码进行补全。
2.2令可编译代码集合Data={};
2.3令变量n=1;
2.4从训练集中抽取第n个代码段CCn,判断CCn是否可编译,若CCn可编译,转2.5,否则转2.6;
2.5将CCn加入Data中,令n=n+1,转2.9;
2.6使用JCoffee-1.0工具补全CCn,得到补全后的代码CC′n,转2.7;
2.7判断CC′n是否可编译,若可编译,转2.8,否则转2.9;
2.8将CC′n加入Data中,令n=n+1,转2.9;
2.9若n≥N,说明Bigclonebench数据集中的所有代码均已经过补全,令补全后的Data中数据总数M=n,将补全后的Data发送给代码中间表示提取模块,转第三步;否则转2.4;
第三步,代码中间表示提取模块从代码补全模块接收可编译代码集合Data,采用代码中间表示提取方法从Data中提取代码中间表示,构建代码中间表示集合IR。具体方法为:
3.1令代码中间表示集合IR={};
3.2令变量m=1;
3.3从Data中抽取第m个代码CCm,若CCm为JAVA语言代码,转3.4;若为C语言代码,则转3.5;
3.4提取JAVA代码的代码中间表示,方法为:
3.4.1使用JavaC编译代码CCm,得到二进制文件Classm;
3.4.2根据二进制文件Classm,使用Soot-4.1.0工具(见R Vallée-Rai等人在CASC1999会议上的文献“Soot:A Java bytecode optimization framework”:Soot:一个JAVA字节码优化框架,下载地址:http://soot-oss.github.io/soot/)提取代码的中间表示Rm,将Rm加入IR,令m=m+1,转3.6;
3.5利用LLVM-9.0工具(见C Lattner等人在CGO2004会议上发表的文献“LLVM:Acompilation framework for lifelong program analysis&transformation”LLVM:一个程序分析和转化的编译器框架,下载地址:https://releases.llvm.org/download.html)编译代码CCm,得到代码CCm的中间表示Rm,将Rm加入IR,令m=m+1,转3.6;
3.6若m>M,说明已为所有可编译代码提取代码中间表示,将代码中间表示集合IR发送至语义图构建模块,转第四步;若m≤M,转3.3。
第四步,语义图构建模块从代码表示提取模块接收代码中间表示集合IR,采用语义图集合构建方法根据IR构建语义图集合SG,方法为:
4.1令语义图集合SG={};
4.2令变量p=0;
4.3从IR中抽取第p个代码中间表示Rp,由于代码的中间表示中常常包含了语义无关的噪音,例如所使用的编译器类型,或编译过程中的通用信息等,而语义相关的关键信息通常是指代码中实际实现代码语义的指令,因此为了构建语义图首先需要从Rp中提取关键语义表示信息,过滤无用噪音信息。方法是:
4.3.1初始化关键语义表示信息队列Sp为空;
4.3.2初始化变量a=1,初始化标识flag=0;
4.3.4令a=a+1,若a≤Rp的长度,转4.3.3;若a>Rp的长度,转4.3.12;
4.3.6由于根据代码生成的指令在“{}”符号的范围内,因此根据判断是否包含符号“{”或“}”可判断当前中间表示行是否为中间表示的起始位置、结束位置或中间位置。若包含符号“{”,说明为中间表示语句块的开始位置,转4.3.7;若包含符号“}”,说明为中间表示语句块的结束位置,转4.3.9;若既不包含“{”,也不包含“}”,说明为中间表示语句块的中间位置,转4.3.8;
4.3.7令flag=1,表示开始存储中间表示关键指令信息,转4.3.10;
4.3.9令flag=0,表示停止存储中间表示关键指令信息,转4.3.11;
4.3.10令a=a+1,转4.3.6;
4.3.11令a=a+1,若a小于Rp的长度,转4.3.3,否则转4.3.12;
4.3.12得到关键语义表示信息队列Sp,Sp中的元素为过滤掉了无用噪音信息的Rp中的代码,转4.4;
4.4语义图构建模块采用语义图构建方法根据Sp构建语义图Gp。方法是:
4.4.1初始化语义图Gp为空,即初始化语义图Gp的节点集合Vp、数据流边集合E_datap和控制流边集合E_controlp为空;
4.4.2语义图构建模块为Gp的节点集合Vp添加变量节点,方法是:
4.4.2.1初始化变量k=1;
4.4.2.3利用正则表达式从中提取变量var以及var的类型type,根据变量var以及var的类型type,以三元组的形式构建变量节点(var,type,vvar),vvar是变量节点的标识,表示此节点的类型为变量节点,vvar中存储的值为var,var数据类型为type,将变量节点(var,type,vvar)加入Vp中;
4.4.2.4令k=k+1,若k大于Sp的长度,说明已经将所有变量节点加入到Vp中,转到4.4.3;否则转4.4.2.2;
4.4.3语义图构建模块为Gp的节点集合Vp添加语句块节点,方法是:
4.4.3.1初始化变量k=1;
4.4.3.3利用正则表达式从中提取语句块标识符marker,根据标识符marker,以二元组的形式构建语句块标识符节点(marker,vcontrol),vcontrol是语句块标识符节点的标识,表示此节点类型为语句块标识符节点,vcontrol中存储的值为marker,将语句块标识符节点(marker,vcontrol)加入Vp中;
4.4.3.4令k=k+1,若k大于Sp的长度,说明已经将所有变量节点加入到Vp中,转到4.4.4;否则转4.4.3.2;
4.4.4语义图构建模块为语义图Gp添加操作符节点、数据流边和控制流边,操作符节点包括函数调用节点、运算符节点、取值操作符节点,方法是:
4.4.4.1初始化变量k=1;
4.4.4.2初始化变量u=1;
4.4.4.4利用正则表达式从中提取语句块标识符marker,对变量u赋值,使u=marker,说明当前的中间表示语句属于语句块标识符节点(u,vcontrol)所代表的语句块,vcontrol表示此节点类型为语句块标识符节点,vcontrol中存储的值为u;
4.4.4.5判断是否为函数调用语句,即判断是否包含“invoke”关键词,若包含“invoke”,转4.4.4.6向Gp的节点集合Vp中添加函数调用节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.6使用正则表达式从中提取调用函数的函数名method、函数调用的输入变量varin、函数的返回值变量varreturn。根据函数名method,以二元组的形式构建函数调用节点(method,vinvoke),vinvoke是构建函数调用节点的标识,表示此节点类型为函数调用节点,vinvoke中存储的值为method,将函数调用节点(method,vinvoke)加入Vp中。在Gp的控制流边集合E_controlp中以三元组的形式添加控制流边((u,vcontrol),(method,vinvoke),econtrol-flow),表示函数调用节点(method,vinvoke)属于语句块标识符节点(u,vcontrol)所代表的语句块,econtrol-flow表示添加的边的属性为控制流边。在Gp的数据流边集合E_datap中以三元组形式添加两条数据流边,分别为((varin,type,vvar),(method,vinvoke),edata-flow)和((method,vinvoke),(varreturn,type,vvar),edata-flow),说明数据从变量节点(varin,type,vvar)输入函数调用节点(method,vinvoke)进行函数调用计算,经过函数调用计算得到的数据从函数调用节点(method,vinvoke)输出到变量节点(varreturn,type,vvar),edata-flow表示添加的边的属性为数据流边;
4.4.4.7判断Sp中第w个元素是否为数据运算语句,即是否包含关键词“/”、“%”、“+”、“-”、“*”、“cmp”中的任意一个,若是数据运算语句,转4.4.4.8向Vp中添加运算符节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.8使用正则表达式从中提取数据运算的运算符op、参与运算的变量varin、运算的结果变量varreturn。根据运算符op,以二元组的形式构建运算符节点(op,voperator),voperator是运算符节点的标识,表示此节点为运算符节点,voperator中存储的值为op,将运算符节点(op,voperator)加入Vp中。在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(op,voperator),econtrol-flow),表示运算符节点(op,voperator)属于语句块标识符节点(u,vcontrol)所代表的语句块。在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(op,voperator),edata-flow)和((op,voperator),(varreturn,type,vvar),edata-flow),表示数据从变量节点(varin,type,vvar)输入运算符节点(op,voperator),运算后的数据从运算符节点(op,voperator)输出到变量节点(varreturn,type,vvar);
4.4.4.9判断Sp中第w个元素是否为数组取值语句,即是否包含取值操作符“getelem”,若包含关键词“getelem”,转4.4.4.10向Gp中添加操作符节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.10使用正则表达式从中提取数组变量varin,并提取结果变量varreturn。以二元组的形式构建取值操作符节点(getelem,voperator),表示运算符节点voperator中存储的值为取值操作符getelem,将取值操作符节点加入Vp中。在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(getelem,voperator),econtrol-flow),表示取值操作符节点(getelem,voperator)属于语句块标识符节点(u,vcontrol)所代表的语句块。在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(getelem,voperator),edata-flow),和((getelem,voperator),(varreturn,type,vvar),edata-flow),表示数组中的数据从数组变量节点(varin,type,vvar)输入取值操作符节点(getelem,voperator),经过取值操作从数组变量中得到的数据从取值操作符节点(getelem,voperator)输出到结果变量节点(varreturn,type,vvar);
4.4.4.11判断Sp中第w个元素是否为判断语句或跳转语句,即是否包含关键词“goto”或“if”,若包含关键词“goto”或“if”,转4.4.4.12向Gp中添加控制流边;否则转4.4.4.15;
4.4.4.12使用正则表达式从中提取判断语句或跳转语句的目标语句块节点标识符newmarker。在Gp的控制流边集合E_controlp中以三元组的形式添加控制流边((u,vcontrol),(newmarker,vcontrol),econtrol-flowr),表示程序执行时将从当前语句块标识符节点(u,vcontrol)所代表的语句块跳转到语句块标识符节点(newmarker,vcontrol)所代表的语句块。
4.4.4.14使用正则表达式从中提取输入变量varin以及输出变量varreturn。在Gp的数据流边集合E_datap中以三元组的形式添加数据流边((varin,type,vvar),(varreturn,type,vvar),edata-flow),说明数据从变量varin输出到变量varreturn中。
4.4.4.15令k=k+1,若k大于Sp的长度,说明得到Gp,将Gp加入语义图集合SG中,转4.5;否则,转到4.4.4.3;
4.5若p大于代码中间表示数据集IR的大小,则得到语义图集合SG,转第五步;否则令p=p+1,转4.3;
第五步,根据语义图集合SG制作代码向量生成模块所需的训练数据集。方法为:
5.1令变量i=1;
5.2初始化训练数据集TrainingSet={};
5.3随机从语义图集合SG中任意抽取两个语义图,令第i次抽取的语义图为和若和所对应的代码功能相同,则标注Labeli为True,表示和所对应的代码为克隆代码;否则标注Labeli为False,表示和所对应的代码不为克隆代码;令第i个三元组将Di放入训练数据集TrainingSet,转5.4;
5.4令i=i+1,若i>10,000,则训练集制作完成,将训练数据集TrainingSet发送到代码向量生成模块,转第六步;否则转5.3;
第六步:采用TrainingSet训练代码向量生成模块,得到可以表示语义图信息的图匹配网络。具体方法是:
6.1设置训练图匹配网络所需参数。方法是:
6.1.1设置图匹配网络包含网络层数T=4;
6.1.2设置图匹配网络学习率ir=0.001;
6.1.3设置训练轮数num_epochs=50;
6.1.4初始化训练轮数epochs=0;
6.2令变量i=1;
6.4.1使用Word2vec模型(见T Mikolov等人2013年发表在arxiv网站的文献“Efficient Estimation of Word Representations in Vector Space”,有效的表示文字在向量空间)初始化中节点的向量值。从的节点集合Vi 1中顺序选择节点x,x∈Vi 1,将节点x中存储的内容输入Word2vec模型,将Word2vec模型输出值作为节点x的初始化向量
6.5.1使用Word2vec模型初始化中节点的向量值。从的节点集合Vi 2中顺序选择节点z,z∈Vi 2,将节点z中存储的内容输入Word2vec模型,将Word2vec模型输出值作为节点z的初始化向量
6.6.1初始化变量t=1;
6.6.5更新中x在第t次迭代后的向量表示 其中GRU表示门控循环神经网络,表示利用门控循环神经网络,根据第t-1次迭代后x节点的向量与中与节点x相连的其他节点传递的消息向量和x与的节点集合Vi 2中所有节点的相似度和6.6.3.3中计算得到的生成第t次迭代后的向量表示
6.10利用余弦相似度函数比较Vi 1,Vi 2的相似度。判断SIM是否大于相似度阈值α,一般0.7≤α<1,若是,则认为和所对应的代码是克隆代码,即模型预测结果Labelpredict=True,否则和所对应的代码不为克隆代码,模型预测结果Labelpredict=False;
6.11若Labelpredict不等于Labeli,则转6.12;否则转6.15;
6.12若Labeli=False,跳转到6.13;若Labeli=True则跳转到6.14;
6.13计算模型调整值Loss=-(1-SIM)×ir,将Loss输入word2vec模型,word2vec模型自动更新模型中的参数,转6.15;
6.14设置向量调整值Loss=(1-SIM)×ir,将Loss输入word2vec模型,word2vec模型自动更新模型中的参数,转6.15;
6.15令i=i+1,若i大于语义图数据集SG的大小,说明已训练完一轮,转6.16;否则转6.3;
6.16令epochs=epochs+1,若epochs等于num_epochs,说明训练完毕,得到了可以表示语义图信息的图匹配网络,也即得到了训练后的代码向量生成模块,转第七步;否则转6.2,开始新一轮训练;
第七步:使用代码克隆系统检测用户输入的一对待检测代码C1,C2,判断C1,C2是否是克隆代码对,方法是:
7.1令待检测代码集合Test={C1,C2};
7.2代码补全模块采用第二步所述代码补全方法对待检测代码集合Test进行代码补全,得到补全后可编译的待检测代码集合Test_Data={C‘1,C‘2};
7.3代码中间表示提取模块采用第三步所述代码中间表示提取方法从对Test_Data提取代码中间表示,构建待检测代码集合的代码中间表示集合Test_IR,Test_IR={R1,R2};
7.4语义图生成模块采用第四步所述语义图集合构建方法根据Test_IR构建待检测代码集合的语义图集合Test_SG={G1,G2};
7.5训练好的代码向量生成模块根据Test_SG中的第一语义图G1和第二语义图G2,生成其对应的向量值V1和V2,方法如下;
7.5.1采用6.4所述第一初始化方法初始化G1,得到初始化后的语义图IG1,采用6.5所述第二初始化方法初始化G2得到初始化后的语义图IG2;;
7.5.2采用6.6所述迭代更新方法迭代更新初始化语义图IG1和IG2中节点的向量,分别得到最终语义图FG1和FG2;
7.6训练好的向量生成模块利用余弦相似度函数比较V1和V2的相似度。 判断SIM是否大于相似度阈值α,若SIM>α,则认为G1和G2所对应的代码是克隆代码,即模型预测结果Labelpredict=True;若SIM≤α,G1和G2所对应的代码不为克隆代码,模型预测结果Labelpredict=False。
采用本发明可以达到以下技术效果:
1、采用本发明可以有效的检测语义类代码克隆。采用本发明在BigCloneBench数据集上对本文方法在检测克隆代码的效果进行测试。经过12小时的模型训练,可以有效检测到BigCloneBench中超过44%的代码克隆,并且保证58%的准确率。而已有方法“Neuraldetection of semantic code clones via tree-based convolution”(基于树型卷积的代码克隆语义检测)在检测到37%代码克隆时,仅能取得31%的准确度。
2、本发明第三步中利用编译器在编译代码过程中,对代码的中间表示信息,更准确完整地挖掘到代码中的语义信息(即有效信息),在第四步中根据挖掘出的代码关键语义信息,构建语义图,可以更好的表达代码中间表示中的语义信息。在第六步中使用图匹配网络更好的挖掘代码语义特征。相比于基于字符或者基于语法的克隆检测方法,本发明基于图匹配网络的方法可以更准确的提取代码的实际语义,因此本发明也取得了超过其他方法的代码克隆检测效果。
3、本发明在第二步对输入代码克隆检测系统的代检测代码进行了补全,使其在不可编译时,仍能使用本发明进行代码克隆检测,具有良好的泛用性。
附图说明:
图1为本发明整体流程图。
图2为本发明第一步构建的代码克隆检测系统逻辑结构图。
具体实施方式
下面结合附图对本发明进行说明。图1是本发明整体流程图。如图1所示,本发明包括以下步骤:
第一步,构建代码克隆检测系统。代码克隆检测系统如图2所示,由代码补全模块、代码中间表示提取模块、语义图构建模块、代码向量生成模块和向量相似度计算器构成。
代码补全模块与代码中间表示提取模块相连,使用JCoffee-1.0工具对输入的代码对C1,C2分别进行补全,得到补全后的代码对C‘1,C‘2,将C‘1,C‘2发送给代码中间表示提取模块。
代码中间表示提取模块与代码补全模块、语义图构建模块相连,将从代码补全模块接收的C‘1,C‘2分别进行编译,提取C‘1,C‘2编译过程中的代码中间表示,构成代码中间表示对R1,R2。将R1,R2发送给语义图构建模块。
语义图构建模块与代码中间表示提取模块、代码向量生成模块相连,从代码中间表示提取模块接收R1,R2,从R1,R2中提取代码的常量、变量、操作符、API、数据流和控制流信息,分别构建可以表示代码语义的语义图,得到语义图对G1,G2,将G1,G2发送给代码向量生成模块。
代码向量生成模块与语义图构建模块、向量相似度计算器相连,从代码向量生成模块接收G1,G2,使用图匹配网络将G1,G2分别映射为高层向量空间中的两个代码向量V1,V2,将V1,V2发送给向量相似度计算器。
向量相似度计算器与代码向量生成模块相连,计算V1,V2的向量相似度SIM,根据SIM是否超过设定的阈值来判断V1,V2所表示的代码对C1,C2是否属于语义类代码克隆。
第二步,代码补全模块采用代码补全方法补全数据集中的代码。方法为:
2.1使用BigCloneBench数据集作为训练代码,BigCloneBench数据集包含44种功能的代码,共8961段代码。在构建克隆代码对时,从BigCloneBench数据集中任意抽取两段代码可以构成一个代码对,若抽取的两段代码功能相同,则为克隆代码对,否则为非克隆代码对。从BigCloneBench数据集中总共可以构建11,241,933对克隆代码以及69,057,588对非克隆代码。从所有代码对中选择N(80299521=11,241,933+69,057,588≥N≥10,000)对代码以及对应的标注作为训练集用于模型训练。由于BigCloneBench数据集中存在代码不可编译,无法提取其代码中间表示,因此需要对代码进行补全。
2.2令可编译代码集合Data={};
2.3令变量n=1;
2.4从训练集中抽取第n个代码段CCn,判断CCn是否可编译,若CCn可编译,转2.5,否则转2.6;
2.5将CCn加入Data中,令n=n+1,转2.9;
2.6使用JCoffee-1.0工具补全CCn,得到补全后的代码CC′n,转2.7;
2.7判断CC′n是否可编译,若可编译,转2.8,否则转2.9;
2.8将CC′n加入Data中,令n=n+1,转2.9;
2.9若n≥N,说明Bigclonebench数据集中的所有代码均已经过补全,令补全后的Data中数据总数M=n,将补全后的Data发送给代码中间表示提取模块,转第三步;否则转2.4;
第三步,代码中间表示提取模块从代码补全模块接收可编译代码集合Data,采用代码中间表示提取方法从Data中提取代码中间表示,构建代码中间表示集合IR。具体方法为:
3.1令代码中间表示集合IR={};
3.2令变量m=1;
3.3从Data中抽取第m个代码CCm,若CCm为JAVA语言代码,转3.4;若为C语言代码,则转3.5;
3.4提取JAVA代码的代码中间表示,方法为:
3.4.1使用JavaC编译代码CCm,得到二进制文件Classm;
3.4.2根据二进制文件Classm,使用Soot-4.1.0工具提取代码的中间表示Rm,将Rm加入IR,令m=m+1,转3.6;
3.5利用LLVM-9.0工具编译代码CCm,得到代码CCm的中间表示Rm,将Rm加入IR,令m=m+1,转3.6;
3.6若m>M,说明已为所有可编译代码提取代码中间表示,将代码中间表示集合IR发送至语义图构建模块,转第四步;若m≤M,转3.3。
第四步,语义图构建模块从代码表示提取模块接收代码中间表示集合IR,采用语义图集合构建方法根据IR构建语义图集合SG,方法为:
4.1令语义图集合SG={};
4.2令变量p=0;
4.3从IR中抽取第p个代码中间表示Rp,方法是:
4.3.1初始化关键语义表示信息队列Sp为空;
4.3.2初始化变量a=1,初始化标识flag=0;
4.3.4令a=a+1,若a≤Rp的长度,转4.3.3;若a>Rp的长度,转4.3.12;
4.3.6若包含符号“{”,说明为中间表示语句块的开始位置,转4.3.7;若包含符号“}”,说明为中间表示语句块的结束位置,转4.3.9;若既不包含“{”,也不包含“}”,说明为中间表示语句块的中间位置,转4.3.8;
4.3.7令flag=1,表示开始存储中间表示关键指令信息,转4.3.10;
4.3.9令flag=0,表示停止存储中间表示关键指令信息,转4.3.11;
4.3.10令a=a+1,转4.3.6;
4.3.11令a=a+1,若a小于Rp的长度,转4.3.3,否则转4.3.12;
4.3.12得到关键语义表示信息队列Sp,Sp中的元素为过滤掉了无用噪音信息的Rp中的代码,转4.4;
4.4语义图构建模块采用语义图构建方法根据Sp构建语义图Gp。方法是:
4.4.1初始化语义图Gp为空,即初始化语义图Gp的节点集合Vp、数据流边集合E_datap和控制流边集合E_controlp为空;
4.4.2语义图构建模块为Gp的节点集合Vp添加变量节点,方法是:
4.4.2.1初始化变量k=1;
4.4.2.3利用正则表达式从中提取变量var以及var的类型type,根据变量var以及var的类型type,以三元组的形式构建变量节点(var,type,vvar),vvar是变量节点的标识,表示此节点的类型为变量节点,vvar中存储的值为var,其数据类型为type,将变量节点(var,type,vvar)加入Vp中;
4.4.2.4令k=k+1,若k大于Sp的长度,说明已经将所有变量节点加入到Vp中,转到4.4.3;否则转4.4.2.2;
4.4.3语义图构建模块为Gp的节点集合Vp添加语句块节点,方法是:
4.4.3.1初始化变量k=1;
4.4.3.3利用正则表达式从中提取语句块标识符marker,根据标识符marker,以二元组的形式构建语句块标识符节点(marker,vcontrol),vcontrol是语句块标识符节点的标识,表示此节点类型为语句块标识符节点,其中存储的值为marker,将语句块标识符节点(marker,vcontrol)加入Vp中;
4.4.3.4令k=k+1,若k大于Sp的长度,说明已经将所有变量节点加入到Vp中,转到4.4.4;否则转4.4.3.2;
4.4.4语义图构建模块为语义图Gp添加操作符节点、数据流边和控制流边,操作符节点包括函数调用节点、运算符节点、取值操作符节点,方法是:
4.4.4.1初始化变量k=1;
4.4.4.2初始化变量u=1;
4.4.4.4利用正则表达式从中提取语句块标识符marker,对变量u赋值,使u=marker,说明当前的中间表示语句属于语句块标识符节点(u,vcontrol)所代表的语句块,vcontrol表示此节点类型为语句块标识符节点,vcontrol中存储的值为u;
4.4.4.5判断是否为函数调用语句,即判断是否包含“invoke”关键词,若包含“invoke”,转4.4.4.6向Gp的节点集合Vp中添加函数调用节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.6使用正则表达式从中提取调用函数的函数名method、函数调用的输入变量varin、函数的返回值变量varreturn。根据函数名method,以二元组的形式构建函数调用节点(method,vinvoke),vinvoke是构建函数调用节点的标识,表示此节点类型为函数调用节点,vinvoke中存储的值为method,将函数调用节点(method,vinvoke)加入Vp中。在Gp的控制流边集合E_controlp中以三元组的形式添加控制流边((u,vcontrol),(method,vinvoke),econtrol-flow),表示函数调用节点(method,vinvoke)属于语句块标识符节点(u,vcontrol)所代表的语句块,econtrol-flow表示添加的边的属性为控制流边。在Gp的数据流边集合E_datap中以三元组形式添加两条数据流边,分别为((varin,type,vvar),(method,vinvoke),edata-flow)和((method,vinvoke),(varreturn,type,vvar),edata-flow),说明数据从变量节点(varin,type,vvar)输入函数调用节点(method,vinvoke)进行函数调用计算,经过函数调用计算得到的数据从函数调用节点(method,vinvoke)输出到变量节点(varreturn,type,vvar),edata-flow表示添加的边的属性为数据流边;
4.4.4.7判断Sp中第w个元素是否为数据运算语句,即是否包含关键词“/”、“%”、“+”、“-”、“*”、“cmp”中的任意一个,若是数据运算语句,转4.4.4.8向Vp中添加运算符节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.8使用正则表达式从中提取数据运算的运算符op、参与运算的变量varin、运算的结果变量varreturn。根据运算符op,以二元组的形式构建运算符节点(op,voperator),voperator是运算符节点的标识,表示此节点为运算符节点,voperator中存储的值为op,将运算符节点(op,voperator)加入Vp中。在Gp的控制流边集合E_contrplp中添加控制流边((u,vcontrol),(op,voperator),econtrol-flow),表示运算符节点(op,voperator)属于语句块标识符节点(u,vcontrol)所代表的语句块。在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(op,voperator),edata-flow)和((op,voperator),(varreturn,type,vvar),edata-flow),表示数据从变量节点(varin,type,vvar)输入运算符节点(op,voperator),运算后的数据从运算符节点(op,voperator)输出到变量节点(varreturn,type,vvar);
4.4.4.9判断Sp中第w个元素是否为数组取值语句,即是否包含取值操作符“getelem”,若包含关键词“getelem”,转4.4.4.10向Gp中添加操作符节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.10使用正则表达式从中提取数组变量varin,并提取结果变量varreturn。以二元组的形式构建取值操作符节点(getelem,voperator),表示运算符节点voperator中存储的值为取值操作符getelem,将取值操作符节点加入Vp中。在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(getelem,voperator),econtrol-flow),表示取值操作符节点(getelem,voperator)属于语句块标识符节点(u,vcontrol)所代表的语句块。在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(getelem,voperator),edata-flow),和((getelem,voperator),(varreturn,type,vvar),edata-flow),表示数组中的数据从数组变量节点(varin,type,vvar)输入取值操作符节点(getelem,voperator),经过取值操作从数组变量中得到的数据从取值操作符节点(getelem,voperator)输出到结果变量节点(varreturn,type,vvar);
4.4.4.11判断Sp中第w个元素是否为判断语句或跳转语句,即是否包含关键词“goto”或“if”,若包含关键词“goto”或“if”,转4.4.4.12向Gp中添加控制流边;否则转4.4.4.15;
4.4.4.12使用正则表达式从中提取判断语句或跳转语句的目标语句块节点标识符newmarker。在Gp的控制流边集合E_controlp中以三元组的形式添加控制流边((u,vcontrol),(newmarker,vcontrol),econtrol-flowr),表示程序执行时将从当前语句块标识符节点(u,vcontrol)所代表的语句块跳转到语句块标识符节点(newmarker,vcontrol)所代表的语句块。
4.4.4.14使用正则表达式从中提取输入变量varin以及输出变量varreturn。在Gp的数据流边集合E_datap中以三元组的形式添加数据流边((varin,type,vvar),(varreturn,type,vvar),edata-flow),说明数据从变量varin输出到变量varreturn中。
4.4.4.15令k=k+1,若k大于Sp的长度,说明得到Gp,将Gp加入语义图集合SG中,转4.5;否则,转到4.4.4.3;
4.5若p大于代码中间表示数据集IR的大小,则得到语义图集合SG,转第五步;否则令p=p+1,转4.3;
第五步,根据语义图集合SG制作代码向量生成模块所需的训练数据集。方法为:
5.1令变量i=1;
5.2初始化训练数据集TrainingSet={};
5.3随机从语义图集合SG中任意抽取两个语义图,令第i次抽取的语义图为和若和所对应的代码功能相同,则标注Labeli为True,表示和所对应的代码为克隆代码;否则标注Labeli为False,表示和所对应的代码不为克隆代码;令第i个三元组将Di放入训练数据集TrainingSet,转5.4;
5.4令i=i+1,若i>10,000,则训练集制作完成,将训练数据集TrainingSet发送到代码向量生成模块,转第六步;否则转5.3;
第六步:采用TrainingSet训练代码向量生成模块,得到可以表示语义图信息的图匹配网络。具体方法是:
6.1设置训练图匹配网络所需参数。方法是:
6.1.1设置图匹配网络包含网络层数T=4;
6.1.2设置图匹配网络学习率ir=0.001;
6.1.3设置训练轮数num_epochs=50;
6.1.4初始化训练轮数epochs=0;
6.2令变量i=1;
6.4.1使用Word2vec模型初始化中节点的向量值:从的节点集合Vi 1中顺序选择节点x,x∈Vi 1,将节点x中存储的内容输入Word2vec模型,将Word2vec模型输出值作为节点x的初始化向量
6.5.1使用Word2vec模型初始化中节点的向量值,从的节点集合Vi 2中顺序选择节点z,z∈Vi 2,将节点z中存储的内容输入Word2vec模型,将Word2vec模型输出值作为节点z的初始化向量
6.6.1初始化变量t=1;
6.6.5更新中x在第t次迭代后的向量表示 其中GRU表示门控循环神经网络,表示利用门控循环神经网络,根据第t-1次迭代后x节点的向量与中与节点x相连的其他节点传递的消息向量和x与的节点集合Vi 2中所有节点的相似度和6.6.3.3中计算得到的生成第t次迭代后的向量表示
6.10利用余弦相似度函数比较Vi 1,Vi 2的相似度。判断SIM是否大于相似度阈值α,一般0.7≤α<1,若是,则认为和所对应的代码是克隆代码,即模型预测结果Labelpredict=True,否则和所对应的代码不为克隆代码,模型预测结果Labelpredict=False;
6.11若Labelpredict不等于Labeli,则转6.12;否则转6.15;
6.12若Labeli=False,跳转到6.13;若Labeli=True则跳转到6.14;
6.13计算模型调整值Loss=-(1-SIM)×ir,将Loss输入word2vec模型,word2vec模型自动更新模型中的参数,转6.15;
6.14设置向量调整值Loss=(1-SIM)×ir,将Loss输入word2vec模型,word2vec模型自动更新模型中的参数,转6.15;
6.15令i=i+1,若i大于语义图数据集SG的大小,说明已训练完一轮,转6.16;否则转6.3;
6.16令epochs=epochs+1,若epochs等于num_epochs,说明训练完毕,得到了可以表示语义图信息的图匹配网络,也即得到了训练后的代码向量生成模块,转第七步;否则转6.2,开始新一轮训练;
第七步:使用代码克隆系统检测用户输入的一对待检测代码C1,C2,判断C1,C2是否是克隆代码对,方法是:
7.1令待检测代码集合Test={C1,C2};
7.2代码补全模块采用第二步所述代码补全方法对待检测代码集合Test进行代码补全,得到补全后可编译的待检测代码集合Test_Data={C‘1,C‘2};
7.3代码中间表示提取模块采用第三步所述代码中间表示提取方法从对Test_Data提取代码中间表示,构建待检测代码集合的代码中间表示集合Test_IR,Test_IR={R1,R2};
7.4语义图生成模块采用第四步所述语义图集合构建方法根据Test_IR构建待检测代码集合的语义图集合Test_SG={G1,G2};
7.5训练好的代码向量生成模块根据Test_SG中的第一语义图G1和第二语义图G2,生成其对应的向量值V1和V2,方法如下;
7.5.1采用6.4所述第一初始化方法初始化G1,得到初始化后的语义图IG1,采用6.5所述第二初始化方法初始化G2得到初始化后的语义图IG2;
7.5.2采用6.6所述迭代更新方法迭代更新初始化语义图IG1和IG2中节点的向量,分别得到最终语义图FG1和FG2;
7.6训练好的向量生成模块利用余弦相似度函数比较V1和V2的相似度。 判断SIM是否大于相似度阈值α,若SIM>α,则认为G1和G2所对应的代码是克隆代码,即模型预测结果Labelpredict=True;若SIM≤α,G1和G2所对应的代码不为克隆代码,模型预测结果Labelpredict=False。
表1是本发明与其他代码克隆检测方法在BigCloneBench数据集上训练与测试结果的对比表。
克隆检测方法 | 准确率 | 召回率 | F1值 |
CCGRAPH | 0.28 | 0.39 | 0.32 |
TBCCD | 0.31 | 0.37 | 0.35 |
本发明 | 0.58 | 0.44 | 0.50 |
表1
所有实验基于一台Ubuntu16.04操作系统,搭载2080TiGPU,主要编码语言为Python。在第四步主要利用python中Networkx库实现构建语义图,第五步中从Bigclonebench数据集中抽取10,000对代码作为训练集,在训练集中,克隆代码对与非克隆代码对比例为1:1,第六步中利用Pytorch库实现图匹配网络。
为了更高的评估本发明与背景技术之间的效果,选用准确率、召回率和F1值作为评估指标。准确率为克隆检测工具报告的克隆代码对中,判断正确的比例,召回率为克隆检测工具正确判断的克隆代码对,在所有克隆对中的占比。由于相似度阈值α的调节会导致召回率和准确率无法兼顾,例如调高相似度阈值α,会导致准确率提高,召回率下降。F1指标的计算为(准确率+召回率)/2×准确率×召回率,可以综合评估准确率和召回率。
根据实验结果显示,经过12小时的模型训练,可以有效的检测到BigCloneBench中超过44%的代码克隆(即可以找出44%占比的克隆代码对),并且保证58%的准确率(即找到的克隆代码对中有58%是真正的克隆代码对),F1值为0.50。而已有最优方法TBCCD在同等实验时,只能检测到37%代码克隆,且仅能取得31%的准确度,F1值仅为0.35。另一个常用克隆检测方法CCGRAPH只能检测到39%代码克隆,且仅能取得28%的准确度,F1值仅为0.32。因此本发明相比现有方法对代码克隆的检测准确率有较大提高。
Claims (9)
1.一种基于图匹配网络的语义类代码克隆检测方法,其特征在于包含以下步骤:
第一步,构建代码克隆检测系统,代码克隆检测系统由代码补全模块、代码中间表示提取模块、语义图构建模块、代码向量生成模块和向量相似度计算器构成;
代码补全模块与代码中间表示提取模块相连,对输入的代码对C1,C2分别进行补全,得到补全后的代码对C‘1,C‘2,将C‘1,C‘2发送给代码中间表示提取模块;
代码中间表示提取模块与代码补全模块、语义图构建模块相连,将从代码补全模块接收的C‘1,C‘2分别进行编译,提取C‘1,C‘2编译过程中的代码中间表示,构成代码中间表示对R1,R2;将R1,R2发送给语义图构建模块;
语义图构建模块与代码中间表示提取模块、代码向量生成模块相连,从代码中间表示提取模块接收R1,R2,从R1,R2中提取代码的常量、变量、操作符、API、数据流和控制流信息,分别构建表示代码语义的语义图,得到语义图对G1,G2,将G1,G2发送给代码向量生成模块;
代码向量生成模块与语义图构建模块、向量相似度计算器相连,从代码向量生成模块接收G1,G2,使用图匹配网络将G1,G2分别映射为高层向量空间中的两个代码向量V1,V2,将V1,V2发送给向量相似度计算器;
向量相似度计算器与代码向量生成模块相连,计算V1,V2的向量相似度SIM,根据SIM是否超过设定的阈值来判断V1,V2所表示的代码对C1,C2是否属于语义类代码克隆;
第二步,代码补全模块采用代码补全方法对训练集中的代码进行补全:
2.1使用BigCloneBench数据集作为训练代码,从BigCloneBench数据集中所有代码对中选择N对代码以及对应的标注作为训练集,N为正整数;
2.2令可编译代码集合Data={};
2.3令变量n=1;
2.4从训练集中抽取第n个代码段CCn,判断CCn是否可编译,若CCn可编译,转2.5,否则转2.6;
2.5将CCn加入Data中,令n=n+1,转2.9;
2.6使用JCoffee-1.0工具补全CCn,得到补全后的代码CC′n,转2.7;
2.7判断CC′n是否可编译,若可编译,转2.8,否则转2.9;
2.8将CC′n加入Data中,令n=n+1,转2.9;
2.9若n≥N,令补全后的Data中数据总数M=n,将补全后的Data发送给代码中间表示提取模块,转第三步;否则转2.4;
第三步,代码中间表示提取模块从代码补全模块接收可编译代码集合Data,采用代码中间表示提取方法从Data中提取代码中间表示,构建代码中间表示集合IR,方法为:
3.1令代码中间表示集合IR={};
3.2令变量m=1;
3.3从Data中抽取第m个代码CCm,若CCm为JAVA语言代码,转3.4;若为C语言代码,则转3.5;
3.4提取JAVA代码的代码中间表示,方法为:
3.4.1使用JavaC编译代码CCm,得到二进制文件Classm;
3.4.2根据二进制文件Classm,使用Soot-4.1.0工具提取代码的中间表示Rm,将Rm加入IR,令m=m+1,转3.6;
3.5利用LLVM-9.0工具编译代码CCm,得到代码CCm的中间表示Rm,将Rm加入IR,令m=m+1,转3.6;
3.6若m>M,将代码中间表示集合IR发送至语义图构建模块,转第四步;若m≤M,转3.3;
第四步,语义图构建模块从代码表示提取模块接收代码中间表示集合IR,采用语义图集合构建方法根据IR构建语义图集合SG,方法为:
4.1令语义图集合SG={};
4.2令变量p=0;
4.4语义图构建模块采用语义图构建方法根据Sp构建语义图Gp,方法是:
4.4.1初始化语义图Gp为空,即初始化语义图Gp的节点集合Vp、数据流边集合E_datap和控制流边集合E_contrplp为空;
4.4.3语义图构建模块为Gp的节点集合Vp添加语句块标识符节点,语句块标识符节点(marker,vcontrol)为二元组,marker是从中提取的语句块标识符,vcontrol表示此节点类型为语句块标识符节点;
4.4.4语义图构建模块为语义图Gp添加操作符节点、数据流边和控制流边:
首先查找当前语句所属的语句块标识符节点(u,vcontrol),u为节点存储的语句块标识符marker,vcontrol表示此节点类型为语句块标识符节点;
将操作符节点添加到Vp中,操作符节点包括函数调用节点、运算符节点、取值操作符节点,函数调用节点(method,vinvoke)为二元组,method为从中提取的调用函数的函数名,vinvoke表示此节点类型为函数调用节点;运算符节点(op,voperator)为二元组,voperator表示此节点类型为运算符节点,其中存储的值为op;取值操作符节点(getelem,voperator)是二元组,voperator表示此节点运算符节点,其中存储的值为取值操作符getelem;当将函数调用节点(method,vinvoke)添加到Vp中时,将控制流边添加到Gp的控制流边集合E_controlp中,控制流边((u,vcontrol),(method,vinvoke),econtrol-flow)是三元组,表示函数调用节点(method,vinvoke)属于语句块标识符节点(u,vcontrol)所代表的语句块,econtrol-flow表示添加的边的属性为控制流边;在Gp的数据流边集合E_datap中添加两条数据流边,分别为((varin,type,vvar),(method,vinvoke),edata-flow)和((method,vinvoke),(varreturn,type,vvar),edata-flow),说明数据从变量节点(varin,type,vvar)输入函数调用节点(method,vinvoke)进行函数调用计算,经过函数调用计算得到的数据从函数调用节点(method,vinvoke)输出到变量节点(varreturn,type,vvar),edata-flow表示添加的边的属性为数据流边;
当将运算符节点添加到Vp中时,在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(op,voperator),econtrol-flow),表示函数运算符节点(op,voperator)属于语句块标识符节点(u,vcontrol)所代表的语句块;在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(op,voperator),edata-flow)和((op,voperator),(varreturn,type,vvar),edata-flow),表示数据从变量节点(varin,type,vvar)输入运算符节点(op,voperator),运算后的数据从运算符节点(op,voperator)输出到变量节点(varreturn,type,vvar);
当将取值操作符节点加入Vp中时,在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(getelem,voperator),econtrol-flow),表示取值操作符节点(getelem,voperator)属于语句块标识符节点(u,vcontrol)所代表的语句块;在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(getelem,voperator),edata-flow),和((getelem,voperator),(varreturn,type,vvar),edata-flow),表示数组中的数据从数组变量节点(varin,type,vvar)输入取值操作符节点(getelem,voperator),经过取值操作从数组变量中得到的数据从取值操作符节点(getelem,voperator)输出到变量节点(varreturn,type,vvar);
当为判断语句或跳转语句时,在Gp的控制流边集合E_controlp中以三元组的形式添加控制流边((u,vcontrol),(newmarker,vcontrol),econtrol-flowr),表示程序执行时将从当前语句块标识符节点(u,vcontrol)所代表的语句块跳转到语句块标识符节点(newmarker,vcontrol)所代表的语句块;在Gp的数据流边集合E_datap中以三元组的形式添加数据流边((varin,type,vvar),(varreturn,type,vvar),edata-flow),说明数据从变量varin输出到变量varreturn中;
将Gp加入语义图集合SG中;
4.5若p大于代码中间表示数据集IR的大小,则得到语义图集合SG,转第五步;否则令p=p+1,转4.3;
第五步,根据语义图集合SG制作代码向量生成模块所需的训练数据集TrainingSet,TrainingSet中的第i个元素为三元组将TrainingSet发送到代码向量生成模块;Labeli为True,表示和所对应的代码功能相同,为克隆代码;Labeli为False,表示和所对应的代码不为克隆代码;
第六步:采用TrainingSet训练代码向量生成模块,得到表示语义图信息的图匹配网络,方法是:
6.1设置训练图匹配网络所需参数;方法是:
6.1.1设置图匹配网络包含网络层数T=4;
6.1.2设置图匹配网络学习率ir=0.001;
6.1.3设置训练轮数num_epochs=50;
6.1.4初始化训练轮数epochs=0;
6.2令变量i=1;
6.4.1使用Word2vec模型初始化中节点的向量值:从的节点集合Vi 1中顺序选择节点x,x∈Vi 1,将节点x中存储的内容输入Word2vec模型,将Word2vec模型输出值作为节点x的初始化向量
6.5.1使用Word2vec模型初始化中节点的向量值,从的节点集合Vi 2中顺序选择节点z,z∈Vi 2,将节点z中存储的内容输入Word2vec模型,将Word2vec模型输出值作为节点z的初始化向量
6.6.1初始化变量t=1;
6.10利用余弦相似度函数比较Vi 1,Vi 2的相似度;判断SIM是否大于相似度阈值α,若是,则认为和所对应的代码是克隆代码,即模型预测结果Labelpredict=True,否则和所对应的代码不为克隆代码,模型预测结果Labelpredict=False;
6.11若Labelpredict不等于Labeli,则转6.12;否则转6.15;
6.12若Labeli=False,跳转到6.13;若Labeli=True则跳转到6.14;
6.13计算模型调整值Loss=-(1-SIM)×ir,将Loss输入word2vec模型,word2vec模型自动更新模型中的参数,转6.15;
6.14设置向量调整值Loss=(1-SIM)×ir,将Loss输入word2vec模型,word2vec模型自动更新模型中的参数,转6.15;
6.15令i=i+1,若i大于语义图数据集SG的大小,说明已训练完一轮,转6.16;否则转6.3;
6.16令epochs=epochs+1,若epochs等于num_epochs,说明训练完毕,得到了图匹配网络,也即得到了训练后的代码向量生成模块,转第七步;否则转6.2,开始新一轮训练;
第七步:使用代码克隆系统检测用户输入的一对待检测代码C1,C2,判断C1,C2是否是克隆代码对,方法是:
7.1令待检测代码集合Test={C1,C2};
7.2代码补全模块采用第二步所述代码补全方法对待检测代码集合Test进行代码补全,得到补全后可编译的待检测代码集合Test_Data={C‘1,C‘2};
7.3代码中间表示提取模块采用第三步所述代码中间表示提取方法从对Test_Data 提取代码中间表示,构建待检测代码集合的代码中间表示集合Test_IR,Test_IR={R1,R2};
7.4语义图生成模块采用第四步所述语义图集合构建方法根据Test_IR构建待检测代码集合的语义图集合Test_SG={G1,G2};
7.5训练好的代码向量生成模块根据Test_SG中的第一语义图G1和第二语义图G2,生成其对应的向量值V1和V2,方法如下;
7.5.1采用6.4所述第一初始化方法初始化G1,得到初始化后的语义图IG1,采用6.5所述第二初始化方法初始化G2得到初始化后的语义图IG2;
7.5.2采用6.6所述迭代更新方法迭代更新初始化语义图IG1和IG2中节点的向量,分别得到最终语义图FG1和FG2;
2.如权利要求1所述的一种基于图匹配网络的语义类代码克隆检测方法,其特征在于2.1步所述N满足80299521≥N≥10,000。
3.如权利要求1所述的一种基于图匹配网络的语义类代码克隆检测方法,其特征在于4.3步所述从Rp中提取关键语义表示信息,过滤无用噪音信息的方法是:
4.3.1初始化关键语义表示信息队列Sp为空;
4.3.2初始化变量a=1,初始化标识flag=0;
4.3.4令a=a+1,若a≤Rp的长度,转4.3.3;若a>Rp的长度,转4.3.12;
4.3.6若包含符号“{”,说明为中间表示语句块的开始位置,转4.3.7;若包含符号“}”,说明为中间表示语句块的结束位置,转4.3.9;若既不包含“{”,也不包含“}”,说明为中间表示语句块的中间位置,转4.3.8;
4.3.7令flag=1,表示开始存储中间表示关键指令信息,转4.3.10;
4.3.9令flag=0,表示停止存储中间表示关键指令信息,转4.3.11;
4.3.10令a=a+1,转4.3.6;
4.3.11令a=a+1,若a小于Rp的长度,转4.3.3,否则转4.3.12;
4.3.12得到关键语义表示信息队列Sp。
4.如权利要求1所述的一种基于图匹配网络的语义类代码克隆检测方法,其特征在于4.4.2步所述语义图构建模块为Vp添加变量节点的方法是:
4.4.2.1初始化变量k=1;
4.4.2.3利用正则表达式从中提取变量var以及var的类型type,根据变量var以及var的类型type,以三元组的形式构建变量节点(var,type,vvar),vvar是变量节点的标识,表示此节点的类型为变量节点,vvar中存储的值为var,var数据类型为type,将变量节点(var,type,vvar)加入Vp中;
4.4.2.4令k=k+1,若k大于Sp的长度,说明已经将所有变量节点加入到Vp中,结束;否则转4.4.2.2。
5.如权利要求1所述的一种基于图匹配网络的语义类代码克隆检测方法,其特征在于4.4.3步所述语义图构建模块为Gp添加语句块标识符节点,方法是:
4.4.3.1初始化变量k=1;
4.4.3.3利用正则表达式从中提取语句块标识符marker,根据标识符marker,以二元组的形式构建语句块标识符节点(marker,vcontrol),vcontrol是语句块标识符节点的标识,表示此节点类型为语句块标识符节点,vcontrol中存储的值为marker,将语句块标识符节点(marker,vcontrol)加入Vp中;
4.4.3.4令k=k+1,若k大于Sp的长度,说明已经将所有变量节点加入到语义图Vp中,结束;否则转4.4.3.2。
6.如权利要求1所述的一种基于图匹配网络的语义类代码克隆检测方法,其特征在于4.4.4步所述语义图构建模块为语义图Gp添加操作符节点、数据流边和控制流边的方法是:
4.4.4.1初始化变量k=1;
4.4.4.2初始化变量u=1;
4.4.4.4利用正则表达式从中提取语句块标识符marker,对变量u赋值,使u=marker,说明当前的中间表示语句属于语句块标识符节点(u,vcontrol)所代表的语句块,vcontrol表示此节点类型为语句块标识符节点,vcontrol中存储的值为u;
4.4.4.5判断是否为函数调用语句,即判断是否包含“invoke”关键词,若包含“invoke”,转4.4.4.6向Gp的节点集合Vp中添加函数调用节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.6使用正则表达式从中提取调用函数的函数名method、函数调用的输入变量varin、函数的返回值变量varreturn;根据函数名method,以二元组的形式构建函数调用节点(method,vinvoke),vinvoke是构建函数调用节点的标识,表示此节点类型为函数调用节点,vinvoke中存储的值为method,将函数调用节点(method,vinvoke)加入Vp中;在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(method,vinvoke),econtrol-flow);在Gp的数据流边集合E_datap中添加两条数据流边,分别为((varin,type,vvar),(method,vinvoke),edata-flow)和((method,vinvoke),(varreturn,type,vvar),edata-flow);
4.4.4.7判断Sp中第w个元素是否为数据运算语句,即是否包含关键词“/”、“%”、“+”、“-”、“*”、“cmp”中的任意一个,若是数据运算语句,转4.4.4.8向Gp中添加运算符节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.8使用正则表达式从中提取数据运算的运算符op、参与运算的变量varin、运算的结果变量varreturn;根据运算符op,以二元组的形式构建运算符节点(op,voperator),voperator是运算符节点的标识,表示此节点为运算符节点,voperator中存储的值为op,将运算符节点(op,voperator)加入Vp中;在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(op,voperator),econtrol-flow);在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(op,voperator),edata-flow)和((op,voperator),(varreturn,type,vvar),edata-flow);
4.4.4.9判断Sp中第w个元素是否为数组取值语句,即是否包含取值操作符“getelem”,若包含关键词“getelem”,转4.4.4.10向Gp中添加操作符节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.10使用正则表达式从中提取数组变量varin,并提取结果变量varreturn;以二元组的形式构建取值操作符节点(getelem,voperator),将取值操作符节点加入Vp中;在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(getelem,voperator),econtrol-flow);在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(getelem,voperator),edata-flow),和((getelem,voperator),(varreturn,type,vvar),edata-flow);
4.4.4.11判断Sp中第w个元素是否为判断语句或跳转语句,即是否包含关键词“goto”或“if”,若包含关键词“goto”或“if”,转4.4.4.12向Gp中添加控制流边;否则转4.4.4.15;
4.4.4.12使用正则表达式从中提取判断语句或跳转语句的目标语句块节点标识符newmarker;在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(newmarker,vcontrol),econtrol-flowr);
4.4.4.14使用正则表达式从中提取输入变量varin以及输出变量varreturn;在Gp的数据流边集合E_datap中添加数据流边((varin,type,vvar),(varreturn,type,vvar),edata-flow);
4.4.4.15令k=k+1,若k大于Sp的长度,说明得到Gp,将Gp加入语义图集合SG中,结束;否则,转到4.4.4.3。
9.如权利要求1所述的一种基于图匹配网络的语义类代码克隆检测方法,其特征在于所述相似度阈值α满足0.7≤α<1。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202210450356.XA CN114780103B (zh) | 2022-04-26 | 2022-04-26 | 一种基于图匹配网络的语义类代码克隆检测方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202210450356.XA CN114780103B (zh) | 2022-04-26 | 2022-04-26 | 一种基于图匹配网络的语义类代码克隆检测方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN114780103A CN114780103A (zh) | 2022-07-22 |
CN114780103B true CN114780103B (zh) | 2022-12-20 |
Family
ID=82432774
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202210450356.XA Active CN114780103B (zh) | 2022-04-26 | 2022-04-26 | 一种基于图匹配网络的语义类代码克隆检测方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN114780103B (zh) |
Families Citing this family (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN117034273A (zh) * | 2023-08-28 | 2023-11-10 | 山东省计算中心(国家超级计算济南中心) | 基于图卷积网络的安卓恶意软件检测方法及系统 |
Citations (8)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN112215013A (zh) * | 2020-11-02 | 2021-01-12 | 天津大学 | 一种基于深度学习的克隆代码语义检测方法 |
CN112286575A (zh) * | 2020-10-20 | 2021-01-29 | 杭州云象网络技术有限公司 | 基于图匹配模型的智能合约相似度检测方法及系统 |
KR20210098297A (ko) * | 2020-01-31 | 2021-08-10 | 고려대학교 산학협력단 | 바이너리 코드 클론 기반 소프트웨어 취약점 탐지를 위한 컴퓨터 프로그램 |
CN113961241A (zh) * | 2021-11-02 | 2022-01-21 | 南京大学 | 一种基于gat图神经网络模型的代码克隆检测方法 |
CN113986345A (zh) * | 2021-11-01 | 2022-01-28 | 天津大学 | 一种预训练增强的代码克隆检测方法 |
CN114035843A (zh) * | 2021-10-09 | 2022-02-11 | 北京天融信网络安全技术有限公司 | 基于Seq2Seq模型的代码克隆检测方法及检测装置 |
CN114064117A (zh) * | 2021-11-19 | 2022-02-18 | 重庆邮电大学 | 一种基于字节码和神经网络的代码克隆检测方法及系统 |
CN114138330A (zh) * | 2021-12-07 | 2022-03-04 | 中国人民解放军国防科技大学 | 基于知识图谱的代码克隆检测优化方法、装置和电子设备 |
-
2022
- 2022-04-26 CN CN202210450356.XA patent/CN114780103B/zh active Active
Patent Citations (8)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
KR20210098297A (ko) * | 2020-01-31 | 2021-08-10 | 고려대학교 산학협력단 | 바이너리 코드 클론 기반 소프트웨어 취약점 탐지를 위한 컴퓨터 프로그램 |
CN112286575A (zh) * | 2020-10-20 | 2021-01-29 | 杭州云象网络技术有限公司 | 基于图匹配模型的智能合约相似度检测方法及系统 |
CN112215013A (zh) * | 2020-11-02 | 2021-01-12 | 天津大学 | 一种基于深度学习的克隆代码语义检测方法 |
CN114035843A (zh) * | 2021-10-09 | 2022-02-11 | 北京天融信网络安全技术有限公司 | 基于Seq2Seq模型的代码克隆检测方法及检测装置 |
CN113986345A (zh) * | 2021-11-01 | 2022-01-28 | 天津大学 | 一种预训练增强的代码克隆检测方法 |
CN113961241A (zh) * | 2021-11-02 | 2022-01-21 | 南京大学 | 一种基于gat图神经网络模型的代码克隆检测方法 |
CN114064117A (zh) * | 2021-11-19 | 2022-02-18 | 重庆邮电大学 | 一种基于字节码和神经网络的代码克隆检测方法及系统 |
CN114138330A (zh) * | 2021-12-07 | 2022-03-04 | 中国人民解放军国防科技大学 | 基于知识图谱的代码克隆检测优化方法、装置和电子设备 |
Non-Patent Citations (3)
Title |
---|
Neural Detection of Semantic Code Clones Via Tree-Based Convolution;Hao Yu;《2019 IEEE/ACM 27th International Conference on Program Comprehension (ICPC)》;20190829;全文 * |
基于差异代码克隆搜索的代码块补全推荐算法研究;殷康麒;《中国科学技术大学硕士学位论文》;20190815;全文 * |
语义级代码克隆检测数据集的评估与改进;华为云开发者联盟;《https://www.cnblogs.com/huaweiyun/p/15881973.html》;20220211;全文 * |
Also Published As
Publication number | Publication date |
---|---|
CN114780103A (zh) | 2022-07-22 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN111639344B (zh) | 一种基于神经网络的漏洞检测方法及装置 | |
Huang et al. | Gamepad: A learning environment for theorem proving | |
Allamanis et al. | Learning to represent programs with graphs | |
CN113360915B (zh) | 基于源代码图表示学习的智能合约多漏洞检测方法及系统 | |
Li et al. | Gated graph sequence neural networks | |
CN112541180B (zh) | 一种基于语法特征和语义特征的软件安全漏洞检测方法 | |
CN112215013B (zh) | 一种基于深度学习的克隆代码语义检测方法 | |
CN112364352B (zh) | 可解释性的软件漏洞检测与推荐方法及系统 | |
CN110990058B (zh) | 软件相似性度量方法及装置 | |
Saifullah et al. | Learning from examples to find fully qualified names of api elements in code snippets | |
CN111767547A (zh) | 一种基于复杂网络社团的软件漏洞检测方法 | |
CN114780103B (zh) | 一种基于图匹配网络的语义类代码克隆检测方法 | |
Lu et al. | Program classification using gated graph attention neural network for online programming service | |
Cusumano-Towner et al. | Automating involutive MCMC using probabilistic and differentiable programming | |
CN111045670B (zh) | 一种二进制代码与源代码间复用关系的识别方法与装置 | |
CN110737469B (zh) | 一种功能粒度上基于语义信息的源代码相似度评估方法 | |
CN115617395A (zh) | 一种融合全局和局部特征的智能合约相似性检测方法 | |
Schwier et al. | Zero knowledge hidden markov model inference | |
CN114254323A (zh) | 基于PCODE和Bert的软件脆弱性分析方法及系统 | |
CN115373737B (zh) | 一种基于特征融合的代码克隆检测方法 | |
CN116663018A (zh) | 一种基于代码可执行路径的漏洞检测方法及装置 | |
Cummins et al. | Deep data flow analysis | |
CN113076089B (zh) | 一种基于对象类型的api补全方法 | |
CN116361788A (zh) | 一种基于机器学习的二进制软件漏洞预测方法 | |
CN116628695A (zh) | 基于多任务学习的漏洞挖掘方法及装置 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |