about summary refs log tree commit diff
path: root/src/afl-fuzz-redqueen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/afl-fuzz-redqueen.c')
-rw-r--r--src/afl-fuzz-redqueen.c87
1 files changed, 85 insertions, 2 deletions
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index c21c973f..296fcd98 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;
 
@@ -120,6 +122,8 @@ u8 colorization(u8* buf, u32 len, u32 exec_cksum) {
   while ((rng = pop_biggest_range(&ranges)) != NULL && stage_cur) {
 
     u32 s = rng->end - rng->start;
+    if (s == 0) goto empty_range;
+
     memcpy(backup, buf + rng->start, s);
     rand_replace(buf + rng->start, s);
 
@@ -132,8 +136,11 @@ 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;
+
+  empty_range:
     ck_free(rng);
     --stage_cur;
 
@@ -151,6 +158,32 @@ u8 colorization(u8* buf, u32 len, u32 exec_cksum) {
 
   }
 
+  // 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;
 
 }
@@ -270,6 +303,48 @@ u8 cmp_extend_encoding(struct cmp_header* h, u64 pattern, u64 repl, u32 idx,
 
 }
 
+void try_to_add_to_dict(u64 v, u8 shape) {
+
+  u8* b = (u8*)&v;
+
+  u32 k;
+  u8  cons_ff = 0, cons_0 = 0;
+  for (k = 0; k < shape; ++k) {
+
+    if (b[k] == 0)
+      ++cons_0;
+    else if (b[k] == 0xff)
+      ++cons_0;
+    else
+      cons_0 = cons_ff = 0;
+
+    if (cons_0 > 1 || cons_ff > 1) return;
+
+  }
+
+  maybe_add_auto((u8*)&v, shape);
+
+  u64 rev;
+  switch (shape) {
+
+    case 1: break;
+    case 2:
+      rev = SWAP16((u16)v);
+      maybe_add_auto((u8*)&rev, shape);
+      break;
+    case 4:
+      rev = SWAP32((u32)v);
+      maybe_add_auto((u8*)&rev, shape);
+      break;
+    case 8:
+      rev = SWAP64(v);
+      maybe_add_auto((u8*)&rev, shape);
+      break;
+
+  }
+
+}
+
 u8 cmp_fuzz(u32 key, u8* orig_buf, u8* buf, u32 len) {
 
   struct cmp_header* h = &cmp_map->headers[key];
@@ -311,6 +386,14 @@ u8 cmp_fuzz(u32 key, u8* orig_buf, u8* buf, u32 len) {
 
     }
 
+    // If failed, add to dictionary
+    if (fails == 8) {
+
+      try_to_add_to_dict(o->v0, SHAPE_BYTES(h->shape));
+      try_to_add_to_dict(o->v1, SHAPE_BYTES(h->shape));
+
+    }
+
   cmp_fuzz_next_iter:
     stage_cur++;
 
@@ -362,7 +445,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;