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
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

No packages published