RIMfuzz is built on GraphFuzz (https://github.com/hgarrereyn/GraphFuzz) and enables real-time impact-aware mutation for fuzzing library APIs. The basic flow of using RIMfuzz is also similar to Basic Usage of GraphFuzz.
Native GraphFuzz consists of:
gfuzz: A command-line tool to synthesize harnesseslibgraphfuzz: A runtime graph-model engine for mutation and execution
The core of RI-Mutation strategies is mainly contained in the libgraphfuzz component, and we also change many contents of gfuzz to support more pratical requirements.
- Clang - provide basic support for compiling and libFuzzer
- Python3 environment (developed in python 3.8.8)
Before installation, we can just perform the commands like below to satisfy the basic prerequisites:
$ [sudo] apt-get update && apt-get -y upgrade && \
apt-get -y install clang cmake python3 python3-pip lcov-
For
gfuzz cli:$ [sudo] apt-get -y install doxygen # (1/2) Build via poetry: $ python3 -m pip install poetry /path/to/rimfuzz/cli$ poetry build /path/to/rimfuzz/cli$ python3 -m pip install ./dist/gfuzz-*.whl # (Uninstallation) /path/to/rimfuzz/cli$ python3 -m pip uninstall ./dist/gfuzz-*.whl # (2/2) Build via setting an env variable (This lets us do not need to re-install after making modifications to the code): # First, install the required packages (PyYAML, beautifulsoup4, pstutil, tqdm, pyparsing, lxml, matplotlib and pyelftools): # Note: also require 'dataclasses' if python < 3.7. $ python3 -m pip install pyyaml beautifulsoup4 psutil tqdm pyparsing lxml matplotlib pyelftools # Then, set the env variable for all (/usr/bin/): /path/to/rimfuzz/cli$ [sudo] make # Remove the env variable from /usr/bin/: /path/to/rimfuzz/cli$ [sudo] make clean
-
For
libgraphfuzz:# Commands for installation: $ [sudo] apt-get -y install libprotobuf-dev protobuf-compiler /path/to/rimfuzz/$ mkdir build && cd build /path/to/rimfuzz/build$ cmake .. /path/to/rimfuzz/build$ [sudo] make install # The final log is just like below: Scanning dependencies of target graphfuzz [ 25%] Building CXX object CMakeFiles/graphfuzz.dir/core/harness.cpp.o [ 50%] Linking CXX static library libgraphfuzz.a [100%] Built target graphfuzz Install the project... -- Install configuration: "" -- Installing: /usr/local/lib/libgraphfuzz.a
The build environment and commands are also packed into Dockerfile, we may also attempt RIMFuzz via a docker image:
$ docker build -t rimfuzz_docker -f docker/Dockerfile .
$ docker run -it rimfuzz_dockerFor the example as shown in motivation_example, there are typically four steps to run with RIMFuzz:
-
Extract metadata from given header file(s):
$ gfuzz doxygen --inputs ./lib.h --output .A directory
xmlwill be generated. -
Infer schema based on the metadata:
$ gfuzz schema infer --xml ./xml
auto_schema.yamlwill be generated. -
Generate harness file:
$ gfuzz gen cpp auto_schema.yaml .fuzz_exec.cpp,fuzz_write.cpp, andschema.jsonwill be generated. -
Compile the harness:
$ clang++ \ -o fuzz_exec \ fuzz_exec.cpp \ -fsanitize=fuzzer,address \ -lprotobuf -lgraphfuzz
Then the executable harness fuzz_exec is ready for testing along with schema.json.
Goto the motivation_example directory and run build.sh:
/path/to/rimfuzz/motivation_example/$ ./build_shThen test the generated harness:
/path/to/rimfuzz/motivation_example/$ ./fuzz_execNormally, the bug in the example code will be triggered in 100s while the original graphfuzz needs to fuzz for almost 2000s on average.
Given a crashed input, we can minimize it and use fuzz_write to see the serialized code:
/path/to/rimfuzz/motivation_example/$ gfuzz min fuzz_exec --input crash-xxx
/path/to/rimfuzz/motivation_example/$ ./fuzz_write crash-xxxIn addition, there are several options to control the real-time impact-aware mutation strategies:
--disable-impact-selectionis to disable the guiding on mutation object selection.--graphfuzz_context_mutation_prob=is to set a fixed probability of performing value mutation.
For example of the above options:
$ ./fuzz_exec --disable-impact-selection --graphfuzz_context_mutation_prob=0.5-
The command line interface
gfuzzalso supports to generate coverage results and visualize coverage results.Use
--helpto know more details ofgfuzzcommand line interface. -
The harness inherits all the options of libFuzzer.
--helpis also able to know the specific usage of the executable harness. -
fuzz_wirteis used to reproduce the corresponding code of a graph-based input.
Some relevant documents are put in the directory docs.
For ease of use, more relevant documents will be disclosed gradually in the future (if I have enough spare time as this framework has some limitations (e.g., we cannot directly intervene in the handling of fuzzer itself) which prevent me from achieving several ideas so that I may not continue to maintain and develop on it).