Skip to main content
FRIDA mode provides an alternative binary-only fuzzer for AFL++ using the FRIDA dynamic instrumentation framework. It offers a similar user experience to QEMU mode with comparable features and environment variable configuration.

Overview

FRIDA mode uses FRIDA Stalker for dynamic instrumentation of binary targets, supporting multiple architectures and platforms. Platform Support: Linux, macOS, Android Architectures: x86, x86_64, aarch64 (aarch32 and Windows support planned) Tutorial: Android Greybox Fuzzing with AFL FRIDA Mode

Feature Support

FeatureStatusNotes
NeverZero
Persistent Modex86/x64/aarch64 only
CMPLOGx86/x64/aarch64 only
Selective Instrumentation
In-Memory Test Casesx86/x64/aarch64 only
LAF-Intel / CompCov-CMPLOG is better 90% of the time
Non-Colliding Coverage-Not possible in binary-only
Snapshot LKM Support-

Building FRIDA Mode

1
Build for 64-bit
2
From the frida_mode directory:
3
make
4
Build for 32-bit (Optional)
5
For 32-bit fuzzing:
6
make 32
7
afl-fuzz doesn’t need to be 32-bit, but the FRIDA mode shared library must be since it’s injected into the target process.
8
Test the Build
9
Run tests to verify the build:
10
cd test/
make
make frida  # Run FRIDA mode tests
11
For 32-bit tests:
12
make ARCH=x86 frida

Android Setup

1
Download Android NDK
2
Get the Android SDK from:
4
Create Standalone Toolchain
5
Follow the instructions at:

Basic Usage

FRIDA mode uses the -O flag (in homage to FRIDA’s author):
afl-fuzz -O -i input_dir -o output_dir -- /path/to/binary @@

Core Environment Variables

FRIDA mode mirrors QEMU mode’s environment variables with FRIDA replacing QEMU:
VariableDescription
AFL_FRIDA_DEBUG_MAPSDisplay memory layout
AFL_FRIDA_EXCLUDE_RANGESExclude specific ranges from instrumentation
AFL_FRIDA_INST_RANGESInstrument only specific ranges
AFL_FRIDA_PERSISTENT_ADDRAddress for persistent mode entry
AFL_FRIDA_PERSISTENT_CNTNumber of iterations in persistent mode
AFL_FRIDA_PERSISTENT_HOOKHook address for persistent mode
AFL_FRIDA_PERSISTENT_RETReturn address for persistent mode

CMPLOG Mode

Enable CMPLOG by setting the comparison module to the target:
afl-fuzz -O -c 0 -i input_dir -o output_dir -- /path/to/binary @@

JavaScript Scripting

One of FRIDA mode’s most powerful features is JavaScript configuration:
export AFL_FRIDA_JS_SCRIPT=/path/to/script.js
For detailed scripting documentation, see Scripting.md in the FRIDA mode directory.

Performance

FRIDA mode includes libpng benchmarks compatible with FuzzBench, supporting:
  • Basic fork-server mode
  • Persistent mode
  • Persistent mode with in-memory test cases
These benchmarks allow direct performance comparison with QEMU mode.

Design Architecture

FRIDA mode works by:
  1. Injection: Using LD_PRELOAD (DYLD_INSERT_LIBRARIES on macOS) to inject afl-frida-trace.so
  2. Instrumentation: Using FRIDA Stalker for dynamic code instrumentation
  3. Coverage: Augmenting the target with coverage information similar to afl-gcc/afl-clang
  4. Fork Server: Providing AFL++ integration via compiler-rt
  5. Prefetching: Sharing instrumented blocks between parent and child to avoid regeneration

Optimized Assembly

FRIDA mode uses optimized assembly snippets on aarch64 and x86/64 instead of C functions, avoiding the need to push/pop full register context. This significantly improves performance as instrumentation runs on every basic block.

Advanced Configuration

Coverage and Debugging

VariableDescription
AFL_FRIDA_INST_COVERAGE_FILEWrite DynamoRIO format coverage (for IDA Lighthouse)
AFL_FRIDA_INST_COVERAGE_ABSOLUTEUse absolute addresses in coverage files
AFL_FRIDA_INST_DEBUG_FILEWrite raw assembly of original and instrumented blocks
AFL_FRIDA_INST_TRACELog executed block addresses (implies NO_OPTIMIZE)
AFL_FRIDA_INST_TRACE_UNIQUELog each edge only once
AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILECoverage file for unstable edges

Performance Tuning

VariableDescription
AFL_FRIDA_INST_CACHE_SIZESet instrumentation cache size (default: 256MB)
AFL_FRIDA_INST_NO_CACHEDisable address translation cache
AFL_FRIDA_INST_NO_OPTIMIZEDisable optimized inline assembly
AFL_FRIDA_INST_NO_PREFETCHDisable prefetching of instrumented blocks
AFL_FRIDA_INST_NO_PREFETCH_BACKPATCHDisable prefetching of backpatches
AFL_FRIDA_INST_NO_SUPPRESSDisable deterministic branch suppression
AFL_FRIDA_STALKER_IC_ENTRIESInline cache entries (default: 32)
AFL_FRIDA_STALKER_NO_BACKPATCHDisable backpatching
AFL_FRIDA_STALKER_ADJACENT_BLOCKSNumber of adjacent blocks to fetch

Instrumentation Control

VariableDescription
AFL_FRIDA_INST_INSNInstrument conditional instructions (e.g., CMOV)
AFL_FRIDA_INST_JITInstrument JIT-compiled code
AFL_FRIDA_INST_NO_DYNAMIC_LOADDon’t instrument late-loaded code
AFL_FRIDA_INST_SEEDSet initial hash seed for block IDs
AFL_FRIDA_INST_REGS_FILEWrite register contents at block start

Persistent Mode Debugging

Debug persistent mode setup:
export AFL_FRIDA_PERSISTENT_DEBUG=1

gdb \
    --ex 'set environment AFL_FRIDA_PERSISTENT_ADDR=0x12345678' \
    --ex 'set environment AFL_FRIDA_PERSISTENT_RET=0x87654321' \
    --ex 'set environment AFL_FRIDA_PERSISTENT_DEBUG=1' \
    --ex 'set environment AFL_DEBUG_CHILD=1' \
    --ex 'set environment LD_PRELOAD=afl-frida-trace.so' \
    --args /path/to/binary

Output Control

VariableDescription
AFL_FRIDA_OUTPUT_STDOUTRedirect target stdout to file
AFL_FRIDA_OUTPUT_STDERRRedirect target stderr to file
AFL_FRIDA_VERBOSEEnable verbose output
AFL_FRIDA_DRIVER_NO_HOOKRead from stdin instead of in-memory test cases

Statistics and Analysis

export AFL_FRIDA_STATS_FILE=/path/to/stats.txt
export AFL_FRIDA_STATS_INTERVAL=1  # seconds
Generates detailed statistics including:
  • Transition counts (calls, jumps, returns)
  • Instrumentation metrics (blocks, instructions)
  • End-of-block instruction breakdown
  • Relocated instruction analysis

Security and Debugging

VariableDescription
AFL_FRIDA_SECCOMP_FILELog syscalls to file
AFL_FRIDA_TRACEABLEMake child traceable (Linux only, for gcore)

FASAN - FRIDA Address Sanitizer

FRIDA mode supports Address Sanitizer for binary-only targets:
1
Load Address Sanitizer DSO
2
Add the Address Sanitizer shared object first in AFL_PRELOAD:
3
export AFL_PRELOAD=/path/to/libasan.so:/path/to/other.so
4
Run Fuzzer
5
FASAN automatically instruments memory operations:
6
afl-fuzz -O -i input_dir -o output_dir -- /path/to/binary @@
FASAN adds instrumentation for memory operands and calls __asan_loadN and __asan_storeN functions to validate memory accesses. This avoids instrumenting standard libraries and handles load-widening issues.

Map Density Improvements

FRIDA mode includes improvements to reduce edge collisions. See MapDensity.md for details.

macOS Library Fuzzing

Example of fuzzing dynamic libraries on macOS:
1
Create Test Harness
2
Build a simple executable that loads the library:
3
__attribute__((constructor))
void load_library() {
    void* handle = dlopen("/path/to/lib.dylib", RTLD_NOW);
    // Or link directly against the library
}

int main() {
    // Call target function
}
4
Configure Instrumentation
5
export AFL_FRIDA_INST_RANGES=lib.dylib
6
Run Fuzzer
7
afl-fuzz -O -i input_dir -o output_dir -- ./harness @@
The library must be loaded before main executes, as that’s when FRIDA mode initializes.

Troubleshooting

For debugging assistance, refer to DEBUGGING.md in the FRIDA mode directory.

Future Development

Planned features:
  • Aarch32 support
  • Windows target support
  • Additional performance improvements
  • Feature parity with QEMU mode
Contributions are welcome - please coordinate to avoid duplicate efforts.

Build docs developers (and LLMs) love