summaryrefslogtreecommitdiff
path: root/libfuzzer-example
diff options
context:
space:
mode:
authortongzongzhen <[email protected]>2023-11-28 11:21:10 +0800
committertongzongzhen <[email protected]>2023-11-28 11:21:10 +0800
commit5ac0c46c0519223ca3204029d0819ed24ee7127c (patch)
treec1d7c8027d1498d394b67bda323b360871fd815f /libfuzzer-example
parenta776a2c85bc4331de759e41be7ceac95c2f7fb96 (diff)
add-libfuzzer的基本使用
Diffstat (limited to 'libfuzzer-example')
-rw-r--r--libfuzzer-example/1-hello-world/CORPUS/A1
-rw-r--r--libfuzzer-example/1-hello-world/README.md17
-rw-r--r--libfuzzer-example/2-Seed-corpus/README.md4
-rw-r--r--libfuzzer-example/3-dict/README.md6
-rw-r--r--libfuzzer-example/README.md37
5 files changed, 62 insertions, 3 deletions
diff --git a/libfuzzer-example/1-hello-world/CORPUS/A b/libfuzzer-example/1-hello-world/CORPUS/A
new file mode 100644
index 0000000..8c7e5a6
--- /dev/null
+++ b/libfuzzer-example/1-hello-world/CORPUS/A
@@ -0,0 +1 @@
+A \ No newline at end of file
diff --git a/libfuzzer-example/1-hello-world/README.md b/libfuzzer-example/1-hello-world/README.md
new file mode 100644
index 0000000..b7dc3e2
--- /dev/null
+++ b/libfuzzer-example/1-hello-world/README.md
@@ -0,0 +1,17 @@
+
+```shell
+# 代码覆盖率
+clang++ -fsanitize=address,fuzzer -fprofile-instr-generate -fcoverage-mapping test_fuzzer.cc
+
+# 种子库
+# ./a.out CORPUS
+
+# 种子可以提供的覆盖率,不包括突变的部分
+./a.out CORPUS/*
+
+# 合并代码覆盖率
+llvm-profdata merge -sparse *.profraw -o default.profdata
+
+# 远程连接的机器看不到图片
+llvm-cov show a.out -instr-profile=default.profdata -name=FuzzMe
+``` \ No newline at end of file
diff --git a/libfuzzer-example/2-Seed-corpus/README.md b/libfuzzer-example/2-Seed-corpus/README.md
index 6d08386..825e62f 100644
--- a/libfuzzer-example/2-Seed-corpus/README.md
+++ b/libfuzzer-example/2-Seed-corpus/README.md
@@ -5,4 +5,8 @@ tips: woff有特定的格式。程序从字符串模糊生成,效率太低,�
../../../../fuzzer-test-suite/woff2-2016-05-06/build.sh
./woff2-2016-05-06-fsanitize_fuzzer
+
+mkdir MY_CORPUS
+./woff2-2016-05-06-fsanitize_fuzzer MY_CORPUS/ seeds/
+# ==1396==ERROR: AddressSanitizer: heap-buffer-overflow on address...
``` \ No newline at end of file
diff --git a/libfuzzer-example/3-dict/README.md b/libfuzzer-example/3-dict/README.md
new file mode 100644
index 0000000..6f07d5b
--- /dev/null
+++ b/libfuzzer-example/3-dict/README.md
@@ -0,0 +1,6 @@
+
+```shell
+mkdir -p libxml; rm -rf libxml/*; cd libxml
+../../../../fuzzer-test-suite/libxml2-v2.9.2/build.sh
+# 上面脚本会运行失败
+``` \ No newline at end of file
diff --git a/libfuzzer-example/README.md b/libfuzzer-example/README.md
index 4b70692..3429b49 100644
--- a/libfuzzer-example/README.md
+++ b/libfuzzer-example/README.md
@@ -3,18 +3,23 @@
```shell
# 版本不低于6.0
-sudo apt install clang
+sudo apt install clang # 编译C/C++代码需要
+sudo dnf install llvm # 获取覆盖率的时候需要
clang -v
clang version 16.0.6 (Red Hat 16.0.6-1.el9)
```
-## 直觉
+## 基本使用
-一个完成的程序进行黑盒测试,可能需要考虑从标准输入,还是从文件输入(当然这两者可以互相转换)。
+### 简单的target
+
+一个完整的程序进行黑盒测试,可能需要考虑从标准输入,还是从文件输入(当然这两者可以互相转换)。
libfuzzer更像单元测试。构建输入。输入来自于种子文件。接口如下。
+但是模糊测试的粒度,相较于单元测试,必然更粗些。应该按照场景去组合使用库提供的API。
+
```c++
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
DoSomethingInterestingWithMyAPI(Data, Size);
@@ -22,6 +27,32 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
}
```
+编译。
+
+```shell
+# 编译和链接的时候都进行插桩;内存错误检查
+clang++ -fsanitize=address,fuzzer test_fuzzer.cc
+```
+
+### 其他
+
+1. 语料库。
+ * 输入需要特定结构的模糊测试,直接生成输入是低效的,需要提供(优质)种子库。
+ * 最小化语料库。(将语料库合并,不能提供新的路径的种子丢弃。-merge选项控制)
+ * fork模式:进程本身不会进行任何模糊处理,但会产生多达 N 个并发子进程,为它们提供语料库的随机子集。在孩子退出后,top进程将孩子生成的语料库合并回主语料库。(基本上,-fork=N 等效为-jobs=N and -workers=N)
+ * ...
+ * 字典。如果被模糊化的输入格式由标记组成或具有大量魔法值,那么这种方法很有效。(单纯的模糊测试,突变的时候是不进行语法分析的。) (这个字典是咋创建的?更具语法,将拆出每个关键字?根据字典,模糊测试器,有一定几率生成合法的种子,应该是这样)
+ * 直接使用崩溃输入可以复现崩溃。也可以突变崩溃文件。很少用,感觉。
+2. 突变。
+ * 突变策略。非模糊器的开发者,通常不需要考虑。
+3. 加速测试与资源限制。
+ * 默认是单线程进行测试(除非被测试的库启动自己的线程)。`-jobs`参数可以控制,测试使用的(处理器)数量。(-job=30。但是当前cpu只有12个,默认只能分配一半(-work=min(jobs, NumberOfCpuCores()/2)),即6个cpu。所以同时运行的这6个测试进程,平均每个需要发现5个bug(进程因为bug停止后,会重新再创建一个),程序才会停止。这也是为什么,不使用job参数的时候,遇到一个bug程序即停止) (这里的并行测试会共享语料库。但应该共享不了路径吧。)
+ * -runs 限制尝试次数。
+ * 可以拒绝不需要的输入。比如,只希望解析的输入进入语料库。
+4. 暂时忽略部分。
+ * 代码覆盖率。使用clang coverage。(先测试,然后拿个原来的种子和生成的种子重新跑一遍,得到覆盖率) (生成的覆盖率文件llvm-cov show,远程连接看不到。后面尝试尝试转成图片格式查看吧。)
+ * 与其他模糊测试器的兼容。
+ * ...
## 参考链接
* https://llvm.org/docs/LibFuzzer.html