Skip to content

aptos-labs/move-smith

Repository files navigation

MoveSmith

A Move source code level fuzzer.

Compile

# Rebuild is necessary for using your uid
make build-docker

# The run script will run commands in the docker container
./run make

If you have Rust and cargo installed locally, you can simply run make.

Fuzzing

Fuzz Targets

The fuzz targets lives in fuzz/fuzz_targets:

Target Oracle Fuzzing Engine
v2_only.rs Crash libFuzzer
v1v2.rs Compiler V1 vs. V2 libFuzzer
opt_noopt.rs Optimization On vs. Off libFuzzer
hfuzz_v1v2.rs Compiler V1 vs. V2 honggfuzz
afl_v1v2.rs Compiler V1 vs. V2 afl++
random.rs Compiler V1 vs. V2 Pure random input

Running a session

./scripts/fuzz.sh <fuzz_target> [total_hour] [jobs] [max_input_len] [timeout]

# For example
./scripts/fuzz.sh v1v2 24 32 4 3
# This will run the `v1v2` target for 24 hours using 32 cores,
# with randomly created seeds whose size doesn't exceed 4KB.
# For each input, it will timeout after 3 seconds.


# If a fuzz target starts with `afl++`, the script will spawn nodes in a tmux session:
./scripts/fuzz.sh afl-v1v2 24
# This will create a tmux session `afl_fuzzing` where each node occupies a window.

The script will keep a copy of log under logs. Note that the script will automatically spawn tmux sessions for running AFL++ fuzzing sessions so be careful using AFL inside a tmux session.

For libFuzzer, crashing inputs are stored in fuzz/artifacts/<fuzz_target>. For AFL++, they are stored in fuzz/afl/<fuzz_target>_out/fuzzer#/crashes.

Coverage

After running a fuzzing session, the coverage of all stored corpus can be generated by:

./scripts/coverage.sh <fuzz_target> [base_dir]

If the fuzzing session was run on the local machine, you can ignore base_dir.

If you want to generate the coverage from a different corpus (e.g. generated from another machine), use the base_dir to specify the directory that contains fuzz/ where corpus is stored for libFuzzer, or afl is stored for AFL++.

This will create an HTML report at [base_dir/]coverage/<fuzz_target>/index.html.

Coverage over time

For libFuzzer results, you can use the scipts/coverage_graph.py to draw a coverage over time graph:

python scripts/coverage_graph.py path/to/log

Dependencies

MoveSmith depend on the following crates for fuzzing:

cargo install cargo-fuzz
cargo install cargo-afl
cargo install cargo-binutils
cargo install honggfuzz

[Optional] Coverage

To generate human-readable coverage reports, we need llvm coverage tools. They can be installed with:

cargo install cargo-binutils
rustup component add --toolchain nightly llvm-tools-preview

We also need a demangler installed:

cargo install rustfilt

[Optional] cargo-afl

To run AFL++ targets, you need to install [cargo-afl][cargo-afl]:

cargo install cargo-afl

To plot AFL++ statistics, you might need to install gnuplot:

brew install gnuplot

To view AFL++ coverage over time, you can use

cargo afl plot fuzz/afl/<fuzz_target>_out/fuzzer0 <ouput_dir>

to plot several key statistics. They can be viewed at <output_dir>/index.html.

Code Structure

.
├── enuminto               // Helper crate
├── framework              // The core generation framework
├── fuzz
│   └── fuzz_targets       // All the fuzz targets
├── msmith                 // The Move generators, states, and peripherals
│   └── src
│       ├── cli            // The `msmith` command line tool
│       ├── codegen        // Turn MoveAST to text format Move code
│       ├── execution      // Execution engine using transactional test
│       ├── generators     // Move generators
│       └── states         // Move states
└── scripts                // Helper scripts for running fuzzing and collecting coverage 

About

Specialized fuzzer for the Move compilers and the VM

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors