Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Building QEMU Support for AFL Binary-only Fuzzing with Dependency Resolution

Tech May 28 1

The standard build_qemu_support.sh script shipped with AFL uses outdated QEMU versions and encounters numerous installation issues. An alternative approach using an updated build script resolves these compatibility prolbems. This guide covers the installation process on Ubuntu 18.04, though other distributions may require adjustments.

Updated Build Script

#!/bin/bash
# Version can be modified as needed
QEMU_VERSION="6.1.1"
DOWNLOAD_URL="http://download.qemu-project.org/qemu-${QEMU_VERSION}.tar.xz"
# Checksum verification commented out due to complexity
EXPECTED_CHECKSUM="68216c935487bc8c0596ac309e1e3ee75c2c4ce898aab796faa321db5740609ced365fedda025678d072d09ac8928105"

echo "==============================================="
echo "AFL binary-only instrumentation QEMU build script" 
echo "==============================================="
echo

echo "[*] Running preliminary validation checks..."

if [ ! "$(uname -s)" = "Linux" ]; then
  echo "[-] Error: QEMU instrumentation is supported only on Linux."
  exit 1
fi

if [ ! -f "patches/afl-qemu-cpu-inl.h" -o ! -f "../config.h" ]; then
  echo "[-] Error: essential files missing - incorrect working directory?"
  exit 1
fi

if [ ! -f "../afl-showmap" ]; then
  echo "[-] Error: ../afl-showmap not located - compile AFL first!"
  exit 1
fi

for tool in libtool wget python automake autoconf sha384sum bison iconv; do
  BINARY_PATH=$(which "$tool" 2>/dev/null)
  if [ "$BINARY_PATH" = "" ]; then
    echo "[-] Error: '$tool' not installed, please install first."
    exit 1
  fi
done

if [ ! -d "/usr/include/glib-2.0/" -a ! -d "/usr/local/include/glib-2.0/" ]; then
  echo "[-] Error: development headers for 'glib2' not found, please install first."
  exit 1
fi

if echo "$CC" | grep -qF /afl-; then
  echo "[-] Error: do not use afl-gcc or afl-clang to compile this tool."
  exit 1
fi

echo "[+] All validation checks passed!"

ARCHIVE_FILE="$(basename -- "$DOWNLOAD_URL")"

CHECKSUM_RESULT=$(sha384sum -- "$ARCHIVE_FILE" 2>/dev/null | cut -d' ' -f1)

# Skipping checksum verification for simplicity
echo "[*] Fetching QEMU ${QEMU_VERSION} from remote source..."
rm -f "$ARCHIVE_FILE"
wget -O "$ARCHIVE_FILE" -- "$DOWNLOAD_URL" || exit 1

CHECKSUM_RESULT=$(sha384sum -- "$ARCHIVE_FILE" 2>/dev/null | cut -d' ' -f1)

# Verification code removed for clarity

echo "[*] Extracting archive (may take time)..."
rm -rf "qemu-${QEMU_VERSION}" || exit 1
tar xf "$ARCHIVE_FILE" || exit 1

echo "[+] Extraction completed successfully."

echo "[*] Setting up QEMU for $TARGET_ARCH..."

ORIGINAL_TARGET="$TARGET_ARCH"

test "$TARGET_ARCH" = "" && TARGET_ARCH="$(uname -m)"
test "$TARGET_ARCH" = "i686" && TARGET_ARCH="i386"

cd qemu-$QEMU_VERSION || exit 1

echo "[*] Applying modifications..."
echo "[*] QEMU ${QEMU_VERSION} requires no patches"

# Legacy patching code removed
#patch -p1 <../patches/elfload.diff || exit 1
#patch -p1 <../patches/cpu-exec.diff || exit 1
#patch -p1 <../patches/syscall.diff || exit 1
#patch -p1 <../patches/configure.diff || exit 1
#patch -p1 <../patches/memfd.diff || exit 1

echo "[+] Modification process completed."

CFLAGS="-O3 -ggdb" ./configure --disable-system \
  --enable-linux-user --disable-gtk --disable-sdl --disable-vnc \
  --target-list="${TARGET_ARCH}-linux-user" --enable-pie --enable-kvm || exit 1

echo "[+] Setup configuration completed."

echo "[*] Starting QEMU compilation (hope for the best!)..."
make || exit 1

echo "[+] Compilation process completed successfully!"

echo "[*] Moving executable file..."
cp -f "./build/${TARGET_ARCH}-linux-user/qemu-${TARGET_ARCH}" "../../afl-qemu-trace" || exit 1

cd ..
ls -l ../afl-qemu-trace || exit 1

echo "[+] Successfully generated '../afl-qemu-trace'."

if [ "$ORIGINAL_TARGET" = "" ]; then
  echo "[*] Validating the build..."

  cd ..

  make >/dev/null || exit 1
  
  # Using afl-gcc for testing instead of gcc to avoid instrumentation errors
  afl-gcc test-instr.c -o test-instr || exit 1

  unset AFL_INST_RATIO

  echo 0 | ./afl-showmap -m none -Q -q -o .test-instr0 ./test-instr || exit 1
  echo 1 | ./afl-showmap -m none -Q -q -o .test-instr1 ./test-instr || exit 1

  rm -f test-instr

  cmp -s .test-instr0 .test-instr1
  DIFF_RESULT="$?"

  rm -f .test-instr0 .test-instr1

  if [ "$DIFF_RESULT" = "0" ]; then
    echo "[-] Error: afl-qemu-trace instrumentation doesn't seem to work!"
    exit 1
  fi

  echo "[+] Instrumentation validation passed. "
  echo "[+] Ready to use -Q mode in afl-fuzz!"
else
  echo "[!] Warning: cannot validate instrumentation when TARGET_ARCH specified."
  echo "[+] Ready to use (hopefully) -Q mode in afl-fuzz!"
fi
exit 0

Environment Path Configuration

The build script references afl-gcc at line 183 (afl-gcc test-instr.c -o test-instr || exit 1). If afl-gcc is not accessible through system PATH, the build will fail. Add the path to environment configuration:

sudo vim /etc/environment

# Add afl-gcc directory path with proper colon separation:

System restart required for changes to take effect.

Common Dependency Issues and Solutions

Libtool Missing

[-] Error: 'libtool' not found, please install first.

Solution:

sudo apt-get install libtool libtool-bin

Automake Missing

[-] Error: 'automake' not found, please install first.

Solution:

sudo apt-get install automake

Bison Missing

[-] Error: 'bison' not found, please install first.

Solution:

sudo apt-get install bison

GLib Development Headers Missing

[-] Error: devel version of 'glib2' not found, please install first.

Solution:

sudo apt-get install libglib2.0-dev

Ninja Build System Missing

ERROR: Cannot find Ninja

Solutoin:

sudo apt-get install ninja-build

Architecture Mismatch Issue

When using 64-bit afl-qemu-trace to test 32-bit programs:

[-] Error: afl-qemu-trace instrumentation doesn't seem to work!

Solution - specify 32-bit architecture during build:

sudo TARGET_ARCH=i386 ./build_qemu.sh

Successful Installation Confirmation

Upon successful completion, you should see:

[+] Successfully created '../afl-qemu-trace'.
[!] Note: can't test instrumentation when TARGET_ARCH set.
[+] All set, you can now (hopefully) use the -Q mode in afl-fuzz!
Tags: AFL

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.