详细讲解FuzzBench如何添加新的Fuzzer

这篇具有很好参考价值的文章主要介绍了详细讲解FuzzBench如何添加新的Fuzzer。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近几天一直在弄FuzzBench添加新的fuzzer,在添加过程中遇到各种问题,在此做详细记录。

拉取fuzzbench到本地

这一部分可以直接参考此链接FuzzBench预备条件

1.拉取代码到本地

git clone https://github.com/google/fuzzbench
cd fuzzbench
git submodule update --init

2.安装fuzzbench

sudo apt-get install build-essential

3.安装fuzzbench需要使用的依赖

sudo apt-get install python3.8-dev python3.8-venv
make install-dependencies
#接下里是进入虚拟环境,这一步可以不执行,执行后也可以执行deactivate退出虚拟环境
source .venv/bin/activate

4.安装本地依赖

如果想要在本地执行fuzzbench需要执行一下语句进行rsync的安装
sudo apt-get install rsync

添加新的Fuzzer

1.创建目录

首先到fuzzbench的fuzzer目录下创建需要添加的fuzzer对应的文件名,该文件夹用于存放接下来需要创建的三个文件

export FUZZER_NAME= < your_fuzzer_name>
cd fuzzers
mkdir $FUZZER_NAME

例如本文新增的fuzzer名为agilefuzz,注意这里fuzzer_name名称只能是小写字母,否则会报错。
详细讲解FuzzBench如何添加新的Fuzzer

2.编写fuzzer文件

接下来编写的文件都保存在(1)中创建的目录下

cd $FUZZER_NAME

builder.Dockerfile编写

此处使用vim对该文件进行编写,直接参考它给出的例子afl。

vim builder.Dockerfile

写入代码如下:

# Copyright 2020 Google LLC
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

ARG parent_image
FROM $parent_image

# Download and compile AFL v2.57b.
# Set AFL_NO_X86 to skip flaky tests.
#注意这里的git clone的地址要改成你需要添加的fuzzer的拉取地址
#拉取到afl目录下是为了方便在afl编写的其他代码中进行兼容,看了一下其他模糊器的builder.Dockerfile也是拉取到afl目录下
RUN git clone https://github.com/12qwetyd/agile.git /afl  && \
    cd /afl && \
    AFL_NO_X86=1 make

# Use afl_driver.cpp from LLVM as our fuzzing library.
#wget部分用于拉取编译fuzzer的函数,此处可以直接使用AFL的驱动程序
RUN apt-get update && \
    apt-get install wget -y && \
    wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/afl/afl_driver.cpp -O /afl/afl_driver.cpp && \
    clang -Wno-pointer-sign -c /afl/llvm_mode/afl-llvm-rt.o.c -I/afl && \
    clang++ -stdlib=libc++ -std=c++11 -O2 -c /afl/afl_driver.cpp && \
    ar r /libAFL.a *.o

run.Dockerfile

这里对于大部分模糊测试只需要一句from语句用于拉取镜像即可,但如果fuzzer需要一些依赖也可以直接使用apt-get语句下载,在本次实验中并不需要其他依赖,因此代码如下:
首先创建run.Dockerfile

vim run.Dockerfile

在编译器中输入如下代码:

FROM gcr.io/fuzzbench/base-image    

详细讲解FuzzBench如何添加新的Fuzzer

fuzzer.py

vim fuzzer.py

直接复制AFL的fuzzer.py文件即可,由于在上面runner.Dockerfile中直接将fuzzer拉取并命名为afl,因此对该文件不需要做修改,但如果添加的fuzzer中存在一些新的执行参数或者删除了一些参数,则需要对fuzzer.py中的参数进行修改。

fuzzer.py代码
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Integration code for AFL fuzzer."""

import json
import os
import shutil
import subprocess

from fuzzers import utils


def prepare_build_environment():
    """Set environment variables used to build targets for AFL-based
    fuzzers."""
    cflags = ['-fsanitize-coverage=trace-pc-guard']
    utils.append_flags('CFLAGS', cflags)
    utils.append_flags('CXXFLAGS', cflags)

    os.environ['CC'] = 'clang'
    os.environ['CXX'] = 'clang++'
    os.environ['FUZZER_LIB'] = '/libAFL.a'


def build():
    """Build benchmark."""
    prepare_build_environment()

    utils.build_benchmark()

    print('[post_build] Copying afl-fuzz to $OUT directory')
    # Copy out the afl-fuzz binary as a build artifact.
    shutil.copy('/afl/afl-fuzz', os.environ['OUT'])


def get_stats(output_corpus, fuzzer_log):  # pylint: disable=unused-argument
    """Gets fuzzer stats for AFL."""
    # Get a dictionary containing the stats AFL reports.
    stats_file = os.path.join(output_corpus, 'fuzzer_stats')
    with open(stats_file) as file_handle:
        stats_file_lines = file_handle.read().splitlines()
    stats_file_dict = {}
    for stats_line in stats_file_lines:
        key, value = stats_line.split(': ')
        stats_file_dict[key.strip()] = value.strip()

    # Report to FuzzBench the stats it accepts.
    stats = {'execs_per_sec': float(stats_file_dict['execs_per_sec'])}
    return json.dumps(stats)


def prepare_fuzz_environment(input_corpus):
    """Prepare to fuzz with AFL or another AFL-based fuzzer."""
    # Tell AFL to not use its terminal UI so we get usable logs.
    os.environ['AFL_NO_UI'] = '1'
    # Skip AFL's CPU frequency check (fails on Docker).
    os.environ['AFL_SKIP_CPUFREQ'] = '1'
    # No need to bind affinity to one core, Docker enforces 1 core usage.
    os.environ['AFL_NO_AFFINITY'] = '1'
    # AFL will abort on startup if the core pattern sends notifications to
    # external programs. We don't care about this.
    os.environ['AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES'] = '1'
    # Don't exit when crashes are found. This can happen when corpus from
    # OSS-Fuzz is used.
    os.environ['AFL_SKIP_CRASHES'] = '1'
    # Shuffle the queue
    os.environ['AFL_SHUFFLE_QUEUE'] = '1'

    # AFL needs at least one non-empty seed to start.
    utils.create_seed_file_for_empty_corpus(input_corpus)


def check_skip_det_compatible(additional_flags):
    """ Checks if additional flags are compatible with '-d' option"""
    # AFL refuses to take in '-d' with '-M' or '-S' options for parallel mode.
    # (cf. https://github.com/google/AFL/blob/8da80951/afl-fuzz.c#L7477)
    if '-M' in additional_flags or '-S' in additional_flags:
        return False
    return True

#这部分是编译afl的代码,如果添加的fuzzer修改了一些参数在此处进行修改
def run_afl_fuzz(input_corpus,
                 output_corpus,
                 target_binary,
                 additional_flags=None,
                 hide_output=False):
    """Run afl-fuzz."""
    # Spawn the afl fuzzing process.
    print('[run_afl_fuzz] Running target with afl-fuzz')
    command = [
        './afl-fuzz',
        '-i',
        input_corpus,
        '-o',
        output_corpus,
        # Use no memory limit as ASAN doesn't play nicely with one.
        '-m',
        'none',
        '-t',
        '1000+',  # Use same default 1 sec timeout, but add '+' to skip hangs.
    ]
    # Use '-d' to skip deterministic mode, as long as it it compatible with
    # additional flags.
    if not additional_flags or check_skip_det_compatible(additional_flags):
        command.append('-d')
    if additional_flags:
        command.extend(additional_flags)
    dictionary_path = utils.get_dictionary_path(target_binary)
    if dictionary_path:
        command.extend(['-x', dictionary_path])
    command += [
        '--',
        target_binary,
        # Pass INT_MAX to afl the maximize the number of persistent loops it
        # performs.
        '2147483647'
    ]
    print('[run_afl_fuzz] Running command: ' + ' '.join(command))
    output_stream = subprocess.DEVNULL if hide_output else None
    subprocess.check_call(command, stdout=output_stream, stderr=output_stream)


def fuzz(input_corpus, output_corpus, target_binary):
    """Run afl-fuzz on target."""
    prepare_fuzz_environment(input_corpus)

    run_afl_fuzz(input_corpus, output_corpus, target_binary)

执行文件

在fuzzbench目录下执行如下语句,其中FUZZER_NAME在前文中已经给出了定义,为新添加的fuzzer目录名称:

export BENCHMARK_NAME=libpng-1.2.56
make build-$FUZZER_NAME-$BENCHMARK_NAME
#debug a build
make debug-builder-$FUZZER_NAME-$BENCHMARK_NAME

执行完以上语句会生成多个镜像

下面这两句执行任意一句即可,后一句执行一个更快的测试
make run-$FUZZER_NAME-$BENCHMARK_NAME
make test-run-$FUZZER_NAME-$BENCHMARK_NAME

上面的语句执行速度比较慢,我这边执行的第一句,等了一天多还没执行完。
如果需要为新建的fuzzer构建所有的benchmark,在fuzzbench目录下执行以下语句(但通常情况下并不需要所有的BENCHMARK):

make build-$FUZZER_NAME-all

详细讲解FuzzBench如何添加新的Fuzzer
以上为添加fuzzer的全过程,结束。

遇见问题

如果添加的fuzzer删除或新增了一些指令,在复制完fuzzer.py后应该上上文中文提到的部分修改参数引用,例如本文添加的fuzzer删除了-d参数,由于没有及时修改fuzzer.py文件,在执行过程中报错如下:
详细讲解FuzzBench如何添加新的Fuzzer
这是因为在执行afl-fuzz时新增的fuzzer没有-d参数,直接在fuzzer.py文件中删除这一参数即可:
详细讲解FuzzBench如何添加新的Fuzzer

需要提交

fuzzbench更新了代码后需要执行git commit提交命令,否则会报失败,这里可以直接修改它的检查语句:
在fuzzbench的experiment目录下修改run_experiment.py文件
详细讲解FuzzBench如何添加新的Fuzzer

在vim非编译模式下输入一下命令查找到git提交检查部分,删除该部分代码即可:
详细讲解FuzzBench如何添加新的Fuzzer文章来源地址https://www.toymoban.com/news/detail-416859.html

到了这里,关于详细讲解FuzzBench如何添加新的Fuzzer的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Proteus添加新的元件库

    在这个网站里我们可以搜索自己需要的元件下载: https://componentsearchengine.com 下载找到下载之后路径并解压 打开Proteus 点击库,选择Import parts 点击Select File,找到下载库文件路径。 打开,找到Proteus文件夹 选择.pdif后缀文件 可以看到已经出现了对应的原理图与封装,然后我们选

    2023年04月11日
    浏览(39)
  • idea如何设置注释模板,图文超详细讲解

    目录 先打开idea设置 一,idea类注释 1,找到以下设置 2,设置模板 3,apply保存完成 二,idea方法注释 1,创建自定义的组 2,创建模板 3,设置模板 4,选择生成模板的文件 5,绑定选择参数 6,完成ok 类注释模板和接口注释模板 方法注释模板 生成模板 /** +模板名+快捷键, 选择

    2024年02月14日
    浏览(47)
  • Wine源码中添加新的DLL模块

    编译环境:debootstrap 安装 debian bullseye 源码版本:Wine 9.0-rc4 基础环境搭建 在dlls目录下新建一个文件夹:nfs 将amsi目录下的三个文件全部复制到nfs目录下: main.c 文件内容中新加一个函数如下: spec文件改名为nfs.spec, 将上面实现的函数导出给外部调用,nfs.spec内容如下: Make

    2024年01月16日
    浏览(78)
  • 详细讲解如何在github上编辑个人主页?

     在 GitHub 上编辑个人主页可以让您展示您的项目、技能和个人信息,以及与其他开发者互动。以下是详细的步骤来在 GitHub 上编辑个人主页: 如果您还没有 GitHub 账户,首先需要注册一个。 使用您的用户名和密码登录到 GitHub。 您需要创建一个特殊的仓库,仓库名必须是 用户

    2024年02月13日
    浏览(39)
  • 详细讲解Docker架构的原理、功能以及如何使用

    LXC为Linux Container的简写。可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。相当于C++中的NameSpace。容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求。

    2024年03月21日
    浏览(45)
  • Linux 用户账号管理-添加新的用户账号

    在Linux系统中,用户账号的管理是非常重要的一项工作。其中,添加新用户账号是最基本的操作之一。本文将介绍Linux系统中添加新的用户账号的方法,包括命令行语法、实操和各种添加新的用户账号方法之间的区别。 在Linux系统中,添加新用户账号使用useradd命令,其语法为

    2024年02月13日
    浏览(44)
  • Midjourney教程之添加新的服务器

    1.1 登录discord账号 目前的Midjourney 已经不再提供免费版了,使用的话需要定制高级会员,可以私信博主: 1.2 点击添加服务器,创建新服务器 , 弹出窗口点击亲自创建 1.3 点击仅供我和我的朋友使用 1.4 自定义服务器名称 2.1 将midjourney bot添加到刚刚建好的新的服务器 2.2 在弹出

    2024年02月09日
    浏览(34)
  • 如何仿写简易tomcat 实现思路+代码详细讲解

    仿写之前,我们要搞清楚都要用到哪些技术 自定义注解,比如Tomcat使用的是@Servlet,我们可以定义一个自己的@MyServlet 构造请求体和返回体,比如tomcat使用HttpRequest,我们可以自己定义myHttpRequest java去遍历一个指定目录,然后获取到.java文件,再获取到带有@MyServlet注解的类 然

    2024年02月12日
    浏览(38)
  • 【Linux】Linux之间如何互传文件(详细讲解)

    👉博__主👈:米码收割机 👉技__能👈:C++/Python语言 👉公众号👈:测试开发自动化【获取源码+商业合作】 👉荣__誉👈:阿里云博客专家博主、51CTO技术博主 👉专__注👈:专注主流机器人、人工智能等相关领域的开发、测试技术。 在两台Linux机器之间传输文件,通常有以

    2024年02月04日
    浏览(36)
  • Leanback(1)-播放控制栏下添加新的行

      我们要在播放控制栏下面加入下面一行。 这个就是标准的row。 leanback的原理 Android Leanback结构源码简析 - 简书 我们知道Row用来提供数据,row可以通过一个ObjectAdapter来管理和提供数据 我们知道presenter是一个负责将数据绑定到视图上的对象,它可以根据不同的数据类型创建不

    2024年02月01日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包