about summary refs log tree commit diff
path: root/qemu_mode
diff options
context:
space:
mode:
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