学习libfuzzer使用(一)

学习libfuzzer使用

可以参考的教程:
教程
官方git网址:
git
官方说明页面:
说明
翻译git的说明:www.giantbranch.cn/2020/03/08/libfuzzer 文档/

安装

依照官方教程,运行下面命令

# Install git and get this tutorial
sudo apt-get --yes install git
git clone https://github.com/google/fuzzing.git fuzzing

# Get fuzzer-test-suite
git clone https://github.com/google/fuzzer-test-suite.git FTS

./fuzzing/tutorial/libFuzzer/install-deps.sh  # Get deps
./fuzzing/tutorial/libFuzzer/install-clang.sh # Get fresh clang binaries

测试目标

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
  DoSomethingWithData(Data, Size);
  return 0;
}

DoSomethingWithData函数就是要被测试的目标,他需要接收Data和Size两个输入。extern "C"指名函数从此开始测试。
比如下面的fuzz_me.cc程序,被测函数格式如此

#include <stdint.h>
#include <stddef.h>

bool FuzzMe(const uint8_t *Data, size_t DataSize) {
  return DataSize >= 3 &&
      Data[0] == 'F' &&
      Data[1] == 'U' &&
      Data[2] == 'Z' &&
      Data[3] == 'Z';  // :‑<
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
  FuzzMe(Data, Size);
  return 0;
}

运行

使用如下命令运行:

clang++ -g -fsanitize=address,fuzzer fuzzing/tutorial/libFuzzer/fuzz_me.cc -o fuzz_me

其中clang是编译器,-g启用调试信息,使错误消息更易于阅读(可选);-fsanitize=fuzzer 向libfuzzer提供进程内覆盖信息,并与libfuzzer运行时链接(必须);-fsanitize=address 启用AddressSanitizer 是一个内存泄漏检测工具,可以检测内存泄漏,参考链接AddressSanitizer;后面就是要测试的程序的路径;-o fuzz_me指明了生成文件的格式。
运行后会在执行的文件夹下生成一个可执行程序fuzz_me和crash文件(如有)
在这里插入图片描述
随后执行:

./fuzz_me

会看到本次测试的详细信息,包括ERROR等。
在这里插入图片描述其中,输出的含义:

  1. 首先输出的是配置信息,有关fuzzer的选项和配置的信息,包括当前的初始种子,可以通过-seed=N来指定。
  2. 下面是输出事件和统计信息:
READ:fuzzer已经从语料库目录读取了所有输入样本
INITED:模糊器已完成初始化,包括运行语料库中的所有样本
NEW:发现新路径,并将输入保存到语料库目录
REDUCE:找到一个更好,一般指更小的输入触发以前的路径(设置-reduce_inputs=0,可以禁用)
pulse:fuzzer已经生成2^n的输入(主要是定期生成让用户知道模糊器仍在工作)
DONE:模糊测试完成,达到了迭代限制(-runs)或者时间限制(-max_total_time)
RELOAD:fuzzer定期从语料库重新加载输入,这样,就可以发现其他模糊测试工具发现的输入
  1. cov是覆盖的范围,代码块或者边数。
  2. libfuzzer用不同的signals来评估代码覆盖率:边覆盖率,边的数量,value profiles,间接调用和被调用等,将他们合并在一起,就是features (ft)。
  3. corp:当前内存中测试的语料库的数量/大小(单位为bytes),覆盖cov的内容。
  4. lim:当前限制的输入长度,随着时间推移,会增加到-max_len。
  5. exec/s:每秒的迭代次数。
  6. rss:当前内存的消耗。
    在这里插入图片描述
    倒数第二行是本次崩溃的信息,记录到了crash-0eb8e4e…中,可以复现该崩溃信息:
    在这里插入图片描述

可选的参数

  • 与自定义种子库一起使用:
./woff2-2016-05-06-fsanitize_fuzzer MY_CORPUS/ seeds/

其中MY_CORPUS/是语料库目录,触发有趣代码路径的输入会写入该文件夹。seeds/是自定义的种子语料库

  • -jobs=N 将生成N个独立的作业,但不超过拥有的内核数量的一半。
  • -workers=M 用于设置允许的并行作业数
  • –dict=afl/dictionaries/xml.dict 用于指定字典,当输入格式由标记组成或者具有大量魔术值,使用字典会很有效。
mkdir CORPUS
./libxml2-v2.9.2-fsanitize_fuzzer -dict=afl/dictionaries/xml.dict -jobs=8 -workers=8 CORPUS

代码覆盖率可视化

使用clang的覆盖统计功能,更多功能参见clang

clang -fprofile-instr-generate -fcoverage-mapping ~/fuzzing/tutorial/libFuzzer/fuzz_me.cc \
                                                  ~/Fuzzer/standalone/StandaloneFuzzTargetMain.c
mkdir CORPUS # Create an empty corpus dir.

echo -n A > CORPUS/A && ./a.out CORPUS/* && \
             llvm-profdata merge -sparse *.profraw -o default.profdata && \
             llvm-cov show a.out -instr-profile=default.profdata -name=FuzzMe

在这里插入图片描述
行覆盖统计:
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值