about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Dockerfile2
-rw-r--r--TODO1
-rw-r--r--qemu_mode/patches/afl-qemu-common.h6
-rw-r--r--qemu_mode/patches/afl-qemu-cpu-inl.h22
-rw-r--r--qemu_mode/patches/afl-qemu-cpu-translate-inl.h96
-rw-r--r--src/afl-fuzz-cmplog.c12
-rw-r--r--src/afl-fuzz-redqueen.c32
7 files changed, 149 insertions, 22 deletions
diff --git a/Dockerfile b/Dockerfile
index 7bb60610..396954ab 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,7 +1,7 @@
 FROM ubuntu:eoan
 MAINTAINER David Carlier <devnexen@gmail.com>
 LABEL "about"="AFLplusplus docker image"
-RUN apt-get update && apt-get install -y \
+RUN apt-get update && apt-get -y install \
     --no-install-suggests --no-install-recommends \
     automake \
     bison \
diff --git a/TODO b/TODO
index e935eafa..d153f1b4 100644
--- a/TODO
+++ b/TODO
@@ -7,6 +7,7 @@ Makefile:
 
 afl-fuzz:
  - sync_fuzzers(): only masters sync from all, slaves only sync from master
+ - ascii_only mode
 
 gcc_plugin:
  - laf-intel
diff --git a/qemu_mode/patches/afl-qemu-common.h b/qemu_mode/patches/afl-qemu-common.h
index 4d651385..18c36f73 100644
--- a/qemu_mode/patches/afl-qemu-common.h
+++ b/qemu_mode/patches/afl-qemu-common.h
@@ -35,6 +35,9 @@
 #define __AFL_QEMU_COMMON
 
 #include "../../config.h"
+#include "../../include/cmplog.h"
+
+#define PERSISTENT_DEFAULT_MAX_CNT 1000
 
 #ifndef CPU_NB_REGS
 #define AFL_REGS_NUM 1000
@@ -74,6 +77,9 @@ extern int            persisent_retaddr_offset;
 
 extern __thread abi_ulong afl_prev_loc;
 
+extern struct cmp_map* __afl_cmp_map;
+extern __thread u32    __afl_cmp_counter;
+
 void afl_debug_dump_saved_regs();
 
 void afl_persistent_loop();
diff --git a/qemu_mode/patches/afl-qemu-cpu-inl.h b/qemu_mode/patches/afl-qemu-cpu-inl.h
index ac847371..0ae6364b 100644
--- a/qemu_mode/patches/afl-qemu-cpu-inl.h
+++ b/qemu_mode/patches/afl-qemu-cpu-inl.h
@@ -32,11 +32,8 @@
  */
 
 #include <sys/shm.h>
-#include "../../config.h"
 #include "afl-qemu-common.h"
 
-#define PERSISTENT_DEFAULT_MAX_CNT 1000
-
 /***************************
  * VARIOUS AUXILIARY STUFF *
  ***************************/
@@ -81,6 +78,9 @@ u8 afl_compcov_level;
 
 __thread abi_ulong afl_prev_loc;
 
+struct cmp_map* __afl_cmp_map;
+__thread u32    __afl_cmp_counter;
+
 /* Set in the child process in forkserver mode: */
 
 static int forkserver_installed = 0;
@@ -181,6 +181,22 @@ static void afl_setup(void) {
     if (inst_r) afl_area_ptr[0] = 1;
 
   }
+  
+  if (getenv("___AFL_EINS_ZWEI_POLIZEI___")) { // CmpLog forkserver
+  
+    id_str = getenv(CMPLOG_SHM_ENV_VAR);
+
+    if (id_str) {
+
+      u32 shm_id = atoi(id_str);
+
+      __afl_cmp_map = shmat(shm_id, NULL, 0);
+
+      if (__afl_cmp_map == (void*)-1) _exit(1);
+
+    }
+    
+  }
 
   if (getenv("AFL_INST_LIBS")) {
 
diff --git a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h
index 6d42bf3d..9f032feb 100644
--- a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h
+++ b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h
@@ -102,31 +102,103 @@ static void afl_compcov_log_64(target_ulong cur_loc, target_ulong arg1,
 
 }
 
+static void afl_cmplog_16(target_ulong cur_loc, target_ulong arg1,
+                          target_ulong arg2) {
+
+  register uintptr_t k = (uintptr_t)cur_loc;
+
+  u32 hits = __afl_cmp_map->headers[k].hits;
+  __afl_cmp_map->headers[k].hits = hits + 1;
+  // if (!__afl_cmp_map->headers[k].cnt)
+  //  __afl_cmp_map->headers[k].cnt = __afl_cmp_counter++;
+
+  __afl_cmp_map->headers[k].shape = 1;
+  //__afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+
+  hits &= CMP_MAP_H - 1;
+  __afl_cmp_map->log[k][hits].v0 = arg1;
+  __afl_cmp_map->log[k][hits].v1 = arg2;
+
+}
+
+static void afl_cmplog_32(target_ulong cur_loc, target_ulong arg1,
+                          target_ulong arg2) {
+
+  register uintptr_t k = (uintptr_t)cur_loc;
+
+  u32 hits = __afl_cmp_map->headers[k].hits;
+  __afl_cmp_map->headers[k].hits = hits + 1;
+
+  __afl_cmp_map->headers[k].shape = 3;
+
+  hits &= CMP_MAP_H - 1;
+  __afl_cmp_map->log[k][hits].v0 = arg1;
+  __afl_cmp_map->log[k][hits].v1 = arg2;
+
+}
+
+static void afl_cmplog_64(target_ulong cur_loc, target_ulong arg1,
+                          target_ulong arg2) {
+
+  register uintptr_t k = (uintptr_t)cur_loc;
+
+  u32 hits = __afl_cmp_map->headers[k].hits;
+  __afl_cmp_map->headers[k].hits = hits + 1;
+
+  __afl_cmp_map->headers[k].shape = 7;
+
+  hits &= CMP_MAP_H - 1;
+  __afl_cmp_map->log[k][hits].v0 = arg1;
+  __afl_cmp_map->log[k][hits].v1 = arg2;
+
+}
+
+
 static void afl_gen_compcov(target_ulong cur_loc, TCGv_i64 arg1, TCGv_i64 arg2,
                             TCGMemOp ot, int is_imm) {
 
   void *func;
 
-  if (!afl_compcov_level || cur_loc > afl_end_code || cur_loc < afl_start_code)
+  if (cur_loc > afl_end_code || cur_loc < afl_start_code)
     return;
 
-  if (!is_imm && afl_compcov_level < 2) return;
+  if (__afl_cmp_map) {
+  
+    cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
+    cur_loc &= CMP_MAP_W - 1;
 
-  switch (ot) {
+    switch (ot) {
 
-    case MO_64: func = &afl_compcov_log_64; break;
-    case MO_32: func = &afl_compcov_log_32; break;
-    case MO_16: func = &afl_compcov_log_16; break;
-    default: return;
+      case MO_64: func = &afl_cmplog_64; break;
+      case MO_32: func = &afl_cmplog_32; break;
+      case MO_16: func = &afl_cmplog_16; break;
+      default: return;
 
-  }
+    }
+
+    tcg_gen_afl_compcov_log_call(func, cur_loc, arg1, arg2);
+  
+  } else if (afl_compcov_level) {
+  
+    if (!is_imm && afl_compcov_level < 2) return;
+
+    cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
+    cur_loc &= MAP_SIZE - 7;
 
-  cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
-  cur_loc &= MAP_SIZE - 7;
+    if (cur_loc >= afl_inst_rms) return;
+    
+    switch (ot) {
 
-  if (cur_loc >= afl_inst_rms) return;
+      case MO_64: func = &afl_compcov_log_64; break;
+      case MO_32: func = &afl_compcov_log_32; break;
+      case MO_16: func = &afl_compcov_log_16; break;
+      default: return;
 
-  tcg_gen_afl_compcov_log_call(func, cur_loc, arg1, arg2);
+    }
+
+    tcg_gen_afl_compcov_log_call(func, cur_loc, arg1, arg2);
+  
+  }
 
 }
 
diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c
index 92bac4ab..69efcffa 100644
--- a/src/afl-fuzz-cmplog.c
+++ b/src/afl-fuzz-cmplog.c
@@ -150,8 +150,10 @@ void init_cmplog_forkserver(char** argv) {
            "msan_track_origins=0",
            0);
 
-    argv[0] = cmplog_binary;
-    execv(cmplog_binary, argv);
+    setenv("___AFL_EINS_ZWEI_POLIZEI___", "1", 1);
+
+    if (!qemu_mode) argv[0] = cmplog_binary;
+    execv(argv[0], argv);
 
     /* Use a distinctive bitmap signature to tell the parent about execv()
        falling through. */
@@ -440,9 +442,11 @@ u8 run_cmplog_target(char** argv, u32 timeout) {
       setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":"
                              "symbolize=0:"
                              "msan_track_origins=0", 0);
+      
+      setenv("___AFL_EINS_ZWEI_POLIZEI___", "1", 1);
 
-      argv[0] = cmplog_binary;
-      execv(cmplog_binary, argv);
+      if (!qemu_mode) argv[0] = cmplog_binary;
+      execv(argv[0], argv);
 
       /* Use a distinctive bitmap value to tell the parent about execv()
          falling through. */
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index c21c973f..6fb1964f 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -108,6 +108,8 @@ u8 colorization(u8* buf, u32 len, u32 exec_cksum) {
   struct range* ranges = add_range(NULL, 0, len);
   u8*           backup = ck_alloc_nozero(len);
 
+  u8 needs_write = 0;
+
   u64 orig_hit_cnt, new_hit_cnt;
   orig_hit_cnt = queued_paths + unique_crashes;
 
@@ -132,7 +134,7 @@ u8 colorization(u8* buf, u32 len, u32 exec_cksum) {
       ranges = add_range(ranges, rng->start + s / 2 + 1, rng->end);
       memcpy(buf + rng->start, backup, s);
 
-    }
+    } else needs_write = 1;
 
     ck_free(rng);
     --stage_cur;
@@ -150,6 +152,32 @@ u8 colorization(u8* buf, u32 len, u32 exec_cksum) {
     ck_free(rng);
 
   }
+  
+  // save the input with the high entropy
+  
+  if (needs_write) {
+
+    s32 fd;
+
+    if (no_unlink) {
+
+      fd = open(queue_cur->fname, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+
+    } else {
+
+      unlink(queue_cur->fname);                                    /* ignore errors */
+      fd = open(queue_cur->fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
+
+    }
+
+    if (fd < 0) PFATAL("Unable to create '%s'", queue_cur->fname);
+
+    ck_write(fd, buf, len, queue_cur->fname);
+    queue_cur->len = len; // no-op, just to be 100% safe
+    
+    close(fd);
+    
+  }
 
   return 0;
 
@@ -362,7 +390,7 @@ u8 input_to_state_stage(char** argv, u8* orig_buf, u8* buf, u32 len,
 
   }
 
-  memcpy(buf, orig_buf, len);
+  memcpy(orig_buf, buf, len);
 
   new_hit_cnt = queued_paths + unique_crashes;
   stage_finds[STAGE_ITS] += new_hit_cnt - orig_hit_cnt;