Libfuzzer的g++实现

一、下载libfuzzer

由于最新版本的libfuzzer只支持clang++,不支持g++,所以我们需要下载老版本的libfuzzer
下载网址:https://github.com/llvm/llvm-project/tree/8f7fc95ab7aab395ec06affa8c705eee2432fcdc/compiler-rt/lib/fuzzer
在这里插入图片描述

二、安装

在编译libfuzzer的时候会报关于-fPIE的错误。此时需要在libfuzzer目录下改动build.sh,用以下代码替换「加了一个-fPIE」
libfuzzer目录:/home/ise/lj/libfuzzer/libfuzzer-workshop/libFuzzer/Fuzzer

#!/bin/sh
LIBFUZZER_SRC_DIR=$(dirname $0)
CXX="${CXX:-clang}"
for f in $LIBFUZZER_SRC_DIR/*.cpp; do
  $CXX -g -fPIE -O2 -fno-omit-frame-pointer -std=c++11 $f -c &
done
wait
rm -f libFuzzer.a
ar ru libFuzzer.a Fuzzer*.o
rm -f Fuzzer*.o

然后运行build.sh,得到编译好的libFuzzer.a文件「我把它拷贝到了待测函数的目录下」

三、设置fuzzer入口

待测函数目录:/home/ise/lj/libfuzzer/libfuzzer-workshop/lessons/04
在这里插入图片描述然后就可以开始准备运行fuzzer了

四、运行时「选项」及「代码」

选项

-fsanitize=fuzzer (必需):为 libFuzzer 提供进程内覆盖信息并与 libFuzzer 运行时链接。
-fsanitize=address(推荐):启用AddressSanitizer
-g(推荐):启用调试信息,使错误消息更易于阅读。
trace-pc:追踪执行过的基本块BB,在每个edge中插入__saitizer_cov_trace_pc()函数,可定义该函数作为相应的回调处理

代码

路径:/home/ise/lj/libfuzzer/libfuzzer-workshop/lessons/04
使用g++将「first_fuzzer.cc」和「libFuzzer.a」进行链接得到「first_fuzzer」文件

/usr/bin/x86_64-linux-gnu-g++ -g -fsanitize=address -fsanitize-coverage=trace-pc -pthread first_fuzzer.cc ./libFuzzer.a -o first_fuzzer
# 或者链接后直接运行first_fuzzer 
 /usr/bin/x86_64-linux-gnu-g++ -g -fsanitize=address -fsanitize-coverage=trace-pc -pthread first_fuzzer.cc ./libFuzzer.a -o first_fuzzer && ./first_fuzzer 

将标准输出与标准错误输出合并后存储在fuzz-0.log文件中,在面板上过滤并显示出错误信息:
执行「first_fuzzer」文件,设定语料库目录CORPUS_DIR/。将标准输出与标准错误输出合并后,过滤出错误信息

# 输出错误到.log中
./first_fuzzer CORPUS_DIR/  > fuzz-0.log 2>&1 | grep ERROR
# 或者只输出错误
./first_fuzzer CORPUS_DIR/ 2>&1 | grep ERROR
# 或者全部输出
./first_fuzzer CORPUS_DIR/ 2>&1

五、输出部分解析

在操作期间,模糊器将信息打印到stderr。

INFO: Seed: 1523017872
INFO: Loaded 1 modules (16 guards): [0x744e60, 0x744ea0),
INFO: -max_len is not provided, using 64
INFO: A corpus is not provided, starting from an empty corpus
#0    READ units: 1
#1    INITED cov: 3 ft: 2 corp: 1/1b exec/s: 0 rss: 24Mb
#3811 NEW    cov: 4 ft: 3 corp: 2/2b exec/s: 0 rss: 25Mb L: 1 MS: 5 ChangeBit-ChangeByte-ChangeBit-ShuffleBytes-ChangeByte-
#3827 NEW    cov: 5 ft: 4 corp: 3/4b exec/s: 0 rss: 25Mb L: 2 MS: 1 CopyPart-
#3963 NEW    cov: 6 ft: 5 corp: 4/6b exec/s: 0 rss: 25Mb L: 2 MS: 2 ShuffleBytes-ChangeBit-
#4167 NEW    cov: 7 ft: 6 corp: 5/9b exec/s: 0 rss: 25Mb L: 3 MS: 1 InsertByte-
...

输出的早期部分包括有关fuzzer选项和配置的信息,包括当前随机种子(在seed:line中;这可以用-seed=n标志覆盖)。
其他输出行具有事件代码和统计信息的形式。可能的事件代码为:

  • READ:Fuzzer已经从语料库目录中读取了所有提供的输入样本。
  • INITED:fuzzer已经完成初始化,包括通过被测代码运行每个初始输入样本。
  • NEW:fuzzer已经创建了一个测试输入,它覆盖了被测代码的新领域。此输入将保存到主语料库目录。
  • REDUCE:fuzzer发现了一个更好(更小)的输入,可以触发先前发现的特征(设置-reduce_inputs=0以禁用)。
  • pulse:fuzzer已产生2N输入(定期产生,以保证用户fuzzer仍在工作)。
  • DONE:fuzzer已完成操作,因为它已达到指定的迭代限制(-runs)或时间限制(-max_total_time)。
  • RELOAD:fuzzer正在定期从corpus目录重新加载输入;这允许它发现由其他fuzzer进程发现的任何输入(请参见并行模糊)。

每个输出行还报告以下统计信息(非零时):

  • COV:执行当前语料库所涵盖的代码块或边的总数。
  • FT:libFuzzer使用不同的信号来评估代码覆盖率:边缘覆盖,边缘计数器,值配置文件,间接调用者/被调用者对等。这些组合的信号称为特征(ft : )。
  • CORP:当前内存中测试语料库中的条目数及其大小(以字节为单位)。
  • LIM:语料库中新条目长度的当前限制。 随着时间的推移逐渐增加,直到达到最大长度(-max_len)。
  • EXEC/ S:每秒的模糊器迭代次数。
  • RSS:当前的内存消耗。

对于NEW事件,输出行还包括有关生成新输入的变异操作的信息:

  • L:新输入的大小(以字节为单位)。
  • MS: <操作>计数和用于生成输入的变异操作列表。
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值