CEVulDet A Code Edge Representation Learnable Vulnerability Detector

0 Abstract

许多研究者已开始应用深度学习算法来检测源代码的漏洞。然而,现有方法的检测结果仍然不够准确。大多数这些方法将程序源代码直接视为自然语言。这些方法可能会忽略特定于程序代码的结构信息,而这些信息是代码构成语义的关键部分。在本文中,我们提出了一种名为CEVulDet的新型漏洞检测方法。**首先,我们采用中心性分析来从PDG中去除不重要的节点,以获得保留程序重要部分的新图。其次,我们提出了一种新的程序语义提取方法,该方法获取特征向量以表示程序代码和图边信息的语义信息。它可以借助模型解释技术定位漏洞触发路径。**最后,我们的方法提取的向量被输入到CNN中训练漏洞检测器。在我们的实验中,我们评价了CEVulDet在一个包含33,360个函数的数据集上的性能,其中包括12,303个有漏洞的函数和21,057个无漏洞的函数。实验结果表明,CEVulDet远远优于基于规则的检测器,并超越了最先进的基于深度学习的检测器。CEVulDet在准确率、精确度、召回率和F1指标方面分别提高了3.2%、3.4%、5.1%和4.2%。

1 Intro or Overview

1.1 Problem and Challenge

1.2 Motivation

我们的主要目标是准确地将一个函数代码标记为易受攻击或不易受攻击。为了做到这一点,我们以两种方式提高模型的准确性。一方面,我们需要使模型能够专注于函数的重要部分。另一方面,必须以适当的方式从源代码中提取丰富的语义。

为了让模型关注函数的重要部分。我们使用中心性分析来计算函数代码中每行代码的重要性,然后提取重要的代码行。函数代码中的不同代码行具有不同级别的语义重要性。例如,有些代码仅仅声明或定义变量,而其他代码实现了函数的核心算法。显然,后者对函数更重要,因为它们是函数语义的主要部分。获取这些关键代码(即高重要性代码)有助于模型做出更准确的判断。中心性分析计算图中节点的中心性值,这些值反映了图中节点的重要性。我们对函数进行静态分析,获取相应的PDG,然后使用中心性分析计算图中每个节点的中心性值。PDG中的每个节点对应函数中的一行代码,因此我们得到每行代码的重要性。

在这里,我们将度值视为度中心性,并计算其度中心性值,以弱点函数为示例。如图1所示,PDG中每个节点的内容是一行代码,在图中的实线和虚线表示代码之间的控制流和数据流。我们计算了图中每个节点的入度、出度和度,得到了表I。

image-20240422150829338 image-20240422150839897

从表格I中,我们可以看到不同代码行的度基本不同,因为代码行之间有不同的关系(即控制流和数据流),这在一定程度上可以反映出代码行的重要性。为了更全面地考虑每行代码的重要性,我们使用三种不同的中心性分析(即度中心性[8]、接近中心性[8]和PageRank中心性[9])。

从源代码中提取丰富的语义。我们提出了一个新颖的想法,可以从源代码中提取更丰富的语义意义。我们观察到,大多数先前的方法只是简单地堆叠代码行,然后将它们馈送到神经网络模型中。它们忽略了函数中的一些逻辑结构,特别是函数代码中的控制流和数据流,函数中的漏洞是基于这些流触发的。这些结构(即控制流边和数据流边)存在于与函数对应的PDG中。因此,我们提出了代码边,其中代码边对应于PDG中的一条边,由该边的两个节点组成。通过这种方式,我们可以将函数转换为代码边列表并获得语义丰富的数据。我们已经结合了这两个方面,并实施了CEVulDet,这使得能够更准确地检测函数(即易受攻击或不易受攻击)。

1.3 Contribution

我们使用中心性分析来拦截函数中的重要代码行,让神经网络模型专注于函数的重要部分。

我们提出了一种新颖的特征提取方法,能够从PDG中提取更丰富的语义(即控制流和数据流),并将函数转换为代码边缘列表。可解释的分析能帮助我们在一定程度上发现漏洞触发的路径。

我们实现了我们的漏洞检测器并将其与其他几种先进的检测方案进行比较。我们的方法在SARD [10]上取得了最佳结果。

2 Architecture & Method

2.1 System Overview

image-20240422151938485

  • 获取代码的PDG:我们对每个函数的源代码进行规范化,然后进行静态分析以提取该函数的程序相关图。

  • 生成中心图:PDG使用图的中心性值来删除程序相关图中的不重要节点,从而获得中心图。

  • 生成代码边列表:我们使用中心图生成代码边缘列表,列表的每一行包含图中一个有向边的两个节点。

  • 将代码边列表转换为向量列表:我们将一行代码视为一个句子,并遵循将句子嵌入向量的方法,同时将代码边嵌入向量中。

  • 分类:最后,我们选择使用CNN模型构建我们的分类器,并将其用于检测漏洞。

2.2 Method

代码边定义:

函数的程序依赖图包含其控制流和数据流,函数内代码行之间的逻辑关系嵌入在这两种流中。这些流(即控制流和数据流)在程序依赖图中被具体表示为有向边(例如,图1中的实线和虚线)。

考虑一个函数 f 的 PDG G = (V, E),其中 V = {n1, …, nk} 是一组节点。一个节点对应于函数中的一行代码。E = {e1, …, ek} 是一组有向边,每条边代表一对节点之间的数据或控制依赖关系。使用代码边来表示PDG中的有向边,并且我们将有向边看作是两个节点之间的方向关系。因此,在PDG的Eei中,代码边缘ei = [nis,nie]由ei的起始节点和结束节点组成。因此,代码边在PDG中包含两个节点(即两行代码),这两个代码节点可能存在数据依赖性、控制依赖性,或者两者兼有。每个节点都包含函数中相应的代码行。请注意,这些边是有向边,这意味着节点“a”指向“b”的语义与节点“b”指向“a”的语义完全不同

image-20240422154739402 image-20240422155240908

3 Experiment and Evaluation

3.1 DataSet and Process

3.2 Evaluation

4 Discusion

Conclusion