Linux kernel fuzzing example (#2496)
* linux kernel (x509_cert) and process fuzzing example * rework filters * update to latest qemu * working for process and kernel fuzzing * new i2s mutator for binary only fuzzers * refactoring modules with new filtering interface * add state as parameter of harness * hide unused global in usermode * Script for stub bindings generation * do not try to check whether it is worth generating the bindings, always generate when the env variable is on. * add taplo to fmt_all.sh * Moved fuzzers (again) in a target-centric way. * fix rust 2024 warnings. * new libafl_qemu harness structure. * rename qemu_systemmode into qemu_baremetal * fix qemu baremetal makefile * fix formatter --------- Co-authored-by: Toka <tokazerkje@outlook.com>
109
.github/workflows/build_and_test.yml
vendored
@ -206,7 +206,7 @@ jobs:
|
|||||||
- name: Run a maturin build
|
- name: Run a maturin build
|
||||||
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
|
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/qemu/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-24.04
|
runs-on: ubuntu-24.04
|
||||||
@ -269,55 +269,53 @@ jobs:
|
|||||||
- ./fuzzers/baby/backtrace_baby_fuzzers/command_executor
|
- ./fuzzers/baby/backtrace_baby_fuzzers/command_executor
|
||||||
- ./fuzzers/baby/backtrace_baby_fuzzers/forkserver_executor
|
- ./fuzzers/baby/backtrace_baby_fuzzers/forkserver_executor
|
||||||
|
|
||||||
|
# Binary-only
|
||||||
|
- ./fuzzers/binary-only/fuzzbench_fork_qemu
|
||||||
|
- ./fuzzers/binary-only/frida_executable_libpng
|
||||||
|
- ./fuzzers/binary-only/frida_gdiplus
|
||||||
|
- ./fuzzers/binary-only/frida_libpng
|
||||||
|
- ./fuzzers/binary-only/fuzzbench_qemu
|
||||||
|
- ./fuzzers/binary-only/tinyinst_simple
|
||||||
|
|
||||||
# Forkserver
|
# Forkserver
|
||||||
- ./fuzzers/forkserver/forkserver_simple
|
- ./fuzzers/forkserver/forkserver_simple
|
||||||
- ./fuzzers/forkserver/forkserver_libafl_cc
|
- ./fuzzers/forkserver/forkserver_libafl_cc
|
||||||
|
- ./fuzzers/forkserver/fuzzbench_forkserver
|
||||||
|
- ./fuzzers/forkserver/fuzzbench_forkserver_cmplog
|
||||||
|
- ./fuzzers/forkserver/libafl-fuzz
|
||||||
|
|
||||||
# Frida
|
# Full-system
|
||||||
- ./fuzzers/frida/frida_executable_libpng
|
- ./fuzzers/full-system/nyx_libxml2_standalone
|
||||||
- ./fuzzers/frida/frida_gdiplus
|
- ./fuzzers/full-system/nyx_libxml2_parallel
|
||||||
- ./fuzzers/frida/frida_libpng
|
|
||||||
|
|
||||||
# Fuzzbench
|
# Grammar-aware
|
||||||
- ./fuzzers/fuzzbench/fuzzbench
|
- ./fuzzers/grammar-aware/nautilus_sync
|
||||||
- ./fuzzers/fuzzbench/fuzzbench_qemu
|
|
||||||
- ./fuzzers/fuzzbench/fuzzbench_fork_qemu
|
|
||||||
- ./fuzzers/fuzzbench/fuzzbench_text
|
|
||||||
- ./fuzzers/fuzzbench/fuzzbench_ctx
|
|
||||||
- ./fuzzers/fuzzbench/fuzzbench_forkserver_cmplog
|
|
||||||
- ./fuzzers/fuzzbench/fuzzbench_forkserver
|
|
||||||
|
|
||||||
# LibPNG
|
# In-process
|
||||||
- ./fuzzers/libpng/libfuzzer_libpng
|
- ./fuzzers/inprocess/cargo_fuzz
|
||||||
- ./fuzzers/libpng/libfuzzer_libpng_launcher
|
# - ./fuzzers/inprocess/dynamic_analysis
|
||||||
- ./fuzzers/libpng/libfuzzer_libpng_accounting
|
- ./fuzzers/inprocess/fuzzbench
|
||||||
- ./fuzzers/libpng/libfuzzer_libpng_centralized
|
- ./fuzzers/inprocess/fuzzbench_text
|
||||||
- ./fuzzers/libpng/libfuzzer_libpng_cmin
|
- ./fuzzers/inprocess/fuzzbench_ctx
|
||||||
- ./fuzzers/libpng/libfuzzer_libpng_norestart
|
- ./fuzzers/inprocess/libfuzzer_libmozjpeg
|
||||||
# - ./fuzzers/libpng/libfuzzer_libpng_tcp_manager
|
- ./fuzzers/inprocess/libfuzzer_libpng
|
||||||
|
- ./fuzzers/inprocess/libfuzzer_libpng_launcher
|
||||||
# Nyx
|
- ./fuzzers/inprocess/libfuzzer_libpng_accounting
|
||||||
- ./fuzzers/nyx/nyx_libxml2_standalone
|
- ./fuzzers/inprocess/libfuzzer_libpng_centralized
|
||||||
- ./fuzzers/nyx/nyx_libxml2_parallel
|
- ./fuzzers/inprocess/libfuzzer_libpng_cmin
|
||||||
|
- ./fuzzers/inprocess/libfuzzer_libpng_norestart
|
||||||
# Stb
|
# - ./fuzzers/inprocess/libfuzzer_libpng_tcp_manager
|
||||||
- ./fuzzers/stb/libfuzzer_stb_image_sugar
|
- ./fuzzers/inprocess/libfuzzer_stb_image_sugar
|
||||||
- ./fuzzers/stb/libfuzzer_stb_image
|
- ./fuzzers/inprocess/libfuzzer_stb_image
|
||||||
# - ./fuzzers/stb/libfuzzer_stb_image_concolic
|
# - ./fuzzers/inprocess/libfuzzer_stb_image_concolic
|
||||||
|
# - ./fuzzers/inprocess/libfuzzer_windows_asan
|
||||||
|
- ./fuzzers/inprocess/push_harness
|
||||||
|
- ./fuzzers/inprocess/push_stage_harness
|
||||||
|
# - ./fuzzers/inprocess/sqlite_centralized_multi_machine
|
||||||
|
- ./fuzzers/inprocess/tutorial
|
||||||
|
|
||||||
# Others
|
# Others
|
||||||
- ./fuzzers/others/cargo_fuzz
|
|
||||||
# - ./fuzzers/others/dynamic_analysis
|
|
||||||
- ./fuzzers/others/libafl_atheris
|
- ./fuzzers/others/libafl_atheris
|
||||||
- ./fuzzers/others/libafl-fuzz
|
|
||||||
- ./fuzzers/others/libfuzzer_libmozjpeg
|
|
||||||
# - ./fuzzers/others/libfuzzer_windows_asan
|
|
||||||
- ./fuzzers/others/nautilus_sync
|
|
||||||
- ./fuzzers/others/push_harness
|
|
||||||
- ./fuzzers/others/push_stage_harness
|
|
||||||
# - ./fuzzers/others/sqlite_centralized_multi_machine
|
|
||||||
- ./fuzzers/others/tinyinst_simple
|
|
||||||
- ./fuzzers/others/tutorial
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@ -356,10 +354,15 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-24.04]
|
os: [ubuntu-24.04]
|
||||||
fuzzer:
|
fuzzer:
|
||||||
- ./fuzzers/qemu/qemu_cmin
|
# Binary only
|
||||||
- ./fuzzers/qemu/qemu_systemmode
|
- ./fuzzers/binary-only/qemu_cmin
|
||||||
- ./fuzzers/qemu/qemu_coverage
|
- ./fuzzers/binary-only/qemu_coverage
|
||||||
- ./fuzzers/qemu/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
|
||||||
@ -426,8 +429,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- 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/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
|
||||||
@ -436,8 +439,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/workflows/windows-tester-prepare
|
- uses: ./.github/workflows/windows-tester-prepare
|
||||||
- name: Build fuzzers/stb/libfuzzer_stb_image
|
- name: Build fuzzers/inprocess/libfuzzer_stb_image
|
||||||
run: cd fuzzers/stb/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
|
||||||
@ -446,8 +449,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/workflows/windows-tester-prepare
|
- uses: ./.github/workflows/windows-tester-prepare
|
||||||
- name: Build fuzzers/frida/frida_gdiplus
|
- name: Build fuzzers/binary-only/frida_gdiplus
|
||||||
run: cd fuzzers/frida/frida_gdiplus/ && cargo make test && cargo make test_cmplog
|
run: cd fuzzers/binary-only/frida_gdiplus/ && cargo make test && cargo make test_cmplog
|
||||||
|
|
||||||
windows-tinyinst-simple:
|
windows-tinyinst-simple:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
@ -458,8 +461,8 @@ jobs:
|
|||||||
run: cargo install cxxbridge-cmd
|
run: cargo install cxxbridge-cmd
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/workflows/windows-tester-prepare
|
- uses: ./.github/workflows/windows-tester-prepare
|
||||||
- name: Build fuzzers/others/tinyinst_simple
|
- name: Build fuzzers/binary-only/tinyinst_simple
|
||||||
run: cd fuzzers/others/tinyinst_simple/ && cargo make test
|
run: cd fuzzers/binary-only/tinyinst_simple/ && cargo make test
|
||||||
|
|
||||||
windows-clippy:
|
windows-clippy:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
3
.github/workflows/md-config.json
vendored
@ -2,6 +2,9 @@
|
|||||||
"ignorePatterns": [
|
"ignorePatterns": [
|
||||||
{
|
{
|
||||||
"pattern": "^https://crates.io"
|
"pattern": "^https://crates.io"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pattern": "^https://github.com/AFLplusplus/linux-qemu-image-builder"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"aliveStatusCodes": [0, 200, 403]
|
"aliveStatusCodes": [0, 200, 403]
|
||||||
|
@ -93,7 +93,7 @@ cargo make run
|
|||||||
|
|
||||||
as long as the fuzzer directory has `Makefile.toml` file.
|
as long as the fuzzer directory has `Makefile.toml` file.
|
||||||
|
|
||||||
The best-tested fuzzer is [`./fuzzers/libpng/libfuzzer_libpng`](./fuzzers/libpng/libfuzzer_libpng), a multicore libfuzzer-like fuzzer using LibAFL for a libpng harness.
|
The best-tested fuzzer is [`./fuzzers/inprocess/libfuzzer_libpng`](./fuzzers/inprocess/libfuzzer_libpng), a multicore libfuzzer-like fuzzer using LibAFL for a libpng harness.
|
||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
|
|
||||||
|
@ -6,18 +6,17 @@ You can find here all the example fuzzers built on top of LibAFL.
|
|||||||
They are sorted by fuzzer types:
|
They are sorted by fuzzer types:
|
||||||
|
|
||||||
- `baby`: Minimal fuzzers demonstrating a specific feature.
|
- `baby`: Minimal fuzzers demonstrating a specific feature.
|
||||||
|
- `binary-only`: Fuzzers for binary-only targets.
|
||||||
- `forkserver`: Fuzzers using a forkserver-style executor.
|
- `forkserver`: Fuzzers using a forkserver-style executor.
|
||||||
- `frida`: Fuzzers using [Frida](../libafl_frida).
|
- `full-system`: Fuzzers for full-system targets (kernels, firmwares, etc...).
|
||||||
- `fuzzbench`: Fuzzbench fuzzers.
|
- `fuzzbench`: Fuzzbench fuzzers.
|
||||||
- `libpng`: Fuzzers targeting libpng.
|
- `grammar-aware`: Grammar-aware fuzzers.
|
||||||
- `nyx`: Fuzzers based on [Nyx](../libafl_nyx).
|
- `inprocess`: In-process fuzzers, whn they don't fit another more specific type.
|
||||||
- `others`: Various fuzzers, with no specific categories.
|
- `others`: Fuzzers for specific / specialized things, that do not go in a specific category.
|
||||||
- `qemu`: Fuzzers using [Qemu](../libafl_qemu).
|
|
||||||
- `stb`: Fuzzers targeting stb.
|
|
||||||
|
|
||||||
## Paper Artifacts
|
## Paper Artifacts
|
||||||
|
|
||||||
Multiple papers based on LibAFL have been published alongside artifacts.
|
Multiple papers based on LibAFL have been published and include artifacts.
|
||||||
Here is a list of LibAFL artifacts:
|
Here is a list of LibAFL artifacts:
|
||||||
|
|
||||||
- Fuzzbench implementation: https://github.com/AFLplusplus/libafl_fuzzbench
|
- Fuzzbench implementation: https://github.com/AFLplusplus/libafl_fuzzbench
|
||||||
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 218 B |
Before Width: | Height: | Size: 376 B After Width: | Height: | Size: 376 B |
Before Width: | Height: | Size: 228 B After Width: | Height: | Size: 228 B |
Before Width: | Height: | Size: 427 B After Width: | Height: | Size: 427 B |
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 218 B |
Before Width: | Height: | Size: 376 B After Width: | Height: | Size: 376 B |
Before Width: | Height: | Size: 228 B After Width: | Height: | Size: 228 B |
Before Width: | Height: | Size: 427 B After Width: | Height: | Size: 427 B |
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 218 B |
Before Width: | Height: | Size: 376 B After Width: | Height: | Size: 376 B |
Before Width: | Height: | Size: 228 B After Width: | Height: | Size: 228 B |
Before Width: | Height: | Size: 427 B After Width: | Height: | Size: 427 B |
@ -52,7 +52,7 @@ make -C libpng-1.6.37
|
|||||||
cc -c "${PROJECT_DIR}/libfuzzer_main.c"
|
cc -c "${PROJECT_DIR}/libfuzzer_main.c"
|
||||||
# Build the libpng harness
|
# Build the libpng harness
|
||||||
c++ \
|
c++ \
|
||||||
../../libpng/libfuzzer_libpng/harness.cc \
|
../../inprocess/libfuzzer_libpng/harness.cc \
|
||||||
./libpng-1.6.37/.libs/libpng16.a \
|
./libpng-1.6.37/.libs/libpng16.a \
|
||||||
./libfuzzer_main.o \
|
./libfuzzer_main.o \
|
||||||
-I./libpng-1.6.37/ \
|
-I./libpng-1.6.37/ \
|
@ -50,7 +50,7 @@ use libafl_qemu::{
|
|||||||
filter_qemu_args,
|
filter_qemu_args,
|
||||||
modules::{
|
modules::{
|
||||||
cmplog::{CmpLogChildModule, CmpLogMap, CmpLogObserver},
|
cmplog::{CmpLogChildModule, CmpLogMap, CmpLogObserver},
|
||||||
edges::{EdgeCoverageChildModule, EDGES_MAP_PTR, EDGES_MAP_SIZE_IN_USE},
|
edges::{StdEdgeCoverageChildModule, EDGES_MAP_PTR, EDGES_MAP_SIZE_IN_USE},
|
||||||
},
|
},
|
||||||
Emulator, GuestReg, MmapPerms, QemuExitError, QemuExitReason, QemuForkExecutor,
|
Emulator, GuestReg, MmapPerms, QemuExitError, QemuExitReason, QemuForkExecutor,
|
||||||
QemuShutdownCause, Regs,
|
QemuShutdownCause, Regs,
|
||||||
@ -151,7 +151,7 @@ fn fuzz(
|
|||||||
let env: Vec<(String, String)> = env::vars().collect();
|
let env: Vec<(String, String)> = env::vars().collect();
|
||||||
|
|
||||||
let emulator_modules = tuple_list!(
|
let emulator_modules = tuple_list!(
|
||||||
EdgeCoverageChildModule::default(),
|
StdEdgeCoverageChildModule::builder().build(),
|
||||||
CmpLogChildModule::default(),
|
CmpLogChildModule::default(),
|
||||||
);
|
);
|
||||||
|
|
@ -52,7 +52,7 @@ make -C libpng-1.6.37
|
|||||||
cc -c "${PROJECT_DIR}/libfuzzer_main.c"
|
cc -c "${PROJECT_DIR}/libfuzzer_main.c"
|
||||||
# Build the libpng harness
|
# Build the libpng harness
|
||||||
c++ \
|
c++ \
|
||||||
../../libpng/libfuzzer_libpng/harness.cc \
|
../../inprocess/libfuzzer_libpng/harness.cc \
|
||||||
./libpng-1.6.37/.libs/libpng16.a \
|
./libpng-1.6.37/.libs/libpng16.a \
|
||||||
./libfuzzer_main.o \
|
./libfuzzer_main.o \
|
||||||
-I./libpng-1.6.37/ \
|
-I./libpng-1.6.37/ \
|
||||||
@ -76,7 +76,7 @@ args = [
|
|||||||
"./${FUZZER_NAME}",
|
"./${FUZZER_NAME}",
|
||||||
"--",
|
"--",
|
||||||
"--libafl-in",
|
"--libafl-in",
|
||||||
"../../libpng/libfuzzer_libpng/corpus",
|
"../../inprocess/libfuzzer_libpng/corpus",
|
||||||
"--libafl-out",
|
"--libafl-out",
|
||||||
"./out",
|
"./out",
|
||||||
"./${FUZZER_NAME}",
|
"./${FUZZER_NAME}",
|
@ -51,7 +51,7 @@ use libafl_qemu::{
|
|||||||
// asan::{init_with_asan, QemuAsanHelper},
|
// asan::{init_with_asan, QemuAsanHelper},
|
||||||
modules::cmplog::{CmpLogModule, CmpLogObserver},
|
modules::cmplog::{CmpLogModule, CmpLogObserver},
|
||||||
modules::edges::{
|
modules::edges::{
|
||||||
edges_map_mut_ptr, EdgeCoverageModule, EDGES_MAP_SIZE_IN_USE, MAX_EDGES_FOUND,
|
edges_map_mut_ptr, StdEdgeCoverageModule, EDGES_MAP_SIZE_IN_USE, MAX_EDGES_FOUND,
|
||||||
},
|
},
|
||||||
Emulator,
|
Emulator,
|
||||||
GuestReg,
|
GuestReg,
|
||||||
@ -326,38 +326,39 @@ fn fuzz(
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |_emulator: &mut Emulator<_, _, _, _, _>, input: &BytesInput| {
|
let mut harness =
|
||||||
let target = input.target_bytes();
|
|_emulator: &mut Emulator<_, _, _, _, _>, _state: &mut _, input: &BytesInput| {
|
||||||
let mut buf = target.as_slice();
|
let target = input.target_bytes();
|
||||||
let mut len = buf.len();
|
let mut buf = target.as_slice();
|
||||||
if len > MAX_INPUT_SIZE {
|
let mut len = buf.len();
|
||||||
buf = &buf[0..MAX_INPUT_SIZE];
|
if len > MAX_INPUT_SIZE {
|
||||||
len = MAX_INPUT_SIZE;
|
buf = &buf[0..MAX_INPUT_SIZE];
|
||||||
}
|
len = MAX_INPUT_SIZE;
|
||||||
|
|
||||||
unsafe {
|
|
||||||
qemu.write_mem(input_addr, buf);
|
|
||||||
|
|
||||||
qemu.write_reg(Regs::Rdi, input_addr).unwrap();
|
|
||||||
qemu.write_reg(Regs::Rsi, len as GuestReg).unwrap();
|
|
||||||
qemu.write_reg(Regs::Rip, test_one_input_ptr).unwrap();
|
|
||||||
qemu.write_reg(Regs::Rsp, stack_ptr).unwrap();
|
|
||||||
|
|
||||||
match qemu.run() {
|
|
||||||
Ok(QemuExitReason::Breakpoint(_)) => {}
|
|
||||||
Ok(QemuExitReason::End(QemuShutdownCause::HostSignal(Signal::SigInterrupt))) => {
|
|
||||||
process::exit(0)
|
|
||||||
}
|
|
||||||
Err(QemuExitError::UnexpectedExit) => return ExitKind::Crash,
|
|
||||||
_ => panic!("Unexpected QEMU exit."),
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ExitKind::Ok
|
unsafe {
|
||||||
};
|
qemu.write_mem(input_addr, buf);
|
||||||
|
|
||||||
|
qemu.write_reg(Regs::Rdi, input_addr).unwrap();
|
||||||
|
qemu.write_reg(Regs::Rsi, len as GuestReg).unwrap();
|
||||||
|
qemu.write_reg(Regs::Rip, test_one_input_ptr).unwrap();
|
||||||
|
qemu.write_reg(Regs::Rsp, stack_ptr).unwrap();
|
||||||
|
|
||||||
|
match qemu.run() {
|
||||||
|
Ok(QemuExitReason::Breakpoint(_)) => {}
|
||||||
|
Ok(QemuExitReason::End(QemuShutdownCause::HostSignal(
|
||||||
|
Signal::SigInterrupt,
|
||||||
|
))) => process::exit(0),
|
||||||
|
Err(QemuExitError::UnexpectedExit) => return ExitKind::Crash,
|
||||||
|
_ => panic!("Unexpected QEMU exit."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExitKind::Ok
|
||||||
|
};
|
||||||
|
|
||||||
let modules = tuple_list!(
|
let modules = tuple_list!(
|
||||||
EdgeCoverageModule::default(),
|
StdEdgeCoverageModule::builder().build(),
|
||||||
CmpLogModule::default(),
|
CmpLogModule::default(),
|
||||||
// QemuAsanHelper::default(asan),
|
// QemuAsanHelper::default(asan),
|
||||||
//QemuSnapshotHelper::new()
|
//QemuSnapshotHelper::new()
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 218 B |
Before Width: | Height: | Size: 376 B After Width: | Height: | Size: 376 B |
Before Width: | Height: | Size: 228 B After Width: | Height: | Size: 228 B |
Before Width: | Height: | Size: 427 B After Width: | Height: | Size: 427 B |
@ -28,7 +28,7 @@ use libafl_bolts::{
|
|||||||
};
|
};
|
||||||
use libafl_qemu::{
|
use libafl_qemu::{
|
||||||
elf::EasyElf,
|
elf::EasyElf,
|
||||||
modules::edges::{EdgeCoverageChildModule, EDGES_MAP_PTR, EDGES_MAP_SIZE_IN_USE},
|
modules::edges::{StdEdgeCoverageChildModule, EDGES_MAP_PTR, EDGES_MAP_SIZE_IN_USE},
|
||||||
ArchExtras, CallingConvention, Emulator, GuestAddr, GuestReg, MmapPerms, Qemu, QemuExitError,
|
ArchExtras, CallingConvention, Emulator, GuestAddr, GuestReg, MmapPerms, Qemu, QemuExitError,
|
||||||
QemuExitReason, QemuForkExecutor, QemuShutdownCause, Regs,
|
QemuExitReason, QemuForkExecutor, QemuShutdownCause, Regs,
|
||||||
};
|
};
|
||||||
@ -218,7 +218,7 @@ pub fn fuzz() -> Result<(), Error> {
|
|||||||
ExitKind::Ok
|
ExitKind::Ok
|
||||||
};
|
};
|
||||||
|
|
||||||
let modules = tuple_list!(EdgeCoverageChildModule::default(),);
|
let modules = tuple_list!(StdEdgeCoverageChildModule::builder().build());
|
||||||
|
|
||||||
let emulator = Emulator::empty().qemu(qemu).modules(modules).build()?;
|
let emulator = Emulator::empty().qemu(qemu).modules(modules).build()?;
|
||||||
|
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 218 B |
Before Width: | Height: | Size: 376 B After Width: | Height: | Size: 376 B |
Before Width: | Height: | Size: 228 B After Width: | Height: | Size: 228 B |
Before Width: | Height: | Size: 427 B After Width: | Height: | Size: 427 B |
@ -27,7 +27,7 @@ use libafl_bolts::{
|
|||||||
};
|
};
|
||||||
use libafl_qemu::{
|
use libafl_qemu::{
|
||||||
elf::EasyElf,
|
elf::EasyElf,
|
||||||
modules::{drcov::DrCovModule, QemuInstrumentationAddressRangeFilter},
|
modules::{drcov::DrCovModule, StdAddressFilter},
|
||||||
ArchExtras, CallingConvention, Emulator, GuestAddr, GuestReg, MmapPerms, Qemu, QemuExecutor,
|
ArchExtras, CallingConvention, Emulator, GuestAddr, GuestReg, MmapPerms, Qemu, QemuExecutor,
|
||||||
QemuExitReason, QemuRWError, QemuShutdownCause, Regs,
|
QemuExitReason, QemuRWError, QemuShutdownCause, Regs,
|
||||||
};
|
};
|
||||||
@ -175,18 +175,19 @@ pub fn fuzz() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut harness = |_emulator: &mut Emulator<_, _, _, _, _>, input: &BytesInput| {
|
let mut harness =
|
||||||
let target = input.target_bytes();
|
|_emulator: &mut Emulator<_, _, _, _, _>, _state: &mut _, input: &BytesInput| {
|
||||||
let mut buf = target.as_slice();
|
let target = input.target_bytes();
|
||||||
let mut len = buf.len();
|
let mut buf = target.as_slice();
|
||||||
if len > MAX_INPUT_SIZE {
|
let mut len = buf.len();
|
||||||
buf = &buf[0..MAX_INPUT_SIZE];
|
if len > MAX_INPUT_SIZE {
|
||||||
len = MAX_INPUT_SIZE;
|
buf = &buf[0..MAX_INPUT_SIZE];
|
||||||
}
|
len = MAX_INPUT_SIZE;
|
||||||
let len = len as GuestReg;
|
}
|
||||||
reset(buf, len).unwrap();
|
let len = len as GuestReg;
|
||||||
ExitKind::Ok
|
reset(buf, len).unwrap();
|
||||||
};
|
ExitKind::Ok
|
||||||
|
};
|
||||||
|
|
||||||
let mut run_client =
|
let mut run_client =
|
||||||
|state: Option<_>, mut mgr: LlmpRestartingEventManager<_, _, _>, core_id| {
|
|state: Option<_>, mut mgr: LlmpRestartingEventManager<_, _, _>, core_id| {
|
||||||
@ -233,7 +234,7 @@ pub fn fuzz() {
|
|||||||
cov_path.set_file_name(format!("{coverage_name}-{core:03}.{coverage_extension}"));
|
cov_path.set_file_name(format!("{coverage_name}-{core:03}.{coverage_extension}"));
|
||||||
|
|
||||||
let emulator_modules = tuple_list!(DrCovModule::new(
|
let emulator_modules = tuple_list!(DrCovModule::new(
|
||||||
QemuInstrumentationAddressRangeFilter::None,
|
StdAddressFilter::default(),
|
||||||
cov_path,
|
cov_path,
|
||||||
false,
|
false,
|
||||||
));
|
));
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 218 B |
Before Width: | Height: | Size: 376 B After Width: | Height: | Size: 376 B |
Before Width: | Height: | Size: 228 B After Width: | Height: | Size: 228 B |
Before Width: | Height: | Size: 427 B After Width: | Height: | Size: 427 B |
@ -16,8 +16,8 @@ use libafl_qemu::{
|
|||||||
asan::{init_qemu_with_asan, AsanModule},
|
asan::{init_qemu_with_asan, AsanModule},
|
||||||
asan_guest::{init_qemu_with_asan_guest, AsanGuestModule},
|
asan_guest::{init_qemu_with_asan_guest, AsanGuestModule},
|
||||||
cmplog::CmpLogModule,
|
cmplog::CmpLogModule,
|
||||||
edges::EdgeCoverageModule,
|
edges::StdEdgeCoverageModule,
|
||||||
QemuInstrumentationAddressRangeFilter,
|
StdAddressFilter,
|
||||||
},
|
},
|
||||||
ArchExtras, GuestAddr, Qemu,
|
ArchExtras, GuestAddr, Qemu,
|
||||||
};
|
};
|
||||||
@ -68,7 +68,7 @@ impl<'a> Client<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::similar_names)] // elf != self
|
#[allow(clippy::similar_names)] // elf != self
|
||||||
fn coverage_filter(&self, qemu: &Qemu) -> Result<QemuInstrumentationAddressRangeFilter, Error> {
|
fn coverage_filter(&self, qemu: &Qemu) -> Result<StdAddressFilter, Error> {
|
||||||
/* Conversion is required on 32-bit targets, but not on 64-bit ones */
|
/* Conversion is required on 32-bit targets, but not on 64-bit ones */
|
||||||
if let Some(includes) = &self.options.include {
|
if let Some(includes) = &self.options.include {
|
||||||
#[cfg_attr(target_pointer_width = "64", allow(clippy::useless_conversion))]
|
#[cfg_attr(target_pointer_width = "64", allow(clippy::useless_conversion))]
|
||||||
@ -79,7 +79,7 @@ impl<'a> Client<'a> {
|
|||||||
end: x.end.into(),
|
end: x.end.into(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<Range<GuestAddr>>>();
|
.collect::<Vec<Range<GuestAddr>>>();
|
||||||
Ok(QemuInstrumentationAddressRangeFilter::AllowList(rules))
|
Ok(StdAddressFilter::allow_list(rules))
|
||||||
} else if let Some(excludes) = &self.options.exclude {
|
} else if let Some(excludes) = &self.options.exclude {
|
||||||
#[cfg_attr(target_pointer_width = "64", allow(clippy::useless_conversion))]
|
#[cfg_attr(target_pointer_width = "64", allow(clippy::useless_conversion))]
|
||||||
let rules = excludes
|
let rules = excludes
|
||||||
@ -89,16 +89,14 @@ impl<'a> Client<'a> {
|
|||||||
end: x.end.into(),
|
end: x.end.into(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<Range<GuestAddr>>>();
|
.collect::<Vec<Range<GuestAddr>>>();
|
||||||
Ok(QemuInstrumentationAddressRangeFilter::DenyList(rules))
|
Ok(StdAddressFilter::deny_list(rules))
|
||||||
} else {
|
} else {
|
||||||
let mut elf_buffer = Vec::new();
|
let mut elf_buffer = Vec::new();
|
||||||
let elf = EasyElf::from_file(qemu.binary_path(), &mut elf_buffer)?;
|
let elf = EasyElf::from_file(qemu.binary_path(), &mut elf_buffer)?;
|
||||||
let range = elf
|
let range = elf
|
||||||
.get_section(".text", qemu.load_addr())
|
.get_section(".text", qemu.load_addr())
|
||||||
.ok_or_else(|| Error::key_not_found("Failed to find .text section"))?;
|
.ok_or_else(|| Error::key_not_found("Failed to find .text section"))?;
|
||||||
Ok(QemuInstrumentationAddressRangeFilter::AllowList(vec![
|
Ok(StdAddressFilter::allow_list(vec![range]))
|
||||||
range,
|
|
||||||
]))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +165,9 @@ impl<'a> Client<'a> {
|
|||||||
|
|
||||||
let is_cmplog = self.options.is_cmplog_core(core_id);
|
let is_cmplog = self.options.is_cmplog_core(core_id);
|
||||||
|
|
||||||
let edge_coverage_module = EdgeCoverageModule::new(self.coverage_filter(&qemu)?);
|
let edge_coverage_module = StdEdgeCoverageModule::builder()
|
||||||
|
.address_filter(self.coverage_filter(&qemu)?)
|
||||||
|
.build();
|
||||||
|
|
||||||
let instance = Instance::builder()
|
let instance = Instance::builder()
|
||||||
.options(self.options)
|
.options(self.options)
|