【技术实现步骤摘要】
一种基于图匹配网络的语义类代码克隆检测方法
[0001]本专利技术涉及大型软件维护中的克隆检测技术,具体涉及一种基于图匹配网络的代码克隆检测方法。
技术介绍
[0002]随着计算机的发展,计算机软件已经在社会各个领域得到了广泛的应用,在现代社会中扮演着举足轻重的角色,发挥了重要的作用。随着各行各业对软件系统的需求日益扩增,现代软件系统的代码规模逐渐扩大,导致现代软件系统的开发往往需要耗费大量的人力以及时间。为了提高现代软件系统开发人员在软件开发中的效率,开发人员在开发软件过程中往往会复用一些已有的代码。复用代码的方法主要包括从代码仓库中搜索满足需求的代码,对代码简要修改和复制到目标软件系统中、使用成熟的开发框架例如Spring、Tensorflow等、针对具体任务使用前人总结的设计模式。上述方法虽然提高了开发人员的软件开发效率,但也催生了代码克隆现象。代码克隆是指代码仓库中两段相同或相似的代码。根据已有的研究工作显示,代码克隆已经广泛的存在于现代软件系统之中。在Linux操作系统内核中包含27%
‑
35%的代码存在代码克隆,在当前最大的代码仓库Github中,超过70%的代码都存在代码克隆。虽然重复使用已有的代码可以显著提升软件开发人员的开发效率,但是重复使用已有代码也有可能引入潜藏的漏洞,如在复用代码时,为根据上下文对代码进行更改,使得引入预期外的控制流或数据流。因此代码克隆检测尤为重要。利用代码克隆检测,软件维护人员可以根据已知的恶意程序代码或含有漏洞的代码检测在软件中其他可能潜藏的恶意软件代码 ...
【技术保护点】
【技术特征摘要】
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个代码段CC
n
,判断CC
n
是否可编译,若CC
n
可编译,转2.5,否则转2.6;2.5将CC
n
加入Data中,令n=n+1,转2.9;2.6使用JCoffee
‑
1.0工具补全CC
n
,得到补全后的代码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个代码CC
m
,若CC
m
为JAVA语言代码,转3.4;若为C语言代码,则转3.5;3.4提取JAVA代码的代码中间表示,方法为:3.4.1使用JavaC编译代码CC
m
,得到二进制文件Class
m
;3.4.2根据二进制文件Class
m
,使用Soot
‑
4.1.0工具提取代码的中间表示R
m
,将R
m
加入IR,令m=m+1,转3.6;
3.5利用LLVM
‑
9.0工具编译代码CC
m
,得到代码CC
m
的中间表示R
m
,将R
m
加入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个代码中间表示R
p
,从R
p
中提取关键语义表示信息,过滤无用噪音信息,得到关键语义表示信息队列S
p
,S
p
中第k个元素为过滤掉了无用噪音信息的R
p
中的代码,k为正整数,转4.4;4.4语义图构建模块采用语义图构建方法根据S
p
构建语义图G
p
,方法是:4.4.1初始化语义图G
p
为空,即初始化语义图G
p
的节点集合V
p
、数据流边集合E_data
p
和控制流边集合E_contrpl
p
为空;4.4.2语义图构建模块为G
p
的节点集合V
p
添加变量节点,变量节点(var,type,v
var
)为三元组,var为从中提取的变量,type为var的数据类型,v
var
表示此节点类型为变量节点;4.4.3语义图构建模块为G
p
的节点集合V
p
添加语句块标识符节点,语句块标识符节点(marker,v
control
)为二元组,marker是从中提取的语句块标识符,v
control
表示此节点类型为语句块标识符节点;4.4.4语义图构建模块为语义图G
p
添加操作符节点、数据流边和控制流边:首先查找当前语句所属的语句块标识符节点(u,v
control
),u为节点存储的语句块标识符marker,v
control
表示此节点类型为语句块标识符节点;将操作符节点添加到V
p
中,操作符节点包括函数调用节点、运算符节点、取值操作符节点,函数调用节点(method,v
invoke
)为二元组,method为从中提取的调用函数的函数名,v
invoke
表示此节点类型为函数调用节点;运算符节点(op,v
operator
)为二元组,v
operator
表示此节点类型为运算符节点,其中存储的值为op;取值操作符节点(getelem,v
operator
)是二元组,v
operator
表示此节点运算符节点,其中存储的值为取值操作符getelem;当将函数调用节点(method,v
invoke
)添加到V
p
中时,将控制流边添加到G
p
的控制流边集合E_control
p
中,控制流边((u,v
control
),(method,v
invoke
),e
control
‑
flow
)是三元组,表示函数调用节点(method,v
invoke
)属于语句块标识符节点(u,v
control
)所代表的语句块,e
control
‑
flow
表示添加的边的属性为控制流边;在G
p
的数据流边集合E_data
p
中添加两条数据流边,分别为((var
in
,type,v
var
),(method,v
invoke
),e
data
‑
flow
)和((method,v
invoke
),(var
return
,type,v
var
),e
data
‑
flow
),说明数据从变量节点(var
in
,type,v
var
)输入函数调用节点(method,v
invoke
)进行函数调用计算,经过函数调用计算得到的数据从函数调用节点(method,v
invoke
)输出到变量节点(var
return
,type,v
var
),e
data
‑
flow
表示添加的边的属性为数据流边;当将运算符节点添加到V
p
中时,在G
p
的控制流边集合E_control
p
中添加控制流边((u,v
control
),(op,v
operator
),e
control
‑
flow
),表示函数运算符节点(op,v
operator
)属于语句块标识符节点(u,v
control
)所代表的语句块;在G
p
的数据流边集合E_data
p
中以三元组的形式添加两条数据流边,即((var
in
,type,v
var
),(op,v
operator
),e
data
‑
flow
)和((op,v
operator
),(var
return
,
type,v
var
),e
data
‑
flow
),表示数据从变量节点(var
in
,type,v
var
)输入运算符节点(op,v
operator
),运算后的数据从运算符节点(op,v
operator
)输出到变量节点(var
return
,type,v
var
);当将取值操作符节点加入V
p
中时,在G
p
的控制流边集合E_control
p
中添加控制流边((u,v
control
),(getelem,v
operator
),e
control
‑
flow
),表示取值操作符节点(getelem,v
operator
)属于语句块标识符节点(u,v
control
)所代表的语句块;在G
p
的数据流边集合E_data
p
中以三元组的形式添加两条数据流边,即((var
in
,type,v
var
),(getelem,v
operator
),e
data
‑
flow
),和((getelem,v
operator
),(var
return
,type,v
var
),e
data
‑
flow
),表示数组中的数据从数组变量节点(var
in
,type,v
var
)输入取值操作符节点(getelem,v
operator
),经过取值操作从数组变量中得到的数据从取值操作符节点(getelem,v
operator
)输出到变量节点(var
return
,type,v
var
);当为判断语句或跳转语句时,在G
p
的控制流边集合E_control
p
中以三元组的形式添加控制流边((u,v
control
),(newmarker,v
control
),e
control
‑
flowr
),表示程序执行时将从当前语句块标识符节点(u,v
control
)所代表的语句块跳转到语句块标识符节点(newmarker,v
control
)所代表的语句块;在G
p
的数据流边集合E_data
p
中以三元组的形式添加数据流边((var
in
,type,v
var
),(var
return
,type,v
var
),e
data
‑
flow
),说明数据从变量var
in
输出到变量var
return
中;将G
p
加入语义图集合SG中;4.5若p大于代码中间表示数据集IR的大小,则得到语义图集合SG,转第五步;否则令p=p+1,转4.3;第五步,根据语义图集合SG制作代码向量生成模块所需的训练数据集TrainingSet,TrainingSet中的第i个元素为三元组将TrainingSet发送到代码向量生成模块;Label
i
为True,表示和所对应的代码功能相同,为克隆代码;Label
i
为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.3从训练数据集TrainingSet中抽取第i个数据D
i
,6.4采用第一初始化方法初始化中节点的向量值与边的权重值,得到初始化后的第一语义图方法如下:6.4.1使用Word2vec模型初始化中节点的向量值:从的节点集合V
i1
中顺序选择节点x,x∈V
i1
,将节点x中存储的内容输入Word2vec模型,将Word2vec模型输出值作为节点x的初始化向量6.4.2令的数据流边集合中每条边的权重值为1;
6.4.3令的控制流边集合中每条边的权重值为
‑
1;6.5采用第二初始化方法初始化中节点的向量值与边的权重值,得到初始化后的第二语义图方法如下:6.5.1使用Word2vec模型初始化中节点的向量值,从的节点集合V
i2
中顺序选择节点z,z∈V
i2
,将节点z中存储的内容输入Word2vec模型,将Word2vec模型输出值作为节点z的初始化向量6.5.2令的数据流边集合中每条边的权重值为1;6.5.3令的控制流边集合中每条边的权重值为
‑
1;6.6采用迭代更新方法更新第一语义图中各节点的向量表示,得到第一最终语义图迭代更新方法如下:6.6.1初始化变量t=1;6.6.2从的节点集合V
i1
中顺序选择第一节点x,若的节点集合V
i1
中所有节点都已被选择,则转6.6.7;否则转6.6.3;6.6.3计算在第t次迭代时,中的节点与的相似性,方法是:6.6.3.1从的节点集合V
i2
中顺序选择第二节点,令第二节点为z,若的节点集合V
i2
中所有节点都已被选择,则转6.6.3.3;否则转6.6.3.2;6.6.3.2计算x与z的相似度α
z
→
x
,其中指x在t
‑
1次迭代后的向量表示,指z在t
‑
1次迭代后的向量表示,指中任意一个不是z的节点在t
‑
1次迭代后的向量表示,转到6.6.3.1;6.6.3.3计算在第t次迭代时x与的节点集合V
i2
中所有节点的相似度和中所有节点的相似度和6.6.4计算在第t次迭代时,第一语义图中与x有边相连的其它节点即所有第三节点y传递给x的消息向量和m
y
→
x
为中y对x的消息向量;6.6.5更新中x在第t次迭代后的向量表示其中GRU表示门控循环神经网络,表示利用门控循环神经网络根据第t
‑
1次迭代后x节点的向量生成第t次迭代后的向量表示6.6.6令t=t+1;若t小于T,转6.6.2;否则说明迭代更新完毕,得到第一最终语义图转6.7;6.7采用6.6所述迭代更新方法更新中各节点的向量表示,得到第二最终语义图6.8计算的向量表示其中MLP为多层感知器模型,表示
利用多层感知器模型将中所有节点的向量汇总为向量V
i1
,其中为经过T轮迭代后得到的最终语义图中各个节点的向量值;6.9计算的向量表示V
i2
,6...
【专利技术属性】
技术研发人员:李姗姗,薛志鹏,余跃,姜志杰,董威,陈振邦,陈立前,徐如林,周海芳,
申请(专利权)人:中国人民解放军国防科技大学,
类型:发明
国别省市:
还没有人留言评论。发表了对其他浏览者有用的留言会获得科技券。