## 容器创建

docker run -it --privileged unifuzz:2.0 bash

## 编译源码工程

**首先在进行以下编译之前，要保证正常情况下是能够编译通过的，也就是工程相关的依赖都已经安装，我们假设工程依赖都已经安装好。**
我们以vim工程为例，说明下编译流程

- 用AFL编译工程生成用于fuzz的可执行文件（我们称之为fuzz_binary），该编译过程可以参照AFL编译流程，对应的vim编译流程为:
  
  - $cd /path/to/vim-afl 进入到vim工程源码目录
  - $CC=/home/AFL/afl-gcc ./configure
  - $make -j20
  - 完成之后我们可以得到AFL插桩后的可执行文件vim，也就是fuzz_binary

- 用llvm编译工程生成用于产生精确覆盖率的可执行文件（我们称之为visual_binary）和用于可视化展示的静态分析json文件（我们称之为visual_json），对应的vim编译流程为:
  
  - $cd /path/to/vim-llvm 进入到另外一个vim工程源码目录（一般需要将源码压缩文件解压到两个不同的目录中，一个用于AFL的编译，一个用于llvm的编译）
  
  一、如果构建系统是Makefile，相应的命令为:
  
  - $CC="/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/clang" CFLAGS="-w -flto -g /home/afl-llvm-rt.o.c.o" CXX="/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/clang++" CXXFLAGS="-w -flto -g /home/afl-llvm-rt.o.c.o" LDFLAGS="-L/home/llvm-10-visual-mode-1.0/llvm-build-release-install/lib/clang/10.0.0/lib/linux -lclang_rt.builtins-x86_64" RANLIB=/bin/true AR=/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/llvm-ar NM=/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/llvm-nm ./configure
    二、如果构建系统是cmake，相应的命令为:
    cmake -DCMAKE_C_COMPILER=/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/clang -DCMAKE_CXX_COMPILER=/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/clang++ -DCMAKE_C_FLAGS="-w -flto -g /home/afl-llvm-rt.o.c.o" -DCMAKE_CXX_FLAGS="-w -flto -g /home/afl-llvm-rt.o.c.o" -DCMAKE_RANLIB=/bin/true -DCMAKE_AR=/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/llvm-ar -DCMAKE_NM=/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/llvm-nm .
    三、如果构建系统为meson时：
  - 将llvm中的CC和CXX设置为环境变量：  
  1. export CC="/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/clang" CFLAGS="-w -flto -g /home/afl-llvm-rt.o.c.o" CXX="/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/clang++" CXXFLAGS="-w -flto -g /home/afl-llvm-rt.o.c.o" LDFLAGS="-L/home/llvm-10-visual-mode-1.0/llvm-build-release-install/lib/clang/10.0.0/lib/linux -lclang_rt.builtins-x86_64" RANLIB=/bin/true AR=/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/llvm-ar NM=/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/llvm-nm
  2. meson setup _build (以表格步骤命令为准)
  3. meson compile -C _build
     四、Makefile构建系统的工程中，有时候上述configure构建命令会在编译时出现xxx.o: file not recognized: file format not recognized导致编译失败，这时可以用CC="/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/clang -w -flto -g /home/afl-llvm-rt.o.c.o" CXX="/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/clang++ -w -flto -g /home/afl-llvm-rt.o.c.o" LDFLAGS="-L/home/llvm-10-visual-mode-1.0/llvm-build-release-install/lib/clang/10.0.0/lib/linux -lclang_rt.builtins-x86_64" RANLIB=/bin/true AR=/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/llvm-ar NM=/home/llvm-10-visual-mode-1.0/llvm-build-release-install/bin/llvm-nm ./configure构建命令来替代原来的构建命令
  - $make -j20
  - 完成之后我们可以得到llvm插桩后的可执行文件vim，也就是visual_binary，还有用于可视化展示的静态分析json文件vim-172825.json，其中172825表示该可执行文件中包含的基本块个数

# 镜像制作

- 用docker cp命令从容器中拷贝fuzz_binary、visual_binary、visual_json三个文件到本地
  - docker cp container-id:/path/to/fuzz_binary /local/path/dir
  - docker cp container-id:/path/to/visual_binary /local/path/dir
  - docker cp container-id:/path/to/visual_json /local/path/dir
- 从容器中删除llvm目录和AFL目录（为了使生成的docker镜像尽可能小）
  - docker exec -it container-id bash
  - cd /home && rm -rf llvm-10-visual-mode-1.0 && rm -rf AFL
- export容器到镜像文件
  - docker export -o image_name.tar container-id
- 用save命令生成镜像文件（原因是目前unifuzz网页系统不支持export命令生成的镜像文件，只支持save命令生成的镜像文件）
  - docker import image_name.tar REPOSITORY:TAG
  - docker run -it REPOSITORY:TAG bash（假设生成的容器为container-id2）
  - docker commit container-id2 REPOSITORY1:TAG1
  - docker save -o image_name2.tar REPOSITORY1:TAG1

**最终我们生成一个名字为image_name2.tar的镜像文件**

# 测试

- 正常的unifuzz测试参照unifuzz使用文档
- 精确覆盖率测试
  - 首先在程序管理中找到要被测程序，点击修改
  - 分别上传分析程序（对应于生成的visual_binary）、源代码（对应于源代码的压缩包）、JSON文件（对应于生成的visual_json）
  - 在任务管理中找到对应的任务，点击启动按钮进行正常fuzz测试，运行一段时间后，点击“暂停”按钮，再点击“分析”按钮开始做精确覆盖率分析，等待分析完成，点击“详情”按钮，在详情页面点击“精确覆盖率”
