You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
5.3 KiB
211 lines
5.3 KiB
2 months ago
|
#!/bin/sh
|
||
|
#
|
||
|
# Copyright 2015 Google LLC All rights reserved.
|
||
|
#
|
||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
# you may not use this file except in compliance with the License.
|
||
|
# You may obtain a copy of the License at:
|
||
|
#
|
||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||
|
#
|
||
|
# Unless required by applicable law or agreed to in writing, software
|
||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
# See the License for the specific language governing permissions and
|
||
|
# limitations under the License.
|
||
|
# -----------------------------------------
|
||
|
# american fuzzy lop - QEMU build script
|
||
|
# --------------------------------------
|
||
|
#
|
||
|
# Written by Andrew Griffiths <agriffiths@google.com> and
|
||
|
# Michal Zalewski <lcamtuf@google.com>
|
||
|
#
|
||
|
# This script downloads, patches, and builds a version of QEMU with
|
||
|
# minor tweaks to allow non-instrumented binaries to be run under
|
||
|
# afl-fuzz.
|
||
|
#
|
||
|
# The modifications reside in patches/*. The standalone QEMU binary
|
||
|
# will be written to ../afl-qemu-trace.
|
||
|
#
|
||
|
|
||
|
|
||
|
VERSION="2.10.0"
|
||
|
QEMU_URL="http://download.qemu-project.org/qemu-${VERSION}.tar.xz"
|
||
|
QEMU_SHA384="68216c935487bc8c0596ac309e1e3ee75c2c4ce898aab796faa321db5740609ced365fedda025678d072d09ac8928105"
|
||
|
|
||
|
echo "================================================="
|
||
|
echo "AFL binary-only instrumentation QEMU build script"
|
||
|
echo "================================================="
|
||
|
echo
|
||
|
|
||
|
echo "[*] Performing basic sanity 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: key files not found - wrong working directory?"
|
||
|
exit 1
|
||
|
|
||
|
fi
|
||
|
|
||
|
if [ ! -f "../afl-showmap" ]; then
|
||
|
|
||
|
echo "[-] Error: ../afl-showmap not found - compile AFL first!"
|
||
|
exit 1
|
||
|
|
||
|
fi
|
||
|
|
||
|
|
||
|
for i in libtool wget python automake autoconf sha384sum bison iconv; do
|
||
|
|
||
|
T=`which "$i" 2>/dev/null`
|
||
|
|
||
|
if [ "$T" = "" ]; then
|
||
|
|
||
|
echo "[-] Error: '$i' not found, 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: devel version of '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 checks passed!"
|
||
|
|
||
|
ARCHIVE="`basename -- "$QEMU_URL"`"
|
||
|
|
||
|
CKSUM=`sha384sum -- "$ARCHIVE" 2>/dev/null | cut -d' ' -f1`
|
||
|
|
||
|
if [ ! "$CKSUM" = "$QEMU_SHA384" ]; then
|
||
|
|
||
|
echo "[*] Downloading QEMU ${VERSION} from the web..."
|
||
|
rm -f "$ARCHIVE"
|
||
|
wget -O "$ARCHIVE" -- "$QEMU_URL" || exit 1
|
||
|
|
||
|
CKSUM=`sha384sum -- "$ARCHIVE" 2>/dev/null | cut -d' ' -f1`
|
||
|
|
||
|
fi
|
||
|
|
||
|
if [ "$CKSUM" = "$QEMU_SHA384" ]; then
|
||
|
|
||
|
echo "[+] Cryptographic signature on $ARCHIVE checks out."
|
||
|
|
||
|
else
|
||
|
|
||
|
echo "[-] Error: signature mismatch on $ARCHIVE (perhaps download error?)."
|
||
|
exit 1
|
||
|
|
||
|
fi
|
||
|
|
||
|
echo "[*] Uncompressing archive (this will take a while)..."
|
||
|
|
||
|
rm -rf "qemu-${VERSION}" || exit 1
|
||
|
tar xf "$ARCHIVE" || exit 1
|
||
|
|
||
|
echo "[+] Unpacking successful."
|
||
|
|
||
|
echo "[*] Configuring QEMU for $CPU_TARGET..."
|
||
|
|
||
|
ORIG_CPU_TARGET="$CPU_TARGET"
|
||
|
|
||
|
test "$CPU_TARGET" = "" && CPU_TARGET="`uname -m`"
|
||
|
test "$CPU_TARGET" = "i686" && CPU_TARGET="i386"
|
||
|
|
||
|
cd qemu-$VERSION || exit 1
|
||
|
|
||
|
echo "[*] Applying patches..."
|
||
|
|
||
|
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 "[+] Patching done."
|
||
|
|
||
|
# --enable-pie seems to give a couple of exec's a second performance
|
||
|
# improvement, much to my surprise. Not sure how universal this is..
|
||
|
|
||
|
CFLAGS="-O3 -ggdb" ./configure --disable-system \
|
||
|
--enable-linux-user --disable-gtk --disable-sdl --disable-vnc \
|
||
|
--target-list="${CPU_TARGET}-linux-user" --enable-pie --enable-kvm || exit 1
|
||
|
|
||
|
echo "[+] Configuration complete."
|
||
|
|
||
|
echo "[*] Attempting to build QEMU (fingers crossed!)..."
|
||
|
|
||
|
make || exit 1
|
||
|
|
||
|
echo "[+] Build process successful!"
|
||
|
|
||
|
echo "[*] Copying binary..."
|
||
|
|
||
|
cp -f "${CPU_TARGET}-linux-user/qemu-${CPU_TARGET}" "../../afl-qemu-trace" || exit 1
|
||
|
|
||
|
cd ..
|
||
|
ls -l ../afl-qemu-trace || exit 1
|
||
|
|
||
|
echo "[+] Successfully created '../afl-qemu-trace'."
|
||
|
|
||
|
if [ "$ORIG_CPU_TARGET" = "" ]; then
|
||
|
|
||
|
echo "[*] Testing the build..."
|
||
|
|
||
|
cd ..
|
||
|
|
||
|
make >/dev/null || exit 1
|
||
|
|
||
|
gcc test-instr.c -o test-instr || exit 1
|
||
|
|
||
|
unset AFL_INST_RATIO
|
||
|
|
||
|
# We shouldn't need the /dev/null hack because program isn't compiled with any
|
||
|
# optimizations.
|
||
|
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
|
||
|
DR="$?"
|
||
|
|
||
|
rm -f .test-instr0 .test-instr1
|
||
|
|
||
|
if [ "$DR" = "0" ]; then
|
||
|
|
||
|
echo "[-] Error: afl-qemu-trace instrumentation doesn't seem to work!"
|
||
|
exit 1
|
||
|
|
||
|
fi
|
||
|
|
||
|
echo "[+] Instrumentation tests passed. "
|
||
|
echo "[+] All set, you can now use the -Q mode in afl-fuzz!"
|
||
|
|
||
|
else
|
||
|
|
||
|
echo "[!] Note: can't test instrumentation when CPU_TARGET set."
|
||
|
echo "[+] All set, you can now (hopefully) use the -Q mode in afl-fuzz!"
|
||
|
|
||
|
fi
|
||
|
|
||
|
exit 0
|