ProFuzzBench入门教学——使用(Ubuntu22.04)

1、设置环境变量

  • 克隆项目,设置环境变量。
    • git clone https://github.com/profuzzbench/profuzzbench.git
      cd profuzzbench
      nano ~/.bashrc
  • 添加下面内容。 
    • # profuzzbench
      export PFBENCH=/home/zzs/GitProject/profuzzbench
      export PATH=$PATH:$PFBENCH/scripts/execution:$PFBENCH/scripts/analysis
  • 重新加载配置文件以使更改生效。
    • source ~/.bashrc

2、构建docker镜像

  • 安装docker,参考:Docker——简介、安装(Ubuntu22.04)-CSDN博客
  • 构建docker镜像。
    • cd $PFBENCH
      cd subjects/FTP/LightFTP
      sudo docker build . -t lightftp
      # docker build .:在当前目录(LightFTP)下寻找 Dockerfile 并构建 Docker 镜像
      # -t lightftp:将创建的 Docker 镜像标记为 lightftp
    • 【注】这里创建了一个名为 lightFTP 的 Docker 镜像,该镜像包含了 LightFTP 及其所需的所有依赖项,使其可以在隔离的 Docker 容器中运行。这对于模糊测试和代码覆盖率收集特别有用,因为它提供了一个一致的、可重复的测试环境。
    • 构建时间较长,耐心等待。
    • 【注】可能遇到网络不好,多尝试。
  • 查看构建的镜像。
    • docker images

3、运行模糊测试

  • 运行‘profuzzbench_exec_common.sh’脚本以启动实验。该脚本接受以下 8 个参数:
    • 第一个参数 (DOCIMAGE):Docker镜像的名称。
    • 第二个参数 (RUNS):运行次数,每次运行都会启动一个独立的Docker容器。
    • 第三个参数 (SAVETO):存储结果的文件夹路径。
    • 第四个参数 (FUZZER):模糊测试工具的名称(例如,aflnet)——该名称必须与Docker容器内模糊测试工具文件夹的名称匹配(例如,/home/ubuntu/aflnet)。 
    • 第五个参数 (OUTDIR):在Docker容器内创建的输出文件夹的名称。
    • 第六个参数 (OPTIONS):除目标特定的run.sh脚本中写入的标准选项外,所有模糊测试所需的选项。
    • 第七个参数 (TIMEOUT):模糊测试的时间(以秒为单位)。
    • 第八个参数 (SKIPCOUNT):用于计算随时间变化的覆盖率。例如,SKIPCOUNT=5表示我们在每5个测试用例后运行一次gcovr,因为gcovr需要时间,我们不希望在每个测试用例后都运行它。
  • 以下命令运行一个AFLNet实例,对LightFTP进行60分钟模糊测试。
    • cd $PFBENCH
      mkdir results-lightftp
      profuzzbench_exec_common.sh lightftp 1 results-lightftp aflnet out-lightftp-aflnet "-P FTP -D 10000 -q 3 -s 3 -E -K -R" 3600 5

4、收集结果

  • 所有结果(在 tar 文件中)都应存储在上个步骤(results-lightftp)创建的文件夹中。
  • 具体来说,这些tar文件是所有模糊测试实例生成的输出文件夹的压缩版本。如果模糊测试器是基于AFL的(例如,AFLNet,AFLnwe),每个文件夹应包含诸如 crashes、hangs、queue 等子文件夹。
  • 使用profuzzbench_generate_csv.sh脚本可以收集代码覆盖率随时间变化的结果。该脚本需要以下5个参数:
    • 第一个参数 (PROG):目标程序的名称(例如,lightftp)。
    • 第二个参数 (RUNS):运行次数。
    • 第三个参数 (FUZZER):模糊测试器的名称(例如,aflnet)。
    • 第四个参数 (COVFILE):用于保存结果的 CSV 格式的输出文件。
    • 第五个参数 (APPEND):追加模式;对第一个模糊测试器设置为0,对后续的模糊测试器设置为1。
  • 以下命令收集AFLNet生成的代码覆盖率结果,并将其保存到results.csv。
    • cd $PFBENCH/results-lightftp
      profuzzbench_generate_csv.sh lightftp 1 aflnet results.csv 0
  • results.csv文件如下。该文件有六列,分别显示:
    • 时间(time)
    • 目标程序(subject)
    • 模糊测试器名称(fuzzer)
    • 运行索引(run)
    • 覆盖类型(cov_type)
    • 覆盖率(cov)
  • 文件包含了随时间变化的行覆盖率(l_per、l_abs)分支覆盖率(b_per、b_abs)信息。每种覆盖类型都有两个值,一个是百分比形式(_per),另一个是绝对数值(_abs)。
    • 【注】这里时间为空,暂不知道什么原因。

5、分析结果

  • results.csv中收集的结果可用于绘图。例如,使用示例python脚本绘制代码随时间变化的覆盖率。使用以下命令打印结果并将其保存到文件中。
    • cd $PFBENCH/results-lightftp
      
      profuzzbench_plot.py -i results.csv -p lightftp -r 4 -c 60 -s 1 -o cov_over_time.png
    • 报错:IndexError: index 0 is out of bounds for axis 0 with size 0。
      • 原因是因为文件中time为空,并且只有一个模糊测试器。
  • 改使用aflnwe。删除原先的results-lightftp。
    • cd $PFBENCH
      
      rm -rf resluts-lightftp
      
      mkdir results-lightftp
      profuzzbench_exec_common.sh lightftp 1 results-lightftp aflnwe out-lightftp-aflnwe "-D 10000 -K" 3600 5
      
      cd $PFBENCH/results-lightftp
      profuzzbench_generate_csv.sh lightftp 1 aflnwe results.csv 0
      cat results.csv
  • 修改profuzzbench_plot.py。
    • #!/usr/bin/env python
      
      import argparse
      from pandas import read_csv
      from pandas import DataFrame
      from pandas import Grouper
      from matplotlib import pyplot as plt
      import pandas as pd
      
      
      def main(csv_file, put, runs, cut_off, step, out_file):
          # Read the results
          df = read_csv(csv_file)
      
          # Calculate the mean of code coverage
          mean_list = []
      
          for subject in [put]:
              fuzzer = 'aflnwe'  # Only use aflnwe
              for cov_type in ['b_abs', 'b_per', 'l_abs', 'l_per']:
                  # Get subject & fuzzer & cov_type-specific dataframe
                  df1 = df[(df['subject'] == subject) & 
                           (df['fuzzer'] == fuzzer) & 
                           (df['cov_type'] == cov_type)]
      
                  mean_list.append((subject, fuzzer, cov_type, 0, 0.0))
                  for time in range(1, cut_off + 1, step):
                      cov_total = 0
                      run_count = 0
      
                      for run in range(1, runs + 1, 1):
                          # Get run-specific data frame
                          df2 = df1[df1['run'] == run]
      
                          if df2.empty:
                              continue
      
                          # Get the starting time for this run
                          start = df2.iloc[0, 0]
      
                          # Get all rows given a cutoff time
                          df3 = df2[df2['time'] <= start + time * 60]
      
                          if df3.empty:
                              continue
      
                          # Update total coverage and #runs
                          cov_total += df3.tail(1).iloc[0, 5]
                          run_count += 1
      
                      # Add a new row
                      if run_count > 0:
                          mean_list.append((subject, fuzzer, cov_type, time, cov_total / run_count))
      
          # Convert the list to a dataframe
          mean_df = pd.DataFrame(mean_list, columns=['subject', 'fuzzer', 'cov_type', 'time', 'cov'])
      
          fig, axes = plt.subplots(2, 2, figsize=(20, 10))
          fig.suptitle("Code coverage analysis")
      
          for key, grp in mean_df.groupby(['fuzzer', 'cov_type']):
              if key[1] == 'b_abs':
                  axes[0, 0].plot(grp['time'], grp['cov'])
                  axes[0, 0].set_xlabel('Time (in min)')
                  axes[0, 0].set_ylabel('#edges')
              if key[1] == 'b_per':
                  axes[1, 0].plot(grp['time'], grp['cov'])
                  axes[1, 0].set_ylim([0, 100])
                  axes[1, 0].set_xlabel('Time (in min)')
                  axes[1, 0].set_ylabel('Edge coverage (%)')
              if key[1] == 'l_abs':
                  axes[0, 1].plot(grp['time'], grp['cov'])
                  axes[0, 1].set_xlabel('Time (in min)')
                  axes[0, 1].set_ylabel('#lines')
              if key[1] == 'l_per':
                  axes[1, 1].plot(grp['time'], grp['cov'])
                  axes[1, 1].set_ylim([0, 100])
                  axes[1, 1].set_xlabel('Time (in min)')
                  axes[1, 1].set_ylabel('Line coverage (%)')
      
          for i, ax in enumerate(fig.axes):
              ax.legend(('AFLNwe',), loc='upper left')  # Only AFLNwe
              ax.grid()
      
          # Save to file
          plt.savefig(out_file)
      
      
      # Parse the input arguments
      if __name__ == '__main__':
          parser = argparse.ArgumentParser()
          parser.add_argument('-i', '--csv_file', type=str, required=True, help="Full path to results.csv")
          parser.add_argument('-p', '--put', type=str, required=True, help="Name of the subject program")
          parser.add_argument('-r', '--runs', type=int, required=True, help="Number of runs in the experiment")
          parser.add_argument('-c', '--cut_off', type=int, required=True, help="Cut-off time in minutes")
          parser.add_argument('-s', '--step', type=int, required=True, help="Time step in minutes")
          parser.add_argument('-o', '--out_file', type=str, required=True, help="Output file")
          args = parser.parse_args()
          main(args.csv_file, args.put, args.runs, args.cut_off, args.step, args.out_file)
  • 重新执行:
    • cd $PFBENCH/results-lightftp
      
      profuzzbench_plot.py -i results.csv -p lightftp -r 4 -c 60 -s 1 -o cov_over_time.png

相关推荐

  1. notebook入门使用教程

    2024-07-13 19:46:01       48 阅读
  2. Ubuntu Linux完全入门视频教程

    2024-07-13 19:46:01       25 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-13 19:46:01       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-13 19:46:01       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-13 19:46:01       58 阅读
  4. Python语言-面向对象

    2024-07-13 19:46:01       69 阅读

热门阅读

  1. ThreadLocal有哪些应用场景?底层如何实现?

    2024-07-13 19:46:01       21 阅读
  2. IPython:提升Python编程效率的实用技巧与案例

    2024-07-13 19:46:01       19 阅读
  3. 赋值运算符.二

    2024-07-13 19:46:01       18 阅读
  4. 数据结构第25节 深度优先搜索

    2024-07-13 19:46:01       16 阅读
  5. Python面试题:如何在 Python 中发送 HTTP 请求?

    2024-07-13 19:46:01       18 阅读
  6. ThreadLocal使用的场景有哪些?

    2024-07-13 19:46:01       18 阅读
  7. Leetcode(经典题)day1

    2024-07-13 19:46:01       23 阅读
  8. Git:分布式版本控制系统

    2024-07-13 19:46:01       20 阅读
  9. Android Studio下载与安装

    2024-07-13 19:46:01       16 阅读
  10. 搭建项目时前后端的两个注意事项

    2024-07-13 19:46:01       16 阅读