diff options
Diffstat (limited to 'src/afl-fuzz-redqueen.c')
-rw-r--r-- | src/afl-fuzz-redqueen.c | 87 |
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; |