4 个版本

0.1.3 2022年4月11日
0.1.2 2022年4月11日
0.1.1 2022年4月11日
0.1.0 2022年4月11日

#320测试

MIT/Apache

470KB
2K SLoC

crates.io docs.rs

Fazi

fazi

在 Rust 中对 libfuzzer 的改进重实现

支持的功能

  • libFuzzer 的变异
  • SanCov 反馈
  • 无 main 入口点的构建
  • 崩溃回放
  • 重新覆盖
  • 自定义用户初始化
  • 缩放/分叉支持
  • 超时检测
  • 自定义词典
  • 自定义用户定义变异

libFuzzer 功能集中缺失的任何其他功能可能不会得到支持。如果您想表达对这些功能的支持,请随时提交问题。

用法

步骤 1:构建 fazi(需要 Rust nightly 版本)

$ cargo build --release

注意:可以通过提供 --no-default-features 标志来构建不需要 main 入口点的 Fazi

步骤 2:构建您的 harness

$ FAZI_DIR="../path-to-fazi" clang ./main.c -fsanitize=fuzzer-no-link -fsanitize=address -lfazi -L$FAZI_DIR/target/release/

步骤 3:运行 harness

$ ./a.out

fazi_running

您可以使用 --help 标志列出命令行选项

fazi

USAGE:
    a.out [OPTIONS] [SUBCOMMAND]

OPTIONS:
        --corpus-dir <CORPUS_DIR>
            Location at which inputs that cause new coverage will be saved [default: ./corpus]

        --crashes-dir <CRASHES_DIR>
            Location at which crashing inputs will be saved [default: ./crashes]

    -h, --help
            Print help information

        --len-control <LEN_CONTROL>
            Length control is used in an algorithm for deciding how quickly the input size grows. A
            larger value will result in faster growth while a smaller value will result in slow
            growth [default: 100]

        --max-input-len <MAX_INPUT_LEN>
            The maximum size (in bytes) that an input can extend to [default: 65000]

        --max-iters <MAX_ITERS>
            Maximum number of fuzzing iterations before the fuzzer should exit

        --max-mutation-depth <MAX_MUTATION_DEPTH>
            The maximum number of times to mutate a single input before moving on to another
            [default: 15]

        --seed <SEED>
            RNG seed

SUBCOMMANDS:
    help     Print this message or the help of the given subcommand(s)
    repro    Reproduce some crash

原因

虽然 libfuzzer 可以作为一个库使用,但与某些环境交互时可能难以设置。Fazi 提供了与 libfuzzer 相似的功能,但提供了更大的灵活性。例如,需要一个自己 main 入口点的本地应用程序可能设置如下

/// compiled with -fsanitize=fuzer-no-link

extern "C" int LLVMFuzzerRunDriver(int *argc, char ***argv,
                  int (*UserCb)(const uint8_t *Data, size_t Size));

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
    // fuzz
}

int main(int *argc, char ***argv) {
    // Do my own thing
    LLVMFuzzerRunDriver(argc, argv, LLVMFuzzerTestOneInput);
}

当将此模型集成到具有大量状态或自己的运行时环境的应用程序中时,例如 JVM,这会很困难。Fazi 不是提供回调,而是允许您只需请求数据,并在测试用例完成后通知它

extern "C" void fazi_start_iteration(char** data, size_t* size);
extern "C" void fazi_end_iteration(bool need_more_data);
extern "C" void fazi_initialize();
extern "C" void fazi_set_corpus_dir(const char*);
extern "C" void fazi_set_crashes_dir(const char*);

int main() {
    // Setup fazi globals
    fazi_initialize();

    while (true) {
        const char* data = nullptr;
        size_t len = 0;
        fazi_start_iteration(&data, &len);

        bool need_more_data = some_api(data, len);

        fazi_end_iteration(need_more_data);
    }
}

依赖

~4MB
~79K SLoC