WIP: port to 0.14.1

This commit is contained in:
Alwin Berger 2024-12-03 15:32:17 +01:00
commit c13537a620
1081 changed files with 49113 additions and 36906 deletions

View File

@ -9,7 +9,10 @@
"customizations": { "customizations": {
"vscode": { "vscode": {
// Add the IDs of extensions you want installed when the container is created. // Add the IDs of extensions you want installed when the container is created.
"extensions": ["matklad.rust-analyzer", "microsoft.Docker"], "extensions": [
"rust-lang.rust-analyzer",
"microsoft.Docker"
],
// Set *default* container specific settings.json values on container create. // Set *default* container specific settings.json values on container create.
"settings": { "settings": {
"rust-analyzer.cargo.noDefaultFeatures": true "rust-analyzer.cargo.noDefaultFeatures": true
@ -20,7 +23,7 @@
// "forwardPorts": [], // "forwardPorts": [],
// Uncomment the next line to run commands after the container is created - for example installing curl. // Uncomment the next line to run commands after the container is created - for example installing curl.
// Install development components that shouldn't be in the main Dockerfile // Install development components that shouldn't be in the main Dockerfile
"postCreateCommand": "rustup component add --toolchain nightly rustfmt clippy llvm-tools-preview && cargo install --locked cargo-make", "postCreateCommand": "rustup component add --toolchain nightly rustfmt clippy llvm-tools-preview && cargo binstall --locked cargo-make",
// Uncomment when using a ptrace-based debugger like C++, Go, and Rust // Uncomment when using a ptrace-based debugger like C++, Go, and Rust
"runArgs": [ "runArgs": [
"--cap-add=SYS_PTRACE", "--cap-add=SYS_PTRACE",

View File

@ -1,4 +1,5 @@
target **/target
**/.git
Cargo.lock Cargo.lock
*.o *.o

14
.github/.linkspector.yml vendored Normal file
View File

@ -0,0 +1,14 @@
dirs:
- .
useGitIgnore: true
ignorePatterns:
- pattern: "^https://crates.io"
- pattern: "^https://github.com/AFLplusplus/linux-qemu-image-builder"
- pattern: "https://www.romu-random.org/"
aliveStatusCodes:
- 0
- 200
- 403

View File

@ -4,3 +4,5 @@ updates:
directory: "/" directory: "/"
schedule: schedule:
interval: "daily" interval: "daily"
ignore:
- dependency-name: "pyo3"

View File

@ -5,11 +5,14 @@ on:
branches: [ main, "pr/**" ] branches: [ main, "pr/**" ]
pull_request: pull_request:
branches: [ main ] branches: [ main ]
types: ["labeled", "opened", "synchronize", "reopened"]
workflow_dispatch: workflow_dispatch:
merge_group: merge_group:
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
CARGO_NET_GIT_FETCH_WITH_CLI: true CARGO_NET_GIT_FETCH_WITH_CLI: true
MAIN_LLVM_VERSION: 18
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
@ -19,29 +22,29 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ ubuntu-latest, windows-latest, macOS-latest ] os: [ ubuntu-24.04, windows-latest, macOS-latest ]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- name: Install mimetype - name: Install mimetype
if: runner.os == 'Linux' if: runner.os == 'Linux'
run: sudo apt-get install libfile-mimeinfo-perl run: sudo apt-get update && sudo apt-get install -y libfile-mimeinfo-perl
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
override: true
- name: Install mimetype
if: runner.os == 'Linux'
run: sudo apt-get install libfile-mimeinfo-perl
- name: install mdbook - name: install mdbook
uses: baptiste0928/cargo-install@v1.3.0 uses: baptiste0928/cargo-install@v3
with: with:
crate: mdbook crate: mdbook
- name: install linkcheck - name: install linkcheck
uses: baptiste0928/cargo-install@v1.3.0 uses: baptiste0928/cargo-install@v3
with: with:
crate: mdbook-linkcheck crate: mdbook-linkcheck
- uses: actions/checkout@v3 # NOTE: The current crates.io release of mdbook-linkcheck (v0.7.7) is broken
# => https://github.com/Michael-F-Bryan/mdbook-linkcheck/pull/82#issuecomment-2241058491
git: https://github.com/Michael-F-Bryan/mdbook-linkcheck.git
rev: 8c783c5d754d83bcd50c28fb4174854b04ece990
- name: default nightly
run: rustup default nightly
- uses: actions/checkout@v4
- if: runner.os == 'Linux'
uses: ./.github/workflows/ubuntu-prepare
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
with: { shared-key: "ubuntu" } with: { shared-key: "ubuntu" }
if: runner.os == 'Linux' if: runner.os == 'Linux'
@ -50,14 +53,15 @@ jobs:
- name: Check for binary blobs - name: Check for binary blobs
if: runner.os == 'Linux' if: runner.os == 'Linux'
run: ./scripts/check_for_blobs.sh run: ./scripts/check_for_blobs.sh
- name: default nightly
run: rustup default nightly
- name: Build libafl debug - name: Build libafl debug
run: cargo build -p libafl run: cargo build -p libafl
- name: Test the book - name: Test the book (Linux)
# TODO: fix books test fail with updated windows-rs # TODO: fix books test fail with updated windows-rs
if: runner.os != 'Windows' if: runner.os == 'Linux'
run: cd docs && mdbook test -L ../target/debug/deps run: cd docs && mdbook test -L ../target/debug/deps
- name: Test the book (MacOS)
if: runner.os == 'MacOS'
run: cd docs && mdbook test -L ../target/debug/deps $(python3-config --ldflags | cut -d ' ' -f1)
- name: Run tests - name: Run tests
run: cargo test run: cargo test
- name: Test libafl no_std - name: Test libafl no_std
@ -67,33 +71,10 @@ jobs:
- name: Test libafl_targets no_std - name: Test libafl_targets no_std
run: cd libafl_targets && cargo test --no-default-features run: cd libafl_targets && cargo test --no-default-features
llvm-tester:
runs-on: ubuntu-22.04
continue-on-error: true
strategy:
matrix:
llvm-version: [ "16", "17" ] # Add 18 when KyleMayes/install-llvm-action enables it
steps:
- name: Remove Dotnet & Haskell
run: rm -rf /usr/share/dotnet && rm -rf /opt/ghc
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
- uses: actions/checkout@v3
- uses: Swatinem/rust-cache@v2
with: { shared-key: "llvm-tester" }
- name: Install LLVM and Clang
uses: KyleMayes/install-llvm-action@v2
with:
version: "${{matrix.llvm-version}}"
- name: Build and test with llvm-${{ matrix.llvm-version }}
run: pwd && ls & cd libafl_cc && cargo build --release
ubuntu-doc-build: ubuntu-doc-build:
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: ./.github/workflows/ubuntu-prepare - uses: ./.github/workflows/ubuntu-prepare
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
# ---- doc check ---- # ---- doc check ----
@ -101,9 +82,9 @@ jobs:
run: RUSTFLAGS="--cfg docsrs" cargo +nightly doc --all-features --no-deps run: RUSTFLAGS="--cfg docsrs" cargo +nightly doc --all-features --no-deps
ubuntu-doc-test: ubuntu-doc-test:
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: ./.github/workflows/ubuntu-prepare - uses: ./.github/workflows/ubuntu-prepare
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
# ---- doc check ---- # ---- doc check ----
@ -111,41 +92,27 @@ jobs:
run: RUSTFLAGS="--cfg docsrs" cargo +nightly test --doc --all-features run: RUSTFLAGS="--cfg docsrs" cargo +nightly test --doc --all-features
ubuntu-miri: ubuntu-miri:
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
needs: ubuntu if: contains( github.event.pull_request.labels.*.name, 'pre-release')
steps: steps:
- uses: actions/checkout@v3
- uses: ./.github/workflows/ubuntu-prepare
- uses: Swatinem/rust-cache@v2
- name: Add nightly clippy - name: Add nightly clippy
run: rustup toolchain install nightly --component miri --allow-downgrade run: rustup toolchain install nightly --component miri --allow-downgrade
- uses: actions/checkout@v4
- uses: ./.github/workflows/ubuntu-prepare
- uses: Swatinem/rust-cache@v2
# --- miri undefined behavior test -- # --- miri undefined behavior test --
- name: Run miri tests - name: Run miri tests
run: RUST_BACKTRACE=1 MIRIFLAGS="-Zmiri-disable-isolation" cargo +nightly miri test run: RUST_BACKTRACE=1 MIRIFLAGS="-Zmiri-disable-isolation" cargo +nightly miri test
ubuntu: ubuntu:
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
steps: steps:
- name: Remove Dotnet & Haskell - name: Remove Dotnet & Haskell
run: rm -rf /usr/share/dotnet && rm -rf /opt/ghc run: rm -rf /usr/share/dotnet && rm -rf /opt/ghc
- uses: actions-rs/toolchain@v1 - uses: actions/checkout@v4
with: - uses: ./.github/workflows/ubuntu-prepare
profile: minimal
toolchain: stable
- name: Remove existing clang and LLVM
run: sudo apt purge llvm* clang* lld* lldb* opt*
- name: Install and cache deps
run: sudo apt update && sudo apt install ninja-build shellcheck libgtk-3-dev gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libslirp-dev libz3-dev
- name: Add nightly clippy
run: rustup toolchain install nightly --component clippy --component miri --allow-downgrade
- uses: actions/checkout@v3
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
with: { shared-key: "ubuntu" } with: { shared-key: "ubuntu" }
- name: Install LLVM and Clang
uses: KyleMayes/install-llvm-action@v2
with:
directory: ${{ runner.temp }}/llvm
version: 17
# pcguard edges and pcguard hitcounts are not compatible and we need to build them seperately # pcguard edges and pcguard hitcounts are not compatible and we need to build them seperately
- name: Check pcguard edges - name: Check pcguard edges
run: cargo check --features=sancov_pcguard_edges run: cargo check --features=sancov_pcguard_edges
@ -158,42 +125,31 @@ jobs:
run: cargo build --examples --verbose run: cargo build --examples --verbose
ubuntu-clippy: ubuntu-clippy:
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
steps: steps:
- name: Remove Dotnet & Haskell - name: Remove Dotnet & Haskell
run: rm -rf /usr/share/dotnet && rm -rf /opt/ghc run: rm -rf /usr/share/dotnet && rm -rf /opt/ghc
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
- name: Install and cache deps
run: sudo apt update && sudo apt install ninja-build shellcheck libgtk-3-dev gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libslirp-dev libz3-dev
- name: Add nightly clippy - name: Add nightly clippy
run: rustup toolchain install nightly --component clippy --allow-downgrade && rustup default nightly run: rustup toolchain install nightly --component clippy --allow-downgrade && rustup default nightly
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: ./.github/workflows/ubuntu-prepare
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
with: { shared-key: "ubuntu" } with: { shared-key: "ubuntu" }
- name: Install LLVM and Clang
uses: KyleMayes/install-llvm-action@v2
with:
directory: ${{ runner.temp }}/llvm
version: 17
- name: Run clippy - name: Run clippy
run: ./scripts/clippy.sh run: LLVM_CONFIG=llvm-config-${{env.MAIN_LLVM_VERSION}} ./scripts/clippy.sh
# --- test embedding the libafl_libfuzzer_runtime library # --- test embedding the libafl_libfuzzer_runtime library
# Fix me plz # Fix me plz
# - name: Test Build libafl_libfuzzer with embed # - name: Test Build libafl_libfuzzer with embed
# run: cargo +nightly test --features=embed-runtime --manifest-path libafl_libfuzzer/Cargo.toml # run: cargo +nightly test --features=embed-runtime --manifest-path libafl_libfuzzer/Cargo.toml
ubuntu-check: ubuntu-check:
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
needs: ubuntu needs: ubuntu
strategy: strategy:
matrix: matrix:
instance_idx: [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17" ] instance_idx: [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17" ]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: ./.github/workflows/ubuntu-prepare - uses: ./.github/workflows/ubuntu-prepare
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
with: { shared-key: "ubuntu" } with: { shared-key: "ubuntu" }
@ -205,14 +161,13 @@ jobs:
run: python3 ./scripts/parallellize_cargo_check.py ${{ matrix.instance_idx }} run: python3 ./scripts/parallellize_cargo_check.py ${{ matrix.instance_idx }}
ubuntu-concolic: ubuntu-concolic:
runs-on: ubuntu-latest runs-on: ubuntu-24.04
needs: ubuntu needs: ubuntu
steps: steps:
- uses: actions-rs/toolchain@v1 - name: Install curl
with: run: sudo apt-get update && sudo apt-get install clang
profile: minimal - uses: dtolnay/rust-toolchain@stable
toolchain: stable - uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
with: { shared-key: "ubuntu" } with: { shared-key: "ubuntu" }
- name: Install smoke test deps - name: Install smoke test deps
@ -221,208 +176,254 @@ jobs:
run: ./libafl_concolic/test/smoke_test.sh run: ./libafl_concolic/test/smoke_test.sh
python-bindings: python-bindings:
runs-on: ubuntu-latest runs-on: ubuntu-24.04
steps: steps:
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
- name: Remove existing clang and LLVM
run: sudo apt purge llvm* clang*
- name: Install LLVM and Clang
uses: KyleMayes/install-llvm-action@v2
with:
directory: ${{ runner.temp }}/llvm
version: 17
- name: Install deps - name: Install deps
run: sudo apt-get install -y ninja-build python3-dev python3-pip python3-venv libz3-dev run: sudo apt-get update && sudo apt-get install -y lsb-release wget software-properties-common gnupg ninja-build python3-dev python3-pip python3-venv libz3-dev
- name: Install maturin - name: Install maturin
run: python3 -m pip install maturin run: cargo install --locked maturin
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: ./.github/workflows/ubuntu-prepare
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
with: { shared-key: "ubuntu" }
- name: Run a maturin build - name: Run a maturin build
run: export LLVM_CONFIG=llvm-config-16 && cd ./bindings/pylibafl && python3 -m venv .env && . .env/bin/activate && pip install --upgrade --force-reinstall . && ./test.sh run: export LLVM_CONFIG=llvm-config-${{env.MAIN_LLVM_VERSION}} && cd ./bindings/pylibafl && python3 -m venv .env && . .env/bin/activate && pip install --upgrade --force-reinstall . && ./test.sh
- name: Run python test - name: Run python test
run: . ./bindings/pylibafl/.env/bin/activate # && cd ./fuzzers/python_qemu/ && python3 fuzzer.py 2>&1 | grep "Bye" run: . ./bindings/pylibafl/.env/bin/activate # && cd ./fuzzers/binary_only/python_qemu/ && python3 fuzzer.py 2>&1 | grep "Bye"
cargo-fmt: cargo-fmt:
runs-on: ubuntu-latest runs-on: ubuntu-24.04
env:
MAIN_LLVM_VERSION: 19
steps: steps:
- uses: actions-rs/toolchain@v1 - uses: actions/checkout@v4
with: - uses: ./.github/workflows/ubuntu-prepare
profile: minimal - name: Add rustfmt nightly
toolchain: nightly shell: bash
override: true run: rustup component add --toolchain nightly-x86_64-unknown-linux-gnu rustfmt
components: rustfmt - uses: Swatinem/rust-cache@v2
- uses: actions/checkout@v3 with: { shared-key: "ubuntu" }
- name: Remove existing clang and LLVM - name: Installing black
run: sudo apt purge llvm* clang* run: python3 -m pip install black
- name: Install LLVM and Clang
uses: KyleMayes/install-llvm-action@v2
with:
directory: ${{ runner.temp }}/llvm
version: 17
- name: Format Check - name: Format Check
run: ./scripts/fmt_all.sh check run: ./scripts/fmt_all.sh check
fuzzers-preflight: check-md-links:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Install linkspector
shell: bash
run: sudo apt-get update && sudo apt-get install -y npm && npm install -g @umbrelladocs/linkspector
- name: Run linkspector
shell: bash
run: ./scripts/check_md_links.sh
# TODO: Use github action once it's fixed (https://github.com/UmbrellaDocs/action-linkspector/issues/20)
# - name: Run linkspector
# uses: umbrelladocs/action-linkspector@v1
# with:
# fail_on_error: 'true'
# config_file: '.github/.linkspector.yml'
msrv:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: taiki-e/install-action@cargo-hack
# Note: We currently only specify minimum rust versions for the default workspace members
- run: cargo hack check --rust-version -p libafl -p libafl_bolts -p libafl_derive -p libafl_cc -p libafl_targets
fuzzers-preflight:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Fuzzer in CI Check - name: Fuzzer in CI Check
run: ./scripts/check_tested_fuzzers.sh run: ./scripts/check_tested_fuzzers.sh
fuzzers: fuzzers:
needs: needs:
- ubuntu
- fuzzers-preflight - fuzzers-preflight
strategy: strategy:
fail-fast: true
matrix: matrix:
os: [ ubuntu-latest ] os: [ ubuntu-24.04 ]
fuzzer: fuzzer:
- ./fuzzers/cargo_fuzz # Baby
- ./fuzzers/fuzzbench_fork_qemu - ./fuzzers/baby/baby_fuzzer_swap_differential
- ./fuzzers/libfuzzer_stb_image_sugar - ./fuzzers/baby/tutorial
- ./fuzzers/nyx_libxml2_standalone - ./fuzzers/baby/baby_fuzzer
- ./fuzzers/baby_fuzzer_gramatron # - ./fuzzers/baby/backtrace_baby_fuzzers
- ./fuzzers/tinyinst_simple - ./fuzzers/baby/baby_fuzzer_unicode
- ./fuzzers/baby_fuzzer_with_forkexecutor - ./fuzzers/baby/baby_fuzzer_minimizing
- ./fuzzers/baby_no_std - ./fuzzers/baby/backtrace_baby_fuzzers/c_code_with_fork_executor
- ./fuzzers/baby_fuzzer_swap_differential - ./fuzzers/baby/backtrace_baby_fuzzers/c_code_with_inprocess_executor
- ./fuzzers/baby_fuzzer_grimoire - ./fuzzers/baby/backtrace_baby_fuzzers/rust_code_with_fork_executor
- ./fuzzers/baby_fuzzer - ./fuzzers/baby/backtrace_baby_fuzzers/rust_code_with_inprocess_executor
- ./fuzzers/libfuzzer_libpng_launcher - ./fuzzers/baby/backtrace_baby_fuzzers/command_executor
- ./fuzzers/libfuzzer_libpng_accounting - ./fuzzers/baby/backtrace_baby_fuzzers/forkserver_executor
- ./fuzzers/forkserver_libafl_cc - ./fuzzers/baby/baby_fuzzer_custom_executor
- ./fuzzers/libfuzzer_libpng_tcp_manager
- ./fuzzers/backtrace_baby_fuzzers # Binary-only
- ./fuzzers/fuzzbench_qemu - ./fuzzers/binary_only/fuzzbench_fork_qemu
- ./fuzzers/nyx_libxml2_parallel - ./fuzzers/binary_only/frida_executable_libpng
- ./fuzzers/frida_gdiplus - ./fuzzers/binary_only/frida_windows_gdiplus
- ./fuzzers/libfuzzer_stb_image_concolic - ./fuzzers/binary_only/frida_libpng
- ./fuzzers/nautilus_sync - ./fuzzers/binary_only/fuzzbench_qemu
- ./fuzzers/push_harness - ./fuzzers/binary_only/intel_pt_baby_fuzzer
- ./fuzzers/libfuzzer_libpng_centralized - ./fuzzers/binary_only/intel_pt_command_executor
- ./fuzzers/baby_fuzzer_nautilus - ./fuzzers/binary_only/tinyinst_simple
- ./fuzzers/fuzzbench_text
- ./fuzzers/libfuzzer_libpng_cmin # Forkserver
- ./fuzzers/forkserver_simple - ./fuzzers/forkserver/forkserver_simple
- ./fuzzers/baby_fuzzer_unicode - ./fuzzers/forkserver/forkserver_libafl_cc
- ./fuzzers/libfuzzer_libpng_norestart - ./fuzzers/forkserver/fuzzbench_forkserver
- ./fuzzers/baby_fuzzer_multi - ./fuzzers/forkserver/fuzzbench_forkserver_cmplog
- ./fuzzers/libafl_atheris - ./fuzzers/forkserver/libafl-fuzz
- ./fuzzers/frida_libpng - ./fuzzers/forkserver/baby_fuzzer_with_forkexecutor
- ./fuzzers/fuzzbench_ctx
- ./fuzzers/fuzzbench_forkserver_cmplog # Full-system
- ./fuzzers/push_stage_harness - ./fuzzers/full_system/nyx_libxml2_standalone
- ./fuzzers/libfuzzer_libmozjpeg - ./fuzzers/full_system/nyx_libxml2_parallel
- ./fuzzers/libfuzzer_libpng_aflpp_ui
- ./fuzzers/libfuzzer_libpng # Structure-aware
- ./fuzzers/baby_fuzzer_wasm - ./fuzzers/structure_aware/nautilus_sync
- ./fuzzers/fuzzbench - ./fuzzers/structure_aware/baby_fuzzer_grimoire
- ./fuzzers/libfuzzer_stb_image - ./fuzzers/structure_aware/baby_fuzzer_gramatron
- ./fuzzers/fuzzbench_forkserver - ./fuzzers/structure_aware/baby_fuzzer_tokens
# - ./fuzzers/libfuzzer_windows_asan - ./fuzzers/structure_aware/baby_fuzzer_multi
# - ./fuzzers/dynamic_analysis - ./fuzzers/structure_aware/baby_fuzzer_custom_input
- ./fuzzers/baby_fuzzer_minimizing - ./fuzzers/structure_aware/baby_fuzzer_nautilus
- ./fuzzers/frida_executable_libpng - ./fuzzers/structure_aware/forkserver_simple_nautilus
- ./fuzzers/tutorial
- ./fuzzers/baby_fuzzer_tokens # In-process
- ./fuzzers/backtrace_baby_fuzzers/rust_code_with_inprocess_executor - ./fuzzers/fuzz_anything/cargo_fuzz
- ./fuzzers/backtrace_baby_fuzzers/c_code_with_fork_executor # - ./fuzzers/inprocess/dynamic_analysis
- ./fuzzers/backtrace_baby_fuzzers/command_executor - ./fuzzers/inprocess/fuzzbench
- ./fuzzers/backtrace_baby_fuzzers/forkserver_executor - ./fuzzers/inprocess/fuzzbench_text
- ./fuzzers/backtrace_baby_fuzzers/c_code_with_inprocess_executor - ./fuzzers/inprocess/fuzzbench_ctx
- ./fuzzers/backtrace_baby_fuzzers/rust_code_with_fork_executor - ./fuzzers/inprocess/libfuzzer_libmozjpeg
- ./fuzzers/inprocess/libfuzzer_libpng
- ./fuzzers/inprocess/libfuzzer_libpng_launcher
- ./fuzzers/inprocess/libfuzzer_libpng_accounting
- ./fuzzers/inprocess/libfuzzer_libpng_centralized
- ./fuzzers/inprocess/libfuzzer_libpng_cmin
- ./fuzzers/inprocess/libfuzzer_libpng_norestart
# - ./fuzzers/inprocess/libfuzzer_libpng_tcp_manager
- ./fuzzers/inprocess/libfuzzer_stb_image_sugar
- ./fuzzers/inprocess/libfuzzer_stb_image
# - ./fuzzers/structure_aware/libfuzzer_stb_image_concolic
# - ./fuzzers/inprocess/libfuzzer_windows_asan
# - ./fuzzers/inprocess/sqlite_centralized_multi_machine
# Fuzz Anything
- ./fuzzers/fuzz_anything/push_harness
- ./fuzzers/fuzz_anything/push_stage_harness
- ./fuzzers/fuzz_anything/libafl_atheris
- ./fuzzers/fuzz_anything/baby_no_std
- ./fuzzers/fuzz_anything/baby_fuzzer_wasm
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: ./.github/workflows/fuzzer-tester-prepare - uses: ./.github/workflows/fuzzer-tester-prepare
- name: Build and run example fuzzers (Linux) - name: Build and run example fuzzers (Linux)
if: runner.os == 'Linux' if: runner.os == 'Linux'
shell: bash shell: bash
run: RUN_ON_CI=1 LLVM_CONFIG=llvm-config ./scripts/test_fuzzer.sh ${{ matrix.fuzzer }} run: RUN_ON_CI=1 LLVM_CONFIG=llvm-config-${{env.MAIN_LLVM_VERSION}} ./scripts/test_fuzzer.sh ${{ matrix.fuzzer }}
changes: changes:
runs-on: ubuntu-latest runs-on: ubuntu-24.04
permissions: permissions:
pull-requests: read pull-requests: read
outputs: outputs:
qemu: ${{ steps.filter.outputs.qemu }} qemu: ${{ steps.filter.outputs.qemu }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: dorny/paths-filter@v3 - uses: dorny/paths-filter@v3
id: filter id: filter
with: with:
filters: | filters: |
qemu: qemu:
- '.github/**'
- 'libafl/**'
- 'libafl_bolts/**'
- 'libafl_targets/**'
- 'libafl_qemu/**' - 'libafl_qemu/**'
- 'fuzzers/*qemu*/**' - 'fuzzers/*qemu*/**'
fuzzers-qemu: fuzzers-qemu:
needs: changes needs:
- changes
if: ${{ needs.changes.outputs.qemu == 'true' }} if: ${{ needs.changes.outputs.qemu == 'true' }}
strategy: strategy:
matrix: matrix:
os: [ubuntu-latest] os: [ubuntu-24.04]
fuzzer: fuzzer:
- ./fuzzers/qemu_cmin # Binary only
- ./fuzzers/qemu_systemmode - ./fuzzers/binary_only/qemu_cmin
- ./fuzzers/qemu_coverage - ./fuzzers/binary_only/qemu_coverage
- ./fuzzers/qemu_launcher - ./fuzzers/binary_only/qemu_launcher
# Full-system
- ./fuzzers/full_system/qemu_baremetal
# - ./fuzzers/full_system/qemu_linux_kernel
#- ./fuzzers/full_system/qemu_linux_process
runs-on: [ self-hosted, qemu ] runs-on: [ self-hosted, qemu ]
container: registry.gitlab.com/qemu-project/qemu/qemu/ubuntu2204:latest container: registry.gitlab.com/qemu-project/qemu/qemu/ubuntu2204:latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: ./.github/workflows/qemu-fuzzer-tester-prepare - uses: ./.github/workflows/qemu-fuzzer-tester-prepare
- name: Build and run example QEMU fuzzers (Linux) - name: Build and run example QEMU fuzzers (Linux)
if: runner.os == 'Linux' if: runner.os == 'Linux'
shell: bash shell: bash
run: RUN_ON_CI=1 LLVM_CONFIG=llvm-config ./scripts/test_fuzzer.sh ${{ matrix.fuzzer }} run: RUN_ON_CI=1 LLVM_CONFIG=llvm-config-${{env.MAIN_LLVM_VERSION}} ./scripts/test_fuzzer.sh ${{ matrix.fuzzer }}
nostd-build: nostd-build:
runs-on: ubuntu-latest runs-on: ubuntu-24.04
steps: steps:
- uses: actions-rs/toolchain@v1 - uses: dtolnay/rust-toolchain@nightly
with: with:
profile: minimal
toolchain: nightly
override: true
components: rust-src components: rust-src
- uses: actions/checkout@v3
- uses: Swatinem/rust-cache@v2
- name: Add targets - name: Add targets
run: rustup target add arm-linux-androideabi && rustup target add thumbv6m-none-eabi run: rustup target add arm-linux-androideabi && rustup target add thumbv6m-none-eabi
- uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
- name: Build aarch64-unknown-none - name: Build aarch64-unknown-none
run: cd ./fuzzers/baby_no_std && cargo +nightly build -Zbuild-std=core,alloc --target aarch64-unknown-none -v --release && cd ../.. run: cd ./fuzzers/fuzz_anything/baby_no_std && cargo +nightly build -Zbuild-std=core,alloc --target aarch64-unknown-none -v --release && cd ../..
- name: run x86_64 until panic! - name: run x86_64 until panic!
run: cd ./fuzzers/baby_no_std && cargo +nightly run || test $? -ne 0 || exit 1 run: cd ./fuzzers/fuzz_anything/baby_no_std && cargo +nightly run || test $? -ne 0 || exit 1
- name: no_std tests - name: no_std tests
run: cd ./libafl && cargo test --no-default-features run: cd ./libafl && cargo test --no-default-features
nostd-clippy: nostd-clippy:
runs-on: ubuntu-latest runs-on: ubuntu-24.04
steps: steps:
- uses: actions-rs/toolchain@v1 - uses: dtolnay/rust-toolchain@nightly
with: with:
profile: minimal
toolchain: nightly
override: true
components: clippy, rust-src components: clippy, rust-src
- uses: actions/checkout@v3
- uses: Swatinem/rust-cache@v2
- name: Add targets - name: Add targets
run: rustup target add arm-linux-androideabi && rustup target add thumbv6m-none-eabi run: rustup target add arm-linux-androideabi && rustup target add thumbv6m-none-eabi
- uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
- name: libafl armv6m-none-eabi (32 bit no_std) clippy - name: libafl armv6m-none-eabi (32 bit no_std) clippy
run: cd ./libafl && cargo clippy --target thumbv6m-none-eabi --no-default-features run: cd ./libafl && cargo clippy --target thumbv6m-none-eabi --no-default-features
- name: Build no_std no_alloc bolts - name: Build no_std no_alloc bolts
run: cd ./libafl_bolts && cargo +nightly build -Zbuild-std=core --target aarch64-unknown-none --no-default-features -v --release && cd ../ run: cd ./libafl_bolts && cargo +nightly build -Zbuild-std=core --target aarch64-unknown-none --no-default-features -v --release && cd ../
build-docker: format-toml:
runs-on: ubuntu-latest runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - name: Install taplo
run: curl -fsSL https://github.com/tamasfe/taplo/releases/latest/download/taplo-full-linux-x86_64.gz | gzip -d - | install -m 755 /dev/stdin /usr/local/bin/taplo
- uses: actions/checkout@v4
- name: Run taplo
run: taplo format --check
build-docker:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Build docker - name: Build docker
run: docker build -t libafl . run: docker build -t libafl .
@ -431,53 +432,50 @@ jobs:
needs: needs:
- common - common
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: ./.github/workflows/windows-tester-prepare - uses: ./.github/workflows/windows-tester-prepare
- name: Build fuzzers/frida_libpng - name: Build fuzzers/binary_only/frida_libpng
run: cd fuzzers/frida_libpng/ && cargo make test run: cd fuzzers/binary_only/frida_libpng/ && cargo make test
windows-frida-libfuzzer-stb-image: windows-frida-libfuzzer-stb-image:
runs-on: windows-latest runs-on: windows-latest
needs: needs:
- common - common
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: ./.github/workflows/windows-tester-prepare - uses: ./.github/workflows/windows-tester-prepare
- name: Build fuzzers/libfuzzer_stb_image - name: Build fuzzers/inprocess/libfuzzer_stb_image
run: cd fuzzers/libfuzzer_stb_image && cargo build --release run: cd fuzzers/inprocess/libfuzzer_stb_image && cargo build --release
windows-frida-gdiplus: windows-frida-gdiplus:
runs-on: windows-latest runs-on: windows-latest
needs: needs:
- common - common
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: ./.github/workflows/windows-tester-prepare - uses: ./.github/workflows/windows-tester-prepare
- name: Build fuzzers/frida_gdiplus - name: Build fuzzers/binary_only/frida_windows_gdiplus
run: cd fuzzers/frida_gdiplus/ && cargo make test && cargo make test_cmplog run: cd fuzzers/binary_only/frida_windows_gdiplus/ && cargo make test && cargo make test_cmplog
windows-tinyinst-simple: windows-tinyinst-simple:
runs-on: windows-latest runs-on: windows-latest
needs: needs:
- common - common
steps: steps:
- uses: actions/checkout@v3
- uses: ./.github/workflows/windows-tester-prepare
- name: install cxx bridge - name: install cxx bridge
run: cargo install cxxbridge-cmd run: cargo install cxxbridge-cmd
- name: Build fuzzers/tinyinst_simple - uses: actions/checkout@v4
run: cd fuzzers/tinyinst_simple/ && cargo make test - uses: ./.github/workflows/windows-tester-prepare
- name: Build fuzzers/binary_only/tinyinst_simple
run: cd fuzzers/binary_only/tinyinst_simple/ && cargo make test
windows-clippy: windows-clippy:
runs-on: windows-latest runs-on: windows-latest
needs: needs:
- common - common
steps: steps:
- uses: actions-rs/toolchain@v1 - uses: dtolnay/rust-toolchain@stable
with: - uses: actions/checkout@v4
profile: minimal
toolchain: stable
- uses: actions/checkout@v3
- uses: ./.github/workflows/windows-tester-prepare - uses: ./.github/workflows/windows-tester-prepare
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- name: Run real clippy, not the fake one - name: Run real clippy, not the fake one
@ -487,17 +485,14 @@ jobs:
macos: macos:
runs-on: macOS-latest runs-on: macOS-latest
steps: steps:
- uses: actions-rs/toolchain@v1 - uses: dtolnay/rust-toolchain@stable
with:
profile: minimal
toolchain: stable
- name: Add nightly clippy - name: Add nightly clippy
run: rustup toolchain install nightly --component clippy --allow-downgrade && rustup default nightly run: rustup toolchain install nightly --component clippy --allow-downgrade && rustup default nightly
- name: Install deps - name: Install deps
run: brew install z3 gtk+3 run: brew install z3 gtk+3 python
- name: Install cxxbridge - name: Install cxxbridge
run: cargo install cxxbridge-cmd run: cargo install cxxbridge-cmd
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- name: MacOS Build - name: MacOS Build
run: cargo build --verbose run: cargo build --verbose
@ -511,24 +506,20 @@ jobs:
ios: ios:
runs-on: macOS-latest runs-on: macOS-latest
steps: steps:
- uses: actions-rs/toolchain@v1 - uses: dtolnay/rust-toolchain@stable
with:
profile: minimal
toolchain: stable
- name: install ios - name: install ios
run: rustup target add aarch64-apple-ios run: rustup target add aarch64-apple-ios
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- name: Build iOS - name: Build iOS
run: cargo build --target aarch64-apple-ios && cd libafl_frida && cargo build --target aarch64-apple-ios && cd .. run: PYO3_CROSS_PYTHON_VERSION=$(python3 -c "print('{}.{}'.format(__import__('sys').version_info.major, __import__('sys').version_info.minor))") cargo build --target aarch64-apple-ios && cd libafl_frida && cargo build --target aarch64-apple-ios && cd ..
android: android:
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions-rs/toolchain@v1 - name: Install curl
with: run: sudo apt-get update && sudo apt-get install clang
profile: minimal - uses: dtolnay/rust-toolchain@stable
toolchain: stable
- uses: nttld/setup-ndk@v1 - uses: nttld/setup-ndk@v1
with: with:
ndk-version: r25b ndk-version: r25b
@ -536,10 +527,10 @@ jobs:
run: rustup target add aarch64-linux-android run: rustup target add aarch64-linux-android
- name: install cargo ndk - name: install cargo ndk
run: cargo install cargo-ndk run: cargo install cargo-ndk
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- name: Build Android - name: Build Android
run: cd libafl && cargo ndk -t arm64-v8a build --release run: cd libafl && PYO3_CROSS_PYTHON_VERSION=$(python3 -c "print('{}.{}'.format(__import__('sys').version_info.major, __import__('sys').version_info.minor))") cargo ndk -t arm64-v8a build --release
#run: cargo build --target aarch64-linux-android #run: cargo build --target aarch64-linux-android
# TODO: Figure out how to properly build stuff with clang # TODO: Figure out how to properly build stuff with clang
@ -550,36 +541,3 @@ jobs:
# run: clang -v # run: clang -v
#- name: Windows Test #- name: Windows Test
# run: C:\Rust\.cargo\bin\cargo.exe test --verbose # run: C:\Rust\.cargo\bin\cargo.exe test --verbose
freebsd:
runs-on: ubuntu-22.04
name: Simple build in FreeBSD
steps:
- uses: actions/checkout@v3
- name: Test in FreeBSD
id: test
uses: vmactions/freebsd-vm@v1
with:
usesh: true
sync: rsync
copyback: false
mem: 2048
release: 13.2
prepare: |
pkg install -y curl bash sudo llvm16
curl https://sh.rustup.rs -sSf | sh -s -- -y
run: |
freebsd-version
. "$HOME/.cargo/env"
rustup toolchain install nightly
export LLVM_CONFIG=/usr/local/bin/llvm-config16
pwd
ls -lah
echo "local/bin"
ls -lah /usr/local/bin/
which llvm-config
chmod +x ./scripts/clippy.sh
bash ./scripts/shmem_limits_fbsd.sh
bash ./scripts/clippy.sh
cargo test

View File

@ -3,63 +3,38 @@ description: Sets up the Rust environment for the CI workflow
runs: runs:
using: composite using: composite
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
submodules: true submodules: true
fetch-depth: 0 fetch-depth: 0
- uses: ./.github/workflows/ubuntu-prepare
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
with: { shared-key: "${{ runner.os }}-shared-fuzzer-cache" } with: { shared-key: "${{ runner.os }}-shared-fuzzer-cache" }
- uses: actions-rs/toolchain@v1 - name: Install fuzzers deps
with:
profile: minimal
toolchain: stable
- name: Add stable clippy
shell: bash shell: bash
run: rustup toolchain install stable --component clippy --allow-downgrade run: sudo apt-get update && sudo apt-get install -y nasm nlohmann-json3-dev gcc-aarch64-linux-gnu g++-aarch64-linux-gnu gcc-mipsel-linux-gnu g++-mipsel-linux-gnu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-i386-cross libc6-dev libc6-dev-i386 lib32gcc-11-dev lib32stdc++-11-dev libgtk-3-dev pax-utils python3-msgpack python3-jinja2
- name: Add nightly clippy - name: enable mult-thread for `make`
shell: bash shell: bash
run: rustup toolchain install nightly --component clippy --allow-downgrade run: export MAKEFLAGS="-j$(expr $(nproc) \+ 1)"
- name: Add no_std toolchain - name: Add no_std toolchain
shell: bash shell: bash
run: rustup toolchain install nightly-x86_64-unknown-linux-gnu ; rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu run: rustup toolchain install nightly-x86_64-unknown-linux-gnu ; rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
- name: Add wasm target - name: Add wasm target
shell: bash shell: bash
run: rustup target add wasm32-unknown-unknown run: rustup target add wasm32-unknown-unknown
- name: Remove obsolete llvm (Linux)
if: runner.os == 'Linux'
shell: bash
run: sudo apt purge -y llvm* clang*
- name: Install LLVM and Clang
uses: KyleMayes/install-llvm-action@v2
with:
directory: ${{ runner.temp }}/llvm
version: 17
- name: Install deps
shell: bash
run: sudo apt update && sudo apt install -y nasm nlohmann-json3-dev ninja-build gcc-arm-linux-gnueabi g++-arm-linux-gnueabi gcc-aarch64-linux-gnu g++-aarch64-linux-gnu gcc-mipsel-linux-gnu g++-mipsel-linux-gnu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-i386-cross libc6-dev libc6-dev-i386 lib32gcc-11-dev lib32stdc++-11-dev libgtk-3-dev pax-utils libz3-dev
- name: pip install
shell: bash
run: python3 -m pip install msgpack jinja2 find_libpython
- name: enable mult-thread for `make`
shell: bash
run: export MAKEFLAGS="-j$(expr $(nproc) \+ 1)"
- name: install cargo-make - name: install cargo-make
uses: baptiste0928/cargo-install@v1.3.0 uses: baptiste0928/cargo-install@v3
with: with:
crate: cargo-make crate: cargo-make
- name: install wasm-pack - name: install wasm-pack
uses: baptiste0928/cargo-install@v1.3.0 uses: baptiste0928/cargo-install@v3
with: with:
crate: wasm-pack crate: wasm-pack
- name: install cxxbridge-cmd - name: install cxxbridge-cmd
uses: baptiste0928/cargo-install@v1.3.0 uses: baptiste0928/cargo-install@v3
with: with:
crate: cxxbridge-cmd crate: cxxbridge-cmd
- name: install chrome - name: install chrome
uses: browser-actions/setup-chrome@v1 uses: browser-actions/setup-chrome@v1
with: with:
chrome-version: stable chrome-version: stable
- name: Symlink Headers
if: runner.os == 'Linux'
shell: bash
run: sudo ln -s /usr/include/asm-generic /usr/include/asm

View File

@ -3,45 +3,21 @@ description: Sets up the QEMU fuzzers environment
runs: runs:
using: composite using: composite
steps: steps:
- uses: actions/checkout@v3 - name: Install QEMU deps
with:
submodules: true
fetch-depth: 0
- name: Install deps
shell: bash shell: bash
run: apt update && apt install -y nasm ninja-build libc6-dev libgtk-3-dev pax-utils libz3-dev wget qemu-utils libsqlite3-dev gcc-arm-none-eabi sudo gcc g++ build-essential gcc-arm-linux-gnueabi g++-arm-linux-gnueabi run: apt-get update && apt-get install -y qemu-utils sudo python3-msgpack python3-jinja2 curl python3-dev
- uses: Swatinem/rust-cache@v2 - uses: dtolnay/rust-toolchain@stable
with: { shared-key: "${{ runner.os }}-shared-fuzzer-cache" }
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
- name: Add stable clippy
shell: bash
run: rustup toolchain install stable --component clippy --allow-downgrade
- name: Add nightly clippy
shell: bash
run: rustup toolchain install nightly --component clippy --allow-downgrade
- name: Remove obsolete llvm (Linux)
if: runner.os == 'Linux'
shell: bash
run: sudo apt purge -y llvm* clang*
- name: Install LLVM and Clang
uses: KyleMayes/install-llvm-action@v2
with:
directory: ${{ runner.temp }}/llvm
version: 17
- name: pip install
shell: bash
run: python3 -m pip install msgpack jinja2 find_libpython
- name: enable mult-thread for `make` - name: enable mult-thread for `make`
shell: bash shell: bash
run: export MAKEFLAGS="-j$(expr $(nproc) \+ 1)" run: export MAKEFLAGS="-j$(expr $(nproc) \+ 1)"
- name: install cargo-make - name: install cargo-make
uses: baptiste0928/cargo-install@v1.3.0 uses: baptiste0928/cargo-install@v3
with: with:
crate: cargo-make crate: cargo-make
- name: Symlink Headers - uses: actions/checkout@v4
if: runner.os == 'Linux' with:
shell: bash submodules: true
run: sudo ln -s /usr/include/asm-generic /usr/include/asm fetch-depth: 0
- uses: ./.github/workflows/ubuntu-prepare
- uses: Swatinem/rust-cache@v2
with: { shared-key: "${{ runner.os }}-shared-fuzzer-cache" }

View File

@ -3,25 +3,34 @@ description: Sets up the Rust environment for the CI workflow
runs: runs:
using: composite using: composite
steps: steps:
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
components: llvm-tools
- name: Remove existing clang and LLVM
shell: bash
run: sudo apt purge llvm* clang*
- name: Install and cache deps - name: Install and cache deps
shell: bash shell: bash
run: sudo apt update && sudo apt install ninja-build clang-format shellcheck libgtk-3-dev gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libslirp-dev libz3-dev run: sudo apt-get update && sudo apt-get install -y curl lsb-release wget software-properties-common gnupg ninja-build shellcheck pax-utils nasm libsqlite3-dev libc6-dev libgtk-3-dev gcc g++ gcc-arm-none-eabi gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libslirp-dev libz3-dev build-essential cmake
- uses: dtolnay/rust-toolchain@stable
- name: Add stable clippy
shell: bash
run: rustup toolchain install stable --component clippy --allow-downgrade
- name: Add nightly clippy
shell: bash
run: rustup toolchain install nightly --component clippy --allow-downgrade
- name: Remove existing clang and LLVM
shell: bash
run: sudo apt-get purge -y *llvm* *clang* lld* lldb* opt*
- name: Install cargo-hack - name: Install cargo-hack
shell: bash shell: bash
run: curl -LsSf https://github.com/taiki-e/cargo-hack/releases/latest/download/cargo-hack-x86_64-unknown-linux-gnu.tar.gz | tar xzf - -C ~/.cargo/bin run: curl -LsSf https://github.com/taiki-e/cargo-hack/releases/latest/download/cargo-hack-x86_64-unknown-linux-gnu.tar.gz | tar xzf - -C ~/.cargo/bin
- name: Add nightly - name: Add nightly
shell: bash shell: bash
run: rustup toolchain install nightly --allow-downgrade run: rustup toolchain install nightly --allow-downgrade
- name: Install LLVM and Clang - name: Default to nightly
uses: KyleMayes/install-llvm-action@v2 shell: bash
with: run: rustup default nightly
directory: ${{ runner.temp }}/llvm - name: Add LLVM in sources list
version: 17 shell: bash
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh ${{env.MAIN_LLVM_VERSION}} all
- name: Symlink Headers
shell: bash
run: sudo ln -s /usr/include/asm-generic /usr/include/asm

View File

@ -3,11 +3,10 @@ description: Sets up the Rust environment for the CI workflow
runs: runs:
using: composite using: composite
steps: steps:
- uses: actions-rs/toolchain@v1 - uses: dtolnay/rust-toolchain@nightly
with: with:
profile: minimal components: llvm-tools, clippy, rustfmt
toolchain: stable - uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- name: Build docs - name: Build docs
shell: pwsh shell: pwsh

8
.gitignore vendored
View File

@ -6,7 +6,9 @@ vendor
.DS_Store .DS_Store
.env .env
.vscode
*.test
*.tmp *.tmp
*.swp *.swp
*.o *.o
@ -17,6 +19,7 @@ vendor
*.bin *.bin
*.dll *.dll
*.exe *.exe
*.dylib
*.dSYM *.dSYM
*.obj *.obj
@ -31,17 +34,15 @@ callgrind.out.*
perf.data perf.data
perf.data.old perf.data.old
.vscode .vscode/settings.json
test.dict test.dict
.idea/ .idea/
# Ignore all built fuzzers # Ignore all built fuzzers
fuzzer_*
AFLplusplus AFLplusplus
test_* test_*
*_fuzzer *_fuzzer
*_harness
# Ignore common dummy and logfiles # Ignore common dummy and logfiles
*.log *.log
@ -72,6 +73,5 @@ libafl_nyx/packer
# common harness names # common harness names
harness harness
program program
fuzzer
fuzzer_libpng* fuzzer_libpng*
forkserver_simple forkserver_simple

View File

@ -7,3 +7,7 @@ repos:
name: fmt name: fmt
entry: scripts/fmt_all.sh check entry: scripts/fmt_all.sh check
language: script language: script
- repo: https://github.com/ComPWA/taplo-pre-commit
rev: v0.9.3
hooks:
- id: taplo-format

12
.vscode/settings.json.default vendored Normal file
View File

@ -0,0 +1,12 @@
{
"rust-analyzer.cargo.buildScripts.overrideCommand": [
"cargo",
"check",
"--message-format=json",
],
"rust-analyzer.check.overrideCommand": [
"cargo",
"check",
"--message-format=json",
]
}

View File

@ -4,11 +4,13 @@ For bugs, feel free to open issues or contact us directly. Thank you for your su
## Pull Request guideline ## Pull Request guideline
Even though we will gladly assist you in finishing up your PR, try to Even though we will gladly assist you in finishing up your PR, try to:
- keep all the crates compiling with *stable* rust (hide the eventual non-stable code under [`cfg`s](https://github.com/AFLplusplus/LibAFL/blob/main/libafl/build.rs#L26)) - keep all the crates compiling with *stable* rust (hide the eventual non-stable code under [`cfg`s](https://github.com/AFLplusplus/LibAFL/blob/main/libafl/build.rs#L26))
- run `cargo +nightly fmt` on your code before pushing - run `cargo +nightly fmt` on your code before pushing
- check the output of `cargo clippy --all` or `./clippy.sh` - check the output of `cargo clippy --all` or `./scripts/clippy.sh` (On windows use `.\scripts\clippy.ps1`)
- run `cargo build --no-default-features` to check for `no_std` compatibility (and possibly add `#[cfg(feature = "std")]`) to hide parts of your code. - run `cargo build --no-default-features` to check for `no_std` compatibility (and possibly add `#[cfg(feature = "std")]`) to hide parts of your code.
- Please add and describe your changes to MIGRATION.md if you change the APIs.
Some of the parts in this list may be hard, don't be afraid to open a PR if you cannot fix them by yourself, so we can help. Some of the parts in this list may be hard, don't be afraid to open a PR if you cannot fix them by yourself, so we can help.

View File

@ -1,46 +1,164 @@
[workspace] [workspace]
resolver = "2" resolver = "2"
members = [ members = [
"libafl", "libafl",
"libafl_bolts", "libafl_bolts",
"libafl_cc", "libafl_cc",
"libafl_concolic/symcc_runtime", "libafl_concolic/symcc_runtime",
"libafl_concolic/symcc_libafl", "libafl_concolic/symcc_libafl",
"libafl_concolic/test/dump_constraints", "libafl_derive",
"libafl_concolic/test/runtime_test", "libafl_frida",
"libafl_derive", "libafl_intelpt",
"libafl_frida", "libafl_libfuzzer",
"libafl_libfuzzer", "libafl_nyx",
"libafl_nyx", "libafl_targets",
"libafl_qemu", "libafl_tinyinst",
"libafl_sugar", "libafl_qemu",
"libafl_targets", "libafl_qemu/libafl_qemu_build",
"libafl_tinyinst", "libafl_qemu/libafl_qemu_sys",
"utils/build_and_test_fuzzers", "libafl_sugar",
"utils/deexit", "libafl_concolic/test/dump_constraints",
"utils/libafl_benches", "libafl_concolic/test/runtime_test",
"utils/gramatron/construct_automata", "utils/build_and_test_fuzzers",
"utils/deexit",
"utils/drcov_utils",
"utils/gramatron/construct_automata",
"utils/libafl_benches",
"utils/libafl_jumper",
"bindings/pylibafl",
] ]
default-members = [ default-members = [
"libafl", "libafl",
"libafl_bolts", "libafl_bolts",
"libafl_cc", "libafl_cc",
"libafl_derive", "libafl_derive",
"libafl_targets", "libafl_targets",
] ]
exclude = [ exclude = [
"bindings", "fuzzers",
"fuzzers", "libafl_libfuzzer_runtime",
"libafl_qemu/libafl_qemu_build", "utils/noaslr",
"libafl_qemu/libafl_qemu_sys", "utils/gdb_qemu",
"utils/noaslr", "utils/libafl_fmt",
"utils/gdb_qemu", "utils/desyscall",
"utils/libafl_fmt", "utils/multi_machine_generator",
"scripts", "scripts",
# additional crates
"libafl_concolic/test/symcc/util/symcc_fuzzing_helper",
] ]
[workspace.package] [workspace.package]
version = "0.13.0" version = "0.14.1"
license = "MIT OR Apache-2.0"
[workspace.dependencies]
# Internal deps
libafl = { path = "./libafl", version = "0.14.1", default-features = false }
libafl_bolts = { path = "./libafl_bolts", version = "0.14.1", default-features = false }
libafl_cc = { path = "./libafl_cc", version = "0.14.1", default-features = false }
symcc_runtime = { path = "./libafl_concolic/symcc_runtime", version = "0.14.1", default-features = false }
symcc_libafl = { path = "./libafl_concolic/symcc_libafl", version = "0.14.1", default-features = false }
libafl_derive = { path = "./libafl_derive", version = "0.14.1", default-features = false }
libafl_frida = { path = "./libafl_frida", version = "0.14.1", default-features = false }
libafl_intelpt = { path = "./libafl_intelpt", version = "0.14.1", default-features = false }
libafl_libfuzzer = { path = "./libafl_libfuzzer", version = "0.14.1", default-features = false }
libafl_nyx = { path = "./libafl_nyx", version = "0.14.1", default-features = false }
libafl_targets = { path = "./libafl_targets", version = "0.14.1", default-features = false }
libafl_tinyinst = { path = "./libafl_tinyinst", version = "0.14.1", default-features = false }
libafl_qemu = { path = "./libafl_qemu", version = "0.14.1", default-features = false }
libafl_qemu_build = { path = "./libafl_qemu/libafl_qemu_build", version = "0.14.1", default-features = false }
libafl_qemu_sys = { path = "./libafl_qemu/libafl_qemu_sys", version = "0.14.1", default-features = false }
libafl_sugar = { path = "./libafl_sugar", version = "0.14.1", default-features = false }
dump_constraints = { path = "./libafl_concolic/test/dump_constraints", version = "0.14.1", default-features = false }
runtime_test = { path = "./libafl_concolic/test/runtime_test", version = "0.14.1", default-features = false }
build_and_test_fuzzers = { path = "./utils/build_and_test_fuzzers", version = "0.14.1", default-features = false }
deexit = { path = "./utils/deexit", version = "0.14.1", default-features = false }
drcov_utils = { path = "./utils/drcov_utils", version = "0.14.1", default-features = false }
construct_automata = { path = "./utils/gramatron/construct_automata", version = "0.14.1", default-features = false }
libafl_benches = { path = "./utils/libafl_benches", version = "0.14.1", default-features = false }
libafl_jumper = { path = "./utils/libafl_jumper", version = "0.14.1", default-features = false }
# External deps
ahash = { version = "0.8.11", default-features = false } # The hash function already used in hashbrown
arbitrary-int = "1.2.7" # arbitrary sized integers, useful in combination with bitfields (bitbybit crate)
backtrace = { version = "0.3.74", default-features = false } # Used to get the stacktrace in StacktraceObserver
bindgen = "0.70.1"
bitbybit = "1.3.2" # bitfields, use this for bit fields and bit enums
clap = "4.5.18"
cc = "1.1.21"
cmake = "0.1.51"
document-features = "0.2.10"
hashbrown = { version = "0.14.5", default-features = false } # A faster hashmap, nostd compatible
libc = "0.2.159" # For (*nix) libc
libipt = "0.2.0"
log = "0.4.22"
meminterval = "0.4.1"
mimalloc = { version = "0.1.43", default-features = false }
nix = { version = "0.29.0", default-features = false }
num_enum = { version = "0.7.3", default-features = false }
num-traits = { version = "0.2.19", default-features = false }
paste = "1.0.15"
postcard = { version = "1.0.10", features = [
"alloc",
], default-features = false } # no_std compatible serde serialization format
pyo3 = "0.23.2"
pyo3-build-config = "0.23.2"
rangemap = "1.5.1"
regex = "1.10.6"
rustversion = "1.0.17"
serde = { version = "1.0.210", default-features = false } # serialization lib
serial_test = { version = "3.1.1", default-features = false }
serde_json = { version = "1.0.128", default-features = false }
serde_yaml = { version = "0.9.34" } # For parsing the injections yaml file
static_assertions = "1.1.0"
strum = "0.26.3"
strum_macros = "0.26.4"
toml = "0.8.19" # For parsing the injections toml file
typed-builder = "0.20.0" # Implement the builder pattern at compiletime
uuid = { version = "1.10.0", features = ["serde", "v4"] }
which = "6.0.3"
windows = "0.58.0"
z3 = "0.12.1"
[workspace.lints.rust]
# Forbid
unexpected_cfgs = "forbid"
# Allow
incomplete_features = "allow"
ambiguous_glob_reexports = "allow"
[workspace.lints.clippy]
# Deny
all = { level = "deny", priority = -1 }
pedantic = { level = "deny", priority = -1 }
cargo_common_metadata = "deny"
# Warn
cargo = { level = "warn", priority = -1 }
negative_feature_names = "warn"
# Allow
unreadable_literal = "allow"
type_repetition_in_bounds = "allow"
missing_errors_doc = "allow"
cast_possible_truncation = "allow"
used_underscore_binding = "allow"
ptr_as_ptr = "allow"
missing_panics_doc = "allow"
module_name_repetitions = "allow"
unsafe_derive_deserialize = "allow"
similar_names = "allow"
too_many_lines = "allow"
[workspace.lints.rustdoc]
# Deny
broken_intra_doc_links = "deny"
[profile.release] [profile.release]
lto = true lto = true

View File

@ -3,8 +3,10 @@ FROM rust:1.76.0 AS libafl
LABEL "maintainer"="afl++ team <afl@aflplus.plus>" LABEL "maintainer"="afl++ team <afl@aflplus.plus>"
LABEL "about"="LibAFL Docker image" LABEL "about"="LibAFL Docker image"
# Install cargo-binstall to download the sccache build
RUN curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
# install sccache to cache subsequent builds of dependencies # install sccache to cache subsequent builds of dependencies
RUN cargo install --locked sccache RUN cargo binstall --no-confirm sccache
ENV HOME=/root ENV HOME=/root
ENV SCCACHE_CACHE_SIZE="1G" ENV SCCACHE_CACHE_SIZE="1G"
@ -22,12 +24,11 @@ RUN rustup component add rustfmt clippy
# Install clang 18, common build tools # Install clang 18, common build tools
ENV LLVM_VERSION=18 ENV LLVM_VERSION=18
RUN apt update && apt install -y build-essential gdb git wget python3-venv ninja-build lsb-release software-properties-common gnupg cmake RUN apt update && apt install -y build-essential gdb git wget python3-venv ninja-build lsb-release software-properties-common gnupg cmake
# Workaround until https://github.com/llvm/llvm-project/issues/62475 is resolved
RUN set -ex &&\ RUN set -ex &&\
echo "deb http://apt.llvm.org/bookworm/ llvm-toolchain-bookworm-${LLVM_VERSION} main" > /etc/apt/sources.list.d/apt.llvm.org.list &&\ wget https://apt.llvm.org/llvm.sh &&\
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc &&\ chmod +x llvm.sh &&\
apt update &&\ ./llvm.sh ${LLVM_VERSION}
apt-get install -y clang-${LLVM_VERSION} lldb-${LLVM_VERSION} lld-${LLVM_VERSION} clangd-${LLVM_VERSION} clang-tidy-${LLVM_VERSION} clang-format-${LLVM_VERSION} clang-tools-${LLVM_VERSION} llvm-${LLVM_VERSION}-dev lld-${LLVM_VERSION} lldb-${LLVM_VERSION} llvm-${LLVM_VERSION}-tools libomp-${LLVM_VERSION}-dev libc++-${LLVM_VERSION}-dev libc++abi-${LLVM_VERSION}-dev libclang-common-${LLVM_VERSION}-dev libclang-${LLVM_VERSION}-dev libclang-cpp${LLVM_VERSION}-dev libunwind-${LLVM_VERSION}-dev libclang-rt-${LLVM_VERSION}-dev libpolly-${LLVM_VERSION}-dev
# Copy a dummy.rs and Cargo.toml first, so that dependencies are cached # Copy a dummy.rs and Cargo.toml first, so that dependencies are cached
WORKDIR /libafl WORKDIR /libafl
@ -39,6 +40,10 @@ COPY scripts/dummy.rs libafl_derive/src/lib.rs
COPY libafl/Cargo.toml libafl/build.rs libafl/README.md libafl/ COPY libafl/Cargo.toml libafl/build.rs libafl/README.md libafl/
COPY scripts/dummy.rs libafl/src/lib.rs COPY scripts/dummy.rs libafl/src/lib.rs
# Set up LLVM aliases
COPY scripts/createAliases.sh libafl/
RUN bash libafl/createAliases.sh ${LLVM_VERSION}
COPY libafl_bolts/Cargo.toml libafl_bolts/build.rs libafl_bolts/README.md libafl_bolts/ COPY libafl_bolts/Cargo.toml libafl_bolts/build.rs libafl_bolts/README.md libafl_bolts/
COPY libafl_bolts/examples libafl_bolts/examples COPY libafl_bolts/examples libafl_bolts/examples
COPY scripts/dummy.rs libafl_bolts/src/lib.rs COPY scripts/dummy.rs libafl_bolts/src/lib.rs
@ -47,6 +52,9 @@ COPY libafl_frida/Cargo.toml libafl_frida/build.rs libafl_frida/
COPY scripts/dummy.rs libafl_frida/src/lib.rs COPY scripts/dummy.rs libafl_frida/src/lib.rs
COPY libafl_frida/src/gettls.c libafl_frida/src/gettls.c COPY libafl_frida/src/gettls.c libafl_frida/src/gettls.c
COPY libafl_intelpt/Cargo.toml libafl_intelpt/README.md libafl_intelpt/
COPY scripts/dummy.rs libafl_intelpt/src/lib.rs
COPY libafl_qemu/Cargo.toml libafl_qemu/build.rs libafl_qemu/build_linux.rs libafl_qemu/ COPY libafl_qemu/Cargo.toml libafl_qemu/build.rs libafl_qemu/build_linux.rs libafl_qemu/
COPY scripts/dummy.rs libafl_qemu/src/lib.rs COPY scripts/dummy.rs libafl_qemu/src/lib.rs
@ -59,6 +67,9 @@ COPY scripts/dummy.rs libafl_qemu/libafl_qemu_sys/src/lib.rs
COPY libafl_sugar/Cargo.toml libafl_sugar/ COPY libafl_sugar/Cargo.toml libafl_sugar/
COPY scripts/dummy.rs libafl_sugar/src/lib.rs COPY scripts/dummy.rs libafl_sugar/src/lib.rs
COPY bindings/pylibafl/Cargo.toml bindings/pylibafl/Cargo.toml
COPY bindings/pylibafl/src bindings/pylibafl/src
COPY libafl_cc/Cargo.toml libafl_cc/Cargo.toml COPY libafl_cc/Cargo.toml libafl_cc/Cargo.toml
COPY libafl_cc/build.rs libafl_cc/build.rs COPY libafl_cc/build.rs libafl_cc/build.rs
COPY libafl_cc/src libafl_cc/src COPY libafl_cc/src libafl_cc/src
@ -131,10 +142,13 @@ COPY libafl_concolic/symcc_runtime libafl_concolic/symcc_runtime
COPY libafl_concolic/test libafl_concolic/test COPY libafl_concolic/test libafl_concolic/test
COPY libafl_nyx/src libafl_nyx/src COPY libafl_nyx/src libafl_nyx/src
RUN touch libafl_nyx/src/lib.rs RUN touch libafl_nyx/src/lib.rs
COPY libafl_libfuzzer_runtime libafl_libfuzzer_runtime
COPY libafl_libfuzzer/src libafl_libfuzzer/src COPY libafl_libfuzzer/src libafl_libfuzzer/src
COPY libafl_libfuzzer/libafl_libfuzzer_runtime libafl_libfuzzer/libafl_libfuzzer_runtime COPY libafl_libfuzzer/runtime libafl_libfuzzer/runtime
COPY libafl_libfuzzer/build.rs libafl_libfuzzer/build.rs COPY libafl_libfuzzer/build.rs libafl_libfuzzer/build.rs
RUN touch libafl_libfuzzer/src/lib.rs RUN touch libafl_libfuzzer/src/lib.rs
COPY libafl_intelpt/src libafl_intelpt/src
RUN touch libafl_intelpt/src/lib.rs
RUN cargo build && cargo build --release RUN cargo build && cargo build --release
# Copy fuzzers over # Copy fuzzers over

6
MIGRATION.md Normal file
View File

@ -0,0 +1,6 @@
# Pre 0.9 -> 0.9
- [Migrating from LibAFL <0.9 to 0.9](https://aflplus.plus/libafl-book/design/migration-0.9.html)
# 0.14.0 -> 0.14.1
- Removed `with_observers` from `Executor` trait.
- `MmapShMemProvider::new_shmem_persistent` has been removed in favour of `MmapShMem::persist`. You probably want to do something like this: `let shmem = MmapShMemProvider::new()?.new_shmem(size)?.persist()?;`

119
README.md
View File

@ -4,17 +4,7 @@
Advanced Fuzzing Library - Slot your own fuzzers together and extend their features using Rust. Advanced Fuzzing Library - Slot your own fuzzers together and extend their features using Rust.
LibAFL is written and maintained by LibAFL is a collection of reusable pieces of fuzzers, written in Rust, it gives you many of the benefits of an off-the-shelf fuzzer, while being completely customizable.
* [Andrea Fioraldi](https://twitter.com/andreafioraldi) <andrea@aflplus.plus>
* [Dominik Maier](https://twitter.com/domenuk) <dominik@aflplus.plus>
* [s1341](https://twitter.com/srubenst1341) <github@shmarya.net>
* [Dongjia Zhang](https://github.com/tokatoka) <toka@aflplus.plus>
* [Addison Crump](https://github.com/addisoncrump) <me@addisoncrump.info>
## Why LibAFL?
LibAFL gives you many of the benefits of an off-the-shelf fuzzer, while being completely customizable.
Some highlight features currently include: Some highlight features currently include:
- `fast`: We do everything we can at compile time, keeping runtime overhead minimal. Users reach 120k execs/sec in frida-mode on a phone (using all cores). - `fast`: We do everything we can at compile time, keeping runtime overhead minimal. Users reach 120k execs/sec in frida-mode on a phone (using all cores).
- `scalable`: `Low Level Message Passing`, `LLMP` for short, allows LibAFL to scale almost linearly over cores, and via TCP to multiple machines. - `scalable`: `Low Level Message Passing`, `LLMP` for short, allows LibAFL to scale almost linearly over cores, and via TCP to multiple machines.
@ -23,103 +13,74 @@ feel free to add an AST-based input for structured fuzzing, and more.
- `multi platform`: LibAFL was confirmed to work on *Windows*, *MacOS*, *Linux*, and *Android* on *x86_64* and *aarch64*. `LibAFL` can be built in `no_std` mode to inject LibAFL into obscure targets like embedded devices and hypervisors. - `multi platform`: LibAFL was confirmed to work on *Windows*, *MacOS*, *Linux*, and *Android* on *x86_64* and *aarch64*. `LibAFL` can be built in `no_std` mode to inject LibAFL into obscure targets like embedded devices and hypervisors.
- `bring your own target`: We support binary-only modes, like Frida-Mode, as well as multiple compilation passes for sourced-based instrumentation. Of course it's easy to add custom instrumentation backends. - `bring your own target`: We support binary-only modes, like Frida-Mode, as well as multiple compilation passes for sourced-based instrumentation. Of course it's easy to add custom instrumentation backends.
## Overview ## Core concepts
LibAFL is a collection of reusable pieces of fuzzers, written in Rust. LibAFL is fast, multi-platform, no_std compatible, and scales over cores and machines. It offers a main crate that provide building blocks for custom fuzzers, [libafl](./libafl), a library containing common code that can be used for targets instrumentation, [libafl_targets](./libafl_targets), and a library providing facilities to wrap compilers, [libafl_cc](./libafl_cc). It offers integrations with popular instrumentation frameworks. At the moment, the supported backends are:
It is fast, multi-platform, no_std compatible, and scales over cores and machines. + `SanitizerCoverage`, in [libafl_targets](./libafl_targets)
+ `Frida`, in [libafl_frida](./libafl_frida)
+ `QEMU` user-mode and system mode, including hooks for emulation, in [libafl_qemu](./libafl_qemu)
+ `TinyInst`, in [libafl_tinyinst](./libafl_tinyinst) by [elbiazo](https://github.com/elbiazo)
It offers a main crate that provide building blocks for custom fuzzers, [libafl](./libafl), a library containing common code that can be used for targets instrumentation, [libafl_targets](./libafl_targets), and a library providing facilities to wrap compilers, [libafl_cc](./libafl_cc). ## Building and installing
LibAFL offers integrations with popular instrumentation frameworks. At the moment, the supported backends are: #### Install the Dependencies
- **The Rust development language**
+ SanitizerCoverage, in [libafl_targets](./libafl_targets) - We highly recommend *not* to use e.g. your Linux distribution package as this is likely outdated. So rather install Rust directly, instructions can be found [here](https://www.rust-lang.org/tools/install).
+ Frida, in [libafl_frida](./libafl_frida) - **LLVM tools**
+ QEMU user-mode and system mode, including hooks for emulation, in [libafl_qemu](./libafl_qemu) - The LLVM tools (including clang, clang++) are needed (newer than LLVM 15.0.0 up to LLVM 18.1.3) If you are using Debian/Ubuntu, again, we highly recommmend that you install the package from [here](https://apt.llvm.org/)
+ TinyInst, in [libafl_tinyinst](./libafl_tinyinst) by [elbiazo](https://github.com/elbiazo) - (In `libafl_concolic`, we only support LLVM version newer than 18)
- Cargo-make:
## Getting started - We use cargo-make to build the fuzzers in `fuzzers/` directory. You can install it with `cargo install cargo-make`
1. Install the Dependecies
- The Rust development language.
We highly recommend *not* to use e.g. your Linux distribition package as this is likely outdated. So rather install
Rust directly, instructions can be found [here](https://www.rust-lang.org/tools/install).
- LLVM tools
The LLVM tools (including clang, clang++) are needed (newer than LLVM 15.0.0 up to LLVM 18.1.3)
If you are using Debian/Ubuntu, again, we highly recommmend that you install the package from [here](https://apt.llvm.org/)
(In `libafl_concolic`, we only support LLVM version newer than 18)
- Cargo-make
We use cargo-make to build the fuzzers in `fuzzers/` directory. You can install it with
```sh
cargo install cargo-make
```
2. Clone the LibAFL repository with
#### Clone the LibAFL repository with
```sh ```sh
git clone https://github.com/AFLplusplus/LibAFL git clone https://github.com/AFLplusplus/LibAFL
``` ```
#### Build the library using
3. Build the library using
```sh ```sh
cargo build --release cargo build --release
``` ```
#### Build the API documentation with
4. Build the API documentation with
```sh ```sh
cargo doc cargo doc
``` ```
#### Browse the LibAFL book (WIP!) with (requires [mdbook](https://rust-lang.github.io/mdBook/index.html))
5. Browse the LibAFL book (WIP!) with (requires [mdbook](https://rust-lang.github.io/mdBook/index.html))
```sh ```sh
cd docs && mdbook serve cd docs && mdbook serve
``` ```
## Getting started
We collect all example fuzzers in [`./fuzzers`](./fuzzers/). We collect all example fuzzers in [`./fuzzers`](./fuzzers/).
Be sure to read their documentation (and source), this is *the natural way to get started!* Be sure to read their documentation (and source), this is *the natural way to get started!*
You can run each example fuzzer with
```sh ```sh
cargo make run cargo make run
``` ```
You can run each example fuzzer with this following command, as long as the fuzzer directory has `Makefile.toml` file. The best-tested fuzzer is [`./fuzzers/inprocess/libfuzzer_libpng`](./fuzzers/inprocess/libfuzzer_libpng), a multicore libfuzzer-like fuzzer using LibAFL for a libpng harness.
as long as the fuzzer directory has `Makefile.toml` file. ### Resources
- [Installation guide](./docs/src/getting_started/setup.md)
- [Online API documentation](https://docs.rs/libafl/)
- The LibAFL book (WIP) [online](https://aflplus.plus/libafl-book) or in the [repo](./docs/src/)
- Our research [paper](https://www.s3.eurecom.fr/docs/ccs22_fioraldi.pdf)
- Our RC3 [talk](http://www.youtube.com/watch?v=3RWkT1Q5IV0 "Fuzzers Like LEGO") explaining the core concepts
- Our Fuzzcon Europe [talk](https://www.youtube.com/watch?v=PWB8GIhFAaI "LibAFL: The Advanced Fuzzing Library") with a (a bit but not so much outdated) step-by-step discussion on how to build some example fuzzers
- The Fuzzing101 [solutions](https://github.com/epi052/fuzzing-101-solutions) & series of [blog posts](https://epi052.gitlab.io/notes-to-self/blog/2021-11-01-fuzzing-101-with-libafl/) by [epi](https://github.com/epi052)
- Blogpost on binary-only fuzzing lib libaf_qemu, [Hacking TMNF - Fuzzing the game server](https://blog.bricked.tech/posts/tmnf/part1/), by [RickdeJager](https://github.com/RickdeJager).
- [A LibAFL Introductory Workshop](https://www.atredis.com/blog/2023/12/4/a-libafl-introductory-workshop), by [Jordan Whitehead](https://github.com/jordan9001)
The best-tested fuzzer is [`./fuzzers/libfuzzer_libpng`](./fuzzers/libfuzzer_libpng), a multicore libfuzzer-like fuzzer using LibAFL for a libpng harness. ## Contributors
## Resources LibAFL is written and maintained by
+ [Installation guide](./docs/src/getting_started/setup.md) * [Andrea Fioraldi](https://twitter.com/andreafioraldi) <andrea@aflplus.plus>
* [Dominik Maier](https://twitter.com/domenuk) <dominik@aflplus.plus>
+ [Online API documentation](https://docs.rs/libafl/) * [s1341](https://twitter.com/srubenst1341) <github@shmarya.net>
* [Dongjia Zhang](https://github.com/tokatoka) <toka@aflplus.plus>
+ The LibAFL book (WIP) [online](https://aflplus.plus/libafl-book) or in the [repo](./docs/src/) * [Addison Crump](https://github.com/addisoncrump) <me@addisoncrump.info>
* [Romain Malmain](https://github.com/rmalmain) <rmalmain@pm.me>
+ Our research [paper](https://www.s3.eurecom.fr/docs/ccs22_fioraldi.pdf)
+ Our RC3 [talk](http://www.youtube.com/watch?v=3RWkT1Q5IV0 "Fuzzers Like LEGO") explaining the core concepts
+ Our Fuzzcon Europe [talk](https://www.youtube.com/watch?v=PWB8GIhFAaI "LibAFL: The Advanced Fuzzing Library") with a (a bit but not so much outdated) step-by-step discussion on how to build some example fuzzers
+ The Fuzzing101 [solutions](https://github.com/epi052/fuzzing-101-solutions) & series of [blog posts](https://epi052.gitlab.io/notes-to-self/blog/2021-11-01-fuzzing-101-with-libafl/) by [epi](https://github.com/epi052)
+ Blogpost on binary-only fuzzing lib libaf_qemu, [Hacking TMNF - Fuzzing the game server](https://blog.bricked.tech/posts/tmnf/part1/), by [RickdeJager](https://github.com/RickdeJager).
+ [A LibAFL Introductory Workshop](https://www.atredis.com/blog/2023/12/4/a-libafl-introductory-workshop), by [Jordan Whitehead](https://github.com/jordan9001)
## Contributing
Please check out [CONTRIBUTING.md](CONTRIBUTING.md) for the contributing guideline. Please check out [CONTRIBUTING.md](CONTRIBUTING.md) for the contributing guideline.
## Cite ## Cite
If you use LibAFL for your academic work, please cite the following paper: If you use LibAFL for your academic work, please cite the following paper:
```bibtex ```bibtex

View File

@ -1,19 +1,30 @@
[package] [package]
name = "pylibafl" name = "pylibafl"
version = "0.13.0" description = "Python bindings for LibAFL"
version = "0.14.1"
license = "MIT OR Apache-2.0"
repository = "https://github.com/AFLplusplus/LibAFL/"
keywords = ["fuzzing", "testing", "security", "python"]
edition = "2021" edition = "2021"
categories = ["development-tools::testing", "emulators", "embedded", "os"]
[dependencies] [dependencies]
pyo3 = { version = "0.18.3", features = ["extension-module"] } pyo3 = { workspace = true, features = ["extension-module"] }
pyo3-log = "0.8.1" pyo3-log = { version = "0.12.0" }
libafl_sugar = { path = "../../libafl_sugar", version = "0.13.0", features = ["python"] } libafl_sugar = { path = "../../libafl_sugar", version = "0.14.1", features = [
libafl_bolts = { path = "../../libafl_bolts", version = "0.13.0", features = ["python"] } "python",
] }
libafl_bolts = { path = "../../libafl_bolts", version = "0.14.1", features = [
"python",
] }
[target.'cfg(target_os = "linux")'.dependencies] [target.'cfg(target_os = "linux")'.dependencies]
libafl_qemu = { path = "../../libafl_qemu", version = "0.13.0", features = ["python"] } libafl_qemu = { path = "../../libafl_qemu", version = "0.14.1", features = [
"python",
] }
[build-dependencies] [build-dependencies]
pyo3-build-config = { version = "0.17" } pyo3-build-config = { workspace = true }
[lib] [lib]
name = "pylibafl" name = "pylibafl"

View File

@ -4,16 +4,16 @@ build-backend = "maturin"
[project] [project]
name = "PyLibAFL" name = "PyLibAFL"
version = "0.10.1" version = "0.14.1"
description = "Advanced Fuzzing Library for Python" description = "Advanced Fuzzing Library for Python"
readme = "README.md" readme = "README.md"
requires-python = ">=3.8" requires-python = ">=3.8"
license = {text = "Apache-2.0"} license = { text = "Apache-2.0" }
classifiers = [ classifiers = [
"License :: OSI Approved :: Apache Software License", "License :: OSI Approved :: Apache Software License",
"License :: OSI Approved :: MIT License", "License :: OSI Approved :: MIT License",
"Programming Language :: Rust", "Programming Language :: Rust",
"Topic :: Security", "Topic :: Security",
] ]
[project.urls] [project.urls]

View File

@ -6,27 +6,27 @@ use pyo3::prelude::*;
/// Returns error if python libafl setup failed. /// Returns error if python libafl setup failed.
#[pymodule] #[pymodule]
#[pyo3(name = "pylibafl")] #[pyo3(name = "pylibafl")]
pub fn python_module(py: Python, m: &PyModule) -> PyResult<()> { pub fn python_module(m: &Bound<'_, PyModule>) -> PyResult<()> {
pyo3_log::init(); pyo3_log::init();
let modules = py.import("sys")?.getattr("modules")?; let modules = m.py().import("sys")?.getattr("modules")?;
let sugar_module = PyModule::new(py, "sugar")?; let sugar_module = PyModule::new(m.py(), "sugar")?;
libafl_sugar::python_module(py, sugar_module)?; libafl_sugar::python_module(&sugar_module)?;
m.add_submodule(sugar_module)?; m.add_submodule(&sugar_module)?;
modules.set_item("pylibafl.sugar", sugar_module)?; modules.set_item("pylibafl.sugar", sugar_module)?;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
{ {
let qemu_module = PyModule::new(py, "qemu")?; let qemu_module = PyModule::new(m.py(), "qemu")?;
libafl_qemu::python_module(py, qemu_module)?; libafl_qemu::python_module(&qemu_module)?;
m.add_submodule(qemu_module)?; m.add_submodule(&qemu_module)?;
modules.set_item("pylibafl.qemu", qemu_module)?; modules.set_item("pylibafl.qemu", qemu_module)?;
} }
let bolts_module = PyModule::new(py, "libafl_bolts")?; let bolts_module = PyModule::new(m.py(), "libafl_bolts")?;
libafl_bolts::pybind::python_module(py, bolts_module)?; libafl_bolts::pybind::python_module(&bolts_module)?;
m.add_submodule(bolts_module)?; m.add_submodule(&bolts_module)?;
modules.set_item("pylibafl.libafl_bolts", bolts_module)?; modules.set_item("pylibafl.libafl_bolts", bolts_module)?;
Ok(()) Ok(())

View File

@ -3,5 +3,7 @@ import ctypes
import platform import platform
print("Starting to fuzz from python!") print("Starting to fuzz from python!")
fuzzer = sugar.InMemoryBytesCoverageSugar(input_dirs=["./in"], output_dir="out", broker_port=1337, cores=[0,1]) fuzzer = sugar.InMemoryBytesCoverageSugar(
input_dirs=["./in"], output_dir="out", broker_port=1337, cores=[0, 1]
)
fuzzer.run(lambda b: print("foo")) fuzzer.run(lambda b: print("foo"))

View File

@ -1,6 +1,6 @@
[package] [package]
name = "baby_fuzzer_listing_01" name = "baby_fuzzer_listing_01"
version = "0.1.0" version = "0.14.1"
authors = ["Your Name <you@example.com>"] authors = ["Your Name <you@example.com>"]
edition = "2018" edition = "2018"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "baby_fuzzer_listing_02" name = "baby_fuzzer_listing_02"
version = "0.1.0" version = "0.14.1"
authors = ["Your Name <you@example.com>"] authors = ["Your Name <you@example.com>"]
edition = "2018" edition = "2018"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "baby_fuzzer_listing_03" name = "baby_fuzzer_listing_03"
version = "0.1.0" version = "0.14.1"
authors = ["Your Name <you@example.com>"] authors = ["Your Name <you@example.com>"]
edition = "2018" edition = "2018"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "baby_fuzzer_listing_04" name = "baby_fuzzer_listing_04"
version = "0.1.0" version = "0.14.1"
authors = ["Your Name <you@example.com>"] authors = ["Your Name <you@example.com>"]
edition = "2018" edition = "2018"

View File

@ -3,7 +3,6 @@ extern crate libafl;
extern crate libafl_bolts; extern crate libafl_bolts;
use std::path::PathBuf; use std::path::PathBuf;
use libafl::{ use libafl::{
corpus::{InMemoryCorpus, OnDiskCorpus}, corpus::{InMemoryCorpus, OnDiskCorpus},
events::SimpleEventManager, events::SimpleEventManager,
@ -15,7 +14,7 @@ use libafl::{
schedulers::QueueScheduler, schedulers::QueueScheduler,
state::StdState, state::StdState,
}; };
use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice}; use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice, nonzero};
/* ANCHOR_END: use */ /* ANCHOR_END: use */
fn main() { fn main() {
@ -77,7 +76,7 @@ fn main() {
/* ANCHOR: generator */ /* ANCHOR: generator */
// Generator of printable bytearrays of max size 32 // Generator of printable bytearrays of max size 32
let mut generator = RandPrintablesGenerator::new(32); let mut generator = RandPrintablesGenerator::new(nonzero!(32));
// Generate 8 initial inputs // Generate 8 initial inputs
state state

View File

@ -1,6 +1,6 @@
[package] [package]
name = "baby_fuzzer_listing_05" name = "baby_fuzzer_listing_05"
version = "0.1.0" version = "0.14.1"
authors = ["Your Name <you@example.com>"] authors = ["Your Name <you@example.com>"]
edition = "2018" edition = "2018"

View File

@ -15,7 +15,7 @@ use libafl::{
schedulers::QueueScheduler, schedulers::QueueScheduler,
state::StdState, state::StdState,
}; };
use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice}; use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice, nonzero};
use std::path::PathBuf; use std::path::PathBuf;
/* ANCHOR_END: use */ /* ANCHOR_END: use */
@ -105,7 +105,7 @@ fn main() {
/* ANCHOR_END: executor_with_observer */ /* ANCHOR_END: executor_with_observer */
// Generator of printable bytearrays of max size 32 // Generator of printable bytearrays of max size 32
let mut generator = RandPrintablesGenerator::new(32); let mut generator = RandPrintablesGenerator::new(nonzero!(32));
// Generate 8 initial inputs // Generate 8 initial inputs
state state

View File

@ -1,6 +1,6 @@
[package] [package]
name = "baby_fuzzer_listing_06" name = "baby_fuzzer_listing_06"
version = "0.1.0" version = "0.14.1"
authors = ["Your Name <you@example.com>"] authors = ["Your Name <you@example.com>"]
edition = "2018" edition = "2018"

View File

@ -1,6 +1,7 @@
/* ANCHOR: use */ /* ANCHOR: use */
extern crate libafl; extern crate libafl;
extern crate libafl_bolts; extern crate libafl_bolts;
use std::num::NonZeroUsize;
use libafl::{ use libafl::{
corpus::{InMemoryCorpus, OnDiskCorpus}, corpus::{InMemoryCorpus, OnDiskCorpus},
@ -17,7 +18,7 @@ use libafl::{
stages::mutational::StdMutationalStage, stages::mutational::StdMutationalStage,
state::StdState, state::StdState,
}; };
use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice}; use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice, nonzero};
use std::path::PathBuf; use std::path::PathBuf;
/* ANCHOR_END: use */ /* ANCHOR_END: use */
@ -97,7 +98,7 @@ fn main() {
.expect("Failed to create the Executor"); .expect("Failed to create the Executor");
// Generator of printable bytearrays of max size 32 // Generator of printable bytearrays of max size 32
let mut generator = RandPrintablesGenerator::new(32); let mut generator = RandPrintablesGenerator::new(nonzero!(32));
// Generate 8 initial inputs // Generate 8 initial inputs
state state

View File

@ -20,7 +20,7 @@ Try running the fuzzer with the `introspection` feature of the `libafl`. This wi
``` ```
let map = StdMapObserver::from_mut_ptr("edges", EDGES_MAP.as_mut_ptr(), EDGES_MAP.len()); let map = StdMapObserver::from_mut_ptr("edges", EDGES_MAP.as_mut_ptr(), EDGES_MAP.len());
``` ```
You should *never* use the `EDGES_MAP`'s size as this is just the size of the allocated size of the coverage map. Consider using something smaller or our default value `libafl_targets::LIBAFL_EDGES_MAP_SIZE_IN_USE`. You should *never* use the `EDGES_MAP`'s size as this is just the size of the allocated size of the coverage map. Consider using something smaller or our default value `libafl_targets::LIBAFL_EDGES_MAP_DEFAULT_SIZE`.
## Q. I still have problems with my fuzzer. ## Q. I still have problems with my fuzzer.
Finally, if you really have no idea what is going on, run your fuzzer with logging enabled. (You can use `env_logger`, `SimpleStdoutLogger`, `SimpleStderrLogger` from `libafl_bolts`. `fuzzbench_text` has an example to show how to use it.) (Don't forget to enable stdout and stderr), and you can open an issue or ask us in Discord. Finally, if you really have no idea what is going on, run your fuzzer with logging enabled. (You can use `env_logger`, `SimpleStdoutLogger`, `SimpleStderrLogger` from `libafl_bolts`. `fuzzbench_text` has an example to show how to use it.) (Don't forget to enable stdout and stderr), and you can open an issue or ask us in Discord.

View File

@ -115,7 +115,7 @@ The `symcc_runtime` crate supports this use case and runtimes built with `symcc_
## Hybrid Fuzzing in LibAFL ## Hybrid Fuzzing in LibAFL
The LibAFL repository contains an [example hybrid fuzzer](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/libfuzzer_stb_image_concolic). The LibAFL repository contains an [example hybrid fuzzer](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/structure_aware/libfuzzer_stb_image_concolic).
There are three main steps involved with building a hybrid fuzzer using LibAFL: There are three main steps involved with building a hybrid fuzzer using LibAFL:
@ -130,7 +130,7 @@ For example, we need to have a runtime ready before we can do instrumentation wi
Building a custom runtime can be done easily using the `symcc_runtime` crate. Building a custom runtime can be done easily using the `symcc_runtime` crate.
Note, that a custom runtime is a separate shared object file, which means that we need a separate crate for our runtime. Note, that a custom runtime is a separate shared object file, which means that we need a separate crate for our runtime.
Check out the [example hybrid fuzzer's runtime](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/libfuzzer_stb_image_concolic/runtime) and the [`symcc_runtime` docs](https://docs.rs/symcc_runtime/0.1/symcc_runtime) for inspiration. Check out the [example hybrid fuzzer's runtime](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/structure_aware/libfuzzer_stb_image_concolic/runtime) and the [`symcc_runtime` docs](https://docs.rs/symcc_runtime/0.1/symcc_runtime) for inspiration.
### Instrumentation ### Instrumentation
@ -151,7 +151,7 @@ How exactly this is done does not matter.
However, the SymCC compiler needs to be made aware of the location of the runtime that it should instrument against. However, the SymCC compiler needs to be made aware of the location of the runtime that it should instrument against.
This is done by setting the `SYMCC_RUNTIME_DIR` environment variable to the directory which contains the runtime (typically the `target/(debug|release)` folder of your runtime crate). This is done by setting the `SYMCC_RUNTIME_DIR` environment variable to the directory which contains the runtime (typically the `target/(debug|release)` folder of your runtime crate).
The example hybrid fuzzer instruments the target in its [`build.rs` build script](https://github.com/AFLplusplus/LibAFL/blob/main/fuzzers/libfuzzer_stb_image_concolic/fuzzer/build.rs#L50). The example hybrid fuzzer instruments the target in its [`build.rs` build script](https://github.com/AFLplusplus/LibAFL/blob/main/fuzzers/structure_aware/libfuzzer_stb_image_concolic/fuzzer/build.rs#L50).
It does this by cloning and building a copy of SymCC and then using this version to instrument the target. It does this by cloning and building a copy of SymCC and then using this version to instrument the target.
The [`symcc_libafl` crate](https://docs.rs/symcc_libafl) contains helper functions for cloning and building SymCC. The [`symcc_libafl` crate](https://docs.rs/symcc_libafl) contains helper functions for cloning and building SymCC.
@ -169,7 +169,7 @@ No matter the instrumentation method, the interface between the fuzzer and the i
The only difference between using SymCC and SymQEMU should be the binary that represents the target: The only difference between using SymCC and SymQEMU should be the binary that represents the target:
In the case of SymCC it will be the binary that was build with instrumentation and with SymQEMU it will be the emulator binary (eg. `x86_64-linux-user/symqemu-x86_64`), followed by your uninstrumented target binary and its arguments. In the case of SymCC it will be the binary that was build with instrumentation and with SymQEMU it will be the emulator binary (eg. `x86_64-linux-user/symqemu-x86_64`), followed by your uninstrumented target binary and its arguments.
You can use the [`CommandExecutor`](https://docs.rs/libafl/latest/libafl/executors/command/struct.CommandExecutor.html) to execute your target ([example](https://github.com/AFLplusplus/LibAFL/blob/main/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs#L244)). You can use the [`CommandExecutor`](https://docs.rs/libafl/latest/libafl/executors/command/struct.CommandExecutor.html) to execute your target ([example](https://github.com/AFLplusplus/LibAFL/blob/main/fuzzers/structure_aware/libfuzzer_stb_image_concolic/fuzzer/src/main.rs#L244)).
When configuring the command, make sure you pass the `SYMCC_INPUT_FILE` environment variable (set to the input file path), if your target reads input from a file (instead of standard input). When configuring the command, make sure you pass the `SYMCC_INPUT_FILE` environment variable (set to the input file path), if your target reads input from a file (instead of standard input).
#### Serialization and Solving #### Serialization and Solving
@ -184,4 +184,4 @@ It will attempt to solve all branches, like the original simple backend from Sym
### Example ### Example
The example fuzzer shows how to use the [`ConcolicTracingStage` together with the `SimpleConcolicMutationalStage`](https://github.com/AFLplusplus/LibAFL/blob/main/fuzzers/libfuzzer_stb_image_concolic/fuzzer/src/main.rs#L222) to build a basic hybrid fuzzer. The example fuzzer shows how to use the [`ConcolicTracingStage` together with the `SimpleConcolicMutationalStage`](https://github.com/AFLplusplus/LibAFL/blob/main/fuzzers/structure_aware/libfuzzer_stb_image_concolic/fuzzer/src/main.rs#L222) to build a basic hybrid fuzzer.

View File

@ -4,7 +4,7 @@ LibAFL supports different instrumentation engines for binary-only fuzzing.
A potent cross-platform (Windows, MacOS, Android, Linux, iOS) option for binary-only fuzzing is Frida; the dynamic instrumentation tool. A potent cross-platform (Windows, MacOS, Android, Linux, iOS) option for binary-only fuzzing is Frida; the dynamic instrumentation tool.
In this section, we will talk about the components in fuzzing with `libafl_frida`. In this section, we will talk about the components in fuzzing with `libafl_frida`.
You can take a look at a working example in our [`fuzzers/frida_libpng`](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/frida_libpng) folder for Linux, and [`fuzzers/frida_gdiplus`](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/frida_gdiplus) for Windows. You can take a look at a working example in our [`fuzzers/binary_only/frida_libpng`](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/binary_only/frida_libpng) folder for Linux, and [`fuzzers/binary_only/frida_windows_gdiplus`](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/binary_only/frida_windows_gdiplus) for Windows.
## Dependencies ## Dependencies
@ -84,4 +84,4 @@ You can then link this observer to `FridaInProcessExecutor` as follows:
``` ```
And finally you can run the fuzzer. And finally you can run the fuzzer.
See the `frida_` examples in [`./fuzzers`](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/) for more information and, for linux or full-system, play around with `libafl_qemu`, another binary-only tracer. See the `frida_` examples in [`./fuzzers/binary_only`](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/binary_only/) for more information and, for linux or full-system, play around with `libafl_qemu`, another binary_only tracer.

View File

@ -37,4 +37,4 @@ pub extern "C" fn external_current_millis() -> u64 {
} }
``` ```
See [./fuzzers/baby_no_std](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/baby_no_std) for an example. See [./fuzzers/fuzz_anything/baby_no_std](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/fuzz_anything/baby_no_std) for an example.

View File

@ -24,7 +24,7 @@ For binary-only fuzzing, Nyx uses intel-PT(Intel® Processor Trace). You can fin
## Preparing the Nyx working directory ## Preparing the Nyx working directory
This step is used to pack the target into Nyx's kernel. Don't worry, we have a template shell script in our [example](https://github.com/AFLplusplus/LibAFL/blob/main/fuzzers/nyx_libxml2_parallel/setup_libxml2.sh): This step is used to pack the target into Nyx's kernel. Don't worry, we have a template shell script in our [example](https://github.com/AFLplusplus/LibAFL/blob/main/fuzzers/full_system/nyx_libxml2_parallel/setup_libxml2.sh):
the parameter's meaning is listed below: the parameter's meaning is listed below:
@ -49,7 +49,7 @@ python3 ./packer/packer/nyx_config_gen.py /tmp/nyx_libxml2/ Kernel || exit
## Standalone fuzzing ## Standalone fuzzing
In the [example fuzzer](https://github.com/AFLplusplus/LibAFL/blob/main/fuzzers/nyx_libxml2_standalone/src/main.rs) you first need to run `./setup_libxml2.sh`. It will prepare your target and create your nyx work directory in `/tmp/libxml2`. After that, you can start to write your code. In the [example fuzzer](https://github.com/AFLplusplus/LibAFL/blob/main/fuzzers/full_system/nyx_libxml2_standalone/src/main.rs) you first need to run `./setup_libxml2.sh`. It will prepare your target and create your nyx work directory in `/tmp/libxml2`. After that, you can start to write your code.
First, to create `Nyxhelper`: First, to create `Nyxhelper`:
@ -71,7 +71,7 @@ Finally, use them normally and pass them into `fuzzer.fuzz_loop(&mut stages, &mu
## Parallel fuzzing ## Parallel fuzzing
In the [example fuzzer](https://github.com/AFLplusplus/LibAFL/blob/main/fuzzers/nyx_libxml2_parallel/src/main.rs) you first need to run `./setup_libxml2.sh` as described before. In the [example fuzzer](https://github.com/AFLplusplus/LibAFL/blob/main/fuzzers/full_system/nyx_libxml2_parallel/src/main.rs) you first need to run `./setup_libxml2.sh` as described before.
Parallel fuzzing relies on [`Launcher`](../message_passing/spawn_instances.md), so spawn logic should be written in the scoop of anonymous function `run_client`: Parallel fuzzing relies on [`Launcher`](../message_passing/spawn_instances.md), so spawn logic should be written in the scoop of anonymous function `run_client`:

View File

@ -6,7 +6,7 @@ While the following chapters discuss the components of LibAFL in detail, here we
We are going to fuzz a simple Rust function that panics under a condition. The fuzzer will be single-threaded and will stop after the crash, just like libFuzzer normally does. We are going to fuzz a simple Rust function that panics under a condition. The fuzzer will be single-threaded and will stop after the crash, just like libFuzzer normally does.
You can find a complete version of this tutorial as an example fuzzer in [`fuzzers/baby_fuzzer`](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/baby_fuzzer). You can find a complete version of this tutorial as an example fuzzer in [`fuzzers/baby/baby_fuzzer`](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/baby/baby_fuzzer).
> ### Warning > ### Warning
> >
@ -222,4 +222,4 @@ Bye!
As you can see, after the panic message, the `objectives` count of the log increased by one and you will find the crashing input in `crashes/`. As you can see, after the panic message, the `objectives` count of the log increased by one and you will find the crashing input in `crashes/`.
The complete code can be found in [`./fuzzers/baby_fuzzer`](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/baby_fuzzer) alongside other `baby_` fuzzers. The complete code can be found in [`./fuzzers/baby/baby_fuzzer`](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/baby/baby_fuzzer) alongside other `baby_` fuzzers.

View File

@ -1,6 +1,6 @@
# More Examples # More Examples
Examples can be found under `./fuzzer`. Examples can be found under `./fuzzers/baby`.
|fuzzer name|usage| |fuzzer name|usage|
| ---- | ---- | | ---- | ---- |

View File

@ -57,7 +57,7 @@ On your fuzzer side, you can allocate a shared memory region and make the `EDGES
```rust,ignore ```rust,ignore
let mut shmem; let mut shmem;
unsafe{ unsafe{
shmem = StdShMemProvider::new().unwrap().new_shmem(EDGES_MAP_SIZE_IN_USE).unwrap(); shmem = StdShMemProvider::new().unwrap().new_shmem(EDGES_MAP_DEFAULT_SIZE).unwrap();
} }
let shmem_buf = shmem.as_slice_mut(); let shmem_buf = shmem.as_slice_mut();
unsafe{ unsafe{

View File

@ -6,4 +6,6 @@ Mutators can be composed, and they are generally linked to a specific Input type
There can be, for instance, a Mutator that applies more than a single type of mutation to the input. Consider a generic Mutator for a byte stream, bit flip is just one of the possible mutations but not the only one, there is also, for instance, the random replacement of a byte of the copy of a chunk. There can be, for instance, a Mutator that applies more than a single type of mutation to the input. Consider a generic Mutator for a byte stream, bit flip is just one of the possible mutations but not the only one, there is also, for instance, the random replacement of a byte of the copy of a chunk.
There are also mutators that always produce valid inputs, say a mutator that generates valid JSON or code, but these grammar based mutators need a grammar to work.
In LibAFL, [`Mutator`](https://docs.rs/libafl/latest/libafl/mutators/trait.Mutator.html) is a trait. In LibAFL, [`Mutator`](https://docs.rs/libafl/latest/libafl/mutators/trait.Mutator.html) is a trait.

View File

@ -12,4 +12,4 @@ Beside the entities previously described, we introduce the [`Testcase`](https://
The State, in the implementation, contains only owned objects that are serializable, and it is serializable itself. Some fuzzers may want to serialize their state when pausing or just, when doing in-process fuzzing, serialize on crash and deserialize in the new process to continue to fuzz with all the metadata preserved. The State, in the implementation, contains only owned objects that are serializable, and it is serializable itself. Some fuzzers may want to serialize their state when pausing or just, when doing in-process fuzzing, serialize on crash and deserialize in the new process to continue to fuzz with all the metadata preserved.
Additionally, we group the entities that are "actions", like the `CorpusScheduler` and the `Feedbacks`, in a common place, the [`Fuzzer'](https://docs.rs/libafl/latest/libafl/fuzzer/struct.StdFuzzer.html). Additionally, we group the entities that are "actions", like the `CorpusScheduler` and the `Feedbacks`, in a common place, the [`Fuzzer`](https://docs.rs/libafl/latest/libafl/fuzzer/struct.StdFuzzer.html).

View File

@ -27,7 +27,7 @@ Metadata objects are primarly intended to be used inside [`SerdeAnyMap`](https:/
With these maps, the user can retrieve instances by type (and name). Internally, the instances are stored as SerdeAny trait objects. With these maps, the user can retrieve instances by type (and name). Internally, the instances are stored as SerdeAny trait objects.
Structs that want to have a set of metadata must implement the [`HasMetadata`](https://docs.rs/libafl/latest/libafl/state/trait.HasMetadata.html) trait. Structs that want to have a set of metadata must implement the [`HasMetadata`](https://docs.rs/libafl/latest/libafl/common/trait.HasMetadata.html) trait.
By default, Testcase and State implement it and hold a SerdeAnyMap testcase. By default, Testcase and State implement it and hold a SerdeAnyMap testcase.

View File

@ -12,7 +12,7 @@ Some cross-platform things in bolts include
* ShMem: A cross-platform (Windows, Linux, Android, MacOS) shared memory implementation * ShMem: A cross-platform (Windows, Linux, Android, MacOS) shared memory implementation
* LLMP: A fast, lock-free IPC mechanism via SharedMap * LLMP: A fast, lock-free IPC mechanism via SharedMap
* Core_affinity: A maintained version of `core_affinity` that can be used to get core information and bind processes to cores * Core_affinity: A maintained version of `core_affinity` that can be used to get core information and bind processes to cores
* Rands: Fast random number generators for fuzzing (like [RomuRand](http://www.romu-random.org/)) * Rands: Fast random number generators for fuzzing (like [RomuRand](https://www.romu-random.org/))
* MiniBSOD: get and print information about the current process state including important registers. * MiniBSOD: get and print information about the current process state including important registers.
* Tuples: Haskel-like compile-time tuple lists * Tuples: Haskel-like compile-time tuple lists
* Os: OS specific stuff like signal handling, windows exception handling, pipes, and helpers for `fork` * Os: OS specific stuff like signal handling, windows exception handling, pipes, and helpers for `fork`

View File

@ -169,7 +169,7 @@ from libafl_target's `EDGES_MAP`.
In the future, instead of using: In the future, instead of using:
```rust,ignore ```rust,ignore
let edges = unsafe { &mut EDGES_MAP[0..EDGES_MAP_SIZE_IN_USE] }; let edges = unsafe { &mut EDGES_MAP[0..EDGES_MAP_DEFAULT_SIZE] };
let edges_observer = StdMapObserver::new("edges", edges); let edges_observer = StdMapObserver::new("edges", edges);
``` ```

View File

@ -51,7 +51,7 @@ In it, you'll find highlights like:
The sugar crate abstracts away most of the complexity of LibAFL's API. The sugar crate abstracts away most of the complexity of LibAFL's API.
Instead of high flexibility, it aims to be high-level and easy-to-use. Instead of high flexibility, it aims to be high-level and easy-to-use.
It is not as flexible as stitching your fuzzer together from each individual component, but allows you to build a fuzzer with minimal lines of code. It is not as flexible as stitching your fuzzer together from each individual component, but allows you to build a fuzzer with minimal lines of code.
To see it in action, take a look at the [`libfuzzer_stb_image_sugar` example fuzzer](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/libfuzzer_stb_image_sugar). To see it in action, take a look at the [`libfuzzer_stb_image_sugar` example fuzzer](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/inprocess/libfuzzer_stb_image_sugar).
### [`libafl_derive`](https://github.com/AFLplusplus/LibAFL/tree/main/libafl_derive) ### [`libafl_derive`](https://github.com/AFLplusplus/LibAFL/tree/main/libafl_derive)

View File

@ -54,6 +54,6 @@ explained [here](https://clang.llvm.org/get_started.html).
If you do not have Rust installed, you can easily follow the steps described [here](https://www.rust-lang.org/tools/install) If you do not have Rust installed, you can easily follow the steps described [here](https://www.rust-lang.org/tools/install)
to install it on any supported system. to install it on any supported system.
Be aware that Rust versions shipped with Linux distributions may be outdated, LibAFL always targets the latest `stable` version available via `rustup upgrade`. Be aware that Rust versions shipped with Linux distributions may be outdated, LibAFL always targets the latest `stable` version available via `rustup update`.
We suggest installing Clang and LLVM first. We suggest installing Clang and LLVM first.

View File

@ -75,7 +75,7 @@ So the outgoing messages flow is like this over the outgoing broadcast `Shmem`:
To use `LLMP` in LibAFL, you usually want to use an `LlmpEventManager` or its restarting variant. To use `LLMP` in LibAFL, you usually want to use an `LlmpEventManager` or its restarting variant.
They are the default if using LibAFL's `Launcher`. They are the default if using LibAFL's `Launcher`.
If you should want to use `LLMP` in its raw form, without any `LibAFL` abstractions, take a look at the `llmp_test` example in [./libafl/examples](https://github.com/AFLplusplus/LibAFL/blob/main/libafl/examples/llmp_test/main.rs). If you should want to use `LLMP` in its raw form, without any `LibAFL` abstractions, take a look at the `llmp_test` example in [./libafl/examples](https://github.com/AFLplusplus/LibAFL/blob/main/libafl_bolts/examples/llmp_test/main.rs).
You can run the example using `cargo run --example llmp_test` with the appropriate modes, as indicated by its help output. You can run the example using `cargo run --example llmp_test` with the appropriate modes, as indicated by its help output.
First, you will have to create a broker using `LlmpBroker::new()`. First, you will have to create a broker using `LlmpBroker::new()`.
Then, create some `LlmpClient`s in other threads and register them with the main thread using `LlmpBroker::register_client`. Then, create some `LlmpClient`s in other threads and register them with the main thread using `LlmpBroker::register_client`.

View File

@ -4,7 +4,7 @@ Multiple fuzzer instances can be spawned using different ways.
## Manually, via a TCP port ## Manually, via a TCP port
The straightforward way to do Multi-Threading is to use the [`LlmpRestartingEventManager`](https://docs.rs/libafl/latest/libafl/events/llmp/struct.LlmpRestartingEventManager.html), specifically to use [`setup_restarting_mgr_std`](https://docs.rs/libafl/latest/libafl/events/llmp/fn.setup_restarting_mgr_std.html). The straightforward way to do Multi-Threading is to use the [`LlmpRestartingEventManager`](https://docs.rs/libafl/latest/libafl/events/llmp/restarting/struct.LlmpRestartingEventManager.html), specifically to use [`setup_restarting_mgr_std`](https://docs.rs/libafl/latest/libafl/events/llmp/restarting/fn.setup_restarting_mgr_std.html).
It abstracts away all the pesky details about restarts on crash handling (for in-memory fuzzers) and multi-threading. It abstracts away all the pesky details about restarts on crash handling (for in-memory fuzzers) and multi-threading.
With it, every instance you launch manually tries to connect to a TCP port on the local machine. With it, every instance you launch manually tries to connect to a TCP port on the local machine.

View File

@ -5,4 +5,4 @@
> This section is under construction. > This section is under construction.
> Please check back later (or open a PR) > Please check back later (or open a PR)
> >
> In the meantime, find the final Lain-based fuzzer in [the fuzzers folder](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/tutorial) > In the meantime, find the final Lain-based fuzzer in [the fuzzers folder](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/baby/tutorial)

34
fuzzers/README.md Normal file
View File

@ -0,0 +1,34 @@
# LibAFL Fuzzers
## Example fuzzers
You can find a large amount of example fuzzers built on top of LibAFL.
They are sorted by focus:
- [`baby`](./baby/): Minimal fuzzers and fuzzers demonstrating specific features that don't fit anywhere else.
- [`binary_only`](./binary_only/): Fuzzers for binary-only targets.
- [`forkserver`](./forkserver/): Fuzzers that use a forkserver-style executor.
- [`full_system`](./full_system/): Fuzzers for full-system targets (kernels, firmwares, etc...).
- [`fuzz_anything`](./fuzz_anything/): Fuzzers for advanced targets like WASM or python, and other fuzzers that can be used for anything.
- [`inprocess`](./inprocess/): Common In-process fuzzers. Most of the time, this is what you want.
- [`structure_aware`](./structure_aware/): Grammar fuzzers, fuzzers for certain languages, fuzzers with custom inputs, and more.
(Some fuzzers may fit into multiple categories, in which case we sort them as it makes sense, for example `structure_aware > full_system > binary_only > the rest`)
## Fully-feature Fuzzers
Some rather complete fuzzers worth looking at are:
- [`Libfuzzer_Libpng_Launcher`](./inprocess/libfuzzer_libpng_launcher): That's what most people want to use: our InProcess fuzzer with a lot of features like ASAn on some cores, multi threading (a better libfuzzer).
- [`LibAFL-fuzz`](./forkserver/libafl-fuzz/): A reimplementation of afl-fuzz, the traditional forkserver fuzzer that tries to emulate the command line and behavior.
- [`LibAFL-QEMU-Launcher`](./binary_only/qemu_launcher/): A full-featured QEMU-mode fuzzer that runs on multiple cores
They may not be the best starting point for your own custom fuzzer, but they might be easy enough to just use.
## Paper Artifacts
Multiple papers based on LibAFL have been published and include artifacts.
Here is a list of LibAFL artifacts:
- Fuzzbench implementation: https://github.com/AFLplusplus/libafl_fuzzbench
- LibAFL QEMU experiments: https://github.com/AFLplusplus/libafl_qemu_artifacts

View File

@ -0,0 +1,28 @@
[package]
name = "baby_fuzzer"
version = "0.14.1"
authors = [
"Andrea Fioraldi <andreafioraldi@gmail.com>",
"Dominik Maier <domenukk@gmail.com>",
]
edition = "2021"
[features]
default = ["std"]
tui = []
std = []
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
lto = true
codegen-units = 1
opt-level = 3
debug = true
[dependencies]
libafl = { path = "../../../libafl", features = ["tui_monitor"] }
libafl_bolts = { path = "../../../libafl_bolts" }
log = { version = "0.4.22", features = ["release_max_level_info"] }

View File

@ -3,24 +3,24 @@ use std::ptr::write_volatile;
use std::{path::PathBuf, ptr::write}; use std::{path::PathBuf, ptr::write};
#[cfg(feature = "tui")] #[cfg(feature = "tui")]
use libafl::monitors::tui::{ui::TuiUI, TuiMonitor}; use libafl::monitors::tui::TuiMonitor;
#[cfg(not(feature = "tui"))] #[cfg(not(feature = "tui"))]
use libafl::monitors::SimpleMonitor; use libafl::monitors::SimpleMonitor;
use libafl::{ use libafl::{
corpus::{InMemoryCorpus, OnDiskCorpus}, corpus::{InMemoryCorpus, OnDiskCorpus},
events::SimpleEventManager, events::SimpleEventManager,
executors::{inprocess::InProcessExecutor, ExitKind}, executors::{ExitKind, InProcessExecutor},
feedbacks::{CrashFeedback, MaxMapFeedback}, feedbacks::{CrashFeedback, MaxMapFeedback},
fuzzer::{Fuzzer, StdFuzzer}, fuzzer::{Fuzzer, StdFuzzer},
generators::RandPrintablesGenerator, generators::RandPrintablesGenerator,
inputs::{BytesInput, HasTargetBytes}, inputs::{BytesInput, HasTargetBytes},
mutators::scheduled::{havoc_mutations, StdScheduledMutator}, mutators::{havoc_mutations::havoc_mutations, scheduled::StdScheduledMutator},
observers::StdMapObserver, observers::StdMapObserver,
schedulers::QueueScheduler, schedulers::QueueScheduler,
stages::mutational::StdMutationalStage, stages::mutational::StdMutationalStage,
state::StdState, state::StdState,
}; };
use libafl_bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice}; use libafl_bolts::{current_nanos, nonzero, rands::StdRand, tuples::tuple_list, AsSlice};
/// Coverage map with explicit assignments due to the lack of instrumentation /// Coverage map with explicit assignments due to the lack of instrumentation
static mut SIGNALS: [u8; 16] = [0; 16]; static mut SIGNALS: [u8; 16] = [0; 16];
@ -90,9 +90,10 @@ pub fn main() {
#[cfg(not(feature = "tui"))] #[cfg(not(feature = "tui"))]
let mon = SimpleMonitor::new(|s| println!("{s}")); let mon = SimpleMonitor::new(|s| println!("{s}"));
#[cfg(feature = "tui")] #[cfg(feature = "tui")]
let ui = TuiUI::with_version(String::from("Baby Fuzzer"), String::from("0.0.1"), false); let mon = TuiMonitor::builder()
#[cfg(feature = "tui")] .title("Baby Fuzzer")
let mon = TuiMonitor::new(ui); .enhanced_graphics(false)
.build();
// The event manager handle the various events generated during the fuzzing loop // The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus // such as the notification of the addition of a new item to the corpus
@ -115,7 +116,7 @@ pub fn main() {
.expect("Failed to create the Executor"); .expect("Failed to create the Executor");
// Generator of printable bytearrays of max size 32 // Generator of printable bytearrays of max size 32
let mut generator = RandPrintablesGenerator::new(32); let mut generator = RandPrintablesGenerator::new(nonzero!(32));
// Generate 8 initial inputs // Generate 8 initial inputs
state state

View File

@ -0,0 +1,2 @@
libpng-*
corpus

View File

@ -1,10 +1,15 @@
[package] [package]
name = "rust_code_with_inprocess_executor" name = "fuzzer_custom_executor"
version = "0.0.1" version = "0.14.1"
authors = [
"Andrea Fioraldi <andreafioraldi@gmail.com>",
"Dominik Maier <domenukk@gmail.com>",
]
edition = "2021" edition = "2021"
[features] [features]
default = ["std"] default = ["std"]
tui = ["libafl/tui_monitor"]
std = [] std = []
[profile.dev] [profile.dev]

View File

@ -0,0 +1,50 @@
# Variables
[env]
FUZZER_NAME = 'fuzzer_custom_executor'
PROJECT_DIR = { script = ["pwd"] }
CARGO_TARGET_DIR = { value = "target", condition = { env_not_set = [
"CARGO_TARGET_DIR",
] } }
PROFILE = { value = "release" }
PROFILE_DIR = { value = "release" }
FUZZER = '${CARGO_TARGET_DIR}/${PROFILE_DIR}/${FUZZER_NAME}'
[tasks.build]
alias = "fuzzer"
[tasks.fuzzer]
description = "Build the fuzzer"
script = "cargo build --profile=${PROFILE}"
[tasks.run]
description = "Run the fuzzer"
command = "${CARGO_TARGET_DIR}/${PROFILE_DIR}/${FUZZER_NAME}"
dependencies = ["fuzzer"]
[tasks.test]
description = "Run a short test"
linux_alias = "test_unix"
mac_alias = "test_unix"
windows_alias = "unsupported"
[tasks.test_unix]
script_runner = "@shell"
script = '''
timeout 30s ${CARGO_TARGET_DIR}/${PROFILE_DIR}/${FUZZER_NAME} | tee fuzz_stdout.log || true
if grep -qa "objectives: 1" fuzz_stdout.log; then
echo "Fuzzer is working"
else
echo "Fuzzer does not generate any testcases or any crashes"
exit 1
fi
'''
dependencies = ["fuzzer"]
# Clean up
[tasks.clean]
# Disable default `clean` definition
clear = true
script_runner = "@shell"
script = '''
cargo clean
'''

View File

@ -0,0 +1,12 @@
# Baby fuzzer with Custom Executor
This is a minimalistic example about how to create a LibAFL-based fuzzer.
In contrast to the normal baby fuzzer, this uses a (very simple) custom executor.
The custom executor won't catch any timeouts or actual errors (i.e., memory corruptions, etc.) in the target.
The tested program is a simple Rust function without any instrumentation.
For real fuzzing, you will want to add some sort to add coverage or other feedback.
You can run this example using `cargo run`, and you can enable the TUI feature by running `cargo run --features tui`.

View File

@ -0,0 +1,159 @@
#[cfg(windows)]
use std::ptr::write_volatile;
use std::{marker::PhantomData, path::PathBuf, ptr::write};
#[cfg(feature = "tui")]
use libafl::monitors::tui::TuiMonitor;
#[cfg(not(feature = "tui"))]
use libafl::monitors::SimpleMonitor;
use libafl::{
corpus::{InMemoryCorpus, OnDiskCorpus},
events::SimpleEventManager,
executors::{Executor, ExitKind, WithObservers},
feedback_and_fast,
feedbacks::{CrashFeedback, MaxMapFeedback},
fuzzer::{Fuzzer, StdFuzzer},
generators::RandPrintablesGenerator,
inputs::HasTargetBytes,
mutators::{havoc_mutations::havoc_mutations, scheduled::StdScheduledMutator},
observers::StdMapObserver,
schedulers::QueueScheduler,
stages::mutational::StdMutationalStage,
state::{HasExecutions, State, StdState, UsesState},
};
use libafl_bolts::{current_nanos, nonzero, rands::StdRand, tuples::tuple_list, AsSlice};
/// Coverage map with explicit assignments due to the lack of instrumentation
static mut SIGNALS: [u8; 16] = [0; 16];
static mut SIGNALS_PTR: *mut u8 = &raw mut SIGNALS as _;
static SIGNALS_LEN: usize = unsafe { (*&raw const (SIGNALS)).len() };
/// Assign a signal to the signals map
fn signals_set(idx: usize) {
unsafe { write(SIGNALS_PTR.add(idx), 1) };
}
struct CustomExecutor<S: State> {
phantom: PhantomData<S>,
}
impl<S: State> CustomExecutor<S> {
pub fn new(_state: &S) -> Self {
Self {
phantom: PhantomData,
}
}
}
impl<S: State> UsesState for CustomExecutor<S> {
type State = S;
}
impl<EM, S, Z> Executor<EM, Z> for CustomExecutor<S>
where
EM: UsesState<State = S>,
S: State + HasExecutions,
Z: UsesState<State = S>,
Self::Input: HasTargetBytes,
{
fn run_target(
&mut self,
_fuzzer: &mut Z,
state: &mut Self::State,
_mgr: &mut EM,
input: &Self::Input,
) -> Result<ExitKind, libafl::Error> {
// We need to keep track of the exec count.
*state.executions_mut() += 1;
let target = input.target_bytes();
let buf = target.as_slice();
signals_set(0);
if !buf.is_empty() && buf[0] == b'a' {
signals_set(1);
if buf.len() > 1 && buf[1] == b'b' {
signals_set(2);
if buf.len() > 2 && buf[2] == b'c' {
return Ok(ExitKind::Crash);
}
}
}
Ok(ExitKind::Ok)
}
}
#[allow(clippy::similar_names, clippy::manual_assert)]
pub fn main() {
// Create an observation channel using the signals map
let observer = unsafe { StdMapObserver::from_mut_ptr("signals", SIGNALS_PTR, SIGNALS_LEN) };
// Feedback to rate the interestingness of an input
let mut feedback = MaxMapFeedback::new(&observer);
// A feedback to choose if an input is a solution or not
let mut objective = feedback_and_fast!(
// Look for crashes.
CrashFeedback::new(),
// We `and` the MaxMapFeedback to only end up with crashes that trigger new coverage.
// We use the _fast variant to make sure it's not evaluated every time, even if the crash didn't trigger..
// We have to give this one a name since it differs from the first map.
MaxMapFeedback::with_name("on_crash", &observer)
);
// create a State from scratch
let mut state = StdState::new(
// RNG
StdRand::with_seed(current_nanos()),
// Corpus that will be evolved, we keep it in memory for performance
InMemoryCorpus::new(),
// Corpus in which we store solutions (crashes in this example),
// on disk so the user can get them after stopping the fuzzer
OnDiskCorpus::new(PathBuf::from("./crashes")).unwrap(),
// States of the feedbacks.
// The feedbacks can report the data that should persist in the State.
&mut feedback,
// Same for objective feedbacks
&mut objective,
)
.unwrap();
// The Monitor trait define how the fuzzer stats are displayed to the user
#[cfg(not(feature = "tui"))]
let mon = SimpleMonitor::new(|s| println!("{s}"));
#[cfg(feature = "tui")]
let mon = TuiMonitor::builder()
.title("Baby Fuzzer")
.enhanced_graphics(false)
.build();
// The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus
let mut mgr = SimpleEventManager::new(mon);
// A queue policy to get testcasess from the corpus
let scheduler = QueueScheduler::new();
// A fuzzer with feedbacks and a corpus scheduler
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
// Create the executor for an in-process function with just one observer
let executor = CustomExecutor::new(&state);
let mut executor = WithObservers::new(executor, tuple_list!(observer));
// Generator of printable bytearrays of max size 32
let mut generator = RandPrintablesGenerator::with_min_size(nonzero!(1), nonzero!(32));
// Generate 8 initial inputs
state
.generate_initial_inputs(&mut fuzzer, &mut executor, &mut generator, &mut mgr, 8)
.expect("Failed to generate the initial corpus");
// Setup a mutational stage with a basic bytes mutator
let mutator = StdScheduledMutator::new(havoc_mutations());
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
fuzzer
.fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr)
.expect("Error in the fuzzing loop");
}

View File

@ -0,0 +1,29 @@
[package]
name = "baby_fuzzer_minimizing"
version = "0.14.1"
authors = [
"Andrea Fioraldi <andreafioraldi@gmail.com>",
"Dominik Maier <domenukk@gmail.com>",
"Addison Crump <research@addisoncrump.info>",
]
edition = "2021"
[features]
default = ["std"]
tui = ["libafl/tui_monitor"]
std = []
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
lto = true
codegen-units = 1
opt-level = 3
debug = true
[dependencies]
libafl = { path = "../../../libafl", features = ["prelude"] }
libafl_bolts = { path = "../../../libafl_bolts", features = ["prelude"] }
log = { version = "0.4.22", features = ["release_max_level_info"] }

View File

@ -86,7 +86,7 @@ pub fn main() -> Result<(), Error> {
.expect("Failed to create the Executor"); .expect("Failed to create the Executor");
// Generator of printable bytearrays of max size 32 // Generator of printable bytearrays of max size 32
let mut generator = RandPrintablesGenerator::new(32); let mut generator = RandPrintablesGenerator::new(nonzero!(32));
// Generate 8 initial inputs // Generate 8 initial inputs
state state
@ -94,8 +94,8 @@ pub fn main() -> Result<(), Error> {
.expect("Failed to generate the initial corpus"); .expect("Failed to generate the initial corpus");
// Setup a mutational stage with a basic bytes mutator // Setup a mutational stage with a basic bytes mutator
let mutator = StdScheduledMutator::new(havoc_mutations::<BytesInput>()); let mutator = StdScheduledMutator::new(havoc_mutations());
let minimizer = StdScheduledMutator::new(havoc_mutations::<BytesInput>()); let minimizer = StdScheduledMutator::new(havoc_mutations());
let mut stages = tuple_list!( let mut stages = tuple_list!(
StdMutationalStage::new(mutator), StdMutationalStage::new(mutator),
StdTMinMutationalStage::new(minimizer, factory, 128) StdTMinMutationalStage::new(minimizer, factory, 128)
@ -121,11 +121,11 @@ pub fn main() -> Result<(), Error> {
let mut mgr = SimpleEventManager::new(mon); let mut mgr = SimpleEventManager::new(mon);
let minimizer = StdScheduledMutator::new(havoc_mutations::<BytesInput>()); let minimizer = StdScheduledMutator::new(havoc_mutations());
let mut stages = tuple_list!(StdTMinMutationalStage::new( let mut stages = tuple_list!(StdTMinMutationalStage::new(
minimizer, minimizer,
CrashFeedback::new(), CrashFeedback::new(),
1 << 10 1 << 10,
)); ));
let scheduler = QueueScheduler::new(); let scheduler = QueueScheduler::new();
@ -138,7 +138,9 @@ pub fn main() -> Result<(), Error> {
state.load_initial_inputs_forced(&mut fuzzer, &mut executor, &mut mgr, &[solution_dir])?; state.load_initial_inputs_forced(&mut fuzzer, &mut executor, &mut mgr, &[solution_dir])?;
state.set_corpus_idx(CorpusId::from(0_usize))?; let first_id = state.corpus().first().expect("Empty corpus");
state.set_corpus_id(first_id)?;
stages.perform_all(&mut fuzzer, &mut executor, &mut state, &mut mgr)?; stages.perform_all(&mut fuzzer, &mut executor, &mut state, &mut mgr)?;
Ok(()) Ok(())

View File

@ -0,0 +1,47 @@
[package]
name = "baby_fuzzer_swap_differential"
version = "0.14.1"
authors = ["Addison Crump <research@addisoncrump.info>"]
edition = "2021"
default-run = "fuzzer_sd"
[features]
tui = ["libafl/tui_monitor"]
multimap = []
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
lto = true
codegen-units = 1
opt-level = 3
debug = true
[build-dependencies]
anyhow = "1.0.89"
bindgen = "0.70.1"
cc = "1.1.21"
[dependencies]
libafl = { path = "../../../libafl", features = ["tui_monitor"] }
libafl_bolts = { path = "../../../libafl_bolts" }
libafl_targets = { path = "../../../libafl_targets", features = [
"sancov_pcguard_hitcounts",
"libfuzzer",
"sancov_cmplog",
"pointer_maps",
] }
log = { version = "0.4.22", features = ["release_max_level_info"] }
mimalloc = { version = "0.1.43", default-features = false }
libafl_cc = { path = "../../../libafl_cc" }
[[bin]]
name = "fuzzer_sd"
path = "src/main.rs"
[[bin]]
name = "libafl_cc"
path = "src/bin/libafl_cc.rs"

View File

@ -1,23 +1,25 @@
# Variables # Variables
[env] [env]
FUZZER_NAME='fuzzer_sd' FUZZER_NAME = 'fuzzer_sd'
PROJECT_DIR = { script = ["pwd"] } PROJECT_DIR = { script = ["pwd"] }
CARGO_TARGET_DIR = { value = "target", condition = { env_not_set = ["CARGO_TARGET_DIR"] } } CARGO_TARGET_DIR = { value = "target", condition = { env_not_set = [
"CARGO_TARGET_DIR",
] } }
PROFILE = { value = "release" } PROFILE = { value = "release" }
PROFILE_DIR = {value = "release" } PROFILE_DIR = { value = "release" }
LIBAFL_CC = '${CARGO_TARGET_DIR}/${PROFILE_DIR}/libafl_cc' LIBAFL_CC = '${CARGO_TARGET_DIR}/${PROFILE_DIR}/libafl_cc'
FUZZER = '${CARGO_TARGET_DIR}/${PROFILE_DIR}/${FUZZER_NAME}' FUZZER = '${CARGO_TARGET_DIR}/${PROFILE_DIR}/${FUZZER_NAME}'
# Compilers # Compilers
[tasks.cc] [tasks.cc]
command = "cargo" command = "cargo"
args = ["build" , "--profile", "${PROFILE}", "--bin", "libafl_cc"] args = ["build", "--profile", "${PROFILE}", "--bin", "libafl_cc"]
# Harness # Harness
[tasks.fuzzer] [tasks.fuzzer]
command = "cargo" command = "cargo"
args = ["build" , "--profile", "${PROFILE}", "--bin", "${FUZZER_NAME}"] args = ["build", "--profile", "${PROFILE}", "--bin", "${FUZZER_NAME}"]
dependencies = [ "cc" ] dependencies = ["cc"]
[tasks.build] [tasks.build]
alias = "fuzzer" alias = "fuzzer"
@ -25,7 +27,7 @@ alias = "fuzzer"
# Run the fuzzer # Run the fuzzer
[tasks.run] [tasks.run]
command = "${CARGO_TARGET_DIR}/${PROFILE_DIR}/${FUZZER_NAME}" command = "${CARGO_TARGET_DIR}/${PROFILE_DIR}/${FUZZER_NAME}"
dependencies = [ "fuzzer" ] dependencies = ["fuzzer"]
# Test # Test
[tasks.test] [tasks.test]
@ -35,7 +37,7 @@ windows_alias = "unsupported"
[tasks.test_unix] [tasks.test_unix]
script_runner = "@shell" script_runner = "@shell"
script=''' script = '''
timeout 30s ${CARGO_TARGET_DIR}/${PROFILE_DIR}/${FUZZER_NAME} | tee fuzz_stdout.log || true timeout 30s ${CARGO_TARGET_DIR}/${PROFILE_DIR}/${FUZZER_NAME} | tee fuzz_stdout.log || true
if grep -qa "objectives: 1" fuzz_stdout.log; then if grep -qa "objectives: 1" fuzz_stdout.log; then
echo "Fuzzer is working" echo "Fuzzer is working"
@ -44,13 +46,13 @@ else
exit 1 exit 1
fi fi
''' '''
dependencies = [ "fuzzer" ] dependencies = ["fuzzer"]
# Clean up # Clean up
[tasks.clean] [tasks.clean]
# Disable default `clean` definition # Disable default `clean` definition
clear = true clear = true
script_runner="@shell" script_runner = "@shell"
script=''' script = '''
cargo clean cargo clean
''' '''

View File

@ -6,7 +6,7 @@ use std::{
}; };
#[cfg(feature = "tui")] #[cfg(feature = "tui")]
use libafl::monitors::tui::{ui::TuiUI, TuiMonitor}; use libafl::monitors::tui::TuiMonitor;
#[cfg(not(feature = "tui"))] #[cfg(not(feature = "tui"))]
use libafl::monitors::SimpleMonitor; use libafl::monitors::SimpleMonitor;
use libafl::{ use libafl::{
@ -17,13 +17,13 @@ use libafl::{
fuzzer::{Fuzzer, StdFuzzer}, fuzzer::{Fuzzer, StdFuzzer},
generators::RandPrintablesGenerator, generators::RandPrintablesGenerator,
inputs::{BytesInput, HasTargetBytes}, inputs::{BytesInput, HasTargetBytes},
mutators::scheduled::{havoc_mutations, StdScheduledMutator}, mutators::{havoc_mutations::havoc_mutations, scheduled::StdScheduledMutator},
observers::StdMapObserver, observers::StdMapObserver,
schedulers::QueueScheduler, schedulers::QueueScheduler,
stages::mutational::StdMutationalStage, stages::mutational::StdMutationalStage,
state::{HasSolutions, StdState}, state::{HasSolutions, StdState},
}; };
use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice}; use libafl_bolts::{nonzero, rands::StdRand, tuples::tuple_list, AsSlice};
use libafl_targets::{edges_max_num, DifferentialAFLMapSwapObserver}; use libafl_targets::{edges_max_num, DifferentialAFLMapSwapObserver};
#[cfg(not(miri))] #[cfg(not(miri))]
use mimalloc::MiMalloc; use mimalloc::MiMalloc;
@ -204,9 +204,10 @@ pub fn main() {
#[cfg(not(feature = "tui"))] #[cfg(not(feature = "tui"))]
let mon = SimpleMonitor::with_user_monitor(|s| println!("{s}")); let mon = SimpleMonitor::with_user_monitor(|s| println!("{s}"));
#[cfg(feature = "tui")] #[cfg(feature = "tui")]
let ui = TuiUI::new(String::from("Baby Fuzzer"), false); let mon = TuiMonitor::builder()
#[cfg(feature = "tui")] .title("Baby Fuzzer")
let mon = TuiMonitor::new(ui); .enhanced_graphics(false)
.build();
// The event manager handle the various events generated during the fuzzing loop // The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus // such as the notification of the addition of a new item to the corpus
@ -246,7 +247,7 @@ pub fn main() {
); );
// Generator of printable bytearrays of max size 32 // Generator of printable bytearrays of max size 32
let mut generator = RandPrintablesGenerator::new(32); let mut generator = RandPrintablesGenerator::new(nonzero!(32));
// Generate 8 initial inputs // Generate 8 initial inputs
state state

View File

@ -0,0 +1,28 @@
[package]
name = "baby_fuzzer_unicode"
version = "0.14.1"
authors = [
"Andrea Fioraldi <andreafioraldi@gmail.com>",
"Dominik Maier <domenukk@gmail.com>",
]
edition = "2021"
[features]
default = ["std"]
tui = ["libafl/tui_monitor"]
std = []
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
lto = true
codegen-units = 1
opt-level = 3
debug = true
[dependencies]
libafl = { path = "../../../libafl", features = ["unicode", "tui_monitor"] }
libafl_bolts = { path = "../../../libafl_bolts" }
log = { version = "0.4.22", features = ["release_max_level_info"] }

View File

@ -3,7 +3,7 @@ use std::ptr::write_volatile;
use std::{path::PathBuf, ptr::write}; use std::{path::PathBuf, ptr::write};
#[cfg(feature = "tui")] #[cfg(feature = "tui")]
use libafl::monitors::tui::{ui::TuiUI, TuiMonitor}; use libafl::monitors::tui::TuiMonitor;
#[cfg(not(feature = "tui"))] #[cfg(not(feature = "tui"))]
use libafl::monitors::SimpleMonitor; use libafl::monitors::SimpleMonitor;
use libafl::{ use libafl::{
@ -24,7 +24,8 @@ use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice};
/// Coverage map with explicit assignments due to the lack of instrumentation /// Coverage map with explicit assignments due to the lack of instrumentation
static mut SIGNALS: [u8; 64] = [0; 64]; static mut SIGNALS: [u8; 64] = [0; 64];
static mut SIGNALS_PTR: *mut u8 = unsafe { SIGNALS.as_mut_ptr() }; static mut SIGNALS_PTR: *mut u8 = (&raw mut SIGNALS).cast();
static mut SIGNALS_LEN: usize = unsafe { (*&raw const SIGNALS).len() };
/// Assign a signal to the signals map /// Assign a signal to the signals map
fn signals_set(idx: usize) { fn signals_set(idx: usize) {
@ -56,7 +57,7 @@ pub fn main() {
}; };
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = unsafe { StdMapObserver::from_mut_ptr("signals", SIGNALS_PTR, SIGNALS.len()) }; let observer = unsafe { StdMapObserver::from_mut_ptr("signals", SIGNALS_PTR, SIGNALS_LEN) };
// Feedback to rate the interestingness of an input // Feedback to rate the interestingness of an input
let mut feedback = MaxMapFeedback::new(&observer); let mut feedback = MaxMapFeedback::new(&observer);
@ -85,9 +86,11 @@ pub fn main() {
#[cfg(not(feature = "tui"))] #[cfg(not(feature = "tui"))]
let mon = SimpleMonitor::new(|s| println!("{s}")); let mon = SimpleMonitor::new(|s| println!("{s}"));
#[cfg(feature = "tui")] #[cfg(feature = "tui")]
let ui = TuiUI::with_version(String::from("Baby Fuzzer"), String::from("0.0.1"), false); let mon = TuiMonitor::builder()
#[cfg(feature = "tui")] .title("Baby Fuzzer")
let mon = TuiMonitor::new(ui); .version("0.0.1")
.enhanced_graphics(false)
.build();
// The event manager handle the various events generated during the fuzzing loop // The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus // such as the notification of the addition of a new item to the corpus

View File

@ -1,6 +1,6 @@
[package] [package]
name = "c_code_with_fork_executor" name = "c_code_with_fork_executor"
version = "0.0.1" version = "0.14.1"
edition = "2021" edition = "2021"
[features] [features]
@ -15,9 +15,10 @@ opt-level = 3
debug = true debug = true
[dependencies] [dependencies]
libafl = { path = "../../../libafl/" } libafl = { path = "../../../../libafl" }
libafl_bolts = { path = "../../../libafl_bolts/" } libafl_bolts = { path = "../../../../libafl_bolts" }
libc = "0.2" libc = "0.2.159"
log = { version = "0.4.22", features = ["release_max_level_info"] }
[build-dependencies] [build-dependencies]
cc = "1.0" cc = "1.1.21"

View File

@ -1,4 +1,4 @@
use std::{path::PathBuf, time::Duration}; use std::{path::PathBuf, ptr::NonNull, time::Duration};
use libafl::{ use libafl::{
corpus::{InMemoryCorpus, OnDiskCorpus}, corpus::{InMemoryCorpus, OnDiskCorpus},
@ -10,13 +10,14 @@ use libafl::{
generators::RandPrintablesGenerator, generators::RandPrintablesGenerator,
inputs::{BytesInput, HasTargetBytes}, inputs::{BytesInput, HasTargetBytes},
monitors::SimpleMonitor, monitors::SimpleMonitor,
mutators::scheduled::{havoc_mutations, StdScheduledMutator}, mutators::{havoc_mutations::havoc_mutations, scheduled::StdScheduledMutator},
observers::{BacktraceObserver, ConstMapObserver}, observers::{BacktraceObserver, ConstMapObserver},
schedulers::QueueScheduler, schedulers::QueueScheduler,
stages::mutational::StdMutationalStage, stages::mutational::StdMutationalStage,
state::StdState, state::StdState,
}; };
use libafl_bolts::{ use libafl_bolts::{
nonzero,
ownedref::OwnedRefMut, ownedref::OwnedRefMut,
rands::StdRand, rands::StdRand,
shmem::{ShMemProvider, StdShMemProvider}, shmem::{ShMemProvider, StdShMemProvider},
@ -45,7 +46,14 @@ pub fn main() {
libafl::executors::ExitKind::Ok libafl::executors::ExitKind::Ok
}; };
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = unsafe { ConstMapObserver::<u8, 3>::from_mut_ptr("signals", map_ptr) }; let observer = unsafe {
ConstMapObserver::from_mut_ptr(
"signals",
NonNull::new(map_ptr)
.expect("map ptr is null.")
.cast::<[u8; 3]>(),
)
};
// Create a stacktrace observer // Create a stacktrace observer
let mut bt = shmem_provider.new_on_shmem::<Option<u64>>(None).unwrap(); let mut bt = shmem_provider.new_on_shmem::<Option<u64>>(None).unwrap();
let bt_observer = BacktraceObserver::new( let bt_observer = BacktraceObserver::new(
@ -103,7 +111,7 @@ pub fn main() {
.expect("Failed to create the Executor"); .expect("Failed to create the Executor");
// Generator of printable bytearrays of max size 32 // Generator of printable bytearrays of max size 32
let mut generator = RandPrintablesGenerator::new(32); let mut generator = RandPrintablesGenerator::new(nonzero!(32));
// Generate 8 initial inputs // Generate 8 initial inputs
state state

View File

@ -1,6 +1,6 @@
[package] [package]
name = "c_code_with_inprocess_executor" name = "c_code_with_inprocess_executor"
version = "0.0.1" version = "0.14.1"
edition = "2021" edition = "2021"
[features] [features]
@ -15,9 +15,10 @@ opt-level = 3
debug = true debug = true
[dependencies] [dependencies]
libafl = { path = "../../../libafl/" } libafl = { path = "../../../../libafl" }
libafl_bolts = { path = "../../../libafl_bolts/" } libafl_bolts = { path = "../../../../libafl_bolts" }
libc = "0.2" libc = "0.2.159"
log = { version = "0.4.22", features = ["release_max_level_info"] }
[build-dependencies] [build-dependencies]
cc = "1.0" cc = "1.1.21"

View File

@ -1,4 +1,4 @@
use std::path::PathBuf; use std::{path::PathBuf, ptr::NonNull};
use libafl::{ use libafl::{
corpus::{InMemoryCorpus, OnDiskCorpus}, corpus::{InMemoryCorpus, OnDiskCorpus},
@ -10,13 +10,13 @@ use libafl::{
generators::RandPrintablesGenerator, generators::RandPrintablesGenerator,
inputs::{BytesInput, HasTargetBytes}, inputs::{BytesInput, HasTargetBytes},
monitors::SimpleMonitor, monitors::SimpleMonitor,
mutators::scheduled::{havoc_mutations, StdScheduledMutator}, mutators::{havoc_mutations::havoc_mutations, scheduled::StdScheduledMutator},
observers::{BacktraceObserver, ConstMapObserver}, observers::{BacktraceObserver, ConstMapObserver},
schedulers::QueueScheduler, schedulers::QueueScheduler,
stages::mutational::StdMutationalStage, stages::mutational::StdMutationalStage,
state::StdState, state::StdState,
}; };
use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice}; use libafl_bolts::{nonzero, rands::StdRand, tuples::tuple_list, AsSlice};
use libc::c_uchar; use libc::c_uchar;
extern crate libc; extern crate libc;
@ -35,7 +35,14 @@ pub fn main() {
libafl::executors::ExitKind::Ok libafl::executors::ExitKind::Ok
}; };
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = unsafe { ConstMapObserver::<u8, 3>::from_mut_ptr("signals", array_ptr) }; let observer = unsafe {
ConstMapObserver::from_mut_ptr(
"signals",
NonNull::new(array_ptr)
.expect("map ptr is null")
.cast::<[u8; 3]>(),
)
};
// Create a stacktrace observer // Create a stacktrace observer
let bt_observer = BacktraceObserver::owned( let bt_observer = BacktraceObserver::owned(
"BacktraceObserver", "BacktraceObserver",
@ -89,7 +96,7 @@ pub fn main() {
.expect("Failed to create the Executor"); .expect("Failed to create the Executor");
// Generator of printable bytearrays of max size 32 // Generator of printable bytearrays of max size 32
let mut generator = RandPrintablesGenerator::new(32); let mut generator = RandPrintablesGenerator::new(nonzero!(32));
// Generate 8 initial inputs // Generate 8 initial inputs
state state

View File

@ -1,6 +1,6 @@
[package] [package]
name = "command_executor" name = "command_executor"
version = "0.0.1" version = "0.14.1"
edition = "2021" edition = "2021"
[features] [features]
@ -14,8 +14,9 @@ opt-level = 3
debug = true debug = true
[build-dependencies] [build-dependencies]
cc = "*" cc = "1.1.21"
[dependencies] [dependencies]
libafl = { path = "../../../libafl/" } libafl = { path = "../../../../libafl" }
libafl_bolts = { path = "../../../libafl_bolts/" } libafl_bolts = { path = "../../../../libafl_bolts" }
log = { version = "0.4.22", features = ["release_max_level_info"] }

View File

@ -17,7 +17,7 @@ use libafl::{
generators::RandPrintablesGenerator, generators::RandPrintablesGenerator,
inputs::{BytesInput, HasTargetBytes}, inputs::{BytesInput, HasTargetBytes},
monitors::SimpleMonitor, monitors::SimpleMonitor,
mutators::scheduled::{havoc_mutations, StdScheduledMutator}, mutators::{havoc_mutations::havoc_mutations, scheduled::StdScheduledMutator},
observers::{get_asan_runtime_flags, AsanBacktraceObserver, StdMapObserver}, observers::{get_asan_runtime_flags, AsanBacktraceObserver, StdMapObserver},
schedulers::QueueScheduler, schedulers::QueueScheduler,
stages::mutational::StdMutationalStage, stages::mutational::StdMutationalStage,
@ -25,6 +25,7 @@ use libafl::{
Error, Error,
}; };
use libafl_bolts::{ use libafl_bolts::{
nonzero,
rands::StdRand, rands::StdRand,
shmem::{unix_shmem, ShMem, ShMemId, ShMemProvider}, shmem::{unix_shmem, ShMem, ShMemId, ShMemProvider},
tuples::tuple_list, tuples::tuple_list,
@ -83,6 +84,7 @@ pub fn main() {
#[derive(Debug)] #[derive(Debug)]
struct MyExecutor { struct MyExecutor {
shmem_id: ShMemId, shmem_id: ShMemId,
timeout: Duration,
} }
impl CommandConfigurator<BytesInput> for MyExecutor { impl CommandConfigurator<BytesInput> for MyExecutor {
@ -105,14 +107,19 @@ pub fn main() {
} }
fn exec_timeout(&self) -> Duration { fn exec_timeout(&self) -> Duration {
Duration::from_secs(5) self.timeout
}
fn exec_timeout_mut(&mut self) -> &mut Duration {
&mut self.timeout
} }
} }
let mut executor = MyExecutor { shmem_id }.into_executor(tuple_list!(observer, bt_observer)); let timeout = Duration::from_secs(5);
let mut executor =
MyExecutor { shmem_id, timeout }.into_executor(tuple_list!(observer, bt_observer));
// Generator of printable bytearrays of max size 32 // Generator of printable bytearrays of max size 32
let mut generator = RandPrintablesGenerator::new(32); let mut generator = RandPrintablesGenerator::new(nonzero!(32));
// Generate 8 initial inputs // Generate 8 initial inputs
state state

View File

@ -1,6 +1,6 @@
[package] [package]
name = "forkserver_executor" name = "forkserver_executor"
version = "0.0.1" version = "0.14.1"
edition = "2021" edition = "2021"
@ -14,5 +14,6 @@ codegen-units = 1
opt-level = 3 opt-level = 3
[dependencies] [dependencies]
libafl = { path = "../../../libafl/" } libafl = { path = "../../../../libafl" }
libafl_bolts = { path = "../../../libafl_bolts/" } libafl_bolts = { path = "../../../../libafl_bolts" }
log = { version = "0.4.22", features = ["release_max_level_info"] }

Some files were not shown because too many files have changed in this diff Show More