学习材料:
论文:
1.DeepBalance: Deep-Learning and Fuzzy
Oversampling for Vulnerability Detection:https://download.csdn.net/download/lockhou/15381911
2.Cross-Project Transfer Representation Learning
for Vulnerable Function Discovery:https://download.csdn.net/download/lockhou/15381901
3.POSTER: Vulnerability Discovery with Function Representation
Learning from Unlabeled Projects:https://download.csdn.net/download/lockhou/15381878
博客:
https://blog.csdn.net/qysh123/article/details/106395599
github网址:
1.https://github.com/fabsx00/codesensor(来自论文1)
2.https://github.com/DanielLin1986/function_representation_learning(来自论文3)
3.https://github.com/antlr/website-antlr3/tree/gh-pages/download(安装论文中所说的codesesor所需的antlr-3.4-complete-no-antlrv2下载网址)
学习过程:
step1:读论文
了解将代码转化为ast后再转化为文本向量的基本过程和所使用的基本工具
first:
DeepBalance: Deep-Learning and FuzzyOversampling for Vulnerability Detection
1.论文提供网址:Available: https://github.com/fabsx00/codesensor
2.论文摘要
DeepBalance: Deep-Learning and FuzzyOversampling for Vulnerability Detection
在本节中,我们介绍了所提出的DeepBalance的主要思想,它是一种基于ML的软件漏洞发现方
法,解决了类不平衡问题。图2描述了所提出的框架。如图2所示,该算法分为三个阶段:1)
基于DL的数据预处理;2)基于FOS的DeepBalance建模;3)基于DeepBalance的软件漏洞
发现。
在第一阶段,输入是源代码是带有标签的函数.每个函数都被标记为漏洞函数的或非漏洞函数。
然后,将函数转换为序列化AST数据送入到神经网络作为输入之前,AST序列需要先被标记化。
随后,使用BiLSTM学习AST序列的特征向量表示。
在第二阶段中,针对非漏洞样本数超过漏洞样本数的不平衡数据,提出了一种新的类别不平衡
模型。然后,利用随机森林建立分类模型。新模型命名为DeepBalance在阶段2中。输入到第三阶段即为目标程序的源代码功能。我们应用数据处理工具将源代码函数转换为标记化的AST
序列,并将它们提供给BiLSTMnetwork。输出是函数是否易受攻击或者不基于分类器产生的置
信度。
在下面的讨论中,我们将首先解释BiLSTM网络用于学习功能级别的表示。然后,我们将讨论建
议的用于重新分配训练数据的FOS方案。
A、 数据处理
我们的实验涉及三个人项目:LibTIFF、LibPNG和FFmpeg。这些项目是
开源社区中使用的流行库。我们从Github获得这些项目的源代码。具体来说,
我们手动标记329个易受攻击的函数,并从三个开源项目中收集了6756个非易受
攻击的函数。从NVD和CVE中获得易受攻击函数的标签。在对两个漏洞数据库描述
的基础上,我们下载了每个项目对应版本的源代码,并在源代码中定位了每个漏洞函数,并对
其进行了相应的标记。在本文中,我们考虑函数级漏洞。对于跨多个功能或多个
文件的漏洞,我们会丢弃它们(即不包括易受攻击的功能和跨多个功能和/或
文件的漏洞)。
我们选择ASTs作为提取特征(我们称之为基于AST的特征)的程序代码表示。AST通过描述结构
和代码块的语义。它还包含函数的所有代码组件和函数级控制流。因此,我们假设通过分析函数的AST可以揭示易受攻击的编程模式。
1)基于AST的特征提取:三个开源项目的源代码用于获取ASTs。从源代码解
析AST是非常重要的,因为编译代码时应该有一个生成环境。“CodeSensor”[2]
是[49]基于孤岛语法[50]的概念实现的健壮解析器,我们可以从源代码函数中获
取AST,而不需要支持库和依赖项。CodeSensor的输入是程序的源代码,输出是
所有函数的AST,格式如图3所示。具体来说,序列化AST格式使用表列出树结
构。深度列标记源代码函数组件的位置。例如,在表的第一行(图3的左侧)
,类型名func和深度0表示函数名foo和返回值int是树的根。第二行params表示
函数至少接受一个参数,而Depth 1表示它是根节点的第一个子节点,依此类
推。
使用解析好的AST,我们可以在保存结构信息的同时将它们转换为向量。为了实现
这一点,我们使用深度优先遍历(DFT)对向量的元素进行标记,这样每个节点
都将成为向量的元素。向量中元素的顺序很重要,因为它们部分地反映了AST中
节点的层次位置。通过使用DFT将AST转换为文本向量,根节点foo将是向量的第
一个元素,即函数的名称,第二个元素int表示函数foo的返回类型。第三个元素
params表示函数foo接受参数。第四个和第五个元素是params和int,它们指定
函数foo采用整数参数。将函数的AST映射到文本向量后,它的形式如下:[foo,
int,params,param,int,a,stmnts,decl,int,c,op,=]。这个文本向
量是foo函数的一个特殊语义句子。语义是由向量的每一个元素及其序列所决定
的。
接下来,我们需要标记AST节点的文本元素,以将文本向量转换为数字向
量。建立一个映射,将向量的每个文本元素链接到一个整数。这些整数充当“标
记”,唯一地标识每个文本元素。例如,类型“int”映射到“1”,关键字“static”
映射到“2”,依此类推。通过这样做,矢量中的每个元素都被替换为数字符号,
并且它们的顺序保持不变。为了考虑代码的语义,应用Word2Vec[51]将向量的
每个元素转换为有意义的嵌入。我们使用Gensim包提供的带有默认设置的连续
BOW架构来训练Word2Vec模型。无监督训练过程不需要任何标记数据。我们使用
三个开源项目的代码库来训练Word2Vec模型。训练的结果是一个字典,其中包含
每个单词(代码元素)与其对应的100维向量嵌入之间的映射。
2)基于AST表示的LSTM网络:我们观察到AST和自然语言中的句子有一个有
趣的相似之处。正如我们在上一段所讨论的,向量中元素的序列部分地代表了ASTs
的结构,并形成了“功能意义”。此外,元素之间的联系构成了上下文信息。
例如,向量的第一个元素是函数名,紧跟其后的是函数返回类型。函数名称“FO”
后面的元素应该是返回类型,如“int”或“void”,而不应该是其他的C/C++关键
字,例如“DECL”或“return”。LSTM体系结构是用来处理顺序数据和学习上下文依
赖的。
支持应用LSTM的另一个原因是,函数中易受攻击的编程模式通常可以与多
行代码相关联。当我们将函数映射到向量时,链接到的模式将与多个矢量元素。
标准RNNSareCapableOfHandling短期依赖项,如元素“foo”,后跟类型名“int”
或“void,“但是他们在处理长期依赖性方面存在问题,比如捕获与许多连续或间
歇元素相关的易受攻击的编程模式。因此,我们使用RNN和LSTM单元来捕获长期
依赖性,以了解潜在漏洞的高水平表示。此外,识别易受攻击的编程模式也需要
考虑前后上下文。因此,我们采用LSTM网络的双向形式来学习上下文依赖。
为了获得输入向量的统一长度,我们采用填充和截断的方法来处理不同长度的向
量。考虑到矢量的长度和过稀疏性之间的平衡,我们选择620作为填充/截断阈
值,因为我们观察到85%的转换后的AST序列包含少于620个元素。我们保留长序
列的前620个元素,并使用零作为序列的结尾短序列的填充。该网络以一小批转换
后的AST序列作为输入,预测其脆弱性概率。“1”表示易受攻击的函数,“0”表示不
易受攻击的函数。在我们的实验中,我们将批量大小设置为16,epoch数设置为150,
这将产生最佳性能。
我们提出的基于LSTM的网络结构包含六层,如图4所示。网络体系结构的设计基
于代码的性质和漏洞发现的实践。根据初始实验的性能优化,对网络的设置进行
了优化。第一层是Word2Vec嵌入层,它将序列的每个元素映射到有意义的密集向量
具有固定的维度。带嵌入离散输入将代码分量转换为密集向量。第二层是LSTM层,它包含
64个双向形式的LSTM单元(总共128个LSTM单元)。
BiLSTM层被设计用来学习每个元素的依赖关系,以便生成更高的值-那么,抽
象,aglobalmaxpooling层之后是BiLSTM层,用于增强信号。具体地说,因为我
们将易受攻击的函数标记为“1”,所以我们假设易受攻击的函数的表示将导致接
近1的大值。全局最大池层自动获取最大值,这有助于选择潜在易受攻击的表
示。最后三层是密集层,用于将128维输出汇聚为单个维。为了防止过度拟合,
我们应用值为0.5的“dropout”
second
Cross-Project Transfer Representation Learning
for Vulnerable Function Discovery
论文摘要:
功能级AST工程
我们认为,软件漏洞通常反映在源代码的语法结构中,特别是在功能级别。为了捕捉这些
特性和代码属性,我们遵循Yamaguchi等人的早期工作[25]。作者假设易受攻击的编程模式与
许多漏洞相关,通过分析程序的AST可以揭示这些模式。AST是源代码(例如,函数)的一种语
法结构,它描述了代码层次树视图的组件之间的关系,并忠实地表示了函数级控制流[参见图
2(a)和(b)]。与控制流图(CFGs)相比,ast在函数级提供了一种自然的程序表示,并保
留了更多的源代码信息,而CFGs通常不包含变量声明。因此,本文选择ast来提取潜在的编程
模式。为了实现这一点,AST需要被序列化以转换为向量,同时保留其属性结构和语义。我们提
出的Bi-LSTM网络可以利用包含结构和语义信息的向量来获得能够区分脆弱函数和非脆弱函数
的深层表示。
A、 健壮的AST解析
在从ast中提取特征之前,我们必须从源代码中获取ast。AST通常由编译器在代码解析阶
段生成。然而,如果没有工作构建环境,从C/C++代码中获取ast是不平凡的。“CodeSensor”
是[25]基于孤岛语法[15]的概念实现的健壮解析器,我们可以从单个源文件甚至函数代码片段
中提取AST,而无需依赖库。通过向CodeSensor提供源代码文件,可以以序列化格式生成解析
的AST,为后续处理做好准备。在图2(c)中,序列化AST被组织成适合于表中,呈现出比原始
树视图更用户友好的视图。**第一列是所有节点的类型;第二列记录每个类型的深度/层;最后
两列分别显示原始函数中类型的实际名称和值。**
当提到ASTs的节点时,我们遵循[25]中的命名约定。如图2(b)所示,AST由三种类型的
节点组成:1)占位符节点;2)API节点;以及3)语法节点。占位符节点不是函数的实际组
件,但它们将函数组件链接在一起以形成树。所有AST都有占位符节点,例如“params”,表示
其叶节点是函数参数,或“stmnts”,表示其叶是各种类型的语句。根据[25],API节点是指函
数返回值和函数参数的类型。它们也可以是变量声明和函数调用。例如,具有“void”返回类型
的函数将具有“void”节点。接受任意参数的函数将有一个“int”节点。语法节点是包含控制流
元素和运算符的语法元素。控制流元素来自while/do whilestatements
if/elsestatements,等,如果包含如果是if/else语句,它的AST中将有“if”和“else”节
点。至于运算符,例如“+”、“”-”或“=”,它们将保持不变。
B、 AST精炼
1)代码结构:对于序列化格式的已解析AST,需要将它们转换为向量,以便ML算法能够处
理它们。为了保存ASTs的结构信息,我们采用了我们之前工作[11]中提到的相同方法。首先,
必须遍历AST,使它们的组件以统一的顺序组装起来,形成向量。在本文中,我们使用DFT将
AST元素映射到向量。在未来的工作中,我们将研究宽度优先遍历是否会在后续的分类过程中产
生更好的结果。
对于序列化AST,使用DFT是很简单的,因为序列化格式[参见图2(c)]是按照从上到下
的深度优先搜索序列编写的。对于每个AST,我们将其节点映射到一个向量,这样每个节点就成
为向量中的一个元素。为了保存ast的结构信息,每个元素的顺序很重要。以图2(a)所示的函
数foo为例,其AST的根[参见图2(b)]作为函数名foo,将被映射到向量的第一个元素。AST
的第二层和第三层(通常包含“params”节点、返回类型和参数类型)将分别是向量的第二、第
三和第四个元素,对于后续节点也是如此。将函数foo的AST映射到一个向量后,它的形式将是
[foo,int,params,int,x,stmnts,decl,int,y,=],对于文本向量,我们将其视为
具有语义的“句子”。语义是由向量的元素及其序列构成的。例如,图2(a)中的函数baz类似
于函数foo,两者都采用int类型的参数x并返回int值。它们还共享相同的局部变量名称,并具
有for、if语句和调用相同的函数。然而,他们在行为上是不同的。当将函数baz映射到向量
[baz,int,params,int,x,stmnts,decl,int,y,=]时,我们可以立即发现向量baz
的元素序列与向量foo的不同,尽管它们共享相同的文本内容。因此,转换后的向量应该唯一地
标识函数。通过这样做,我们可以在很大程度上保存结构和环境信息。
2)标记化和填充:由于后续的ML算法将数字向量作为输入,因此向量的文本元素被映射到
数字。为了实现这一点,我们构建了一个映射,将向量的每个文本元素链接到一个整数。这些
整数充当“标记”,唯一地标识每个文本元素。例如,我们将类型“int”映射到“1”,将关键字
“static”映射到“2”,依此类推。通过用数字标记替换向量的文本元素,它们的序列保持不
变。填充和截断是处理不同长度的向量并提供统一长度的输入向量的标准实践。在上一步得到
的向量中,最长的向量包含2200多个元素,最短的不到5个元素。为了平衡向量的长度和过稀疏
性,应该选择合适的长度进行填充/截断。对于短向量,我们使用零作为序列填充的结尾。
3)代码语义保留:除了结构信息外,代码语义还需要通过单词嵌入。单词embedding代表
每个“word”作为固定维数的稠密向量的输入序列。传统的嵌入方法可能会转换单词,在我们的
系统中上下文,AST节点,如类型“int”,或运算符,如“+”和“—”表示任意维向量,而忽略节
点之间可能存在的关系。允许算法利用节点之间的信息(即向量的元素)并且更具表现力,我
们将Word2vec[13]应用于单词连续包模型将向量的每个元素转换为单词嵌入100个维度(这是
默认设置)。我们使用Word2vec直接在CodeSensor的输出端,包括所有代码库和作为文本语
料库的AST节点的类型内容供算法学习借鉴。我们将使用Word2vec学习的嵌入可视化,并使用
二维主成分分析。图3示出了将不同类型的元件分组为可分离簇。因此,使用Word2Vec向量可
以用语义上有意义的向量表示来表示,这样在代码*享相似上下文的元素就在向量中非常接
近空间。
third
POSTER: Vulnerability Discovery with Function Representation
Learning from Unlabeled Projects
1.论文提供网址:
1)http://codeexploration.blogspot.com.au/(作者博客,需要*看但暂时文章已被删除)
2)https://github.com/DanielLin1986/function_representation_learning
2.论文摘要
2 函数表征学习
图1说明了我们提出的框架的工作流程,它包含4个阶段。第一阶段是数据收集。我们的实
验包括三个开源项目:LibTIFF、LibPNG和FFmpeg,它们的源代码可以从Github下载。在第
二阶段,我们从函数的AST中提取原始特征。在第三阶段,我们设计一个堆叠式LSTM网路,并
引入一个学习AST函数表示的代理。最后一个阶段是检验学习到的表示在实际案例中检测脆弱函
数的预测能力。
2.1 AST顺序处理
这是一个由[8] 基于岛语法的概念[4],所以我们可以提取来自源代码的ast没有工作的构建环
境。AST通过描述代码(即函数)的结构信息来表示编程模式。它在树视图中显示函数组件之间
的关系,并包含功能级别控制流程。为了保留结构信息,我们使用深度优先遍历将AST的节点映
射到使每个节点成为向量的一个元素一个向量。向量中的元素序列部分地反映了AST中节点的层
次位置。映射后一个函数到一个向量的AST,它的形式是:[foo,int,params,int,x,
stmnts,decl,int,y,op,=,call,bar,…]。第一个元素foo是函数的名称,第二个元
素int表示函数foo的返回类型。第三和第四元素params和int指定函数foo接受一个参数它是
int类型,依此类推。对于这个文本向量,我们处理它作为一个有语义的“句子”。语义是
由向量的元素及其序列组成。因为我们的数据是从三个不同的软件收集的对于遵循不同命名约
定的项目,需要一个通用的命名标准来规范特定于项目的名称。为了例如,LibPNG项目不太可
能有一个函数在FFmpeg中命名完全相同。我们要做的就是模糊名字是特定于项目的,用“特定
于项目”的术语代替。通过功能级别的漏洞检测训练一个统计模型需要大量的标记数据。然而,
这些标签通常是通过手工获得的。而不是使用实际标签,我们使用代理来近似功能标签的名
称。在本文中,我们从代码度量中选择代理因为这些量度是量化项目质量的量度软件测试的复
杂性[2],因此它们是软件故障和漏洞的重要指标[1]和[6]。 Understand一个商业代码增强
工具,我们能够从源代码收集功能级代码度量。
2.2 深AST表示
ASTs和英语中的“句子”有很大的相似性自然语言,这促使我们应用LSTM来学习高级
表征。从AST映射的向量在序列中包含组件反映了树结构信息。即,AST的结构被部分保留通过
深度优先遍历按顺序组合的元素。在这个意义上,转换向量包含语义它们是由[main,int,
decl,int,op,…,return]。改变任何元素的顺序改变语义。更重要的是,元素之间存在连
接,这些连接构成了上下文信息。
例如,向量的第一个元素是函数名,紧随其后的是它的返回类型。紧跟在函数名“main”后
面的元素应该是它的返回类型,如“int”或“void”,而不应是其他的C/C++关键字,如“DECL”
或“return”。LSTM的体系结构是为处理此类数据而构建的。所以,我们假设一个有漏洞的函数
会显示LSTM发现的“语言”怪事。
另一个理由证明应用LSTM是正确的函数中易受攻击的编程模式通常与多行代码关联。当我
们绘制地图时函数与向量、模式与漏洞相关向量的多个元素。标准RNN能够处理短期依赖关系,
例如元素“main”,它应后跟类型名“int”或“void”,但它们具有处理长期依赖关系的问题,例
如捕获与许多连续或间歇元件。因此,我们将RNN与LSTM单元用于捕获长期依赖性,以学习潜
在漏洞的高级表示。
基于LSTM的网络体系结构包括5层。第一层用于嵌入,映射序列到固定维数的向量。第二
和第三层是堆叠的LSTM层,每个层包含64个LSTM双向形式的单元(每层总共128个LSTM单
元)。叠加的LSTM层能够学习更高层次的抽象表示。最后两层是致密层,有“ReLU”和收敛128
维的“线性”激活函数输出到单一维度。在我们的研究中损失函数的选择实验是“MSE”。我们用
提取的AST给网络供电在三个开源项目中。而不是使用输入ASTs时,我们使用代码度量作为代
理来获取表示是第三层的输出。
总结:
从上述的几篇论文当中我们可以简单总结一下,我们将代码生成AST并在通过词向量模型生成对应的词向量
step1:首先使用codesensor工具将源代码转化为ast形式(第一列是所有节点的类型;第二列记录每个类型的深度/层;最后两列分别显示原始函数中类型的实际名称和值)
step2:将解析好的AST,根据AST的节点层次位置转化为文本向量,文本向量中的元素就是AST中的节点内容,而元素之间的存在联系,通过元素之间的顺序连接表示语义,一旦改变元素之间的顺序都会改变语义,所以文本向量中的元素顺序十分重要,文本向量中的元素顺序代表代码当中的语义信息和结构信息,所以文本向量又称为有“语义”的句子。
step3:将文本向量转化为数字向量
每个.c文件——> 转化为AST——>转化为文本向量——>多个.c文件的文本向量构成二维列表——>输入到word2vec模型当中生成词向量
step1:实现博客
博客地址:https://blog.csdn.net/qysh123/article/details/106395599
这篇文章介绍:一般来讲从源代码中生成AST是non-trivial的,因为需要编译环境的支撑。他们使用了一个叫CodeSensor的工具,基于island grammars [1] 的概念,可以在不需要library支撑的情况下生成AST(Joern其实也用的是这种技术,另外像srcML,应该也是吧?)作者也给出了CodeSensor的GitHub链接:https://github.com/fabsx00/codesensor,我看了一下,已经8年没有更新了。抱着试试看的心理尝试了一下,竟然还可以用!
[1] Moonen, Leon. “Generating robust parsers using island grammars.” In Proceedings Eighth Working Conference on Reverse Engineering, pp. 13-22. IEEE, 2001.
这里简单介绍一下在Windows 10,Java 1.8上使用的经验,感觉这个工具兼容性很强呀。https://github.com/fabsx00/codesensor/issues/1 看到这里有人在求文档,就知道肯定不是我一个人看了论文之后想试试。
首先,在这里https://github.com/fabsx00/codesensor/blob/master/INSTALL,看到作者说是需要Antlr的特殊版本的,如果按照这里面给的网址(https://www.antlr.org/download/antlr-3.4-complete-no-antlrv2.jar),可以预见是下不了的。不过实际上Antlr的所有Jar包都可以在这里下到:https://github.com/antlr/website-antlr3/tree/gh-pages/download
把下载的Jar包放到codesensor目录下,然后借助Git的sh.exe定位到codesensor目录并来运行codesensor目录下的build.sh
方法1:执行下面语句
./build.sh
方法2:双击build.sh文件即可
竟然就可以成功生成CodeSensor.jar了,然后假设我们分析的源码文件是test.c,那么我们只需要运行:
java -jar CodeSensor.jar test.c > output.txt
就可以把codesensor的输出结果存入output.txt这个文件中。我们可以看到其可以将AST生成一个序列化的形式,然后就可以在这个基础上做进一步的分析了。例如针对下面这个c function:
short add (short b){
short a=32767;
if(b>0){
a=a+b;
}
return a;
}
其生成的序列形式是:
SOURCE_FILE 1:0 1:0 0
FUNCTION_DEF 1:0 7:0 1
RETURN_TYPE 1:0 1:0 2 short
TYPE_NAME 1:0 1:0 3 short
LEAF_NODE 1:0 1:0 4 short
FUNCTION_NAME 1:6 1:6 2 add
LEAF_NODE 1:6 1:6 3 add
PARAMETER_LIST 1:10 1:18 2 ( short b )
LEAF_NODE 1:10 1:10 3 (
PARAMETER_DECL 1:11 1:17 3 short b
TYPE 1:11 1:11 4 short
TYPE_NAME 1:11 1:11 5 short
LEAF_NODE 1:11 1:11 6 short
NAME 1:17 1:17 4 b
LEAF_NODE 1:17 1:17 5 b
LEAF_NODE 1:18 1:18 3 )
LEAF_NODE 1:19 1:19 2 {
STATEMENTS 2:1 6:1 2
SIMPLE_DECL 2:1 2:14 3 short a ; a = 32767 ;
VAR_DECL 2:1 2:7 4 short a ; a = 32767
TYPE 2:1 2:1 5 short
TYPE_NAME 2:1 2:1 6 short
LEAF_NODE 2:1 2:1 7 short
NAME 2:7 2:7 5 a
LEAF_NODE 2:7 2:7 6 a
LEAF_NODE 0:0 0:0 5 ;
INIT 2:7 2:7 5 a = 32767
ASSIGN 2:7 2:9 6 a = 32767
LVAL 2:7 2:7 7 a
NAME 2:7 2:7 8 a
LEAF_NODE 2:7 2:7 9 a
ASSIGN_OP 2:8 2:8 7 =
LEAF_NODE 2:8 2:8 8 =
RVAL 2:9 2:9 7 32767
FIELD 2:9 2:9 8 32767
LEAF_NODE 2:9 2:9 9 32767
LEAF_NODE 2:14 2:14 4 ;
SELECTION 3:1 3:8 3
KEYWORD 3:1 3:1 4 if
LEAF_NODE 3:1 3:1 5 if
LEAF_NODE 3:3 3:3 4 (
CONDITION 3:4 3:4 4 b > 0
EXPR 3:4 3:6 5 b > 0
FIELD 3:4 3:4 6 b
LEAF_NODE 3:4 3:4 7 b
REL_OPERATOR 3:5 3:5 6 >
LEAF_NODE 3:5 3:5 7 >
FIELD 3:6 3:6 6 0
LEAF_NODE 3:6 3:6 7 0
LEAF_NODE 3:7 3:7 4 )
STATEMENTS 3:8 5:1 4
LEAF_NODE 3:8 3:8 5 {
STATEMENTS 4:2 4:2 5
EXPR_STATEMENT 4:2 4:7 6 a = a + b ;
EXPR 4:2 4:2 7 a = a + b
ASSIGN 4:2 4:4 8 a = a + b
LVAL 4:2 4:2 9 a
FIELD 4:2 4:2 10 a
LEAF_NODE 4:2 4:2 11 a
ASSIGN_OP 4:3 4:3 9 =
LEAF_NODE 4:3 4:3 10 =
RVAL 4:4 4:6 9 a + b
FIELD 4:4 4:4 10 a
LEAF_NODE 4:4 4:4 11 a
LEAF_NODE 4:5 4:5 10 +
FIELD 4:6 4:6 10 b
LEAF_NODE 4:6 4:6 11 b
LEAF_NODE 4:7 4:7 7 ;
LEAF_NODE 5:1 5:1 5 }
JUMP_STATEMENT 6:1 6:9 3 return a ;
KEYWORD 6:1 6:1 4 return
LEAF_NODE 6:1 6:1 5 return
DESTINATION 6:8 6:8 4 a
EXPR 6:8 6:8 5 a
FIELD 6:8 6:8 6 a
LEAF_NODE 6:8 6:8 7 a
LEAF_NODE 6:9 6:9 4 ;
LEAF_NODE 7:0 7:0 2 }
和文章中相比要更复杂一些,并且感觉有一些冗余。
通过上面博主给的详细教程,完全可以生成博客给出的运行结果,但是在这实践过程当中,我总结了如下问题:
1.本电脑的运行详情:
项目位置:D:\codesensor
sh.exe位置:C:\Program Files\Git\bin\sh.exe
java位置:C:\java\jdk\bin\java.exe
2. 直接使用文件夹中的codesensor.jar文件和先下载altr文件并运行build.sh后生成的codesensor.jar运行结果毫无区别,我并不知道这是为什么,可能是作者后来自己添加的,方便我们使用的也有可能
3.我们虽然得到了结果但是和论文中所写的AST形式不完全一致,尤其在类型名称上有显著差异,这种差异可能会在后续将AST生成文本向量是产生较大的差别,因为他在DFT的时候需要通过匹配节点类型来安排元素顺序。
4.批量处理.c文件,并通过生成的AST文件生成文本向量,我们暂时只安装上了codesensor而已,如果需要批量处理.c文件生成AST并将一个文件对应的AST存在对应名称的.txt文件当中,并且在通过DFT的方法生成文本向量需要.py文件来实现,论文作者将这两种过程写成代码并在github上开源。
step3:实现开源代码
即上面总结第四条中所说的开源代码:网址
Vulnerabilities_info.xlsx文件包含所收集的功能级别漏洞的信息。这些漏洞来自3个开源项目:FFmpeg,LibTIFF和LibPNG。直到2017年7月中旬,漏洞信息都是从国家漏洞数据库(NVD)收集的。
“数据”文件夹包含3个项目的Zip文件中易受攻击的功能和不易受攻击的功能的源代码。解压缩文件后,会发现每个易受攻击的函数的源代码都用其CVE ID命名。对于无漏洞功能,它们以“ {文件名} _ {功能名} .c”格式命名。
“code”文件夹包含Python代码示例。
ProcessCFilesWithCodeSensor.py文件用于调用CodeSensor以序列化格式将函数解析为AST(有关CodeSensor的详细信息和用法,请访问作者的博客:http : //codeexploration.blogspot.com.au/了解更多信息)。
ProcessRawASTs_DFT.py文件用于处理ProcessCFilesWithCodeSensor.py的输出,并将序列化的AST转换为文本向量。
BlurProjectSpecific.py文件用于模糊项目的特定内容,并将文本向量(ProcessRawASTs_DFT.py的输出)转换为可用作ML算法输入的数字向量。
LSTM.py文件包含用于基于Keras和Tensorflow后端实现LSTM网络的Python代码示例。
我们使用了Understand,这是用于提取功能级代码指标的商业代码增强工具。在CodeMetrics.xlsx文件中,我们包括从3个项目的脆弱功能中提取的23个代码度量。
1.ProcessCFilesWithCodeSensor.py
参数:
1)CodeSensor_OUTPUT_PATH:将每个.c文件提取出来AST保存为.txt文件所存储的地址
“G:\论文\论文\ast\function_representation_learningmaster\FFmpeg\Vulnerable_functions\Preprocessed\”
2)CodeSensor_PATH:codesensor.java所在位置
“D:\codesensor\CodeSensor.jar”
3)PATH :.c文件所存储的目录
“G:\论文\论文\ast\function_representation_learning-master\FFmpeg\Vulnerable_functions”
作用:将PATH目录下的C文件遍历,每一个文件都执行语句
java -jar CodeSensor.jar test.c > c文件对应名字.txt
并且将结果txt存储在CodeSensor_OUTPUT_PATH目录下
结果:
CodeSensor_OUTPUT_PATH目录下生成了每一个c文件对应的AST.txt文件,且AST生成形式与上面运行一致,与论文得到的AST形式有较大的差别
2.ProcessRawASTs_DFT.py
作用:遍历CodeSensor_OUTPUT_PATH目录下的.txt文件,对于每一个文件一个文本向量的列表,第一个元素是AST所存的txt文件名,接着是通过类型匹配形成保留结构信息,元素是节点的文本向量。对于所有温江形成一个二维列表并且最后将二维列表写入到"G:\论文\论文\ast\function_representation_learning-master\FFmpeg\Vulnerable_functions\Processed_proASTResult_DFT1.txt"文件当中。
参数:
1)FILE_PATH :存储AST的TXT所在目录
“G:\论文\论文\ast\function_representation_learning-master\” + Project_Name + “\Vulnerable_functions\Preprocessed\”
2)Processed_FILE : 存储文本向量的txt文件
“G:\论文\论文\ast\function_representation_learning-master\” + Project_Name + “\Vulnerable_functions\Processed\”
结果:_proASTResult_DFT1.txt里边只存储所有包含AST的txt文件的文件名
3.总结与反思
现在遇到的问题就是我们通过现在生成AST形式,无法通过DFT进行节点类型匹配生成文本向量,我们首先想到的问题就是我们查ProcessRawASTs_DFT.py文件发现他进行节点类型匹配的方法是与论文当中一致的,而和我们所生成的AST中的节点类型是驴唇不对马嘴的,首先论文中的节点类型是小写,而我们生成的节点类型是大写的。所以当我们进行节点类型匹配生成文本向量的时候一个都匹配不上,所以文本向量列表当中除了无条件添加了文件名以外再无任何元素。
解决方法
错误尝试
最开始我认为可能是我们所生成的codesensor工具不对,可能是antlr-3.4-complete-no-
antlrv2.jar这个是用作结构解析的文件可能是版本不对,我看到博客下面有人的评论使用
antlr-3.4-complete.jar做程序分析,于是我又下载这个文件放在了对应的目录之下,再次运
行build.sh文件,我以为希望来临,然而没想到是厄运的到来,竟然我的codesensor.jar文
件变成了1kb,再一使用存ast的TXT文件当中显示找不到主类,连不想要的AST都没有了,
此时我就陷入了沉思,我感觉我是一步步按照指示安装codesensor的为啥没法生成论文当
中所说的AST形式。后来我一想应该不是antl.jar文件生成的问题,因为我不生成直接用下
载下来的codesenor和生成之后是一个样子的,问题应该也不在这。后来我真的是找不到答
案了,也感觉自己没有错并且别人的博客也是这样生成的。后来走投无路我看到了论文当
中给的作者博客,我寻思去寻找点线索,结果网址还需要*,我终于连上VPN之
后,满脸希望等待春天,但是我等到的是博文已删除,真是把我往死路上逼啊,但是虽然
死路不对但是不容置疑的的是应该是生成AST的工具codesensor.jar存在问题。
正确解法
因为我坚信所给的codesensor工具有问题,正当我发呆看这codesensor工具的开源网站时,模拟一下网站全景:
既然给我的这些代码已经没用,也没有提示,我就看到了侧栏:
我发现Releases有2个tags,我一点开发现由两个版本的codesensor:
机智的我就把两个codesensor都下载了一下并解压,发现codesensor-0.3和页面所提供的codesensor.jar是一样的,还是没有变化。而打开codesensor-0.2也就打开了答案的大门,使用该文件夹下的codesensor.jar文件我们就可以生成和论文中节点类型一致的AST了,结果如下:
这样以后ProcessCFilesWithCodeSensor.py中的codesensor_path就改为:"D:\codesensor\codesensor-codeSensor-0.2\CodeSensor.jar"这样我们的每一个.c文件都可以生成论文中相同结构的AST,再接着运行ProcessRawASTs_DFT.py文件我们就可以匹配到正确的节点类型从而生成文本向量存储在_proASTResult_DFT1.txt文件下,结果如图所示: