about summary refs log tree commit diff
path: root/qemu_mode/patches/afl-qemu-translate-inl.h
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2019-05-28 16:40:24 +0200
committervan Hauser <vh@thc.org>2019-05-28 16:40:24 +0200
commitf367728c4435670caf2e9cc5acad257e7766cc65 (patch)
tree5a4f587630b161f32a548f5c196032e2566741e2 /qemu_mode/patches/afl-qemu-translate-inl.h
parent1b3d018d35d9091bda28e38e066a99491f2415b5 (diff)
downloadafl++-f367728c4435670caf2e9cc5acad257e7766cc65.tar.gz
afl++ 2.52c initial commit
Diffstat (limited to 'qemu_mode/patches/afl-qemu-translate-inl.h')
-rw-r--r--qemu_mode/patches/afl-qemu-translate-inl.h82
1 files changed, 82 insertions, 0 deletions
diff --git a/qemu_mode/patches/afl-qemu-translate-inl.h b/qemu_mode/patches/afl-qemu-translate-inl.h
new file mode 100644
index 00000000..9e778a83
--- /dev/null
+++ b/qemu_mode/patches/afl-qemu-translate-inl.h
@@ -0,0 +1,82 @@
+/*
+   american fuzzy lop - high-performance binary-only instrumentation
+   -----------------------------------------------------------------
+
+   Written by Andrew Griffiths <agriffiths@google.com> and
+              Michal Zalewski <lcamtuf@google.com>
+
+   Idea & design very much by Andrew Griffiths.
+
+   TCG instrumentation and block chaining support by Andrea Biondo
+                                      <andrea.biondo965@gmail.com>
+
+   Copyright 2015, 2016, 2017 Google Inc. 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
+
+   This code is a shim patched into the separately-distributed source
+   code of QEMU 2.10.0. It leverages the built-in QEMU tracing functionality
+   to implement AFL-style instrumentation and to take care of the remaining
+   parts of the AFL fork server logic.
+
+   The resulting QEMU binary is essentially a standalone instrumentation
+   tool; for an example of how to leverage it for other purposes, you can
+   have a look at afl-showmap.c.
+
+ */
+
+#include "../../config.h"
+#include "tcg-op.h"
+
+/* Declared in afl-qemu-cpu-inl.h */
+extern unsigned char *afl_area_ptr;
+extern unsigned int afl_inst_rms;
+extern abi_ulong afl_start_code, afl_end_code;
+
+/* Generates TCG code for AFL's tracing instrumentation. */
+static void afl_gen_trace(target_ulong cur_loc)
+{
+  static __thread target_ulong prev_loc;
+  TCGv index, count, new_prev_loc;
+  TCGv_ptr prev_loc_ptr, count_ptr;
+
+  /* Optimize for cur_loc > afl_end_code, which is the most likely case on
+     Linux systems. */
+
+  if (cur_loc > afl_end_code || cur_loc < afl_start_code || !afl_area_ptr)
+    return;
+
+  /* Looks like QEMU always maps to fixed locations, so ASAN is not a
+     concern. Phew. But instruction addresses may be aligned. Let's mangle
+     the value to get something quasi-uniform. */
+
+  cur_loc  = (cur_loc >> 4) ^ (cur_loc << 8);
+  cur_loc &= MAP_SIZE - 1;
+
+  /* Implement probabilistic instrumentation by looking at scrambled block
+     address. This keeps the instrumented locations stable across runs. */
+
+  if (cur_loc >= afl_inst_rms) return;
+
+  /* index = prev_loc ^ cur_loc */
+  prev_loc_ptr = tcg_const_ptr(&prev_loc);
+  index = tcg_temp_new();
+  tcg_gen_ld_tl(index, prev_loc_ptr, 0);
+  tcg_gen_xori_tl(index, index, cur_loc);
+
+  /* afl_area_ptr[index]++ */
+  count_ptr = tcg_const_ptr(afl_area_ptr);
+  tcg_gen_add_ptr(count_ptr, count_ptr, TCGV_NAT_TO_PTR(index));
+  count = tcg_temp_new();
+  tcg_gen_ld8u_tl(count, count_ptr, 0);
+  tcg_gen_addi_tl(count, count, 1);
+  tcg_gen_st8_tl(count, count_ptr, 0);
+
+  /* prev_loc = cur_loc >> 1 */
+  new_prev_loc = tcg_const_tl(cur_loc >> 1);
+  tcg_gen_st_tl(new_prev_loc, prev_loc_ptr, 0);
+}