diff options
Diffstat (limited to 'src/afl-fuzz-redqueen.c')
-rw-r--r-- | src/afl-fuzz-redqueen.c | 175 |
1 files changed, 86 insertions, 89 deletions
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index d6f117f6..560ec419 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -27,8 +27,6 @@ #include "afl-fuzz.h" #include "cmplog.h" -static char** its_argv; - ///// Colorization struct range { @@ -86,24 +84,24 @@ struct range* pop_biggest_range(struct range** ranges) { } -u8 get_exec_checksum(u8* buf, u32 len, u32* cksum) { +static u8 get_exec_checksum(afl_state_t *afl, u8* buf, u32 len, u32* cksum) { - if (unlikely(common_fuzz_stuff(its_argv, buf, len))) return 1; + if (unlikely(common_fuzz_stuff(afl, buf, len))) return 1; - *cksum = hash32(trace_bits, MAP_SIZE, HASH_CONST); + *cksum = hash32(afl->fsrv.trace_bits, MAP_SIZE, HASH_CONST); return 0; } -static void rand_replace(u8* buf, u32 len) { +static void rand_replace(afl_state_t *afl, u8* buf, u32 len) { u32 i; for (i = 0; i < len; ++i) - buf[i] = UR(256); + buf[i] = UR(afl, 256); } -u8 colorization(u8* buf, u32 len, u32 exec_cksum) { +static u8 colorization(afl_state_t *afl, u8* buf, u32 len, u32 exec_cksum) { struct range* ranges = add_range(NULL, 0, len); u8* backup = ck_alloc_nozero(len); @@ -111,24 +109,24 @@ u8 colorization(u8* buf, u32 len, u32 exec_cksum) { u8 needs_write = 0; u64 orig_hit_cnt, new_hit_cnt; - orig_hit_cnt = queued_paths + unique_crashes; + orig_hit_cnt = afl->queued_paths + afl->unique_crashes; - stage_name = "colorization"; - stage_short = "colorization"; - stage_max = 1000; + afl->stage_name = "colorization"; + afl->stage_short = "colorization"; + afl->stage_max = 1000; struct range* rng; - stage_cur = 0; - while ((rng = pop_biggest_range(&ranges)) != NULL && stage_cur < stage_max) { + afl->stage_cur = 0; + while ((rng = pop_biggest_range(&ranges)) != NULL && afl->stage_cur < afl->stage_max) { u32 s = rng->end - rng->start; if (s == 0) goto empty_range; memcpy(backup, buf + rng->start, s); - rand_replace(buf + rng->start, s); + rand_replace(afl, buf + rng->start, s); u32 cksum; - if (unlikely(get_exec_checksum(buf, len, &cksum))) goto checksum_fail; + if (unlikely(get_exec_checksum(afl, buf, len, &cksum))) goto checksum_fail; if (cksum != exec_cksum) { @@ -142,15 +140,15 @@ u8 colorization(u8* buf, u32 len, u32 exec_cksum) { empty_range: ck_free(rng); - ++stage_cur; + ++afl->stage_cur; } - if (stage_cur < stage_max) queue_cur->fully_colorized = 1; + if (afl->stage_cur < afl->stage_max) afl->queue_cur->fully_colorized = 1; - new_hit_cnt = queued_paths + unique_crashes; - stage_finds[STAGE_COLORIZATION] += new_hit_cnt - orig_hit_cnt; - stage_cycles[STAGE_COLORIZATION] += stage_cur; + new_hit_cnt = afl->queued_paths + afl->unique_crashes; + afl->stage_finds[STAGE_COLORIZATION] += new_hit_cnt - orig_hit_cnt; + afl->stage_cycles[STAGE_COLORIZATION] += afl->stage_cur; ck_free(backup); while (ranges) { @@ -167,21 +165,21 @@ u8 colorization(u8* buf, u32 len, u32 exec_cksum) { s32 fd; - if (no_unlink) { + if (afl->no_unlink) { - fd = open(queue_cur->fname, O_WRONLY | O_CREAT | O_TRUNC, 0600); + fd = open(afl->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); + unlink(afl->queue_cur->fname); /* ignore errors */ + fd = open(afl->queue_cur->fname, O_WRONLY | O_CREAT | O_EXCL, 0600); } - if (fd < 0) PFATAL("Unable to create '%s'", queue_cur->fname); + if (fd < 0) PFATAL("Unable to create '%s'", afl->queue_cur->fname); - ck_write(fd, buf, len, queue_cur->fname); - queue_cur->len = len; // no-op, just to be 100% safe + ck_write(fd, buf, len, afl->queue_cur->fname); + afl->queue_cur->len = len; // no-op, just to be 100% safe close(fd); @@ -206,15 +204,15 @@ checksum_fail: ///// Input to State replacement -u8 its_fuzz(u8* buf, u32 len, u8* status) { +static u8 its_fuzz(afl_state_t *afl, u8* buf, u32 len, u8* status) { u64 orig_hit_cnt, new_hit_cnt; - orig_hit_cnt = queued_paths + unique_crashes; + orig_hit_cnt = afl->queued_paths + afl->unique_crashes; - if (unlikely(common_fuzz_stuff(its_argv, buf, len))) return 1; + if (unlikely(common_fuzz_stuff(afl, buf, len))) return 1; - new_hit_cnt = queued_paths + unique_crashes; + new_hit_cnt = afl->queued_paths + afl->unique_crashes; if (unlikely(new_hit_cnt != orig_hit_cnt)) *status = 1; @@ -225,7 +223,7 @@ u8 its_fuzz(u8* buf, u32 len, u8* status) { } -u8 cmp_extend_encoding(struct cmp_header* h, u64 pattern, u64 repl, u32 idx, +static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header* h, u64 pattern, u64 repl, u32 idx, u8* orig_buf, u8* buf, u32 len, u8 do_reverse, u8* status) { @@ -246,14 +244,14 @@ u8 cmp_extend_encoding(struct cmp_header* h, u64 pattern, u64 repl, u32 idx, if (its_len >= 8 && *buf_64 == pattern) { // && *o_buf_64 == pattern) { *buf_64 = repl; - if (unlikely(its_fuzz(buf, len, status))) return 1; + if (unlikely(its_fuzz(afl, buf, len, status))) return 1; *buf_64 = pattern; } // reverse encoding if (do_reverse) - if (unlikely(cmp_extend_encoding(h, SWAP64(pattern), SWAP64(repl), idx, + if (unlikely(cmp_extend_encoding(afl, h, SWAP64(pattern), SWAP64(repl), idx, orig_buf, buf, len, 0, status))) return 1; @@ -265,14 +263,14 @@ u8 cmp_extend_encoding(struct cmp_header* h, u64 pattern, u64 repl, u32 idx, *buf_32 == (u32)pattern) { // && *o_buf_32 == (u32)pattern) { *buf_32 = (u32)repl; - if (unlikely(its_fuzz(buf, len, status))) return 1; + if (unlikely(its_fuzz(afl, buf, len, status))) return 1; *buf_32 = pattern; } // reverse encoding if (do_reverse) - if (unlikely(cmp_extend_encoding(h, SWAP32(pattern), SWAP32(repl), idx, + if (unlikely(cmp_extend_encoding(afl, h, SWAP32(pattern), SWAP32(repl), idx, orig_buf, buf, len, 0, status))) return 1; @@ -284,14 +282,14 @@ u8 cmp_extend_encoding(struct cmp_header* h, u64 pattern, u64 repl, u32 idx, *buf_16 == (u16)pattern) { // && *o_buf_16 == (u16)pattern) { *buf_16 = (u16)repl; - if (unlikely(its_fuzz(buf, len, status))) return 1; + if (unlikely(its_fuzz(afl, buf, len, status))) return 1; *buf_16 = (u16)pattern; } // reverse encoding if (do_reverse) - if (unlikely(cmp_extend_encoding(h, SWAP16(pattern), SWAP16(repl), idx, + if (unlikely(cmp_extend_encoding(afl, h, SWAP16(pattern), SWAP16(repl), idx, orig_buf, buf, len, 0, status))) return 1; @@ -302,7 +300,7 @@ u8 cmp_extend_encoding(struct cmp_header* h, u64 pattern, u64 repl, u32 idx, if (its_len >= 2 && *buf_8 == (u8)pattern) {// && *o_buf_8 == (u8)pattern) { *buf_8 = (u8)repl; - if (unlikely(its_fuzz(buf, len, status))) + if (unlikely(its_fuzz(afl, buf, len, status))) return 1; *buf_16 = (u16)pattern; @@ -314,7 +312,7 @@ u8 cmp_extend_encoding(struct cmp_header* h, u64 pattern, u64 repl, u32 idx, } -void try_to_add_to_dict(u64 v, u8 shape) { +static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) { u8* b = (u8*)&v; @@ -333,7 +331,7 @@ void try_to_add_to_dict(u64 v, u8 shape) { } - maybe_add_auto((u8*)&v, shape); + maybe_add_auto(afl, (u8*)&v, shape); u64 rev; switch (shape) { @@ -341,24 +339,24 @@ void try_to_add_to_dict(u64 v, u8 shape) { case 1: break; case 2: rev = SWAP16((u16)v); - maybe_add_auto((u8*)&rev, shape); + maybe_add_auto(afl, (u8*)&rev, shape); break; case 4: rev = SWAP32((u32)v); - maybe_add_auto((u8*)&rev, shape); + maybe_add_auto(afl, (u8*)&rev, shape); break; case 8: rev = SWAP64(v); - maybe_add_auto((u8*)&rev, shape); + maybe_add_auto(afl, (u8*)&rev, shape); break; } } -u8 cmp_fuzz(u32 key, u8* orig_buf, u8* buf, u32 len) { +static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8* orig_buf, u8* buf, u32 len) { - struct cmp_header* h = &cmp_map->headers[key]; + struct cmp_header* h = &afl->shm.cmp_map->headers[key]; u32 i, j, idx; u32 loggeds = h->hits; @@ -370,16 +368,16 @@ u8 cmp_fuzz(u32 key, u8* orig_buf, u8* buf, u32 len) { for (i = 0; i < loggeds; ++i) { - struct cmp_operands* o = &cmp_map->log[key][i]; + struct cmp_operands* o = &afl->shm.cmp_map->log[key][i]; // opt not in the paper for (j = 0; j < i; ++j) - if (cmp_map->log[key][j].v0 == o->v0 && cmp_map->log[key][i].v1 == o->v1) + if (afl->shm.cmp_map->log[key][j].v0 == o->v0 && afl->shm.cmp_map->log[key][i].v1 == o->v1) goto cmp_fuzz_next_iter; for (idx = 0; idx < len && fails < 8; ++idx) { - if (unlikely(cmp_extend_encoding(h, o->v0, o->v1, idx, orig_buf, buf, len, + if (unlikely(cmp_extend_encoding(afl, h, o->v0, o->v1, idx, orig_buf, buf, len, 1, &status))) return 1; if (status == 2) @@ -387,7 +385,7 @@ u8 cmp_fuzz(u32 key, u8* orig_buf, u8* buf, u32 len) { else if (status == 1) break; - if (unlikely(cmp_extend_encoding(h, o->v1, o->v0, idx, orig_buf, buf, len, + if (unlikely(cmp_extend_encoding(afl, h, o->v1, o->v0, idx, orig_buf, buf, len, 1, &status))) return 1; if (status == 2) @@ -400,13 +398,13 @@ 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)); + try_to_add_to_dict(afl, o->v0, SHAPE_BYTES(h->shape)); + try_to_add_to_dict(afl, o->v1, SHAPE_BYTES(h->shape)); } cmp_fuzz_next_iter: - stage_cur++; + afl->stage_cur++; } @@ -414,7 +412,7 @@ u8 cmp_fuzz(u32 key, u8* orig_buf, u8* buf, u32 len) { } -u8 rtn_extend_encoding(struct cmp_header* h, u8* pattern, u8* repl, u32 idx, +static u8 rtn_extend_encoding(afl_state_t *afl, struct cmp_header* h, u8* pattern, u8* repl, u32 idx, u8* orig_buf, u8* buf, u32 len, u8* status) { u32 i; @@ -430,7 +428,7 @@ u8 rtn_extend_encoding(struct cmp_header* h, u8* pattern, u8* repl, u32 idx, if (pattern[idx + i] != buf[idx + i] || *status == 1) break; buf[idx + i] = repl[idx + i]; - if (unlikely(its_fuzz(buf, len, status))) return 1; + if (unlikely(its_fuzz(afl, buf, len, status))) return 1; } @@ -439,9 +437,9 @@ u8 rtn_extend_encoding(struct cmp_header* h, u8* pattern, u8* repl, u32 idx, } -u8 rtn_fuzz(u32 key, u8* orig_buf, u8* buf, u32 len) { +static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8* orig_buf, u8* buf, u32 len) { - struct cmp_header* h = &cmp_map->headers[key]; + struct cmp_header* h = &afl->shm.cmp_map->headers[key]; u32 i, j, idx; u32 loggeds = h->hits; @@ -453,17 +451,17 @@ u8 rtn_fuzz(u32 key, u8* orig_buf, u8* buf, u32 len) { for (i = 0; i < loggeds; ++i) { - struct cmpfn_operands* o = &((struct cmpfn_operands*)cmp_map->log[key])[i]; + struct cmpfn_operands* o = &((struct cmpfn_operands*)afl->shm.cmp_map->log[key])[i]; // opt not in the paper for (j = 0; j < i; ++j) - if (!memcmp(&((struct cmpfn_operands*)cmp_map->log[key])[j], o, + if (!memcmp(&((struct cmpfn_operands*)afl->shm.cmp_map->log[key])[j], o, sizeof(struct cmpfn_operands))) goto rtn_fuzz_next_iter; for (idx = 0; idx < len && fails < 8; ++idx) { - if (unlikely(rtn_extend_encoding(h, o->v0, o->v1, idx, orig_buf, buf, len, + if (unlikely(rtn_extend_encoding(afl, h, o->v0, o->v1, idx, orig_buf, buf, len, &status))) return 1; if (status == 2) @@ -471,7 +469,7 @@ u8 rtn_fuzz(u32 key, u8* orig_buf, u8* buf, u32 len) { else if (status == 1) break; - if (unlikely(rtn_extend_encoding(h, o->v1, o->v0, idx, orig_buf, buf, len, + if (unlikely(rtn_extend_encoding(afl, h, o->v1, o->v0, idx, orig_buf, buf, len, &status))) return 1; if (status == 2) @@ -484,13 +482,13 @@ u8 rtn_fuzz(u32 key, u8* orig_buf, u8* buf, u32 len) { // If failed, add to dictionary if (fails == 8) { - maybe_add_auto(o->v0, SHAPE_BYTES(h->shape)); - maybe_add_auto(o->v1, SHAPE_BYTES(h->shape)); + maybe_add_auto(afl, o->v0, SHAPE_BYTES(h->shape)); + maybe_add_auto(afl, o->v1, SHAPE_BYTES(h->shape)); } rtn_fuzz_next_iter: - stage_cur++; + afl->stage_cur++; } @@ -500,51 +498,50 @@ u8 rtn_fuzz(u32 key, u8* orig_buf, u8* buf, u32 len) { ///// Input to State stage -// queue_cur->exec_cksum -u8 input_to_state_stage(char** argv, u8* orig_buf, u8* buf, u32 len, +// afl->queue_cur->exec_cksum +u8 input_to_state_stage(afl_state_t *afl, u8* orig_buf, u8* buf, u32 len, u32 exec_cksum) { u8 r = 1; - its_argv = argv; - if (unlikely(colorization(buf, len, exec_cksum))) return 1; + if (unlikely(colorization(afl, buf, len, exec_cksum))) return 1; - // do it manually, forkserver clear only trace_bits - memset(cmp_map->headers, 0, sizeof(cmp_map->headers)); + // do it manually, forkserver clear only afl->fsrv.trace_bits + memset(afl->shm.cmp_map->headers, 0, sizeof(afl->shm.cmp_map->headers)); - if (unlikely(common_fuzz_cmplog_stuff(argv, buf, len))) return 1; + if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) return 1; u64 orig_hit_cnt, new_hit_cnt; - u64 orig_execs = total_execs; - orig_hit_cnt = queued_paths + unique_crashes; + u64 orig_execs = afl->total_execs; + orig_hit_cnt = afl->queued_paths + afl->unique_crashes; - stage_name = "input-to-state"; - stage_short = "its"; - stage_max = 0; - stage_cur = 0; + afl->stage_name = "input-to-state"; + afl->stage_short = "its"; + afl->stage_max = 0; + afl->stage_cur = 0; u32 k; for (k = 0; k < CMP_MAP_W; ++k) { - if (!cmp_map->headers[k].hits) continue; - if (cmp_map->headers[k].type == CMP_TYPE_INS) - stage_max += MIN(cmp_map->headers[k].hits, CMP_MAP_H); + if (!afl->shm.cmp_map->headers[k].hits) continue; + if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS) + afl->stage_max += MIN(afl->shm.cmp_map->headers[k].hits, CMP_MAP_H); else - stage_max += MIN(cmp_map->headers[k].hits, CMP_MAP_RTN_H); + afl->stage_max += MIN(afl->shm.cmp_map->headers[k].hits, CMP_MAP_RTN_H); } for (k = 0; k < CMP_MAP_W; ++k) { - if (!cmp_map->headers[k].hits) continue; + if (!afl->shm.cmp_map->headers[k].hits) continue; - if (cmp_map->headers[k].type == CMP_TYPE_INS) { + if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS) { - if (unlikely(cmp_fuzz(k, orig_buf, buf, len))) goto exit_its; + if (unlikely(cmp_fuzz(afl, k, orig_buf, buf, len))) goto exit_its; } else { - if (unlikely(rtn_fuzz(k, orig_buf, buf, len))) goto exit_its; + if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, len))) goto exit_its; } @@ -555,9 +552,9 @@ u8 input_to_state_stage(char** argv, u8* orig_buf, u8* buf, u32 len, exit_its: memcpy(orig_buf, buf, len); - new_hit_cnt = queued_paths + unique_crashes; - stage_finds[STAGE_ITS] += new_hit_cnt - orig_hit_cnt; - stage_cycles[STAGE_ITS] += total_execs - orig_execs; + new_hit_cnt = afl->queued_paths + afl->unique_crashes; + afl->stage_finds[STAGE_ITS] += new_hit_cnt - orig_hit_cnt; + afl->stage_cycles[STAGE_ITS] += afl->total_execs - orig_execs; return r; |