Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcondiro committed Feb 17, 2025
2 parents 443d91f + a30cce1 commit 8b99358
Show file tree
Hide file tree
Showing 47 changed files with 2,120 additions and 664 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,27 @@ jobs:
- 'libafl_targets/**'
- 'libafl_qemu/**'
- 'fuzzers/**/*qemu*/**'
fuzzer-unicorn:
runs-on: ubuntu-24.04
needs:
- fuzzers-preflight
strategy:
fail-fast: false
matrix:
os: [ ubuntu-24.04 ]
fuzzer:
- ./fuzzers/full_system/unicorn
steps:
- uses: actions/checkout@v4
- uses: ./.github/workflows/fuzzer-tester-prepare
- name: "Install dependencies"
if: runner.os == 'Linux'
shell: bash
run: sudo apt-get update && sudo apt-get install gcc gcc-arm-linux-gnueabihf gcc-aarch64-linux-gnu
- name: Build and run example fuzzers (Linux)
if: runner.os == 'Linux'
shell: bash
run: RUN_ON_CI=1 LLVM_CONFIG=llvm-config-${{env.MAIN_LLVM_VERSION}} ./scripts/test_fuzzer.sh ${{ matrix.fuzzer }}

fuzzers-qemu:
needs:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,5 @@ harness
program
fuzzer_libpng*
forkserver_simple

*.patch
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ members = [
"libafl_intelpt",
"libafl_libfuzzer",
"libafl_nyx",
"libafl_unicorn",
"libafl_targets",
"libafl_tinyinst",
"libafl_qemu",
Expand Down Expand Up @@ -88,6 +89,7 @@ bindgen = "0.71.1"
# 2024-12-16: bitbybit 1.3.3 is leading CI to fail due to missing docs.
# fixme: Change this to 1.3.3 when the issue https://github.com/danlehmann/bitfield/issues/66 is resolved.
bitbybit = "=1.3.2" # bitfields, use this for bit fields and bit enums
capstone = "0.13.0" # Disassembler used in libafl_unicorn to provide disassembly on crash
clap = "4.5.18"
cc = "1.1.21"
cmake = "0.1.51"
Expand Down Expand Up @@ -121,6 +123,7 @@ strum_macros = "0.27.0"
toml = "0.8.19" # For parsing the injections toml file
typed-builder = "0.20.0" # Implement the builder pattern at compiletime
typeid = "1.0.0" # Safe type_eq that doesn't rely on std specialization
unicorn-engine = "2.0.1" # Used in libafl_unicorn
uuid = { version = "1.10.0", features = ["serde", "v4"] }
which = "6.0.3"
windows = "0.59.0"
Expand Down
17 changes: 11 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ ENV SCCACHE_DIR=$HOME/.cache/sccache
ENV RUSTC_WRAPPER="/usr/local/cargo/bin/sccache"
ENV IS_DOCKER="1"
RUN sh -c 'echo set encoding=utf-8 > /root/.vimrc' \
echo "export PS1='"'[LibAFL \h] \w$(__git_ps1) \$ '"'" >> ~/.bashrc && \
mkdir ~/.cargo && \
echo "[build]\nrustc-wrapper = \"${RUSTC_WRAPPER}\"" >> ~/.cargo/config
echo "export PS1='"'[LibAFL \h] \w$(__git_ps1) \$ '"'" >> ~/.bashrc && \
mkdir ~/.cargo && \
echo "[build]\nrustc-wrapper = \"${RUSTC_WRAPPER}\"" >> ~/.cargo/config

RUN rustup default nightly
RUN rustup component add rustfmt clippy
Expand All @@ -25,9 +25,9 @@ RUN rustup component add rustfmt clippy
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 set -ex &&\
wget https://apt.llvm.org/llvm.sh &&\
chmod +x llvm.sh &&\
./llvm.sh ${LLVM_VERSION}
wget https://apt.llvm.org/llvm.sh &&\
chmod +x llvm.sh &&\
./llvm.sh ${LLVM_VERSION}


# Copy a dummy.rs and Cargo.toml first, so that dependencies are cached
Expand Down Expand Up @@ -55,6 +55,9 @@ 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_unicorn/Cargo.toml libafl_unicorn/
COPY scripts/dummy.rs libafl_unicorn/src/lib.rs

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

Expand Down Expand Up @@ -149,6 +152,8 @@ COPY libafl_libfuzzer/build.rs libafl_libfuzzer/build.rs
RUN touch libafl_libfuzzer/src/lib.rs
COPY libafl_intelpt/src libafl_intelpt/src
RUN touch libafl_intelpt/src/lib.rs
COPY libafl_unicorn/src libafl_unicorn/src
RUN touch libafl_unicorn/src/lib.rs
RUN cargo build && cargo build --release

# Copy fuzzers over
Expand Down
2 changes: 1 addition & 1 deletion fuzzers/binary_only/frida_executable_libpng/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ libafl = { path = "../../../libafl", features = [
"frida_cli",
] } #, "llmp_small_maps", "llmp_debug"]}
libafl_bolts = { path = "../../../libafl_bolts" }
frida-gum = { version = "0.16.5", features = [
frida-gum = { version = "0.16.7", features = [
"auto-download",
"event-sink",
"invocation-listener",
Expand Down
73 changes: 52 additions & 21 deletions fuzzers/binary_only/frida_executable_libpng/src/fuzzer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! A libfuzzer-like fuzzer with llmp-multithreading support and restarts
//! The example harness is built for libpng.
use std::{path::PathBuf, ptr::null};
use std::{cell::RefCell, path::PathBuf, ptr::null, rc::Rc};

use frida_gum::Gum;
use libafl::{
Expand Down Expand Up @@ -43,6 +43,7 @@ use libafl_frida::{
cmplog_rt::CmpLogRuntime,
coverage_rt::{CoverageRuntime, MAP_SIZE},
executor::FridaInProcessExecutor,
frida_helper_shutdown_observer::FridaHelperObserver,
helper::FridaInstrumentationHelper,
};
use libafl_targets::cmplog::CmpLogObserver;
Expand Down Expand Up @@ -113,16 +114,22 @@ unsafe fn fuzz(
let asan = AsanRuntime::new(options);

#[cfg(unix)]
let mut frida_helper =
FridaInstrumentationHelper::new(&gum, options, tuple_list!(coverage, asan));
let frida_helper = Rc::new(RefCell::new(FridaInstrumentationHelper::new(
&gum,
options,
tuple_list!(coverage, asan),
)));
#[cfg(windows)]
let mut frida_helper =
FridaInstrumentationHelper::new(&gum, &options, tuple_list!(coverage));
let frida_helper = Rc::new(RefCell::new(FridaInstrumentationHelper::new(
&gum,
&options,
tuple_list!(coverage),
)));

// Create an observation channel using the coverage map
let edges_observer = HitcountsMapObserver::new(StdMapObserver::from_mut_ptr(
"edges",
frida_helper.map_mut_ptr().unwrap(),
frida_helper.borrow_mut().map_mut_ptr().unwrap(),
MAP_SIZE,
))
.track_indices();
Expand All @@ -131,6 +138,7 @@ unsafe fn fuzz(
let time_observer = TimeObserver::new("time");
#[cfg(unix)]
let asan_observer = AsanErrorsObserver::from_static_asan_errors();
let frida_helper_observer = FridaHelperObserver::new(Rc::clone(&frida_helper));

// Feedback to rate the interestingness of an input
// This one is composed by two Feedbacks in OR
Expand Down Expand Up @@ -196,9 +204,14 @@ unsafe fn fuzz(
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);

#[cfg(unix)]
let observers = tuple_list!(edges_observer, time_observer, asan_observer);
let observers = tuple_list!(
frida_helper_observer,
edges_observer,
time_observer,
asan_observer
);
#[cfg(windows)]
let observers = tuple_list!(edges_observer, time_observer);
let observers = tuple_list!(frida_helper_observer, edges_observer, time_observer);

// Create the executor for an in-process function with just one observer for edge coverage
let mut executor = FridaInProcessExecutor::new(
Expand All @@ -210,7 +223,7 @@ unsafe fn fuzz(
&mut state,
&mut mgr,
)?,
&mut frida_helper,
Rc::clone(&frida_helper),
);

// In case the corpus is empty (on first run), reset
Expand Down Expand Up @@ -238,13 +251,16 @@ unsafe fn fuzz(
let coverage = CoverageRuntime::new();
let cmplog = CmpLogRuntime::new();

let mut frida_helper =
FridaInstrumentationHelper::new(&gum, options, tuple_list!(coverage, cmplog));
let mut frida_helper = Rc::new(RefCell::new(FridaInstrumentationHelper::new(
&gum,
options,
tuple_list!(coverage, cmplog),
)));

// Create an observation channel using the coverage map
let edges_observer = HitcountsMapObserver::new(StdMapObserver::from_mut_ptr(
"edges",
frida_helper.map_mut_ptr().unwrap(),
frida_helper.borrow_mut().map_mut_ptr().unwrap(),
MAP_SIZE,
))
.track_indices();
Expand All @@ -253,6 +269,7 @@ unsafe fn fuzz(
let time_observer = TimeObserver::new("time");
#[cfg(unix)]
let asan_observer = AsanErrorsObserver::from_static_asan_errors();
let frida_helper_observer = FridaHelperObserver::new(Rc::clone(&frida_helper));

// Feedback to rate the interestingness of an input
// This one is composed by two Feedbacks in OR
Expand Down Expand Up @@ -316,9 +333,14 @@ unsafe fn fuzz(
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);

#[cfg(unix)]
let observers = tuple_list!(edges_observer, time_observer, asan_observer);
let observers = tuple_list!(
frida_helper_observer,
edges_observer,
time_observer,
asan_observer
);
#[cfg(windows)]
let observers = tuple_list!(edges_observer, time_observer);
let observers = tuple_list!(frida_helper_observer, edges_observer, time_observer);

// Create the executor for an in-process function with just one observer for edge coverage
let mut executor = FridaInProcessExecutor::new(
Expand All @@ -330,7 +352,7 @@ unsafe fn fuzz(
&mut state,
&mut mgr,
)?,
&mut frida_helper,
Rc::clone(&frida_helper),
);

// In case the corpus is empty (on first run), reset
Expand Down Expand Up @@ -373,13 +395,16 @@ unsafe fn fuzz(

let coverage = CoverageRuntime::new();

let mut frida_helper =
FridaInstrumentationHelper::new(&gum, options, tuple_list!(coverage));
let mut frida_helper = Rc::new(RefCell::new(FridaInstrumentationHelper::new(
&gum,
options,
tuple_list!(coverage),
)));

// Create an observation channel using the coverage map
let edges_observer = HitcountsMapObserver::new(StdMapObserver::from_mut_ptr(
"edges",
frida_helper.map_mut_ptr().unwrap(),
frida_helper.borrow_mut().map_mut_ptr().unwrap(),
MAP_SIZE,
))
.track_indices();
Expand All @@ -388,6 +413,7 @@ unsafe fn fuzz(
let time_observer = TimeObserver::new("time");
#[cfg(unix)]
let asan_observer = AsanErrorsObserver::from_static_asan_errors();
let frida_helper_observer = FridaHelperObserver::new(Rc::clone(&frida_helper));

// Feedback to rate the interestingness of an input
// This one is composed by two Feedbacks in OR
Expand Down Expand Up @@ -451,9 +477,14 @@ unsafe fn fuzz(
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);

#[cfg(unix)]
let observers = tuple_list!(edges_observer, time_observer, asan_observer);
let observers = tuple_list!(
frida_helper_observer,
edges_observer,
time_observer,
asan_observer
);
#[cfg(windows)]
let observers = tuple_list!(edges_observer, time_observer);
let observers = tuple_list!(frida_helper_observer, edges_observer, time_observer);

// Create the executor for an in-process function with just one observer for edge coverage
let mut executor = FridaInProcessExecutor::new(
Expand All @@ -465,7 +496,7 @@ unsafe fn fuzz(
&mut state,
&mut mgr,
)?,
&mut frida_helper,
Rc::clone(&frida_helper),
);

// In case the corpus is empty (on first run), reset
Expand Down
2 changes: 1 addition & 1 deletion fuzzers/binary_only/frida_libpng/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ libafl = { path = "../../../libafl", features = [
"errors_backtrace",
] } #, "llmp_small_maps", "llmp_debug"]}
libafl_bolts = { path = "../../../libafl_bolts" }
frida-gum = { version = "0.16.5", features = [
frida-gum = { version = "0.16.7", features = [
"auto-download",
"event-sink",
"invocation-listener",
Expand Down
23 changes: 17 additions & 6 deletions fuzzers/binary_only/frida_libpng/src/fuzzer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! A libfuzzer-like fuzzer with llmp-multithreading support and restarts
//! The example harness is built for libpng.
use std::path::PathBuf;
use std::{cell::RefCell, path::PathBuf, rc::Rc};

use frida_gum::Gum;
use libafl::{
Expand Down Expand Up @@ -40,6 +40,7 @@ use libafl_frida::{
cmplog_rt::CmpLogRuntime,
coverage_rt::{CoverageRuntime, MAP_SIZE},
executor::FridaInProcessExecutor,
frida_helper_shutdown_observer::FridaHelperObserver,
helper::{FridaInstrumentationHelper, IfElseRuntime},
};
use libafl_targets::cmplog::CmpLogObserver;
Expand Down Expand Up @@ -104,7 +105,7 @@ fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
let options_clone = options.clone();
let client_description_clone2 = client_description.clone();
let options_clone2 = options.clone();
let mut frida_helper = FridaInstrumentationHelper::new(
let frida_helper = Rc::new(RefCell::new(FridaInstrumentationHelper::new(
&gum,
options,
tuple_list!(
Expand All @@ -120,17 +121,22 @@ fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
),
coverage
),
);
)));

// Create an observation channel using the coverage map
let edges_observer = HitcountsMapObserver::new(unsafe {
StdMapObserver::from_mut_ptr("edges", frida_helper.map_mut_ptr().unwrap(), MAP_SIZE)
StdMapObserver::from_mut_ptr(
"edges",
frida_helper.borrow_mut().map_mut_ptr().unwrap(),
MAP_SIZE,
)
})
.track_indices();

// Create an observation channel to keep track of the execution time
let time_observer = TimeObserver::new("time");
let asan_observer = AsanErrorsObserver::from_static_asan_errors();
let frida_helper_observer = FridaHelperObserver::new(Rc::clone(&frida_helper));

// Feedback to rate the interestingness of an input
// This one is composed by two Feedbacks in OR
Expand Down Expand Up @@ -187,7 +193,12 @@ fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
// A fuzzer with feedbacks and a corpus scheduler
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);

let observers = tuple_list!(edges_observer, time_observer, asan_observer);
let observers = tuple_list!(
frida_helper_observer,
edges_observer,
time_observer,
asan_observer
);

// Create the executor for an in-process function with just one observer for edge coverage
let executor = FridaInProcessExecutor::new(
Expand All @@ -200,7 +211,7 @@ fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
&mut mgr,
options.timeout,
)?,
&mut frida_helper,
Rc::clone(&frida_helper),
);
// Create an observation channel using cmplog map
let cmplog_observer = CmpLogObserver::new("cmplog", true);
Expand Down
2 changes: 2 additions & 0 deletions fuzzers/binary_only/frida_windows_gdiplus/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[build]
rustflags = ["-C", "target-feature=+crt-static"]
2 changes: 1 addition & 1 deletion fuzzers/binary_only/frida_windows_gdiplus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ libafl = { path = "../../../libafl", features = [
"errors_backtrace",
] } #, "llmp_small_maps", "llmp_debug"]}
libafl_bolts = { path = "../../../libafl_bolts" }
frida-gum = { version = "0.16.5", features = [
frida-gum = { version = "0.16.7", features = [
"auto-download",
"event-sink",
"invocation-listener",
Expand Down
Loading

0 comments on commit 8b99358

Please sign in to comment.