论文笔记-《Cross Project Transfer Representation Learning for Vulnerable Function Discovery》

主要是分析论文《Cross Project Transfer Representation Learning for Vulnerable Function Discovery》中怎么通过源代码生成AST,并对其进行操作进行分析。

关于AST

为什么需要AST

当在源程序语法分析工作时,是在相应程序设计语言的语法规则指导下进行的。语法规则描述了该语言的各种语法成分的组成结构,通常可以用所谓的前后文无关文法或与之等价的Backus-Naur范式(BNF)将一个程序设计语言的语法规则确切的描述出来。

不依赖具体文法/不依赖语言的细节

如何自动生成程序对应的AST

参考的论文中通过源代码生成AST是通过CodeSensor(Generalized Vulnerability Extrapolation using Abstract Syntax Trees)来实现的。

参考论文中:Our parser is based on a single grammar definition for the ANTLR parser generator [23] and publicly available1。

ANTLR:”ANTLR是一个语法分析工具[12],使用ANTLR来生成AST主要因为:①ANTLR为开源的语法分析器,便于进行二次开发,优化生成的语法树。②ANTLR生成的 AST中的冗余信息较少,便于阅读与优化。③ANTLR可以使用不同的文法文件生成不同的语法分析器,从而对不同的语言进行分析有很高的灵活性。

使用ANTLR生成AST分为两步:第一步,读取解析文件,在读取分析文法文件中的规则后,ANTLR可以生成相应词法和语法分析器;利用生成的词法分析器,先将输入的程序代码转换成由短语组成的流,再作为语法分析器的输入从而得出最终的结果——AST”(基于AST的代码抄袭检测方法研究)

也就是说解析代码的过程分为两个步骤:

​ 1.将源代码字符串分割为语法单元数组

扫描二维码关注公众号,回复: 8404649 查看本文章

​ 2.在分词结果的基础上分析语法单元之间的关系

发现很多工作都是基于ANTLR来实现的,那么ANTLR怎么用呢?

可以从语法文件生成parser,然后用parser扫描源代码

现在通用的版本为antlr v4,语法文件为.g4,直接在编译器中集成环境就可以生成相应的解析文件。

文章中用到的是antlr v3,.g文件的定义会生成一下几个文件:(生成方法为, java org.antlr.Tool XXX.g, 其中 XXX.g 是我们依据Antlr 的语法规则编写的文法文件。)

​ 词法分析类——ArrayInitLexer.java

​ 词法分析的结果——记号流ArrayInit.tokens ,对每一个token赋值一个token数字

​ 语法分析类——ArrayInitParser.java ,每条文法规则的处理方法

​ 语法树遍历操作类——ArrayInitListener.java, ArrayInitBaseListener.java

解析器允许从单个源文件中提取AST,以串行文本格式输出。(即序列化格式)解析器的目标是从源代码中提取尽可能多的信息,假设在语法上有效。

what is CBOW?

参考论文中的word2vec操作是使用gensim包来实现的,但是没给出模型的生成过程(w2v_model_path = w2v_dir + ‘6_projects_w2v_model_CBOW.txt’),直接加载已经训练好的模型。

The implementation of the Bi-LSTM network used Keras (version 2.0.8) [3] with TensorFlow (version 1.3.0) [1] backend. The random forest algorithm was provided by the scikitlearn package (version 0.19.0) [19]. The Word2vec embedding was provided by the gensim package (version 3.0.1) with all default settings.

gensim是一个python NLP的包

怎么保存AST的结构信息?

1)使用DFT将AST元素映射到向量,使遍历AST,让它们的组件以一致的顺序组装成向量。

对于序列化的ast,使用DFT非常简单,因为序列化的格式(图2(c))是从上到下按照深度优先的搜索顺序编写的。对于每一个AST,我们将它的节点映射到一个向量,以便每个节点成为向量中的一个元素。

类似映射结果为:将函数foo的AST映射到一个向量后,它的形式是[foo, int, params, int, x, stmnts, decl, int, y, =, call, bar,…]

2)由于后续的ML算法以数字向量作为输入,所以将向量的文本元素映射为数字。为了实现这一点,构建了一个映射,将向量的每个文本元素链接到一个整数。这些整数充当唯一标识每个文本元素的“令牌”。例如,我们将类型“int”映射为“1”,将关键字“static”映射为“2”,等等。

3)通过embedding保存代码语义。应用Word2vec[13]的连续Bag-of-Words(CBOW)模型将向量的每个元素转换成100维的字嵌入(这是默认设置)。我们直接在CodeSensor的输出端使用Word2vec,将所有的代码库以及AST节点的类型作为文本内容的语料库,供算法学习。

convert each element of the vectors to word embeddings of 100 dimensions

(论文中的Fig3是通过主成分分析将用Word2vec学习的100维向量投影到二维平面上。)

通过Word2vec嵌入层,将序列中的每个元素映射到语义空间中的一个向量,在这个语义空间中,相似的元素彼此非常接近。

训练出来的6_project_w2v_model_CBOW模型如下形式:

arg -0.195152 0.899433 -0.923698 -0.095378 -2.609756 -1.045856 -2.124176 -0.841639 -0.376260 -0.793921 -0.033869 -2.162605 -0.357745 -0.455473 -0.436908 0.476779 1.334105 -1.222931 -2.199303 -1.201391 1.272673 -0.134357 -0.877508 -0.679563 -0.423491 -1.200496 0.110749 0.375623 -0.743074 1.288527 0.406005 1.706166 -0.949359 0.350211 0.466427 -0.340599 0.449379 1.249614 0.377216 -1.939543 0.965690 -0.037645 -0.922677 0.997704 0.788115 0.142408 1.145714 0.897838 -1.394002 0.702028 -0.276714 0.753746 0.565413 0.786392 0.579505 -1.657586 1.137492 -0.119913 0.219764 0.264084 0.432642 0.019049 0.233222 -1.021239 -0.348059 -0.951070 -0.704682 1.404771 0.158120 0.871542 1.637824 -1.660849 0.284447 -1.140679 -0.392187 -0.334200 -1.548801 0.346101 -1.157699 -0.952480 0.606524 -1.521611 -0.698971 1.145704 0.657356 1.387059 -1.341484 0.833579 1.053144 0.637587 1.749883 0.541179 0.912907 -0.400585 -1.284856 -1.459113 -1.543027 0.747928 0.865314 0.827603 call -0.352606 1.264307 -0.433696 -0.198809 -2.041930 -0.424307 -1.382079 -0.413625 -0.468167 -0.451153 0.152857 -1.301601 -0.317609 -0.425080 0.276574 -1.093976 -0.150896 -0.567189 -2.066520 -1.438954 1.607319 0.901448 -0.570599 -0.617706 0.176364 -0.309445 0.012800 0.305604 -0.466587 0.958698 0.249340 0.687791 -0.830486 0.579623 0.792699 0.006345 0.645945 0.002294 -0.373124 -1.477144 0.606195 0.199700 -0.627099 1.807480 0.908750 0.719939 0.644396 0.025323 -0.326040 0.323441 0.617675 -0.514317 -0.009824 0.611838 0.857162 -1.841762 0.251962 -0.370863 0.045544 -0.745090 0.434510 -0.635048 0.367302 -0.802001 0.367597 -1.454302 -0.548120 1.139068 -0.009270 0.203788 0.005670 -1.182922 -0.282675 -0.895837 -0.155358 0.315064 -0.631926 -0.898162 -0.219349 -0.202787 1.056539 -0.939498 -0.552902 1.395001 1.107155 1.129328 0.403259 -0.273634 1.567446 0.289117 1.176591 -0.306782 -0.445889 0.509720 -1.438480 -0.236060 -1.005835 0.828130 0.499013 0.847283

得到每个字段的100维度向量之后怎么用呢?

CBOW模型是给定上下文,预测中心词

与传统方法比较:例如VLC,test_vlc_cm.csv就是VLC的若干个函数的23个CMs(即代码行、圈复杂度、本质等)作为漏洞检测的特征。这个文件每一行都是23个标准对应的指标。

test_vlc_id.csv的每一行都是对应的文件名。

Data中还有.pkl文件(The .pkl files are Python binaries created by pickle which is a Python module.These .pkl files are for the test for FFmpeg project. )

也就是每个.pkl文件相当于对应的训练/测试集中每个函数的AST中心词集合。然后通过w2v模型训练出来的词典,这样的话由于一个复杂的AST会产生一个包含数千个元素的长向量,因此在将其转换为相同长度的向量时,我们需要截断过复杂的AST,以平衡信息丢失和向量过长之间的关系。我们观察到大约93%的AST样本长度都在1000个元素以内,所以我们截断了元素超过1000个的向量,对于元素较少的向量,我们用0填充它们。

猜你喜欢

转载自www.cnblogs.com/lyeeer/p/12143840.html