Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/AFLplusplus/AFLplusplus/llms.txt

Use this file to discover all available pages before exploring further.

Overview

CmpLog instrumentation logs comparison operands to shared memory, enabling AFL++ to apply sophisticated mutations similar to the Redqueen fuzzer. This is particularly effective for passing complex comparisons and magic bytes.
CmpLog is an effective alternative to LAF-Intel with similar benefits but different approach.

How It Works

CmpLog captures the operands of comparison operations during execution:
// Example: Without CmpLog, AFL++ struggles here
if (memcmp(input, "MAGIC123", 8) == 0) {
  // Hard to reach code
}

// With CmpLog:
// - Logs both operands: input value and "MAGIC123"
// - Applies input-to-state mutations
// - Quickly discovers the magic value

Supported Mutators

Currently supports:
  • Redqueen mutator (input-to-state instructions only)
  • Effective for magic bytes, checksums, and complex comparisons
For details, see the Redqueen paper.

Building with CmpLog

You must build TWO versions of your target:
  1. Regular AFL++ instrumented binary
  2. CmpLog instrumented binary

Step-by-Step Build Process

1

Build regular instrumented binary

./configure --cc=~/path/to/afl-clang-fast
make
cp ./program ./program.afl
2

Clean build directory

make clean
3

Build CmpLog binary

export AFL_LLVM_CMPLOG=1
./configure --cc=~/path/to/afl-clang-fast
make
cp ./program ./program.cmplog
4

Clean up environment

unset AFL_LLVM_CMPLOG

Complete Example

#!/bin/bash
set -e

TARGET="myprogram"
AFL_PATH="$HOME/AFLplusplus"

# Build 1: Regular AFL++ binary
echo "Building regular AFL++ binary..."
CC="$AFL_PATH/afl-clang-fast" ./configure
make clean all
cp "$TARGET" "${TARGET}.afl"

# Build 2: CmpLog binary
echo "Building CmpLog binary..."
make clean
export AFL_LLVM_CMPLOG=1
CC="$AFL_PATH/afl-clang-fast" ./configure
make clean all
cp "$TARGET" "${TARGET}.cmplog"
unset AFL_LLVM_CMPLOG

echo "Build complete!"
echo "  Regular binary: ${TARGET}.afl"
echo "  CmpLog binary:  ${TARGET}.cmplog"

Usage with afl-fuzz

Use the -c option to specify the CmpLog binary:
afl-fuzz -i input -o output -c ./program.cmplog -m none -- ./program.afl @@

Command Breakdown

OptionPurpose
-i inputInput corpus directory
-o outputOutput directory for findings
-c ./program.cmplogCmpLog binary (for mutation guidance)
-m noneDisable memory limit (CmpLog uses extra memory)
-- ./program.afl @@Regular binary (actual fuzzing target)
The regular binary (program.afl) is used for actual fuzzing. The CmpLog binary (program.cmplog) is only executed occasionally to gather comparison data.

Compiler Support

CmpLog works with all modern AFL++ instrumentation modes:
export AFL_LLVM_CMPLOG=1
afl-clang-fast -o target target.c

Environment Variables

AFL_LLVM_CMPLOG
boolean
Enable CmpLog instrumentation for LLVM-based compilation.
export AFL_LLVM_CMPLOG=1
afl-clang-fast -o target.cmplog target.c
AFL_GCC_CMPLOG
boolean
Enable CmpLog instrumentation for GCC plugin compilation.
export AFL_GCC_CMPLOG=1
afl-gcc-fast -o target.cmplog target.c

Memory Considerations

CmpLog can map a significant amount of memory pages. Be careful with the -m option.
# Disable memory limit (safest)
afl-fuzz -i input -o output -c ./target.cmplog -m none -- ./target.afl @@

# Or set a high limit (e.g., 2GB)
afl-fuzz -i input -o output -c ./target.cmplog -m 2048 -- ./target.afl @@

Why Memory Usage is Higher

CmpLog requires additional memory for:
  • Logging comparison operands
  • Shared memory for communication
  • Redqueen mutation working space

Performance Impact

No performance impact - runs at normal AFL++ speedThe regular binary is used for actual fuzzing and runs at full speed.

Execution Pattern

Time: 0s     [Regular binary executes 1000x]
Time: 10s    [CmpLog binary executes 1x] ← Gather comparison data
Time: 11s    [Regular binary executes 1000x] 
Time: 21s    [CmpLog binary executes 1x] ← Update mutations
Time: 22s    [Regular binary executes 1000x]
...

When to Use CmpLog

  • Target has magic bytes (e.g., file format signatures)
  • Code contains checksums or hashes
  • Many memcmp/strcmp comparisons
  • Multi-byte comparisons block fuzzing progress
  • Want Redqueen-style input-to-state mutations
  • Target has integer comparisons (not just strings)
  • Want to split switch statements
  • Need compile-time transformations
  • CmpLog memory usage is problematic
See LAF-Intel documentation
  • Maximum coverage desired
  • Different comparison types throughout code
  • Sufficient resources available
# Build with both CmpLog and LAF-Intel
export AFL_LLVM_CMPLOG=1
export AFL_LLVM_LAF_ALL=1
afl-clang-fast -o target.cmplog target.c

Comparison with LAF-Intel

FeatureCmpLogLAF-Intel
ApproachRuntime loggingCompile-time transformation
Magic bytes✅ Excellent❌ Limited
String compares✅ Excellent✅ Good
Integer compares⚠️ Limited✅ Excellent
Switch statements❌ No✅ Yes
Memory overheadHigherLower
Binary sizeSeparate binarySame binary
PerformanceOccasional slowdownAlways active

Example Use Cases

File Format Fuzzing

// Target with magic bytes
if (memcmp(buf, "PNG\x89", 4) != 0) {
  return ERROR_INVALID_FORMAT;
}

// CmpLog helps quickly discover "PNG\x89"
Without CmpLog: May take millions of executions to randomly hit the magic bytes. With CmpLog: Discovers and applies the magic bytes within seconds.

Checksum Validation

// Simplified example
uint32_t expected_crc = calculate_crc32(data, len);
if (header->crc32 != expected_crc) {
  return ERROR_BAD_CRC;
}

// CmpLog logs both values and helps synthesize valid CRCs

Protocol Parsing

if (strncmp(packet->protocol, "HTTP/1.1", 8) == 0) {
  parse_http_request(packet);
} else if (strncmp(packet->protocol, "HTTP/2.0", 8) == 0) {
  parse_http2_request(packet);
}

// CmpLog discovers both protocol strings

Troubleshooting

Out of Memory Errors

Symptom: Fuzzer crashes with memory allocation errors Solution:
# Option 1: Disable memory limit
afl-fuzz -c ./target.cmplog -m none -- ./target.afl @@

# Option 2: Increase limit
afl-fuzz -c ./target.cmplog -m 4096 -- ./target.afl @@

# Option 3: Increase system limits
ulimit -v unlimited

No Coverage Improvement

Symptom: CmpLog doesn’t seem to help Possible reasons:
  1. Target has few string comparisons
  2. Comparisons are not the bottleneck
  3. Try combining with LAF-Intel
Solution: Profile your target to understand comparison patterns

Fuzzer Not Using CmpLog Binary

Symptom: No CmpLog activity in stats Solution: Verify -c option:
# Correct
afl-fuzz -i in -o out -c ./target.cmplog -- ./target.afl @@

# Wrong - missing -c
afl-fuzz -i in -o out -- ./target.afl @@

Complete Fuzzing Example

#!/bin/bash

# 1. Build both versions
export AFL_PATH="$HOME/AFLplusplus"

# Regular binary
CC="$AFL_PATH/afl-clang-lto" \
CXX="$AFL_PATH/afl-clang-lto++" \
./configure --disable-shared
make clean all
cp src/target target.afl

# CmpLog binary
make clean
export AFL_LLVM_CMPLOG=1
CC="$AFL_PATH/afl-clang-lto" \
CXX="$AFL_PATH/afl-clang-lto++" \
./configure --disable-shared
make clean all
cp src/target target.cmplog
unset AFL_LLVM_CMPLOG

# 2. Prepare corpus
mkdir -p input
echo "Initial test case" > input/seed1

# 3. Start fuzzing
afl-fuzz \
  -i input \
  -o output \
  -c ./target.cmplog \
  -m none \
  -- ./target.afl @@

Advanced: Combining Features

CmpLog + LTO Mode

# Best performance with collision-free coverage
export AFL_LLVM_CMPLOG=1
afl-clang-lto -o target.cmplog target.c

CmpLog + LAF-Intel

# Maximum comparison splitting
export AFL_LLVM_CMPLOG=1
export AFL_LLVM_LAF_ALL=1
afl-clang-fast -o target.cmplog target.c

CmpLog + Persistent Mode

__AFL_FUZZ_INIT();

int main() {
#ifdef __AFL_HAVE_MANUAL_CONTROL
  __AFL_INIT();
#endif

  unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF;
  
  while (__AFL_LOOP(10000)) {
    int len = __AFL_FUZZ_TESTCASE_LEN;
    process_input(buf, len);  // Contains comparisons
  }
}
Build both versions with persistent mode and CmpLog for maximum speed!

Next Steps

LAF-Intel

Compare with LAF-Intel instrumentation approach

Persistent Mode

Combine with persistent mode for 10-20x speedup

LTO Mode

Use collision-free instrumentation

Advanced Fuzzing

Learn advanced fuzzing techniques