### Setup Python Bindings for LibAFL Source: https://github.com/aflplusplus/libafl/blob/main/bindings/pylibafl/README.md Follow these steps to set up the Python bindings for LibAFL. This includes navigating to the directory, creating and activating a virtual environment, installing necessary dependencies, and building the Python module. ```bash cd LibAFL/bindings/pylibafl python3 -m venv .env source .env/bin/activate pip install maturin distlib patchelf maturin develop ``` -------------------------------- ### LLMP Raw Usage Example Source: https://github.com/aflplusplus/libafl/blob/main/docs/src/message_passing/message_passing.md Demonstrates the basic setup for using LLMP directly without LibAFL abstractions. This involves creating a broker, registering clients in separate threads, and running the broker's main loop. ```rust let mut broker = LlmpBroker::new(); // In other threads: let mut client = LlmpClient::new(broker.identifier()); broker.register_client(client)?; // In main thread: broker.loop_forever(); ``` -------------------------------- ### Test gdb-qemu Source: https://github.com/aflplusplus/libafl/blob/main/utils/gdb_qemu/README.md This command installs the necessary target architecture and then runs the 'just gdb' command, likely to test the gdb-qemu setup. ```sh rustup target add powerpc-unknown-linux-gnu $ just gdb ``` -------------------------------- ### Install Prerequisites for QEMU Fuzzer Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/binary_only/qemu_launcher/README.md Installs necessary cross-compilers and libraries for fuzzing various architectures using QEMU. ```bash sudo apt install \ gcc-arm-linux-gnueabi \ g++-arm-linux-gnueabi \ gcc-aarch64-linux-gnu \ g++-aarch64-linux-gnu \ gcc \ g++ \ gcc-mipsel-linux-gnu \ g++-mipsel-linux-gnu \ gcc-powerpc-linux-gnu \ g++-powerpc-linux-gnu \ libsqlite3-dev ``` -------------------------------- ### Install QEMU and ARM GCC on Ubuntu/Debian Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/full_system/qemu_baremetal/README.md Installs necessary tools for QEMU emulation and ARM cross-compilation. Run this before building the fuzzer. ```bash sudo apt update sudo apt -y install qemu-utils gcc-arm-none-eabi ``` -------------------------------- ### Example gdb-qemu Usage Source: https://github.com/aflplusplus/libafl/blob/main/utils/gdb_qemu/README.md This example demonstrates how to use gdb-multiarch to connect to a remote target launched by gdb-qemu. It sets architecture, disables pagination and confirmation, loads the 'demo' file, and targets the remote connection. ```sh gdb-multiarch \ -ex "set architecture powerpc:MPC8XX" \ -ex "set pagination off" \ -ex "set confirm off" \ -ex "file demo" \ -ex "target remote | gdb-qemu -p 1234 qemu-ppc -- -L /usr/powerpc-linux-gnu -g 1234 demo ``` -------------------------------- ### Build and Serve LibAFL Documentation Source: https://github.com/aflplusplus/libafl/blob/main/docs/README.md Use `mdbook build` to compile the documentation locally or `mdbook serve` to host it on a local server. Ensure mdBook is installed. ```bash mdbook build ``` ```bash mdbook serve ``` -------------------------------- ### Build LIBAFL Jumper for ARM Cross-Compilation Source: https://github.com/aflplusplus/libafl/blob/main/utils/libafl_jumper/README.md This example shows how to set up a cross-compilation environment and build LIBAFL Jumper statically linked with musl libc for an ARM target. Ensure the target architecture and toolchain are correctly installed. ```sh # Install cross compiler toolchain apt-get install gcc-arm-linux-gnueabihf # Install the rust toolchain parts rustup target add arm-unknown-linux-musleabi # Build for the target. The addresses in the linker script should not be used by your target binary. RUSTFLAGS="-C target-feature=+crt-static, -C link-self-contained=yes -C linker=arm-linux-gnueabi-gcc -C link-arg=T$(realpath linker_script.ld)" cargo build --target=arm-unknown-linux-musleabi --release ``` -------------------------------- ### Install SQLite3 Development Libraries Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/binary_only/qemu_launcher/tests/injection/README.md Install the necessary development libraries for SQLite3, which may be a prerequisite for building the injection test target. ```bash sudo apt install libsqlite3-dev ``` -------------------------------- ### Run Example Fuzzers Source: https://github.com/aflplusplus/libafl/blob/main/README.md Executes the example fuzzers provided in the LibAFL project. This command uses 'just' to manage and run the fuzzers, typically found in the './fuzzers/' directory. ```bash just run ``` -------------------------------- ### Serve LibAFL Book Source: https://github.com/aflplusplus/libafl/blob/main/README.md Builds and serves the LibAFL book documentation locally. Requires mdbook to be installed. Navigate to the docs directory before running. ```bash cd docs && mdbook serve ``` -------------------------------- ### Build Target with Just Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/full_system/qemu_linux_process/README.md Use this command to build the target for the QEMU Linux process fuzzer. Ensure you have 'just' installed. ```bash just target ``` -------------------------------- ### Start Docker Compose Services Source: https://github.com/aflplusplus/libafl/blob/main/docs/src/advanced_features/statsd_monitor.md Command to start the Docker Compose services defined in the docker-compose.yml file. ```shell docker compose up -d ``` -------------------------------- ### Setup EventManager Source: https://github.com/aflplusplus/libafl/blob/main/docs/src/baby_fuzzer/baby_fuzzer.md Initializes the EventManager with a Monitor to display event information to the user during fuzzing. ```rust let mut mgr = SimpleEventManager::new(Monitor::new()); ``` -------------------------------- ### Run the Fuzzer Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/inprocess/libfuzzer_windows_asan/README.md Execute the built fuzzer using the provided command. This will start the fuzzing process. ```bash .\libfuzzer_windows_asan.exe ``` -------------------------------- ### Setup libxml2 Fuzzing Environment Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/full_system/nyx_libxml2_parallel/README.md This script prepares the environment for fuzzing libxml2 with libafl_nyx. It builds libafl compilers, downloads and instruments libxml2, and sets up the Nyx configuration. ```shell ./setup_libxml2.sh ``` -------------------------------- ### Pinning Threads to CPU Cores Source: https://github.com/aflplusplus/libafl/blob/main/crates/core_affinity2/README.md Get available core IDs and spawn a thread for each, pinning it to its respective core. This example demonstrates how to use `get_core_ids` and `set_affinity` to manage thread execution on specific CPU cores. ```rust use std::thread; use core_affinity2::{get_core_ids, CoreId}; // Get the available core IDs if let Ok(core_ids) = get_core_ids() { let core_count = core_ids.len(); println!("Found {} cores:", core_count); let handles: Vec<_> = core_ids.into_iter().map(|id| { thread::spawn(move || { // Pin this thread to a single CPU core. if id.set_affinity().is_ok() { println!("Thread {:?} is running on core {:?}", thread::current().id(), id); // Do some work here } else { eprintln!("Could not pin thread to core {:?}", id); } }) }).collect(); for handle in handles { handle.join().unwrap(); } } else { println!("Could not get core IDs."); } ``` -------------------------------- ### Installing Pre-commit Hooks Source: https://github.com/aflplusplus/libafl/blob/main/CONTRIBUTING.md Enable automatic code checks before commits by installing pre-commit hooks. ```bash pre-commit install ``` -------------------------------- ### Run Specific Example Fuzzer Source: https://github.com/aflplusplus/libafl/blob/main/README.md Runs a specific example fuzzer, such as the libpng fuzzer, which is a multicore libfuzzer-like fuzzer using LibAFL. Assumes the fuzzer directory contains a 'Justfile'. ```bash just run -f fuzzers/inprocess/libfuzzer_libpng ``` -------------------------------- ### Run Fuzzer (Broker Mode) Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/inprocess/libfuzzer_libpng/README.md Executes the fuzzer binary for the first time. This starts the broker process, which opens a TCP port for fuzzer clients to connect. ```bash ./fuzzer_libpng ``` -------------------------------- ### Install afl++ Source: https://github.com/aflplusplus/libafl/blob/main/docs/src/advanced_features/nyx.md Install afl++ using apt or by compiling from source. This is a prerequisite for using libafl_nyx with afl++'s instruction type. ```bash sudo apt install aflplusplus ``` ```bash git clone https://github.com/AFLplusplus/AFLplusplus cd AFLplusplus make all # this will not compile afl's additional extensions ``` -------------------------------- ### Verify PylibAFL Installation Source: https://github.com/aflplusplus/libafl/blob/main/bindings/pylibafl/README.md After setting up the virtual environment and installing dependencies, you can verify the installation by checking the installed packages. Ensure the virtual environment is activated before running this command. ```ini distlib==0.4.0 maturin==1.12.6 patchelf==0.17.2.4 pylibafl==0.7.0 ``` -------------------------------- ### Install Prerequisites for QEMU CMIN Fuzzer Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/binary_only/qemu_cmin/README.md Installs necessary cross-compilation toolchains for various architectures required by the QEMU CMIN fuzzer. Ensure these packages are installed before running the fuzzer. ```bash sudo apt install \ gcc-arm-linux-gnueabi \ g++-arm-linux-gnueabi \ gcc-aarch64-linux-gnu \ g++-aarch64-linux-gnu \ gcc \ g++ \ gcc-mipsel-linux-gnu \ g++-mipsel-linux-gnu \ gcc-powerpc-linux-gnu \ g++-powerpc-linux-gnu ``` -------------------------------- ### Install lief Dependency Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/binary_only/python_qemu/README.md Install the lief library, which is required for Python LibAFL bindings. ```bash pip install lief ``` -------------------------------- ### Windows Exception Handling with `exceptional` Source: https://github.com/aflplusplus/libafl/blob/main/crates/exceptional/README.md Shows how to set up a custom exception handler for Windows. Implement the `ExceptionHandler` trait and use `setup_exception_handler` to register it. This example triggers an access violation to test the handler. ```rust use exceptional::windows_exceptions::{ExceptionCode, ExceptionHandler, setup_exception_handler}; use windows::Win32::System::Diagnostics::Debug::EXCEPTION_POINTERS; use std::ptr; struct MyExceptionHandler; impl ExceptionHandler for MyExceptionHandler { fn handle(&mut self, exception_code: ExceptionCode, _exception_pointers: *mut EXCEPTION_POINTERS) { println!("Caught exception: {:?}", exception_code); // In a real scenario, you might want to inspect the exception pointers and recover. std::process::exit(0); } fn exceptions(&self) -> Vec { vec![ExceptionCode::AccessViolation, ExceptionCode::IllegalInstruction] } } let mut handler = MyExceptionHandler; unsafe { setup_exception_handler(&mut handler).expect("Failed to set up exception handler"); } // Trigger an access violation unsafe { let ptr = ptr::null_mut::(); *ptr = 42; } ``` -------------------------------- ### LLMP Broker and Client Communication Example Source: https://github.com/aflplusplus/libafl/blob/main/crates/ll_mp/README.md Demonstrates a basic client-broker communication pattern within the same process using threads. Requires the `llmp_serde` feature for serializable message types. The client connects to the broker via TCP, sends a serialized message, and the broker receives and prints it. ```rust use libafl_bolts::llmp; use serde::{Serialize, Deserialize}; use std::{thread, time::Duration}; const BROKER_PORT: u16 = 1337; // A simple message type that we can serialize #[derive(Serialize, Deserialize, Debug)] struct MyMessage { data: String, } // The client part fn client_logic() { // Give the broker a moment to start thread::sleep(Duration::from_millis(100)); // Connect to the broker over TCP let mut client = llmp::LlmpClient::new(llmp::LlmpConnection::Tcp { port: BROKER_PORT }, 0).expect("Failed to connect to broker"); // Create a message let msg = MyMessage { data: "Hello from client!".to_string(), }; // Send the message to the broker client.send_obj(&msg).expect("Failed to send message"); println!("Client sent a message."); } // The broker part fn main() { // Create a new broker listening on a TCP port let mut broker = llmp::LlmpBroker::new(llmp::LlmpConnection::Tcp { port: BROKER_PORT }).expect("Failed to start broker"); // Spawn a client thread let client_handle = thread::spawn(client_logic); println!("Broker started, waiting for message..."); // Block until we receive a message let (client_id, msg) = loop { // Handle events, this is non-blocking broker.loop_once().unwrap(); // Try to receive a message. // This is also non-blocking and will return Ok(None) if no message is available. if let Ok(Some(msg)) = broker.recv_obj::() { break msg; } // Don't spin the CPU thread::sleep(Duration::from_millis(10)); }; println!("Broker received: '{:?}' from client {:?}", msg, client_id); // Clean up client_handle.join().unwrap(); } ``` -------------------------------- ### Set Up Visual Studio Environment Variables Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/inprocess/libfuzzer_windows_asan/README.md Use this Powershell script to enable the Visual Studio environment, setting necessary variables for Clang to be available in the PATH. Ensure the path to Visual Studio is correct for your installation. ```powershell Push-Location "C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\Build\" & "C:\Windows\System32\cmd.exe" /c "vcvars64.bat & set" | ForEach-Object { if ($_ -match "=") { $v = $_.split("=", 2); set-item -force -path "ENV:\$($v[0])" -value "$($v[1])" } } Pop-Location Write-Host "`nVisual Studio 2022 Command Prompt variables set." -ForegroundColor Yellow ``` -------------------------------- ### Start Fuzzing Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/binary_only/frida_libpng/README.md Initiates the fuzzing process using the compiled Frida fuzzer executable. This command specifies the test case input, harness DLL, and loaded libraries. ```batch .\frida_fuzzer.exe -F LLVMFuzzerTestOneInput -H .\libpng-harness.dll -l .\libpng-harness.dll -l .\zlib.dll -l .\libpng16.dll --cores 0 ``` -------------------------------- ### Unix Signal Handling with `exceptional` Source: https://github.com/aflplusplus/libafl/blob/main/crates/exceptional/README.md Demonstrates how to set up a custom signal handler for Unix-like systems. Implement the `SignalHandler` trait and use `setup_signal_handler` to register it. This example triggers a segmentation fault to test the handler. ```rust use exceptional::unix_signals::{Signal, SignalHandler, setup_signal_handler}; use libc::{siginfo_t, ucontext_t}; use std::ptr; struct MySignalHandler; impl SignalHandler for MySignalHandler { unsafe fn handle(&mut self, signal: Signal, _info: &mut siginfo_t, _context: Option<&mut ucontext_t>) { println!("Caught signal: {:?}", signal); // In a real scenario, you might longjmp or do something else to recover. std::process::exit(0); } fn signals(&self) -> Vec { vec![Signal::SigSegmentationFault, Signal::SigIllegalInstruction] } } let mut handler = MySignalHandler; unsafe { setup_signal_handler(&mut handler).expect("Failed to set up signal handler"); } // Trigger a segfault unsafe { let ptr = ptr::null_mut::(); *ptr = 42; } ``` -------------------------------- ### Example Fuzzer Output Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/structure_aware/baby_fuzzer_gramatron/README.md This output demonstrates the generated grammar sequences from the Baby Gramatron fuzzer. It shows how different grammar rules and literals are combined to form input strings. ```text b=mlhs_node.isz(c,c, ) d=false.keyword__FILE__(c,b,a,b) a=select.Jan(d) a=first.literal( ) b=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,nil].DomainError(c) next a b=Oo.gsub(a,d,b) d=0.hex( ) ``` -------------------------------- ### Unix Signal Handler Setup for MiniBSOD Source: https://github.com/aflplusplus/libafl/blob/main/crates/minibsod/README.md Sets up a signal handler for Unix-like systems to capture crash information using minibsod. This handler will be invoked when specific signals occur, generating a crash report. ```rust use std::io::{stdout, BufWriter}; use exceptional::unix_signals::{ucontext_t, Sig, Signal, SignalHandler, SignalHandlerFlags}; use libc::siginfo_t; use minibsod::generate_minibsod; extern "C" fn handle_crash( signal: Signal, siginfo: &mut siginfo_t, ucontext: &mut ucontext_t, ) { let mut writer = BufWriter::new(stdout()); // The generate_minibsod function will print a detailed crash report to the writer. generate_minibsod(&mut writer, signal, siginfo, Some(ucontext)).unwrap(); } fn setup_signal_handler() { let handler = SignalHandler::new( handle_crash, // A list of signals to handle. [ Sig::Ill, Sig::Abrt, Sig::Bus, Sig::Segv, Sig::Trap, Sig::Sys, ], SignalHandlerFlags::empty(), ); // Install the handler. handler.install().unwrap(); } fn main() { setup_signal_handler(); // Your application logic here. // If a handled signal occurs, the handle_crash function will be called. // For example, to trigger a crash: // unsafe { // *(0xdeadbeef as *mut u32) = 0; // } } ``` -------------------------------- ### Prepare Input Directory and File Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/binary_only/python_qemu/README.md Create an 'in' directory and place an initial input file for the fuzzer. ```bash mkdir in echo aaaaa > in/input ``` -------------------------------- ### gdb-qemu Usage Help Source: https://github.com/aflplusplus/libafl/blob/main/utils/gdb_qemu/README.md This displays the command-line usage information for gdb-qemu, outlining its arguments, options, and default values. ```sh Tool launching qemu-user for debugging Usage: gdb-qemu [OPTIONS] --port [-- ...] Arguments: Name of the qemu-user binary to launch [ARGS]... Arguments passed to the target Options: -p, --port Port -t, --timeout Timeout Ms [default: 2000] -l, --log-file Log file (Requires --log-level) [default: gdb_qemu.log] -L, --log-level Log level [default: off] [possible values: off, error, warn, info, debug, trace] -h, --help Print help (see a summary with '-h') -V, --version Print version ``` -------------------------------- ### Run QEMU Launcher with Injection Detection Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/binary_only/qemu_launcher/tests/injection/README.md Execute the QEMU launcher with the injection detection feature activated. This command specifies the configuration file, input and output directories, and the injection test static binary. ```bash target/x86_64/release/qemu_launcher -j injections.yaml -i in -o out -- injection_test/static ``` -------------------------------- ### Build libpng with Visual Studio Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/binary_only/frida_libpng/README.md Download and build the libpng library, linking it against the previously built zlib. This step is crucial for fuzzing applications that rely on libpng. ```powershell powershell -Command Invoke-WebRequest -OutFile libpng-1.6.37.tar.gz https://github.com/glennrp/libpng/archive/refs/tags/v1.6.37.tar.gz tar -xvf libpng-1.6.37.tar.gz del /q libpng-1.6.37.tar.gz cd libpng-1.6.37 cmake -A x64 -DCMAKE_CXX_COMPILER=cl -DZLIB_ROOT=..\zlib -DZLIB_LIBRARY=..\zlib\Release\zlib.lib . cmake --build . --config Release ``` -------------------------------- ### Get Build ID and Compare Source: https://github.com/aflplusplus/libafl/blob/main/crates/build_id2/README.md Use the `get` function to retrieve the build ID of the current binary and compare it with another build ID. This helps determine if two processes are running the same binary. ```rust # let remote_build_id = build_id2::get(); let local_build_id = build_id2::get(); if local_build_id == remote_build_id { println!("We're running the same binary as remote!"); } else { println!("We're running a different binary to remote"); } ``` -------------------------------- ### Run Demo App with NOASLR Launcher Source: https://github.com/aflplusplus/libafl/blob/main/utils/noaslr/README.md Launches the demo application using the NOASLR launcher to disable ASLR. This allows observation of consistent loading addresses when `/proc/self/maps` is passed as an argument. ```sh ./target/debug/noaslr ./target/debug/demo -- /proc/self/maps ``` -------------------------------- ### Run Python LibAFL Fuzzer Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/binary_only/python_qemu/README.md Execute the Python fuzzer script to start the fuzzing process. ```bash python fuzzer.py ``` -------------------------------- ### Get Current Time with Std Feature Source: https://github.com/aflplusplus/libafl/blob/main/crates/no_std_time/README.md Use this when the 'std' feature is enabled. It automatically retrieves the current system time. ```rust use no_std_time::current_time; let time = current_time(); println!("Current time: {:?}", time); ``` -------------------------------- ### Clone LibAFL Repository Source: https://github.com/aflplusplus/libafl/blob/main/docs/src/getting_started/setup.md Use git to clone the official LibAFL repository from GitHub. This ensures you have the example fuzzers, utilities, and latest patches. ```sh $ git clone https://github.com/AFLplusplus/LibAFL.git ``` -------------------------------- ### Add Necessary Use Directives Source: https://github.com/aflplusplus/libafl/blob/main/docs/src/baby_fuzzer/baby_fuzzer.md Include the required `use` directives for the feedback and observer functionalities to work correctly within the fuzzer setup. ```rust use libafl::prelude::*; use libafl::Error; use std::collections::HashMap; ``` -------------------------------- ### Build Fuzzer Binary Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/inprocess/libfuzzer_libpng_norestart/README.md Links the libfuzzer harness, libpng static library, and other necessary components to create the final fuzzer binary. ```bash ./target/release/libafl_cxx ./harness.cc libpng-1.6.37/.libs/libpng16.a -I libpng-1.6.37/ -o fuzzer_libpng -lz -lm ``` -------------------------------- ### QEMU Fuzzing with LibAFL_Sugar Source: https://github.com/aflplusplus/libafl/blob/main/crates/libafl_sugar/README.md Implement QEMU fuzzing using `QemuBytesCoverageSugar`. This requires specifying QEMU-specific command-line arguments along with the standard fuzzing configurations like input/output directories and a harness. ```rust use libafl_sugar::qemu::{QemuBytesCoverageSugar, QemuSugarParameter}; use libafl_bolts::core_affinity::Cores; use std::path::PathBuf; let mut harness = |buf: &[u8]| { if buf.len() > 0 && buf[0] == b'a' { if buf.len() > 1 && buf[1] == b'b' { if buf.len() > 2 && buf[2] == b'c' { panic!("Three bytes found!"); } } } }; let qemu_args = &["-d", "unimp,guest_errors", "-L", "."]; QemuBytesCoverageSugar::builder() .input_dirs(&[PathBuf::from("./in")]) .output_dir(PathBuf::from("./out")) .cores(&Cores::from_core_ids(vec![0]).unwrap()) .harness(&mut harness) .build() .run(QemuSugarParameter::QemuCli(qemu_args)); ``` -------------------------------- ### Build libafl_libfuzzer Runtime Source: https://github.com/aflplusplus/libafl/blob/main/crates/libafl_libfuzzer/README.md Build the standalone libafl_libfuzzer runtime library using the 'just build' command or the provided build scripts. ```bash just build ``` -------------------------------- ### Initialize FridaInstrumentationHelper with Runtimes Source: https://github.com/aflplusplus/libafl/blob/main/docs/src/advanced_features/frida.md Initializes Frida's instrumentation helper with a Gum object, Frida options, module name, modules to instrument, and a list of runtimes. Runtimes like CoverageRuntime, AsanRuntime, DrCovRuntime, and CmpLogRuntime can be included. ```rust let gum = Gum::obtain(); let frida_options = FridaOptions::parse_env_options(); let coverage = CoverageRuntime::new(); let mut frida_helper = FridaInstrumentationHelper::new( &gum, &frida_options, module_name, modules_to_instrument, tuple_list!(coverage), ); ``` -------------------------------- ### Example of NULL buffer with sprintf Source: https://github.com/aflplusplus/libafl/blob/main/crates/libafl_qemu/libqasan/printf/README.md When the buffer is set to NULL, sprintf returns the formatted length without writing any data. This is useful for determining the required buffer size. ```c int length = sprintf(NULL, "Hello, world"); // length is set to 12 ``` -------------------------------- ### Getting the Current Time Source: https://github.com/aflplusplus/libafl/blob/main/crates/no_std_time/README.md Retrieves the current system time as a `Duration`. Works out-of-the-box with the `std` feature enabled. For `no_std` environments, an implementation of `external_current_millis` must be provided. ```APIDOC ## Getting the Current Time ### Description Retrieves the current system time as a `Duration`. With the `std` feature enabled (the default), this works out of the box. In a `no_std` environment, you must provide an implementation for `external_current_millis` that returns the milliseconds since the UNIX epoch. ### Usage (with `std` feature) ```rust use no_std_time::current_time; let time = current_time(); println!("Current time: {:?}", time); ``` ### Usage (in `no_std` environment) ```rust // In your no_std binary: #[unsafe(no_mangle)] pub extern "C" fn external_current_millis() -> u64 { // Return time from your platform-specific source, e.g., an RTC. 1678886400000 } ``` ``` -------------------------------- ### Load Dynamic Library and Get Symbol Source: https://github.com/aflplusplus/libafl/blob/main/docs/src/advanced_features/frida.md Loads a dynamic library and retrieves a specific function symbol. Ensure the module name and symbol name are correct for your target. ```rust let lib = libloading::Library::new(module_name).unwrap(); let target_func: libloading::Symbol< unsafe extern "C" fn(data: *const u8, size: usize) -> i32, > = lib.get(symbol_name.as_bytes()).unwrap(); ``` -------------------------------- ### Copy Libraries and Build Harness Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/binary_only/frida_libpng/README.md Copies necessary libraries from zlib and libpng builds and compiles the harness. This prepares the environment for running the fuzzer. ```batch copy libpng-1.6.37\Release\libpng16.lib . copy libpng-1.6.37\Release\libpng16.dll . copy zlib\Release\zlib.lib . copy zlib\Release\zlib.dll . copy target\release\frida_fuzzer.exe . cl /O2 /c /I .\libpng-1.6.37 harness.cc /Fo:harness.obj link /DLL /OUT:libpng-harness.dll harness.obj libpng16.lib zlib.lib ``` -------------------------------- ### Basic Usage of StdRand in Rust Source: https://github.com/aflplusplus/libafl/blob/main/crates/fast_rands/README.md Demonstrates how to create a StdRand generator, get a random u64, generate a number below a specific value, and obtain a number within a range. ```rust use fast_rands::{Rand, StdRand}; use core::num::NonZeroUsize; // Create a new random number generator with a random seed let mut rand = StdRand::new(); // Get a random u64 let n = rand.next(); // Get a random number below 100 let below_100 = rand.below(NonZeroUsize::new(100).unwrap()); // Get a random number between 50 and 100 (inclusive) let between_50_and_100 = rand.between(50, 100); ``` -------------------------------- ### Build zlib with Visual Studio Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/binary_only/frida_libpng/README.md Download and build the zlib library using PowerShell and CMake for Visual Studio. Assumes the fuzzer is already built with `cargo build --release`. ```powershell powershell -Command Invoke-WebRequest -OutFile zlib-1.2.11.tar.gz https://zlib.net/fossils/zlib-1.2.11.tar.gz tar -xvf zlib-1.2.11.tar.gz del /q zlib-1.2.11.tar.gz move zlib-1.2.11 zlib cd zlib cmake -A x64 -DCMAKE_CXX_COMPILER=cl . cmake --build . --config Release ``` -------------------------------- ### Update Rust Toolchain Source: https://github.com/aflplusplus/libafl/blob/main/README.md Ensures your Rust installation is up-to-date to meet LibAFL's minimum version requirements. Run this command if your current version is older than specified in Cargo.toml. ```bash rustup update stable ``` -------------------------------- ### Run Demo App with NOASLR Library via LD_PRELOAD Source: https://github.com/aflplusplus/libafl/blob/main/utils/noaslr/README.md Injects the `libnoaslr.so` shared library into the demo application at startup using `LD_PRELOAD`. This disables ASLR for the application, allowing observation of consistent loading addresses when `/proc/self/maps` is passed as an argument. ```sh LD_PRELOAD=target/debug/libnoaslr.so ./target/debug/demo /proc/self/maps ``` -------------------------------- ### Run the Simple Forkserver Fuzzer Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/structure_aware/forkserver_simple_nautilus/README.md Execute the fuzzer after building. Ensure the fuzzer binary is copied to the current directory. The command includes options for grammar, timeout, and the target program, with taskset for core binding. ```bash cp ./target/release/forkserver_simple . taskset -c 1 ./target/release/forkserver_simple -g src/grammar.py -t 1000 -- ./target/release/program ``` -------------------------------- ### Get First Element by Type with MatchFirstType Source: https://github.com/aflplusplus/libafl/blob/main/crates/tuple_list_ex/README.md Use `MatchFirstType` to retrieve the first element of a specific type from a tuple list. Returns `None` if no element of the specified type is found. ```rust use tuple_list::tuple_list; use tuple_list_ex::MatchFirstType; // Create a tuple list let tuple = tuple_list!(1i32, "hello", 3.0f64); // Get the first element of a specific type let first_i32: Option<&i32> = tuple.match_first_type(); assert_eq!(first_i32, Some(&1)); let first_f64: Option<&f64> = tuple.match_first_type(); assert_eq!(first_f64, Some(&3.0)); ``` -------------------------------- ### Prepare Nyx Working Directory with Packer Source: https://github.com/aflplusplus/libafl/blob/main/docs/src/advanced_features/nyx.md Use the nyx_packer.py script to prepare the target binary and create the Nyx working directory. Specify the target binary, work directory, instruction type, instrumentation, and arguments/files for the target. ```bash git clone https://github.com/nyx-fuzz/packer python3 "./packer/packer/nyx_packer.py" \ ./libxml2/xmllint \ /tmp/nyx_libxml2 \ afl \ instrumentation \ -args "/tmp/input" \ -file "/tmp/input" \ --fast_reload_mode \ --purge || exit ``` -------------------------------- ### Using NamedSerdeAnyMap for Multiple Objects of Same Type Source: https://github.com/aflplusplus/libafl/blob/main/crates/serde_anymap/README.md Utilize `NamedSerdeAnyMap` to store multiple instances of the same type, using a string name as the key. This example demonstrates insertion, retrieval, serialization, and deserialization. ```rust # use serde::{Serialize, Deserialize}; # use serde_anymap::{impl_serdeany, serdeany::{NamedSerdeAnyMap, RegistryBuilder}}; # #[derive(Debug, Serialize, Deserialize, PartialEq)] # struct UserData(String); # impl_serdeany!(UserData); # #[cfg(not(feature = "serdeany_autoreg"))] # unsafe { RegistryBuilder::register::(); } let mut named_map = NamedSerdeAnyMap::new(); named_map.insert("user1", UserData("Alice".to_string())); named_map.insert("user2", UserData("Bob".to_string())); assert_eq!(named_map.get::("user1").unwrap().0, "Alice"); assert_eq!(named_map.get::("user2").unwrap().0, "Bob"); let serialized = serde_json::to_string(&named_map).unwrap(); let deserialized: NamedSerdeAnyMap = serde_json::from_str(&serialized).unwrap(); assert_eq!(deserialized.get::("user1").unwrap().0, "Alice"); ``` -------------------------------- ### Rust: Initialize Logging Source: https://github.com/aflplusplus/libafl/blob/main/docs/src/DEBUGGING.md Initialize a logger, such as `env_logger` or `SimpleStdoutLogger`, before starting the fuzzer to see `log::trace!()` output. Ensure `RUST_LOG` is set and the `log` crate's `release_max_level_info` feature is not used. ```rust use libafl::fuzzers::Fuzzer; use libafl_bolts::prelude::Logger; fn main() { // Initialize logger (e.g., env_logger) env_logger::init(); // ... fuzzer setup ... // Start the fuzzer // fuzzer.fuzz(&mut state, &mut executor)?; } ``` -------------------------------- ### Compile Harness for Windows Source: https://github.com/aflplusplus/libafl/blob/main/fuzzers/binary_only/frida_libpng/README.md Compile the harness and link it with libpng and zlib static libraries to create a shared library for fuzzing on Windows. ```powershell cp .\libpng-1.6.37\projects\vstudio\x64\Release\libpng16.lib . cp .\libpng-1.6.37\projects\vstudio\x64\Release\zlib.lib . cp .\target\release\frida_libpng.exe . clang++ -O3 -c -I.\libpng-1.6.37 .\harness.cc -o .\harness.o clang++ -L.\zlib.dll .\harness.o .\libpng16.lib -lzlib -shared -o .\libpng-harness.dll ```