首页
社区
课程
招聘
[原创]libFuzzer模糊测试引擎调研与自定义开发
发表于: 2024-10-4 15:19 7575

[原创]libFuzzer模糊测试引擎调研与自定义开发

2024-10-4 15:19
7575

项目地址:llvm-project/compiler-rt/lib/fuzzer at main · llvm/llvm-project (github.com)
libFuzzer 是由 LLVM 项目开发的覆盖率引导模糊测试引擎,广泛用于自动发现软件中的漏洞和错误。它通过不断生成和测试输入数据,提高代码覆盖率,找到潜在的缺陷。libFuzzer 尤其适合测试用 C 和 C++ 编写的代码。

libFuzzer 是一个面向库的模糊测试引擎,广泛用于发现软件中的漏洞。了解其模块结构有助于深入理解其工作原理和扩展能力。以下是 libFuzzer 的主要模块结构:

libFuzzer 的主要功能包括:

源码位置:llvm-project/compiler-rt/lib/fuzzer at main · llvm/llvm-project (github.com)
这个 Fuzzer 类的构成可以分为以下几个部分:

主要功能函数:

时间与状态函数:

静态回调函数(Static Callback Functions):

其他功能函数:

这个类主要涉及模糊测试的核心功能,包括种子语料库的处理、崩溃管理、变异调度、统计信息打印等多个方面。

Libfuzzer源码学习项目:Dor1s/libfuzzer-workshop: Repository for materials of "Modern fuzzing of C/C++ Projects" workshop. (github.com)
libfuzzer最新源码位置:llvm-project/compiler-rt/lib/fuzzer at main · llvm/llvm-project (github.com)
源码讲解:https://www.bilibili.com/video/BV1RH4y1r74p/?spm_id_from=333.788

libFuzzer 是 LLVM 项目中的一部分,专门用于通过模糊测试来自动化测试 C/C++ 项目中的漏洞。其核心流程大致分为以下几个步骤:

主函数入口代码如下:

在这个主函数中,调用了 fuzzer::FuzzerDriver 函数,并传入了用户定义的 LLVMFuzzerTestOneInput 函数。LLVMFuzzerTestOneInput 是由用户编写的,用于定义模糊测试的目标函数,它接收输入数据进行测试并返回测试结果。FuzzerDriver 函数则负责模糊测试的核心逻辑。

FuzzerDriver 是 libFuzzer 的核心函数,它的主要作用是设置和启动模糊测试。函数签名如下:

核心步骤包括:

主循环 (Fuzzer::Loop)
Loop 是 libFuzzer 中用于执行模糊测试的核心循环。它会不断从语料库中提取输入数据,进行输入变异,并将变异后的输入传递给 LLVMFuzzerTestOneInput 进行测试。循环的目的是通过广泛探索输入空间,发现导致程序崩溃或行为异常的输入,从而发现潜在的漏洞。

变异引擎
MutationDispatcher 是 libFuzzer 的变异引擎,它会生成各种输入数据变种,覆盖尽可能多的代码路径。变异策略包括:

测试结果收集
每次输入变异后,libFuzzer 会将结果反馈给 Fuzzer 对象,判断程序是否崩溃或异常。出现崩溃时,libFuzzer 会记录触发崩溃的输入,并终止循环进行进一步分析。

更多版本:Release LLVM 18.1.8 · llvm/llvm-project (github.com)
libFuzzer的源码根据需要下载对应版本进行源码编译。

一键配置clang脚本:,该脚本在Ubuntu20上成功测试运行过:

与覆盖率相关的选项如下:

以下是与覆盖率相关的选项的使用方法和案例说明:

在libfuzzer中有很多命令并未实现可以自行寻找,这是在vscode匹配命令选项的正则表达式:Options\.\w+\s*=\s*Flags\.\w+;

为了满足以下二次开发需求:

首先,修改 libFuzzer/FuzzerLoop.cpp,增加用于导出模糊测试过程中数据的接口。我们可以通过直接修改 libFuzzer 的覆盖率部分,创建接口来收集并输出信息。下面是覆盖率和其他统计信息的部分代码片段:

Fuzzer::PrintStats 函数中,我们已经将覆盖率、执行次数、内存使用情况等统计信息打印,并通过 ExportDataToFrontend 函数导出到外部系统,可以进一步传递到前端页面。

要实现 libFuzzer 的持久模糊测试,并且避免在发现 crash 后终止,可以通过修改 libFuzzer 源码来调整其行为。libFuzzer 默认行为是当检测到崩溃(如非法内存访问、堆溢出等)时终止模糊测试。为了避免这种情况,目标是允许 fuzzing 继续进行而不退出。

定位崩溃处理逻辑
libFuzzer 在检测到 crash 后会调用 LLVMFuzzerTestOneInput,这段代码可能会引发未处理异常,导致 fuzzing 过程终止。我们可以通过修改 libFuzzer 的 crash 处理逻辑,使其在崩溃时记录问题但继续模糊测试。

关键代码修改点
需要查找 libFuzzer 源码中的崩溃处理位置,一般在 FuzzerLoop.cppFuzzerDriver.cpp 文件中。

持久化模糊测试的入口
如果你想让模糊测试保持“持久化”,即反复利用同一测试环境进行测试,可以在 FuzzerLoop.cpp 中引入一个持久化模式(Persistent Mode)。这种模式会允许测试继续,而不是每次退出。

实现持久化模式
FuzzerLoop.cpp 中找到模糊测试的主要循环。将其改成持久化循环模式,像这样:

捕获崩溃并继续测试
修改 libFuzzer 中的 FuzzerDriver.cpp 文件,让崩溃不会终止程序。可以在捕获崩溃的地方加入 try-catch 或平台相关的异常处理机制,确保在崩溃时记录并恢复。

处理信号(Signal Handling)
在某些情况下,libFuzzer 可能通过信号(如 SIGSEGV, SIGABRT)来处理崩溃。你可以修改信号处理函数,确保信号不会导致进程终止。

编译脚本文件路径:llvm-project/compiler-rt/lib/fuzzer/build.sh at main · llvm/llvm-project (github.com)
在完成代码修改后,需要重新编译 libFuzzer 生成 libFuzzer.a 静态库。可以使用如下编译脚本:

将修改后的源码放置到 libFuzzer 源码目录,运行该脚本编译,生成一个 libFuzzer.a 静态库,用于后续的模糊测试项目链接使用。

自定义的libFuzzer的使用方式:

这里的libFuzzer.a是自己使用项目提供的build.sh编译出来的版本,还可以添加其他编译选项自行添加!

教程地址:fuzzing/tutorial/libFuzzerTutorial.md 在 master ·谷歌/模糊测试 (github.com)

文件位置:FTS/woff2-2016-05-06/target.cc

准备对:CVE-2014-0160 进行复现
漏洞原理:OpenSSL 心脏滴血漏洞(CVE-2014-0160)漏洞讲解(小白可懂,简单详细)-CSDN博客
使用github项目已经准备好的编译脚本:

创建一个包含 LLVMFuzzerTestOneInput 函数的模糊测试目标:
文件所在路径:fuzzer-test-suite/openssl-1.0.1f

在项目根目录中,运行以下命令编译模糊测试目标,详细的编译选项可以查看build.sh :

在项目根目录中,运行以下命令开始模糊测试,成功跑出堆溢出漏洞:

#include "FuzzerDefs.h"
 
extern "C" {
// 该函数由用户定义,用于测试目标函数
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
// extern "C"
 
ATTRIBUTE_INTERFACE int main(int argc, char **argv) {
  return fuzzer::FuzzerDriver(&argc, &argv, LLVMFuzzerTestOneInput);
}
#include "FuzzerDefs.h"
 
extern "C" {
// 该函数由用户定义,用于测试目标函数
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
// extern "C"
 
ATTRIBUTE_INTERFACE int main(int argc, char **argv) {
  return fuzzer::FuzzerDriver(&argc, &argv, LLVMFuzzerTestOneInput);
}
int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
// 进行对象初始化
  auto *MD = new MutationDispatcher(Rand, Options);
  auto *Corpus = new InputCorpus(Options.OutputCorpus);
  auto *F = new Fuzzer(Callback, *Corpus, *MD, Options);
 
// 解析命令选项
...
 
// 读取并处理输入的语料库文件,传入模糊测试主循环
  auto CorporaFiles = ReadCorpora(*Inputs, ParseSeedInuts(Flags.seed_inputs));
  F->Loop(CorporaFiles);
}
int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
// 进行对象初始化
  auto *MD = new MutationDispatcher(Rand, Options);
  auto *Corpus = new InputCorpus(Options.OutputCorpus);
  auto *F = new Fuzzer(Callback, *Corpus, *MD, Options);
 
// 解析命令选项
...
 
// 读取并处理输入的语料库文件,传入模糊测试主循环
  auto CorporaFiles = ReadCorpora(*Inputs, ParseSeedInuts(Flags.seed_inputs));
  F->Loop(CorporaFiles);
}
#!/bin/bash
 
# 安装 Clang 的依赖
sudo apt-get --yes install curl subversion screen gcc g++ cmake ninja-build golang autoconf libtool apache2 python-dev pkg-config zlib1g-dev libgcrypt20-dev libgss-dev libssl-dev libxml2-dev ragel nasm libarchive-dev make automake libdbus-1-dev libboost-dev autoconf-archive libtinfo5
 
# 定义 Clang 的版本和下载链接
CLANG_VERSION="18.1.8"
CLANG_TAR="clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-18.04.tar.xz"
CLANG_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}/${CLANG_TAR}"
CLANG_INSTALL_DIR="/usr/local/clang-${CLANG_VERSION}"
 
# 检查 Clang 是否已下载
if [ -f "${CLANG_TAR}" ]; then
    echo "Clang 已经下载 (${CLANG_TAR})"
else
    echo "正在下载 Clang..."
    wget "${CLANG_URL}"
fi
 
# 检查 Clang 是否已安装
if [ -d "${CLANG_INSTALL_DIR}" ]; then
    echo "Clang 已经安装在 ${CLANG_INSTALL_DIR}"
else
    echo "正在安装 Clang..."
 
    # 创建目录
    sudo mkdir -p "${CLANG_INSTALL_DIR}"
     
    echo "正在安装 解压时间比较久..."
    # 解压 Clang
    sudo tar -xf "${CLANG_TAR}" -C "${CLANG_INSTALL_DIR}" --strip-components=1
fi
 
# 检查环境变量是否已经设置
if ! grep -q "${CLANG_INSTALL_DIR}/bin" ~/.bashrc; then
    echo "添加环境变量..."
    echo "export PATH=${CLANG_INSTALL_DIR}/bin:\$PATH" >> ~/.bashrc
    echo "export LD_LIBRARY_PATH=${CLANG_INSTALL_DIR}/lib:\$LD_LIBRARY_PATH" >> ~/.bashrc
 
    # 使环境变量生效
    source ~/.bashrc
else
    echo "环境变量已经配置"
fi
 
# 运行 Clang 验证安装
echo "验证 Clang 安装..."
clang --version
echo "如果验证失败再次运行该命令: source ~/.bashrc"
#!/bin/bash
 
# 安装 Clang 的依赖
sudo apt-get --yes install curl subversion screen gcc g++ cmake ninja-build golang autoconf libtool apache2 python-dev pkg-config zlib1g-dev libgcrypt20-dev libgss-dev libssl-dev libxml2-dev ragel nasm libarchive-dev make automake libdbus-1-dev libboost-dev autoconf-archive libtinfo5
 
# 定义 Clang 的版本和下载链接
CLANG_VERSION="18.1.8"
CLANG_TAR="clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-18.04.tar.xz"
CLANG_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}/${CLANG_TAR}"
CLANG_INSTALL_DIR="/usr/local/clang-${CLANG_VERSION}"
 
# 检查 Clang 是否已下载
if [ -f "${CLANG_TAR}" ]; then
    echo "Clang 已经下载 (${CLANG_TAR})"
else
    echo "正在下载 Clang..."
    wget "${CLANG_URL}"
fi
 
# 检查 Clang 是否已安装
if [ -d "${CLANG_INSTALL_DIR}" ]; then
    echo "Clang 已经安装在 ${CLANG_INSTALL_DIR}"
else
    echo "正在安装 Clang..."
 
    # 创建目录
    sudo mkdir -p "${CLANG_INSTALL_DIR}"
     
    echo "正在安装 解压时间比较久..."
    # 解压 Clang
    sudo tar -xf "${CLANG_TAR}" -C "${CLANG_INSTALL_DIR}" --strip-components=1
fi
 
# 检查环境变量是否已经设置
if ! grep -q "${CLANG_INSTALL_DIR}/bin" ~/.bashrc; then
    echo "添加环境变量..."
    echo "export PATH=${CLANG_INSTALL_DIR}/bin:\$PATH" >> ~/.bashrc
    echo "export LD_LIBRARY_PATH=${CLANG_INSTALL_DIR}/lib:\$LD_LIBRARY_PATH" >> ~/.bashrc
 
    # 使环境变量生效
    source ~/.bashrc
else
    echo "环境变量已经配置"
fi
 
# 运行 Clang 验证安装
echo "验证 Clang 安装..."
clang --version
echo "如果验证失败再次运行该命令: source ~/.bashrc"
// 是否打印新覆盖的 PC 地址
Options.PrintNewCovPcs = Flags.print_pcs;
 
// 是否打印新覆盖的函数
Options.PrintNewCovFuncs = Flags.print_funcs;
 
// 是否打印覆盖率信息
Options.PrintCoverage = Flags.print_coverage;
 
// 是否打印完整的覆盖率信息
Options.PrintFullCoverage = Flags.print_full_coverage;
// 是否打印新覆盖的 PC 地址
Options.PrintNewCovPcs = Flags.print_pcs;
 
// 是否打印新覆盖的函数
Options.PrintNewCovFuncs = Flags.print_funcs;
 
// 是否打印覆盖率信息
Options.PrintCoverage = Flags.print_coverage;
 
// 是否打印完整的覆盖率信息
Options.PrintFullCoverage = Flags.print_full_coverage;
./woff2-2016-05-06-fsanitize_fuzzer -print_pcs=1
./woff2-2016-05-06-fsanitize_fuzzer -print_pcs=1
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 2544448443
INFO: Loaded 1 modules   (10708 inline 8-bit counters): 10708 [0x562f5c3345c0, 0x562f5c336f94),
INFO: Loaded 1 PC tables (10708 PCs): 10708 [0x562f5c336f98,0x562f5c360cd8),
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2  INITED cov: 15 ft: 16 corp: 1/1b exec/s: 0 rss: 32Mb
    NEW_PC: 0x562f5c220771 in ReadWOFF2Header /home/ub20/FTS/woff/SRC/src/woff2_dec.cc:987:7
#21 NEW    cov: 16 ft: 17 corp: 2/5b lim: 4 exec/s: 0 rss: 33Mb L: 4/4 MS: 4 CrossOver-InsertByte-ChangeBit-CopyPart-
    NEW_PC: 0x562f5c2161a8 in ReadU32 /home/ub20/FTS/woff/SRC/src/./buffer.h:127:9
#999    NEW    cov: 17 ft: 18 corp: 3/9b lim: 11 exec/s: 0 rss: 34Mb L: 4/4 MS: 3 ChangeByte-ShuffleBytes-CMP- DE: "wOF2"-
    NEW_PC: 0x562f5c22077c in ReadU32 /home/ub20/FTS/woff/SRC/src/./buffer.h:127:9
#1300   NEW    cov: 18 ft: 19 corp: 4/17b lim: 11 exec/s: 0 rss: 34Mb L: 8/8 MS: 1 PersAutoDict- DE: "wOF2"-
    NEW_PC: 0x562f5c22103f in ReadWOFF2Header /home/ub20/FTS/woff/SRC/src/woff2_dec.cc:995:7
#1618   NEW    cov: 19 ft: 20 corp: 5/29b lim: 14 exec/s: 0 rss: 34Mb L: 12/12 MS: 3 InsertRepeatedBytes-PersAutoDict-InsertRepeatedBytes- DE: "wOF2"-
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 2544448443
INFO: Loaded 1 modules   (10708 inline 8-bit counters): 10708 [0x562f5c3345c0, 0x562f5c336f94),
INFO: Loaded 1 PC tables (10708 PCs): 10708 [0x562f5c336f98,0x562f5c360cd8),
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2  INITED cov: 15 ft: 16 corp: 1/1b exec/s: 0 rss: 32Mb
    NEW_PC: 0x562f5c220771 in ReadWOFF2Header /home/ub20/FTS/woff/SRC/src/woff2_dec.cc:987:7
#21 NEW    cov: 16 ft: 17 corp: 2/5b lim: 4 exec/s: 0 rss: 33Mb L: 4/4 MS: 4 CrossOver-InsertByte-ChangeBit-CopyPart-
    NEW_PC: 0x562f5c2161a8 in ReadU32 /home/ub20/FTS/woff/SRC/src/./buffer.h:127:9
#999    NEW    cov: 17 ft: 18 corp: 3/9b lim: 11 exec/s: 0 rss: 34Mb L: 4/4 MS: 3 ChangeByte-ShuffleBytes-CMP- DE: "wOF2"-
    NEW_PC: 0x562f5c22077c in ReadU32 /home/ub20/FTS/woff/SRC/src/./buffer.h:127:9
#1300   NEW    cov: 18 ft: 19 corp: 4/17b lim: 11 exec/s: 0 rss: 34Mb L: 8/8 MS: 1 PersAutoDict- DE: "wOF2"-
    NEW_PC: 0x562f5c22103f in ReadWOFF2Header /home/ub20/FTS/woff/SRC/src/woff2_dec.cc:995:7
#1618   NEW    cov: 19 ft: 20 corp: 5/29b lim: 14 exec/s: 0 rss: 34Mb L: 12/12 MS: 3 InsertRepeatedBytes-PersAutoDict-InsertRepeatedBytes- DE: "wOF2"-
./woff2-2016-05-06-fsanitize_fuzzer -print_funcs=1
./woff2-2016-05-06-fsanitize_fuzzer -print_funcs=1
ub20@ub20:~/FTS/woff$ ./woff2-2016-05-06-fsanitize_fuzzer -print_funcs=1
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 2688967800
INFO: Loaded 1 modules   (10708 inline 8-bit counters): 10708 [0x55b819abf5c0, 0x55b819ac1f94),
INFO: Loaded 1 PC tables (10708 PCs): 10708 [0x55b819ac1f98,0x55b819aebcd8),
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2  INITED cov: 15 ft: 16 corp: 1/1b exec/s: 0 rss: 32Mb
#10 NEW    cov: 16 ft: 17 corp: 2/5b lim: 4 exec/s: 0 rss: 32Mb L: 4/4 MS: 3 CrossOver-InsertByte-CrossOver-
...
#144927 NEW    cov: 29 ft: 30 corp: 14/437b lim: 1390 exec/s: 48309 rss: 47Mb L: 119/119 MS: 1 PersAutoDict- DE: "\012\000\000\000\000\000\000\000"-
    NEW_FUNC[1/1]: 0x55b8199a0050 in woff2::ReadBase128(woff2::Buffer*, unsigned int*) /home/ub20/FTS/woff/SRC/src/variable_length.cc:94
...
ub20@ub20:~/FTS/woff$ ./woff2-2016-05-06-fsanitize_fuzzer -print_funcs=1
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 2688967800
INFO: Loaded 1 modules   (10708 inline 8-bit counters): 10708 [0x55b819abf5c0, 0x55b819ac1f94),
INFO: Loaded 1 PC tables (10708 PCs): 10708 [0x55b819ac1f98,0x55b819aebcd8),
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2  INITED cov: 15 ft: 16 corp: 1/1b exec/s: 0 rss: 32Mb
#10 NEW    cov: 16 ft: 17 corp: 2/5b lim: 4 exec/s: 0 rss: 32Mb L: 4/4 MS: 3 CrossOver-InsertByte-CrossOver-
...
#144927 NEW    cov: 29 ft: 30 corp: 14/437b lim: 1390 exec/s: 48309 rss: 47Mb L: 119/119 MS: 1 PersAutoDict- DE: "\012\000\000\000\000\000\000\000"-
    NEW_FUNC[1/1]: 0x55b8199a0050 in woff2::ReadBase128(woff2::Buffer*, unsigned int*) /home/ub20/FTS/woff/SRC/src/variable_length.cc:94
...
./openssl-1.0.1f-fsanitize_fuzzer -print_coverage=1
./openssl-1.0.1f-fsanitize_fuzzer -print_coverage=1
UNCOVERED_FUNC: hits: 0 edges: 0/5 Init() /home/ub20/FTS/openssl-1.0.1f/target.cc:9
COVERED_FUNC: hits: 42 edges: 2/5 LLVMFuzzerTestOneInput /home/ub20/FTS/openssl-1.0.1f/target.cc:26
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f/target.cc:27
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f/target.cc:27
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f/target.cc:0
 
COVERED_FUNC: hits: 42 edges: 19/34 ssleay_rand_add /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:194
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:228
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:228
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:249
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:249
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:260
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:263
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:266
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:294
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:294
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:0
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:306
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:0
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:311
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:321
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:322
UNCOVERED_FUNC: hits: 0 edges: 0/5 Init() /home/ub20/FTS/openssl-1.0.1f/target.cc:9
COVERED_FUNC: hits: 42 edges: 2/5 LLVMFuzzerTestOneInput /home/ub20/FTS/openssl-1.0.1f/target.cc:26
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f/target.cc:27
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f/target.cc:27
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f/target.cc:0
 
COVERED_FUNC: hits: 42 edges: 19/34 ssleay_rand_add /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:194
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:228
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:228
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:249
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:249
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:260
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:263
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:266
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:294
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:294
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:0
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:306
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:0
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:311
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:321
  UNCOVERED_PC: /home/ub20/FTS/openssl-1.0.1f_crash/BUILD/crypto/rand/md_rand.c:322
./woff2-2016-05-06-fsanitize_fuzzer -print_full_coverage=1
./woff2-2016-05-06-fsanitize_fuzzer -print_full_coverage=1
ub20@ub20:~/FTS/woff$ ./woff2-2016-05-06-fsanitize_fuzzer -print_coverage=1
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 3116423339
INFO: Loaded 1 modules   (10708 inline 8-bit counters): 10708 [0x5652816785c0, 0x56528167af94),
INFO: Loaded 1 PC tables (10708 PCs): 10708 [0x56528167af98,0x5652816a4cd8),
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2  INITED cov: 15 ft: 16 corp: 1/1b exec/s: 0 rss: 32Mb
#27 NEW    cov: 16 ft: 17 corp: 2/5b lim: 4 exec/s: 0 rss: 33Mb L: 4/4 MS: 5 ChangeBit-ChangeBit-ChangeBinInt-CopyPart-CopyPart-
#433    NEW    cov: 17 ft: 18 corp: 3/10b lim: 6 exec/s: 0 rss: 33Mb L: 5/5 MS: 1 CMP- DE: "wOF2"-
#636    REDUCE cov: 17 ft: 18 corp: 3/9b lim: 6 exec/s: 0 rss: 33Mb L: 4/4 MS: 3 ShuffleBytes-ChangeBit-EraseBytes-
#884    REDUCE cov: 18 ft: 19 corp: 4/17b lim: 8 exec/s: 0 rss: 34Mb L: 8/8 MS: 3 InsertRepeatedBytes-ChangeByte-PersAutoDict- DE: "wOF2"-
#1635   NEW    cov: 19 ft: 20 corp: 5/29b lim: 14 exec/s: 0 rss: 34Mb L: 12/12 MS: 1 CrossOver-
#3505   NEW    cov: 20 ft: 21 corp: 6/58b lim: 29 exec/s: 0 rss: 35Mb L: 29/29 MS: 5 PersAutoDict-CrossOver-InsertRepeatedBytes-ChangeByte-ChangeBinInt- DE: "wOF2"-
#4629   NEW    cov: 21 ft: 22 corp: 7/87b lim: 38 exec/s: 0 rss: 35Mb L: 29/29 MS: 4 ChangeBit-CopyPart-ShuffleBytes-ChangeBit-
#9279   REDUCE cov: 21 ft: 22 corp: 7/72b lim: 80 exec/s: 0 rss: 35Mb L: 14/29 MS: 5 EraseBytes-EraseBytes-ChangeBit-EraseBytes-ChangeBinInt-
#9535   REDUCE cov: 22 ft: 23 corp: 8/86b lim: 80 exec/s: 0 rss: 35Mb L: 14/29 MS: 1 ChangeByte-
#27928  REDUCE cov: 23 ft: 24 corp: 9/99b lim: 261 exec/s: 0 rss: 37Mb L: 13/29 MS: 3 ChangeBit-EraseBytes-ChangeBinInt-
#31817  NEW    cov: 24 ft: 25 corp: 10/120b lim: 293 exec/s: 0 rss: 37Mb L: 21/29 MS: 4 ChangeBit-EraseBytes-ChangeBit-ChangeBinInt-
#40024  REDUCE cov: 24 ft: 25 corp: 10/119b lim: 373 exec/s: 0 rss: 38Mb L: 12/29 MS: 2 EraseBytes-CMP- DE: "\001\000\000\000\000\000\000\014"-
#42588  NEW    cov: 25 ft: 26 corp: 11/155b lim: 397 exec/s: 0 rss: 38Mb L: 36/36 MS: 4 CrossOver-CopyPart-InsertByte-ChangeBinInt-
^C==12029== libFuzzer: run interrupted; exiting
COVERAGE:
UNCOVERED_FUNC: hits: 0 edges: 0/19 brotli::ZopfliCreateCommands(unsigned long, unsigned long, unsigned long, std::vector<unsigned int, std::allocator<unsigned int>> const&, brotli::ZopfliNode const*, int*, unsigned long*, brotli::Command*, unsigned long*) /home/ub20/FTS/woff/BROTLI/enc/backward_references.cc:437
UNCOVERED_FUNC: hits: 0 edges: 0/18 brotli::Command::Command(unsigned long, unsigned long, unsigned long, unsigned long) /home/ub20/FTS/woff/BROTLI/enc/././command.h:102
UNCOVERED_FUNC: hits: 0 edges: 0/31 brotli::ZopfliComputeShortestPath(unsigned long, unsigned long, unsigned char const*, unsigned long, unsigned long, int const*, brotli::HashToBinaryTree*, brotli::ZopfliNode*, std::vector<unsigned int, std::allocator<unsigned int>>*) /home/ub20/FTS/woff/BROTLI/enc/backward_references.cc:510
UNCOVERED_FUNC: hits: 0 edges: 0/27 brotli::ZopfliCostModel::SetFromLiteralCosts(unsigned long, unsigned long, unsigned char const*, unsigned long) /home/ub20/FTS/woff/BROTLI/enc/backward_references.cc:77
UNCOVERED_FUNC: hits: 0 edges: 0/44 brotli::HashToBinaryTree::FindAllMatches(unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, brotli::BackwardMatch*) /home/ub20/FTS/woff/BROTLI/enc/././hash.h:681
...
ub20@ub20:~/FTS/woff$ ./woff2-2016-05-06-fsanitize_fuzzer -print_coverage=1
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 3116423339
INFO: Loaded 1 modules   (10708 inline 8-bit counters): 10708 [0x5652816785c0, 0x56528167af94),
INFO: Loaded 1 PC tables (10708 PCs): 10708 [0x56528167af98,0x5652816a4cd8),
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes
INFO: A corpus is not provided, starting from an empty corpus
#2  INITED cov: 15 ft: 16 corp: 1/1b exec/s: 0 rss: 32Mb
#27 NEW    cov: 16 ft: 17 corp: 2/5b lim: 4 exec/s: 0 rss: 33Mb L: 4/4 MS: 5 ChangeBit-ChangeBit-ChangeBinInt-CopyPart-CopyPart-
#433    NEW    cov: 17 ft: 18 corp: 3/10b lim: 6 exec/s: 0 rss: 33Mb L: 5/5 MS: 1 CMP- DE: "wOF2"-
#636    REDUCE cov: 17 ft: 18 corp: 3/9b lim: 6 exec/s: 0 rss: 33Mb L: 4/4 MS: 3 ShuffleBytes-ChangeBit-EraseBytes-
#884    REDUCE cov: 18 ft: 19 corp: 4/17b lim: 8 exec/s: 0 rss: 34Mb L: 8/8 MS: 3 InsertRepeatedBytes-ChangeByte-PersAutoDict- DE: "wOF2"-
#1635   NEW    cov: 19 ft: 20 corp: 5/29b lim: 14 exec/s: 0 rss: 34Mb L: 12/12 MS: 1 CrossOver-
#3505   NEW    cov: 20 ft: 21 corp: 6/58b lim: 29 exec/s: 0 rss: 35Mb L: 29/29 MS: 5 PersAutoDict-CrossOver-InsertRepeatedBytes-ChangeByte-ChangeBinInt- DE: "wOF2"-
#4629   NEW    cov: 21 ft: 22 corp: 7/87b lim: 38 exec/s: 0 rss: 35Mb L: 29/29 MS: 4 ChangeBit-CopyPart-ShuffleBytes-ChangeBit-
#9279   REDUCE cov: 21 ft: 22 corp: 7/72b lim: 80 exec/s: 0 rss: 35Mb L: 14/29 MS: 5 EraseBytes-EraseBytes-ChangeBit-EraseBytes-ChangeBinInt-
#9535   REDUCE cov: 22 ft: 23 corp: 8/86b lim: 80 exec/s: 0 rss: 35Mb L: 14/29 MS: 1 ChangeByte-
#27928  REDUCE cov: 23 ft: 24 corp: 9/99b lim: 261 exec/s: 0 rss: 37Mb L: 13/29 MS: 3 ChangeBit-EraseBytes-ChangeBinInt-
#31817  NEW    cov: 24 ft: 25 corp: 10/120b lim: 293 exec/s: 0 rss: 37Mb L: 21/29 MS: 4 ChangeBit-EraseBytes-ChangeBit-ChangeBinInt-
#40024  REDUCE cov: 24 ft: 25 corp: 10/119b lim: 373 exec/s: 0 rss: 38Mb L: 12/29 MS: 2 EraseBytes-CMP- DE: "\001\000\000\000\000\000\000\014"-
#42588  NEW    cov: 25 ft: 26 corp: 11/155b lim: 397 exec/s: 0 rss: 38Mb L: 36/36 MS: 4 CrossOver-CopyPart-InsertByte-ChangeBinInt-
^C==12029== libFuzzer: run interrupted; exiting
COVERAGE:
UNCOVERED_FUNC: hits: 0 edges: 0/19 brotli::ZopfliCreateCommands(unsigned long, unsigned long, unsigned long, std::vector<unsigned int, std::allocator<unsigned int>> const&, brotli::ZopfliNode const*, int*, unsigned long*, brotli::Command*, unsigned long*) /home/ub20/FTS/woff/BROTLI/enc/backward_references.cc:437
UNCOVERED_FUNC: hits: 0 edges: 0/18 brotli::Command::Command(unsigned long, unsigned long, unsigned long, unsigned long) /home/ub20/FTS/woff/BROTLI/enc/././command.h:102
UNCOVERED_FUNC: hits: 0 edges: 0/31 brotli::ZopfliComputeShortestPath(unsigned long, unsigned long, unsigned char const*, unsigned long, unsigned long, int const*, brotli::HashToBinaryTree*, brotli::ZopfliNode*, std::vector<unsigned int, std::allocator<unsigned int>>*) /home/ub20/FTS/woff/BROTLI/enc/backward_references.cc:510
UNCOVERED_FUNC: hits: 0 edges: 0/27 brotli::ZopfliCostModel::SetFromLiteralCosts(unsigned long, unsigned long, unsigned char const*, unsigned long) /home/ub20/FTS/woff/BROTLI/enc/backward_references.cc:77
UNCOVERED_FUNC: hits: 0 edges: 0/44 brotli::HashToBinaryTree::FindAllMatches(unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, brotli::BackwardMatch*) /home/ub20/FTS/woff/BROTLI/enc/././hash.h:681
...
// 设置详细程度的级别
Options.Verbosity = Flags.verbosity;
 
// 设置最大输入长度
Options.MaxLen = Flags.max_len;
...
// 是否处理 SIGINT 信号
Options.HandleInt = Flags.handle_int;
 
// 是否处理 SIGSEGV 信号
Options.HandleSegv = Flags.handle_segv;
 
// 是否处理 SIGTERM 信号
Options.HandleTerm = Flags.handle_term;
 
// 是否处理 SIGXFSZ 信号
Options.HandleXfsz = Flags.handle_xfsz;
 
// 是否处理 SIGUSR1 信号
Options.HandleUsr1 = Flags.handle_usr1;
 
// 是否处理 SIGUSR2 信号
Options.HandleUsr2 = Flags.handle_usr2;
 
// 是否处理 Windows 异常
Options.HandleWinExcept = Flags.handle_winexcept;
 
// 是否启用分叉的种子组
Options.ForkCorpusGroups = Flags.fork_corpus_groups;
// 设置详细程度的级别
Options.Verbosity = Flags.verbosity;
 
// 设置最大输入长度
Options.MaxLen = Flags.max_len;
...
// 是否处理 SIGINT 信号
Options.HandleInt = Flags.handle_int;
 
// 是否处理 SIGSEGV 信号
Options.HandleSegv = Flags.handle_segv;
 
// 是否处理 SIGTERM 信号
Options.HandleTerm = Flags.handle_term;
 
// 是否处理 SIGXFSZ 信号
Options.HandleXfsz = Flags.handle_xfsz;
 
// 是否处理 SIGUSR1 信号
Options.HandleUsr1 = Flags.handle_usr1;
 
// 是否处理 SIGUSR2 信号
Options.HandleUsr2 = Flags.handle_usr2;
 
// 是否处理 Windows 异常
Options.HandleWinExcept = Flags.handle_winexcept;
 
// 是否启用分叉的种子组
Options.ForkCorpusGroups = Flags.fork_corpus_groups;
// 返回总的程序计数器覆盖率(PC Coverage)
size_t GetTotalPCCoverage() const {
    return TPC.GetTotalPCCoverage();
}
 
// 返回发现的特征数量
size_t GetNumFeatures() const {
    return Corpus.NumFeatures();
}
 
// 返回活跃输入的数量
size_t GetNumActiveUnits() const {
    return Corpus.NumActiveUnits();
}
 
// 返回语料库大小(以字节为单位)
size_t GetSizeInBytes() const {
    return Corpus.SizeInBytes();
}
 
// 返回触发重点功能(Focus Function)的输入数量
size_t GetNumInputsThatTouchFocusFunction() const {
    return Corpus.NumInputsThatTouchFocusFunction();
}
 
// 返回每秒执行次数
size_t GetExecPerSec() const {
    return execPerSec();
}
 
// 返回临时最大变异长度
size_t GetTmpMaxMutationLen() const {
    return TmpMaxMutationLen;
}
 
// 返回峰值内存使用量(以MB为单位)
size_t GetPeakRSSMb() const {
    return GetPeakRSSMb();
}
 
// 打印模糊测试的统计信息并导出数据
void Fuzzer::PrintStats(const char *Where, const char *End, size_t Units,
                        size_t Features) {
    size_t ExecPerSec = GetExecPerSec();
     
    if (!Options.Verbosity)
        return;
     
    Printf("#%zd\t%s", TotalNumberOfRuns, Where);
     
    if (size_t N = GetTotalPCCoverage())
        Printf(" cov: %zd", N);
     
    if (size_t N = Features ? Features : GetNumFeatures())
        Printf(" ft: %zd", N);
     
    if (!Corpus.empty()) {
        Printf(" corp: %zd", GetNumActiveUnits());
         
        if (size_t N = GetSizeInBytes()) {
            if (N < (1 << 14))
                Printf("/%zdb", N);
            else if (N < (1 << 24))
                Printf("/%zdKb", N >> 10);
            else
                Printf("/%zdMb", N >> 20);
        }
         
        if (size_t FF = GetNumInputsThatTouchFocusFunction())
            Printf(" focus: %zd", FF);
    }
 
    if (size_t Lim = GetTmpMaxMutationLen())
        Printf(" lim: %zd", Lim);
     
    if (Units)
        Printf(" units: %zd", Units);
 
    Printf(" exec/s: %zd", ExecPerSec);
    Printf(" rss: %zdMb", GetPeakRSSMb());
 
    // 添加魔改标识
    Printf(" [MODIFIED] Custom version of Fuzzer::PrintStats is running!\n");
     
    // 输出结束符
    Printf("%s", End);
 
    // 可以在这里添加接口将数据传递到前端
    ExportDataToFrontend({
        {"TotalNumberOfRuns", TotalNumberOfRuns},
        {"PCCoverage", GetTotalPCCoverage()},
        {"NumFeatures", GetNumFeatures()},
        {"NumActiveUnits", GetNumActiveUnits()},
        {"SizeInBytes", GetSizeInBytes()},
        {"ExecPerSec", GetExecPerSec()},
        {"PeakRSSMb", GetPeakRSSMb()}
    });
}
 
// 示例数据导出函数,可将数据通过接口传递给前端
void ExportDataToFrontend(const std::map<std::string, size_t>& data) {
    // 通过网络接口、文件、或者其他方式将数据传递到前端页面
    // 这里可以通过 JSON 格式将数据发送到 HTTP 服务器或 WebSocket
}
// 返回总的程序计数器覆盖率(PC Coverage)
size_t GetTotalPCCoverage() const {
    return TPC.GetTotalPCCoverage();
}
 
// 返回发现的特征数量
size_t GetNumFeatures() const {
    return Corpus.NumFeatures();
}
 
// 返回活跃输入的数量
size_t GetNumActiveUnits() const {
    return Corpus.NumActiveUnits();
}
 
// 返回语料库大小(以字节为单位)
size_t GetSizeInBytes() const {
    return Corpus.SizeInBytes();
}
 
// 返回触发重点功能(Focus Function)的输入数量
size_t GetNumInputsThatTouchFocusFunction() const {
    return Corpus.NumInputsThatTouchFocusFunction();
}
 
// 返回每秒执行次数
size_t GetExecPerSec() const {
    return execPerSec();
}
 
// 返回临时最大变异长度
size_t GetTmpMaxMutationLen() const {
    return TmpMaxMutationLen;
}
 
// 返回峰值内存使用量(以MB为单位)
size_t GetPeakRSSMb() const {
    return GetPeakRSSMb();
}
 
// 打印模糊测试的统计信息并导出数据
void Fuzzer::PrintStats(const char *Where, const char *End, size_t Units,
                        size_t Features) {
    size_t ExecPerSec = GetExecPerSec();
     
    if (!Options.Verbosity)
        return;
     
    Printf("#%zd\t%s", TotalNumberOfRuns, Where);
     
    if (size_t N = GetTotalPCCoverage())
        Printf(" cov: %zd", N);
     
    if (size_t N = Features ? Features : GetNumFeatures())
        Printf(" ft: %zd", N);
     
    if (!Corpus.empty()) {
        Printf(" corp: %zd", GetNumActiveUnits());
         
        if (size_t N = GetSizeInBytes()) {
            if (N < (1 << 14))
                Printf("/%zdb", N);
            else if (N < (1 << 24))
                Printf("/%zdKb", N >> 10);
            else
                Printf("/%zdMb", N >> 20);
        }
         
        if (size_t FF = GetNumInputsThatTouchFocusFunction())
            Printf(" focus: %zd", FF);
    }
 
    if (size_t Lim = GetTmpMaxMutationLen())
        Printf(" lim: %zd", Lim);
     
    if (Units)
        Printf(" units: %zd", Units);
 
    Printf(" exec/s: %zd", ExecPerSec);
    Printf(" rss: %zdMb", GetPeakRSSMb());
 
    // 添加魔改标识
    Printf(" [MODIFIED] Custom version of Fuzzer::PrintStats is running!\n");
     
    // 输出结束符
    Printf("%s", End);
 
    // 可以在这里添加接口将数据传递到前端
    ExportDataToFrontend({
        {"TotalNumberOfRuns", TotalNumberOfRuns},
        {"PCCoverage", GetTotalPCCoverage()},
        {"NumFeatures", GetNumFeatures()},
        {"NumActiveUnits", GetNumActiveUnits()},
        {"SizeInBytes", GetSizeInBytes()},
        {"ExecPerSec", GetExecPerSec()},
        {"PeakRSSMb", GetPeakRSSMb()}
    });
}
 
// 示例数据导出函数,可将数据通过接口传递给前端
void ExportDataToFrontend(const std::map<std::string, size_t>& data) {
    // 通过网络接口、文件、或者其他方式将数据传递到前端页面
    // 这里可以通过 JSON 格式将数据发送到 HTTP 服务器或 WebSocket
}
while (true) {
    int result = LLVMFuzzerTestOneInput(Data, Size);
    if (result == 0) {
        // 记录崩溃信息,但不终止
        // 继续模糊测试循环
        continue;
    } else {
        // 如果检测到崩溃,记录日志或者保存问题
        LogCrash();
        // 但不要退出程序,继续模糊测试
        continue;
    }
}
while (true) {
    int result = LLVMFuzzerTestOneInput(Data, Size);
    if (result == 0) {
        // 记录崩溃信息,但不终止
        // 继续模糊测试循环
        continue;
    } else {
        // 如果检测到崩溃,记录日志或者保存问题
        LogCrash();
        // 但不要退出程序,继续模糊测试
        continue;
    }
}
try {
    LLVMFuzzerTestOneInput(Data, Size);
} catch (...) {
    // 捕获异常,记录崩溃,不退出
    ReportCrash();
    continue// 继续模糊测试
}
try {
    LLVMFuzzerTestOneInput(Data, Size);
} catch (...) {
    // 捕获异常,记录崩溃,不退出
    ReportCrash();
    continue// 继续模糊测试
}
signal(SIGSEGV, HandleSignal);
signal(SIGABRT, HandleSignal);
 
void HandleSignal(int signal) {
    // 捕获信号并记录信息
    LogSignalCrash(signal);
    // 继续执行
}
signal(SIGSEGV, HandleSignal);
signal(SIGABRT, HandleSignal);
 
void HandleSignal(int signal) {
    // 捕获信号并记录信息
    LogSignalCrash(signal);
    // 继续执行
}
#!/bin/sh
LIBFUZZER_SRC_DIR=$(dirname $0)
CXX="${CXX:-clang}"
for f in $LIBFUZZER_SRC_DIR/*.cpp; do
  $CXX -g -O2 -fno-omit-frame-pointer -std=c++17 $f -c &
done
wait
rm -f libFuzzer.a
ar r libFuzzer.a Fuzzer*.o
rm -f Fuzzer*.o
#!/bin/sh
LIBFUZZER_SRC_DIR=$(dirname $0)
CXX="${CXX:-clang}"
for f in $LIBFUZZER_SRC_DIR/*.cpp; do
  $CXX -g -O2 -fno-omit-frame-pointer -std=c++17 $f -c &
done
wait
rm -f libFuzzer.a
ar r libFuzzer.a Fuzzer*.o
rm -f Fuzzer*.o
clang++ -g -O1 fuzz_target.cc libFuzzer.a -o mytarget_fuzzer
clang++ -g -O1 fuzz_target.cc libFuzzer.a -o mytarget_fuzzer
#使用官方案例进行测试
ub20@ub20:~$git clone https://github.com/google/fuzzer-test-suite.git FTS
ub20@ub20:~$cd FTS; mkdir -p woff; cd woff;
ub20@ub20:~$~/FTS/woff2-2016-05-06/build.sh
#使用官方案例进行测试
ub20@ub20:~$git clone https://github.com/google/fuzzer-test-suite.git FTS
ub20@ub20:~$cd FTS; mkdir -p woff; cd woff;
ub20@ub20:~$~/FTS/woff2-2016-05-06/build.sh
// Copyright 2016 Google Inc. All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
#include <stddef.h>
#include <stdint.h>
 
#include "woff2_dec.h"
 
// Entry point for LibFuzzer.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  std::string buf;
  woff2::WOFF2StringOut out(&buf);
  out.SetMaxSize(30 * 1024 * 1024);
  woff2::ConvertWOFF2ToTTF(data, size, &out);
  return 0;
}
// Copyright 2016 Google Inc. All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
#include <stddef.h>
#include <stdint.h>
 
#include "woff2_dec.h"
 
// Entry point for LibFuzzer.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  std::string buf;
  woff2::WOFF2StringOut out(&buf);
  out.SetMaxSize(30 * 1024 * 1024);
  woff2::ConvertWOFF2ToTTF(data, size, &out);
  return 0;
}
ub20@ub20:~/woff$ ~/Fuzz/FTS/woff2-2016-05-06/build.sh
ub20@ub20:~/woff$ ~/Fuzz/FTS/woff2-2016-05-06/build.sh
正克隆到 'SRC'...
remote: Enumerating objects: 1150, done.
remote: Counting objects: 100% (24/24), done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 1150 (delta 2), reused 20 (delta 0), pack-reused 1126 (from 1)
接收对象中: 100% (1150/1150), 3.48 MiB | 6.03 MiB/s, 完成.
处理 delta 中: 100% (680/680), 完成.
...
#编译成功后
ub20@ub20:~/woff$ ls
backward_references.o  compress_fragment_two_pass.o  font.o          normalize.o    table_tags.o                       woff2_dec.o
bit_reader.o           decode.o                      glyph.o         seeds          transform.o                        woff2_enc.o
block_splitter.o       dictionary.o                  histogram.o     SRC            utf8_util.o                        woff2_out.o
BROTLI                 encode.o                      huffman.o       state.o        variable_length.o
brotli_bit_stream.o    encode_parallel.o             literal_cost.o  static_dict.o  woff2-2016-05-06-fsanitize_fuzzer
compress_fragment.o    entropy_encode.o              metablock.o     streams.o      woff2_common.o
ub20@ub20:~/woff$ ~/Fuzz/FTS/woff2-2016-05-06/build.sh
ub20@ub20:~/woff$ ~/Fuzz/FTS/woff2-2016-05-06/build.sh

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 3
支持
分享
最新回复 (1)
雪    币: 413
活跃值: (722)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
2
感谢分享,内容有见解,值得学习!
2024-10-9 10:15
0
游客
登录 | 注册 方可回帖
返回
//