把以前的V8相关笔记整理一下,更多关于V8安装请参考链接

对v8进行插桩,gen编译添加参数use_afl=true。这样能够让afl-gcc/afl-clang作为后端来编译v8,能够提供代码覆盖率。

1
2
3
4
5
use_afl
Current value (from the default) = false
From //build/config/sanitizers/sanitizers.gni:83

Compile for fuzzing with AFL.

参考:Ubuntu下编译pdfium

nodejs深入学习系列之v8基础篇

使用afl-gcc/afl-clang编译

修改args.gn中的参数(最终版本见文件末)

配置参数,ninja和传统的make方式不同,不能通过***./configure CC=xxxx***来修改编译工具。

v8使用build.gn文件来进行配置,存在一个参数use_afl,我们将这个选项设置为true并将配置写入args.gn。

命令如下

1
2
3
4
5
6
#配置并且编译v8,使用afl-gcc编译
gn gen out/libfuzzer '--args=use_afl=true is_asan=true optimize_for_fuzzing = true ' --check
$ ninja -C out/libfuzzer d8

#查看所有的可用参数
gn args --list out/Default/

WkojxW

当然,如果我们仅仅下载了v8源码,需要在chromium项目文件中找到afl的支持文件,并且放到third_party/afl目录下,关键文件是Build.gn(见文末,需要将BUILD.gn放在v8/third_party/afl/目录),src中的afl可以用自己的源代码。

PS:添加use_afl参数的程序会自动在程序本地编译一个afl-fuzz,不过如果想在整个系统中使用afl-fuzz,记得在src中执行make指令!make CFLAGS="-std=c11 -D_GNU_SOURCE"

{一开始总是check_binary提示没有插桩,后来发现可能是afl编译的锅,读了afl里面的README之后,添加了编译参数CFLAGS="-std=c11 -D_GNU_SOURCE,重新编译afl。如果没有插桩,只能用dirty模式运行(-n),没有覆盖率的检查。}

一些报错与解决

不知道是不是我的v8版本和chromium的最新版的区别,并不存在no_defalut_deps这个参数。所以需要在BUILD.gn文件中讲其注释掉。

Sh1mVY

pdYHjh

检测是否成功

查看二进制文件编译使用的编译工具。似乎我们这里默认会是clang编译的,否则Sanitizer会罢工不干。

1
objdump -s --section .comment 二进制文件

如果插桩失败,如果直接运行afl-fuzz -i afl-in/ -o afl-out/ d8就会显示没有插桩,提示用-n参数,不过这样就完全是无目的fuzz了。

0cKxyQ

在FUZZ过程中,AFL需要fork多个进程,fuzz v8这样体量的代码,默认分配50MB显然是不够de。所以需要加上-m参数。报错如下。

jPw2MN

运行成功,覆盖率检测运作正常。(不过我使用虚拟机跑的,速度感人)

$ afl-fuzz -m 9999 -i corpus/ -o afl-out/ out/Default/d8

GPVyT4

最终的args.gn文件

1
2
3
4
5
optimize_for_fuzzing = true
is_clang=true
use_afl =true
is_asan = true
v8_current_cpu="x64"

BUILD.gn

是在V8编译时用于调用afl的配置文件,放在v8/third_party/afl/目录,否则use_afl将无法使用

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
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

group("afl") {
deps = [
":afl-cmin",
":afl-fuzz",
":afl-showmap",
":afl-tmin",
":afl_docs",
":afl_runtime",
]
}

source_set("afl_runtime") {
# AFL needs this flag to be built with -Werror. This is because it uses u8*
# and char* types interchangeably in its source code. The AFL Makefiles use
# this flag.
cflags = [ "-Wno-pointer-sign" ]

configs -= [
# These functions should not be compiled with sanitizers since they
# are used by the sanitizers.
"//build/config/sanitizers:default_sanitizer_flags",

# Every function in this library should have "default" visibility.
# Thus we turn off flags which make visibility "hidden" for functions
# that do not specify visibility.
# The functions in this library will not conflict with others elsewhere
# because they begin with a double underscore and/or are static.
"//build/config/gcc:symbol_visibility_hidden",
]

sources = [ "src/llvm_mode/afl-llvm-rt.o.c" ]
}

afl_headers = [
"src/alloc-inl.h",
"src/config.h",
"src/debug.h",
"src/types.h",
"src/hash.h",
]

config("afl-tool") {
cflags = [
# Include flags from afl's Makefile.
"-O3",
"-funroll-loops",
"-D_FORTIFY_SOURCE=2",

# These flags are necessary to build with -Werror.
"-Wno-sign-compare",
"-Wno-pointer-sign",

# afl_docs copies docs/ to this location.
"-DDOC_PATH=\"$root_build_dir/afl/docs/\"",

# This flag is needed for compilation but is only used for QEMU mode which
# we do not use. Therefore its value is unimportant.
"-DBIN_PATH=\"$root_build_dir\"",
]
}

copy("afl-cmin") {
# afl-cmin is a bash script used to minimize the corpus, therefore we can just
# copy it over.
sources = [ "src/afl-cmin" ]
outputs = [ "$root_build_dir/{{source_file_part}}" ]
deps = [ ":afl-showmap" ]
}

copy("afl_docs") {
# Copy the docs folder. This is so that we can use a real value for for
# -DDOC_PATH when compiling.
sources = [ "src/docs" ]
outputs = [ "$root_build_dir/afl/{{source_file_part}}" ]
}

executable("afl-fuzz") {
# Used to fuzz programs.
configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ]
configs += [ ":afl-tool" ]

#no_default_deps = true

sources = [ "src/afl-fuzz.c" ]
sources += afl_headers
}

executable("afl-tmin") {
configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ]
configs += [ ":afl-tool" ]

#no_default_deps = true

sources = [ "src/afl-tmin.c" ]
sources += afl_headers
}

executable("afl-showmap") {
configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ]
configs += [ ":afl-tool" ]

#no_default_deps = true

sources = [ "src/afl-showmap.c" ]
sources += afl_headers
}