aboutsummaryrefslogtreecommitdiff
path: root/qemu_mode
diff options
context:
space:
mode:
authorAlexander Shvedov <60114847+a-shvedov@users.noreply.github.com>2024-05-30 10:43:01 +0300
committerGitHub <noreply@github.com>2024-05-30 10:43:01 +0300
commitf8a5f1cd9ea907654f42fa06ce6b6bfd4b8c1b13 (patch)
tree7aec2a095a30ed609ce96f85ec3c4e0a8b8eb74c /qemu_mode
parent629edb1e78d791894ce9ee6d53259f95fe1a29af (diff)
parente7d871c8bf64962a658e447b90a1a3b43aaddc28 (diff)
downloadafl++-f8a5f1cd9ea907654f42fa06ce6b6bfd4b8c1b13.tar.gz
Merge branch 'AFLplusplus:stable' into stable
Diffstat (limited to 'qemu_mode')
-rw-r--r--qemu_mode/QEMUAFL_VERSION2
-rw-r--r--qemu_mode/README.md33
-rwxr-xr-xqemu_mode/build_qemu_support.sh12
-rw-r--r--qemu_mode/fastexit/Makefile2
-rw-r--r--qemu_mode/libcompcov/Makefile2
-rw-r--r--qemu_mode/libcompcov/compcovtest.cc2
-rw-r--r--qemu_mode/libcompcov/libcompcov.so.c8
-rw-r--r--qemu_mode/libqasan/Makefile2
-rw-r--r--qemu_mode/libqasan/dlmalloc.c40
-rw-r--r--qemu_mode/libqasan/hooks.c2
-rw-r--r--qemu_mode/libqasan/libqasan.c2
-rw-r--r--qemu_mode/libqasan/libqasan.h2
-rw-r--r--qemu_mode/libqasan/malloc.c6
-rw-r--r--qemu_mode/libqasan/patch.c2
-rw-r--r--qemu_mode/libqasan/string.c2
-rw-r--r--qemu_mode/libqasan/uninstrument.c2
m---------qemu_mode/qemuafl0
-rw-r--r--qemu_mode/unsigaction/Makefile2
-rwxr-xr-xqemu_mode/util/qemu_get_symbol_addr.sh53
19 files changed, 132 insertions, 44 deletions
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index 44ea5345..296745f9 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-a1321713c7
+a6f0632a65
diff --git a/qemu_mode/README.md b/qemu_mode/README.md
index 92038737..b78eb297 100644
--- a/qemu_mode/README.md
+++ b/qemu_mode/README.md
@@ -193,12 +193,39 @@ Comparative measurements of execution speed or instrumentation coverage will be
fairly meaningless if the optimization levels or instrumentation scopes don't
match.
-## 12) Other features
+## 12) Coverage information
+
+Coverage information about a run of a target binary can be obtained using a
+dedicated QEMU user mode plugin enabled at runtime: the `drcov.c` plugin
+collects coverage information from the target binary and writes it in the Drcov
+format. This file can then be loaded using tools such as
+[lighthouse](https://github.com/gaasedelen/lighthouse),
+[lightkeeper](https://github.com/WorksButNotTested/lightkeeper) or
+[Cartographer](https://github.com/nccgroup/Cartographer).
+
+To compile the QEMU TCG plugins, run the following command from the `qemuafl`
+directory:
+
+```
+make plugins
+```
+
+Plugins can be loaded using either the `QEMU_PLUGIN` environment variable or
+using the `-plugin` option. For example:
+
+```
+afl-qemu-trace -plugin qemuafl/build/contrib/plugins/libdrcov.so,arg=filename=/tmp/target.drcov.trace <target> <args>
+```
+
+This would execute the target binary with the provided arguments and, once done,
+would write coverage information at `/tmp/target.drcov.trace`.
+
+## 13) Other features
With `AFL_QEMU_FORCE_DFL`, you force QEMU to ignore the registered signal
handlers of the target.
-## 13) Gotchas, feedback, bugs
+## 14) Gotchas, feedback, bugs
If you need to fix up checksums or do other cleanups on mutated test cases, see
`afl_custom_post_process` in custom_mutators/examples/example.c for a viable
@@ -217,7 +244,7 @@ program may be utilizing. In particular, it does not appear to have full support
for AVX2/FMA3. Using binaries for older CPUs or recompiling them with
`-march=core2`, can help.
-## 14) Alternatives: static rewriting
+## 15) Alternatives: static rewriting
Statically rewriting binaries just once, instead of attempting to translate them
at run time, can be a faster alternative. That said, static rewriting is fraught
diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh
index f59cba78..19336114 100755
--- a/qemu_mode/build_qemu_support.sh
+++ b/qemu_mode/build_qemu_support.sh
@@ -13,7 +13,7 @@
# counters by Andrea Fioraldi <andreafioraldi@gmail.com>
#
# Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
-# Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+# Copyright 2019-2024 AFLplusplus Project. 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.
@@ -132,7 +132,10 @@ echo "Building for CPU target $CPU_TARGET"
# --enable-pie seems to give a couple of exec's a second performance
# improvement, much to my surprise. Not sure how universal this is..
+# --enable-plugins allows loading TCG plugins at runtime, for example to obtain
+# coverage information, and does not seem to negatively impact performance
QEMU_CONF_FLAGS=" \
+ --enable-plugins \
--audio-drv-list= \
--disable-blobs \
--disable-bochs \
@@ -162,7 +165,6 @@ QEMU_CONF_FLAGS=" \
--disable-numa \
--disable-opengl \
--disable-parallels \
- --disable-plugins \
--disable-qcow1 \
--disable-qed \
--disable-rbd \
@@ -200,6 +202,8 @@ QEMU_CONF_FLAGS=" \
--disable-xfsctl \
--target-list="${CPU_TARGET}-linux-user" \
--without-default-devices \
+ --extra-cflags=-Wno-int-conversion \
+ --disable-werror \
"
if [ -n "${CROSS_PREFIX}" ]; then
@@ -213,8 +217,10 @@ if [ "$STATIC" = "1" ]; then
echo Building STATIC binary
# static PIE causes https://github.com/AFLplusplus/AFLplusplus/issues/892
+ # plugin support requires dynamic linking
QEMU_CONF_FLAGS="$QEMU_CONF_FLAGS \
--static --disable-pie \
+ --disable-plugins \
--extra-cflags=-DAFL_QEMU_STATIC_BUILD=1 \
"
@@ -239,7 +245,6 @@ if [ "$DEBUG" = "1" ]; then
--enable-debug-stack-usage \
--enable-debug-tcg \
--enable-qom-cast-debug \
- --enable-werror \
"
else
@@ -250,7 +255,6 @@ else
--disable-debug-tcg \
--disable-qom-cast-debug \
--disable-stack-protector \
- --disable-werror \
--disable-docs \
"
diff --git a/qemu_mode/fastexit/Makefile b/qemu_mode/fastexit/Makefile
index c7b79277..be80207d 100644
--- a/qemu_mode/fastexit/Makefile
+++ b/qemu_mode/fastexit/Makefile
@@ -4,7 +4,7 @@
#
# Written by Andrea Fioraldi <andreafioraldi@gmail.com>
#
-# Copyright 2019-2023 Andrea Fioraldi. All rights reserved.
+# Copyright 2019-2024 Andrea Fioraldi. 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.
diff --git a/qemu_mode/libcompcov/Makefile b/qemu_mode/libcompcov/Makefile
index 7260df87..4761ac02 100644
--- a/qemu_mode/libcompcov/Makefile
+++ b/qemu_mode/libcompcov/Makefile
@@ -4,7 +4,7 @@
#
# Written by Andrea Fioraldi <andreafioraldi@gmail.com>
#
-# Copyright 2019-2023 Andrea Fioraldi. All rights reserved.
+# Copyright 2019-2024 Andrea Fioraldi. 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.
diff --git a/qemu_mode/libcompcov/compcovtest.cc b/qemu_mode/libcompcov/compcovtest.cc
index 23215013..11797091 100644
--- a/qemu_mode/libcompcov/compcovtest.cc
+++ b/qemu_mode/libcompcov/compcovtest.cc
@@ -2,7 +2,7 @@
//
// Author: Mateusz Jurczyk (mjurczyk@google.com)
//
-// Copyright 2019-2023 Google LLC
+// Copyright 2019-2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/qemu_mode/libcompcov/libcompcov.so.c b/qemu_mode/libcompcov/libcompcov.so.c
index b6ee0019..36f7b2e2 100644
--- a/qemu_mode/libcompcov/libcompcov.so.c
+++ b/qemu_mode/libcompcov/libcompcov.so.c
@@ -5,7 +5,7 @@
Written and maintained by Andrea Fioraldi <andreafioraldi@gmail.com>
- Copyright 2019-2023 AFLplusplus Project. All rights reserved.
+ Copyright 2019-2024 AFLplusplus Project. 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.
@@ -68,7 +68,11 @@ static int debug_fd = -1;
#define MAX_MAPPINGS 1024
-static struct mapping { void *st, *en; } __compcov_ro[MAX_MAPPINGS];
+static struct mapping {
+
+ void *st, *en;
+
+} __compcov_ro[MAX_MAPPINGS];
static u32 __compcov_ro_cnt;
diff --git a/qemu_mode/libqasan/Makefile b/qemu_mode/libqasan/Makefile
index 61782894..7366d6f6 100644
--- a/qemu_mode/libqasan/Makefile
+++ b/qemu_mode/libqasan/Makefile
@@ -4,7 +4,7 @@
#
# Written by Andrea Fioraldi <andreafioraldi@gmail.com>
#
-# Copyright 2019-2023 Andrea Fioraldi. All rights reserved.
+# Copyright 2019-2024 Andrea Fioraldi. 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.
diff --git a/qemu_mode/libqasan/dlmalloc.c b/qemu_mode/libqasan/dlmalloc.c
index 5d0b65ce..1919ae26 100644
--- a/qemu_mode/libqasan/dlmalloc.c
+++ b/qemu_mode/libqasan/dlmalloc.c
@@ -771,8 +771,8 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP
#include "/usr/include/malloc.h"
#else /* HAVE_USR_INCLUDE_MALLOC_H */
#ifndef STRUCT_MALLINFO_DECLARED
- /* HP-UX (and others?) redefines mallinfo unless _STRUCT_MALLINFO is
- * defined */
+ /* HP-UX (and others?) redefines mallinfo unless _STRUCT_MALLINFO is
+ * defined */
#define _STRUCT_MALLINFO
#define STRUCT_MALLINFO_DECLARED 1
struct mallinfo {
@@ -1660,10 +1660,10 @@ extern size_t getpagesize();
#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0)
/* the number of bytes to offset an address to align it */
- #define align_offset(A) \
- ((((size_t)(A)&CHUNK_ALIGN_MASK) == 0) \
- ? 0 \
- : ((MALLOC_ALIGNMENT - ((size_t)(A)&CHUNK_ALIGN_MASK)) & \
+ #define align_offset(A) \
+ ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0) \
+ ? 0 \
+ : ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & \
CHUNK_ALIGN_MASK))
/* -------------------------- MMAP preliminaries ------------------------- */
@@ -1715,10 +1715,10 @@ static FORCEINLINE int unixmunmap(void *ptr, size_t size) {
#define MUNMAP_DEFAULT(a, s) unixmunmap((a), (s))
#else /* MAP_ANONYMOUS */
- /*
- Nearly all versions of mmap support MAP_ANONYMOUS, so the following
- is unlikely to be needed, but is supplied just in case.
- */
+ /*
+ Nearly all versions of mmap support MAP_ANONYMOUS, so the following
+ is unlikely to be needed, but is supplied just in case.
+ */
#define MMAP_FLAGS (MAP_PRIVATE)
static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */
#define MMAP_DEFAULT(s) \
@@ -1762,7 +1762,7 @@ static FORCEINLINE void *win32direct_mmap(size_t size) {
static FORCEINLINE int win32munmap(void *ptr, size_t size) {
MEMORY_BASIC_INFORMATION minfo;
- char *cptr = (char *)ptr;
+ char *cptr = (char *)ptr;
while (size) {
@@ -1965,7 +1965,7 @@ static FORCEINLINE void x86_clear_lock(int *sl) {
#endif /* ... gcc spins locks ... */
- /* How to yield for a spin lock */
+ /* How to yield for a spin lock */
#define SPINS_PER_YIELD 63
#if defined(_MSC_VER)
#define SLEEP_EX_DURATION 50 /* delay for yield/sleep */
@@ -2008,11 +2008,11 @@ static MLOCK_T malloc_global_mutex = 0;
#define CURRENT_THREAD GetCurrentThreadId()
#define EQ_OWNER(X, Y) ((X) == (Y))
#else
- /*
- Note: the following assume that pthread_t is a type that can be
- initialized to (casted) zero. If this is not the case, you will need
- to somehow redefine these or not use spin locks.
- */
+ /*
+ Note: the following assume that pthread_t is a type that can be
+ initialized to (casted) zero. If this is not the case, you will need
+ to somehow redefine these or not use spin locks.
+ */
#define THREAD_ID_T pthread_t
#define CURRENT_THREAD pthread_self()
#define EQ_OWNER(X, Y) pthread_equal(X, Y)
@@ -2169,7 +2169,7 @@ static int pthread_init_lock(MLOCK_T *lk) {
#endif /* ... lock types ... */
- /* Common code for all lock types */
+ /* Common code for all lock types */
#define USE_LOCK_BIT (2U)
#ifndef ACQUIRE_MALLOC_GLOBAL_LOCK
@@ -3077,7 +3077,7 @@ static size_t traverse_and_check(mstate m);
/* The size of the smallest chunk held in bin with index i */
#define minsize_for_tree_index(i) \
((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \
- (((size_t)((i)&SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1)))
+ (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1)))
/* ------------------------ Operations on bin maps ----------------------- */
@@ -3245,7 +3245,7 @@ static size_t traverse_and_check(mstate m);
#else /* FOOTERS */
- /* Set foot of inuse chunk to be xor of mstate and seed */
+ /* Set foot of inuse chunk to be xor of mstate and seed */
#define mark_inuse_foot(M, p, s) \
(((mchunkptr)((char *)(p) + (s)))->prev_foot = \
((size_t)(M) ^ mparams.magic))
diff --git a/qemu_mode/libqasan/hooks.c b/qemu_mode/libqasan/hooks.c
index a9fd0ce9..cf1b0820 100644
--- a/qemu_mode/libqasan/hooks.c
+++ b/qemu_mode/libqasan/hooks.c
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/libqasan.c b/qemu_mode/libqasan/libqasan.c
index 12be7778..45f47d5a 100644
--- a/qemu_mode/libqasan/libqasan.c
+++ b/qemu_mode/libqasan/libqasan.c
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/libqasan.h b/qemu_mode/libqasan/libqasan.h
index a430c868..f0844e23 100644
--- a/qemu_mode/libqasan/libqasan.h
+++ b/qemu_mode/libqasan/libqasan.h
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/malloc.c b/qemu_mode/libqasan/malloc.c
index d2db3856..ae470b56 100644
--- a/qemu_mode/libqasan/malloc.c
+++ b/qemu_mode/libqasan/malloc.c
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
@@ -80,8 +80,8 @@ static unsigned char __tmp_alloc_zone[TMP_ZONE_SIZE];
#else
// From dlmalloc.c
-void *dlmalloc(size_t);
-void dlfree(void *);
+void *dlmalloc(size_t);
+void dlfree(void *);
#define backend_malloc dlmalloc
#define backend_free dlfree
diff --git a/qemu_mode/libqasan/patch.c b/qemu_mode/libqasan/patch.c
index 38e0903b..4ce8c3d8 100644
--- a/qemu_mode/libqasan/patch.c
+++ b/qemu_mode/libqasan/patch.c
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/string.c b/qemu_mode/libqasan/string.c
index e17cff4b..cd14d57b 100644
--- a/qemu_mode/libqasan/string.c
+++ b/qemu_mode/libqasan/string.c
@@ -1,5 +1,5 @@
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/libqasan/uninstrument.c b/qemu_mode/libqasan/uninstrument.c
index e37a9b46..996f2a74 100644
--- a/qemu_mode/libqasan/uninstrument.c
+++ b/qemu_mode/libqasan/uninstrument.c
@@ -7,7 +7,7 @@ for some strange reason.
*/
/*******************************************************************************
-Copyright (c) 2019-2023, Andrea Fioraldi
+Copyright (c) 2019-2024, Andrea Fioraldi
Redistribution and use in source and binary forms, with or without
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
-Subproject a1321713c7502c152dd7527555e0f8a800d5522
+Subproject a6f0632a65e101e680dd72643a6128dd180dff7
diff --git a/qemu_mode/unsigaction/Makefile b/qemu_mode/unsigaction/Makefile
index c1a7397f..d5e807d8 100644
--- a/qemu_mode/unsigaction/Makefile
+++ b/qemu_mode/unsigaction/Makefile
@@ -4,7 +4,7 @@
#
# Written by Andrea Fioraldi <andreafioraldi@gmail.com>
#
-# Copyright 2019-2023 Andrea Fioraldi. All rights reserved.
+# Copyright 2019-2024 Andrea Fioraldi. 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.
diff --git a/qemu_mode/util/qemu_get_symbol_addr.sh b/qemu_mode/util/qemu_get_symbol_addr.sh
new file mode 100755
index 00000000..5e00f1b2
--- /dev/null
+++ b/qemu_mode/util/qemu_get_symbol_addr.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# Copyright 2024 AFLplusplus
+#
+# 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.
+
+target="$1"
+symbol="$2"
+base="$3"
+
+test -z "$target" -o -z "$symbol" -o '!' -x "$target" && {
+ echo "Syntax: $0 executable function [baseaddress]"
+ echo
+ echo Help script to calculate the function address of a binary QEMU will load it to.
+ echo function is e.g. LLVMFuzzerTestOneInput, afl_qemu_driver_stdin, etc.
+ echo "baseaddress is tried to be auto-detected, you can use 'AFL_QEMU_DEBUG_MAPS=1 afl-qemu-trace ./executable' to see the maps."
+ exit 1
+}
+
+file=$(file $target|sed 's/.*: //')
+
+arch=$(echo $file|awk -F, '{print$2}'|tr -d ' ')
+bits=$(echo $file|sed 's/-bit .*//'|sed 's/.* //')
+pie=$(echo $file|grep -wqi pie && echo pie)
+
+test $(uname -s) = "Darwin" && symbol=_"$symbol"
+tmp_addr=$(nm "$target" | grep -i "T $symbol" | awk '{print$1}' | tr a-f A-F)
+
+test -z "$tmp_addr" && { echo Error: function $symbol not found 1>&2; exit 1; }
+test -z "$pie" && { echo 0x$tmp_addr; exit 0; }
+
+test -z "$base" && {
+ test "$bits" = 32 -o "$bits" = 64 || { echo "Error: could not identify arch (bits=$bits)" 1>&2 ; exit 1; }
+ test "$arch" = Intel80386 && base=0x40000000
+ test "$arch" = x86-64 && base=0x4000000000
+ test "$arch" = ARMaarch64 && base=0x5500000000
+ # add more here, e.g. "$arch" = ARM
+}
+
+test -z "$base" && { echo "Error: could not identify base address! bits=$bits arch=$arch" 1>&2 ; exit 1; }
+
+hex_base=$(echo "$base" | awk '{sub("^0x","");print $0}' | tr a-f A-F )
+echo $tmp_addr | echo "ibase=16;obase=10;$hex_base + $tmp_addr" | bc | tr A-F a-f | awk '{print "0x"$0}'
+exit 0