Skip to content
This repository has been archived by the owner on Mar 22, 2024. It is now read-only.

Support qemu 4.1.0 for non-instrumented binaries (-Q) #43

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions qemu_mode/build_qemu_support.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
#


VERSION="2.10.0"
VERSION="4.1.0"
QEMU_URL="http://download.qemu-project.org/qemu-${VERSION}.tar.xz"
QEMU_SHA384="68216c935487bc8c0596ac309e1e3ee75c2c4ce898aab796faa321db5740609ced365fedda025678d072d09ac8928105"
QEMU_SHA384="ef5aa7b2a77d45dbbaaf3bcd98b0cd25e367d1b036761b68e8b793f51790fa3c41d0ea31d769e2f909b98fd176172498"

echo "================================================="
echo "AFL binary-only instrumentation QEMU build script"
Expand Down Expand Up @@ -62,7 +62,7 @@ if [ ! -f "../afl-showmap" ]; then
fi


for i in libtool wget python automake autoconf sha384sum bison iconv; do
for i in libtool wget python automake autoconf sha384sum bison iconv flex; do

T=`which "$i" 2>/dev/null`

Expand All @@ -82,6 +82,13 @@ if [ ! -d "/usr/include/glib-2.0/" -a ! -d "/usr/local/include/glib-2.0/" ]; the

fi

if [ ! -d "/usr/include/capstone/" -a ! -d "/usr/local/include/capstone/" ]; then

echo "[-] Error: devel version of 'libcapstone' 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."
Expand Down Expand Up @@ -137,8 +144,17 @@ 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

# check to see if we need updated options for libcapstone
grep /usr/include/capstone/capstone.h -e "CS_OPT_SKIPDATA" 2>&1 >/dev/null || grep /usr/local/include/capstone/capstone.h -e "CS_OPT_SKIPDATA" 2>&1 >/dev/null
if [ $? -eq 1 ]; then
# I have a mahcine on Debian jessie still and can confirm the strech debs work
# http://ftp.us.debian.org/debian/pool/main/c/capstone/libcapstone3_3.0.4-1_amd64.deb
# http://ftp.us.debian.org/debian/pool/main/c/capstone/libcapstone-dev_3.0.4-1_amd64.deb
echo "[-] Error: too old of version libcapstone-dev. Please install >= libcapstone3 from source."
fi;
patch -p1 <../patches/capstone.diff || exit 1


echo "[+] Patching done."

Expand Down
18 changes: 11 additions & 7 deletions qemu_mode/patches/afl-qemu-cpu-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,15 @@ struct afl_tsl {
target_ulong pc;
target_ulong cs_base;
uint64_t flags;
uint32_t cflags;
//uint32_t cf_mask;
};

/* Some forward decls: */

TranslationBlock *tb_htable_lookup(CPUState*, target_ulong, target_ulong, uint32_t);
static inline TranslationBlock *tb_find(CPUState*, TranslationBlock*, int);
TranslationBlock *tb_htable_lookup(CPUState*, target_ulong, target_ulong, uint32_t, uint32_t);
static inline TranslationBlock *tb_find(CPUState*, TranslationBlock*, int, uint32_t);


/*************************
* ACTUAL IMPLEMENTATION *
Expand Down Expand Up @@ -295,15 +298,16 @@ static void afl_wait_tsl(CPUState *cpu, int fd) {

if (read(fd, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl))
break;

tb = tb_htable_lookup(cpu, t.pc, t.cs_base, t.flags);
// taken from qemu-2.12.1/accel/tcg/cpu-exec.c:240,241
tb = tb_htable_lookup(cpu, t.pc, t.cs_base, t.flags, 1 & CF_HASH_MASK);

if(!tb) {
mmap_lock();
tb_lock();
tb_gen_code(cpu, t.pc, t.cs_base, t.flags, 0);
// tb_lock(); in qemu-4.1.0 cpu_exec_step_atomic no longer locks tb
// taken from qemu-2.12.1/accel/tcg/cpu-exec.c:240,241
tb_gen_code(cpu, t.pc, t.cs_base, t.flags, 1 & CF_HASH_MASK);
mmap_unlock();
tb_unlock();
// tb_unlock(); see four lines above (no longer locks)
}

}
Expand Down
19 changes: 19 additions & 0 deletions qemu_mode/patches/capstone.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
*** qemu-2.12.1-clean/include/disas/capstone.h 2018-08-02 16:48:53.000000000 -0500
--- qemu-2.12.1/include/disas/capstone.h 2019-10-26 19:51:15.596113994 -0500
***************
*** 3,9 ****

#ifdef CONFIG_CAPSTONE

! #include <capstone.h>

#else

--- 3,9 ----

#ifdef CONFIG_CAPSTONE

! #include <capstone/capstone.h>

#else

11 changes: 0 additions & 11 deletions qemu_mode/patches/configure.diff

This file was deleted.

62 changes: 34 additions & 28 deletions qemu_mode/patches/cpu-exec.diff
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
--- qemu-2.10.0-rc3-clean/accel/tcg/cpu-exec.c 2017-08-15 11:39:41.000000000 -0700
+++ qemu-2.10.0-rc3/accel/tcg/cpu-exec.c 2017-08-22 14:34:55.868730680 -0700
@@ -36,6 +36,8 @@
#include "sysemu/cpus.h"
#include "sysemu/replay.h"

+#include "../patches/afl-qemu-cpu-inl.h"
+
/* -icount align implementation. */

typedef struct SyncClocks {
@@ -144,6 +146,8 @@
int tb_exit;
uint8_t *tb_ptr = itb->tc_ptr;

+ AFL_QEMU_CPU_SNIPPET2;
+
qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc,
"Trace %p [%d: " TARGET_FMT_lx "] %s\n",
itb->tc_ptr, cpu->cpu_index, itb->pc,
@@ -365,6 +369,7 @@
if (!tb) {
/* if no translated code available, then translate it now */
tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
+ AFL_QEMU_CPU_SNIPPET1;
}

mmap_unlock();
*** qemu-4.1.0-clean/accel/tcg/cpu-exec.c 2019-08-15 14:01:42.000000000 -0500
--- qemu-4.1.0/accel/tcg/cpu-exec.c 2019-10-27 00:20:15.997628472 -0500
***************
*** 38,43 ****
--- 38,45 ----
#include "sysemu/cpus.h"
#include "sysemu/replay.h"

+ #include "../patches/afl-qemu-cpu-inl.h"
+
/* -icount align implementation. */

typedef struct SyncClocks {
***************
*** 146,151 ****
--- 148,155 ----
int tb_exit;
uint8_t *tb_ptr = itb->tc.ptr;

+ AFL_QEMU_CPU_SNIPPET2;
+
qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc,
"Trace %d: %p ["
TARGET_FMT_lx "/" TARGET_FMT_lx "/%#x] %s\n",
***************
*** 247,252 ****
--- 251,257 ----
if (tb == NULL) {
mmap_lock();
tb = tb_gen_code(cpu, pc, cs_base, flags, cflags);
+ AFL_QEMU_CPU_SNIPPET1;
mmap_unlock();
}

13 changes: 0 additions & 13 deletions qemu_mode/patches/memfd.diff

This file was deleted.

48 changes: 13 additions & 35 deletions qemu_mode/patches/syscall.diff
Original file line number Diff line number Diff line change
@@ -1,35 +1,13 @@
--- qemu-2.10.0-rc3-clean/linux-user/syscall.c 2017-08-15 11:39:41.000000000 -0700
+++ qemu-2.10.0-rc3/linux-user/syscall.c 2017-08-22 14:34:03.193088186 -0700
@@ -116,6 +116,8 @@

#include "qemu.h"

+extern unsigned int afl_forksrv_pid;
+
#ifndef CLONE_IO
#define CLONE_IO 0x80000000 /* Clone io context */
#endif
@@ -11688,8 +11690,21 @@
break;

case TARGET_NR_tgkill:
- ret = get_errno(safe_tgkill((int)arg1, (int)arg2,
- target_to_host_signal(arg3)));
+
+ {
+ int pid = (int)arg1,
+ tgid = (int)arg2,
+ sig = (int)arg3;
+
+ /* Not entirely sure if the below is correct for all architectures. */
+
+ if(afl_forksrv_pid && afl_forksrv_pid == pid && sig == SIGABRT)
+ pid = tgid = getpid();
+
+ ret = get_errno(safe_tgkill(pid, tgid, target_to_host_signal(sig)));
+
+ }
+
break;

#ifdef TARGET_NR_set_robust_list
*** qemu-4.1.0-clean/linux-user/syscall.c 2019-08-15 14:01:42.000000000 -0500
--- qemu-4.1.0/linux-user/syscall.c 2019-10-27 00:23:44.104978894 -0500
***************
*** 112,117 ****
--- 112,119 ----
#include "qapi/error.h"
#include "fd-trans.h"

+ extern unsigned int afl_forksrv_pid;
+
#ifndef CLONE_IO
#define CLONE_IO 0x80000000 /* Clone io context */
#endif