Peculiar: Smart Contract Vulnerability Detection Based on Crucial Data Flow Graph and Pre-training Techniques-论文链接-源码链接
我这里就主要介绍技术具体实现,前面的就不过多赘述了;
主要贡献:
1、提出来了一个新的表示智能合约的方式通过CDFG也就是关键数据流分析法,这种方法可以捕捉一个合约的关键信息的同时还可以避免对于具体信息的过拟合
2、实现了Peculiar工具并与其他相关漏洞检测工具进行比较,该框架是第一次尝试使用Pre-training-model
3、达到的实验效果是令人满意的
前提知识:
DFG;数据流程图是广泛使用的,对于程序设计而言,其中该图中每个节点代表program的变量,然后边代表了这些变量相互之间的依赖关系。不同与ASTs(抽象语法树),数据流在不同的抽象语法下的相同一段源代码,所对应的数据流关系是不变的。比如说result = maxvalue-minvalue,一般对于机器而谈,他们是很难理解result是什么,但是数据流提供了新的视角去理解result这一变量所代表的语义信息;
而我们文章中使用的CDFG就是DFG的子图;
Pre-training model
定义:pre-training model 是第一个能够在无监督大规模的文本语料信息下进行预训练的模型,并且能够微调下游任务;已知的预训练模型有很多种,比如说ELMo,GPT以及BERT,但是我们这里需要介绍的是GraphCodeBERT,从名字可以看书它是使用了graph,source code,以及bert的预训练模型;其实文章作者没有做什么改动,在原有的GraphCodeBERT模型上面,所以也就没必要再去看那篇文章了。但是这里我先浅浅介绍一下BERT里面的具体结构:
文章使用了一个12层的transformers,transformers可以理解是一个转换器,比如说我现在要实现一个翻译功能,我输入一个中文,转变成英文,而transformers里面具体怎么工作的呢?
有两部分组成的
显示是由encoders以及decoders组成;
那么encoders以及decoders里面又有什么呢?显然会有多个encoder以及多个decoder,而encoder是相连接的,最后encode的输出在输入到每个decoder。
接下来我们又会想encoder里面又有什么呢?
显然就是一个自注意力机制加上一个前馈神经网络了,接下来我们先看看self attention的工作过程;
1、一般而言self-attention输入是词向量。子注意力机制顾名思义就是自己与自己计算一下注意力(也就是最重要的部分),对每一个输入的word我们需要构建self-attention输入。这里transformers首先会把输入x乘以3个矩阵得到QKV-query key value
然后就要计算注意力得分了,这个得分是使用Q来乘以各个单词的k向量点积 得到的我们以上面作为例子‘
接着我们需要让我们计算维度更加稳定所以除以k维度开方
然后把结果softmax隐射到0,1并且保证所有的k向量加起来是1
然后乘以一个v主要是为了把我们所需要的word进行保留而把不需要的进行掩盖操作:
最后就会得到Z1,Z2… 然后把Z拼接到一起也就是我们计算出来的结果:
这个公式就代表了上面的全部过程,但是这还没结束,由于一个子注意力多重头的机制
这个机制一个方面,可以扩展模型关注不同位置的能力,第二方面,它给了自注意力多个
“表示子空间”,也就是说我们不止一组的QKV权重矩阵而是由多组,论文是使用了8组,经过了多头注意力机制后,就会得到多个权重矩阵,然后把他们拼接到一起;
这就是transformers的encoder过程了;接下来言归正传:
图的生成阶段:我们把源代码变成ASTs,通过tree_sitter模块可以完成就不过多说了,接着提取出数据流关系从AST中最后根据DFG去变成CDFG。需要注意的是变成AST之后我们只需要关注terminals leaves 也就是具体的变量序列V= {v1,v2,v3 … …,vk}。并且,如上图所示,变量MinDeposit在第四行以及第14行都有,但是他们不是相同的变量在DFG中;
我们将每个变量作为图的一个节点,从 vi 到 vj 的直接边 = <vi,vj> 表示第 j 个变量的值来自或从第 i 个变量计算。以 x = expr 为例,从 expr 中的所有变量到 x 的边被添加到图中并标记为“computer form”。同时,从 17行 MinDeposit 到 51行 MinDeposit 的边也被添加到图中并标记为“comes from”(没有赋值变化的时候)。我们将有向边的集合表示为 E = { 1, 2, …, l} 并且图 G©=(V, E) 是用于表示源代码 C 的变量之间的依赖关系的数据流。
由dfg 变成 cdfg
Model
I = {[CLS],SC,[SEP],Var} ,这个是输入序列,在输入时候会把I转变成X0,尤其是对于I中的每个Token我们需要的不仅仅是token embed它本身还需要token的position然后这两者链接到一起去表示这个token的embed,我们使用的位置embed是例如95->103,会表示数据流关系的。
Xn = transformern(Xn−1),n ∈ [1,N],,并且每次transformer层包含的等式不仅仅有它自己的计算等式,每一次x(n-1)会先计算多头自注意力Hn然后才会计算Xn
其中LN是一个归一化操作,FFN是一个前馈神经网络,MHSA是一个多头注意力机制计算,对于多头注意力机制的QKV权重矩阵计算如下所示;
计算结果使用如下公式: