diff options
Diffstat (limited to 'src/afl-fuzz-redqueen.c')
-rw-r--r-- | src/afl-fuzz-redqueen.c | 132 |
1 files changed, 118 insertions, 14 deletions
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 724da407..cb4c78df 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -24,6 +24,7 @@ */ +#include <limits.h> #include "afl-fuzz.h" #include "cmplog.h" @@ -177,6 +178,9 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) { afl->stage_cycles[STAGE_COLORIZATION] += afl->stage_cur; ck_free(backup); + ck_free(rng); + rng = NULL; + while (ranges) { rng = ranges; @@ -186,9 +190,6 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) { } - ck_free(rng); - rng = NULL; - // save the input with the high entropy if (needs_write) { @@ -262,11 +263,64 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) { } +static long long strntoll(const char *str, size_t sz, char **end, int base) { + + char buf[64]; + long long ret; + const char *beg = str; + + for (; beg && sz && *beg == ' '; beg++, sz--) {}; + + if (!sz || sz >= sizeof(buf)) { + + if (end) *end = (char *)str; + return 0; + + } + + memcpy(buf, beg, sz); + buf[sz] = '\0'; + ret = strtoll(buf, end, base); + if (ret == LLONG_MIN || ret == LLONG_MAX) return ret; + if (end) *end = (char *)beg + (*end - buf); + return ret; + +} + +static unsigned long long strntoull(const char *str, size_t sz, char **end, + int base) { + + char buf[64]; + unsigned long long ret; + const char * beg = str; + + for (; beg && sz && *beg == ' '; beg++, sz--) + ; + + if (!sz || sz >= sizeof(buf)) { + + if (end) *end = (char *)str; + return 0; + + } + + memcpy(buf, beg, sz); + buf[sz] = '\0'; + ret = strtoull(buf, end, base); + if (end) *end = (char *)beg + (*end - buf); + return ret; + +} + +#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size + static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u64 pattern, u64 repl, u64 o_pattern, u32 idx, u8 *orig_buf, u8 *buf, u32 len, u8 do_reverse, u8 *status) { + if (!buf) { FATAL("BUG: buf was NULL. Please report this.\n"); } + u64 *buf_64 = (u64 *)&buf[idx]; u32 *buf_32 = (u32 *)&buf[idx]; u16 *buf_16 = (u16 *)&buf[idx]; @@ -277,9 +331,56 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u8 * o_buf_8 = &orig_buf[idx]; u32 its_len = len - idx; - *status = 0; + // *status = 0; + + u8 * endptr; + u8 use_num = 0, use_unum = 0; + unsigned long long unum; + long long num; + if (afl->queue_cur->is_ascii) { + + endptr = buf_8; + num = strntoll(buf_8, len - idx, (char **)&endptr, 0); + if (endptr == buf_8) { + + unum = strntoull(buf_8, len - idx, (char **)&endptr, 0); + if (endptr == buf_8) use_unum = 1; + + } else + + use_num = 1; + + } + + if (use_num && num == pattern) { - if (SHAPE_BYTES(h->shape) == 8) { + size_t old_len = endptr - buf_8; + size_t num_len = snprintf(NULL, 0, "%lld", num); + + u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), len + num_len); + memcpy(new_buf, buf, idx); + + snprintf(new_buf + idx, num_len, "%lld", num); + memcpy(new_buf + idx + num_len, buf_8 + old_len, len - idx - old_len); + + if (unlikely(its_fuzz(afl, new_buf, len, status))) { return 1; } + + } else if (use_unum && unum == pattern) { + + size_t old_len = endptr - buf_8; + size_t num_len = snprintf(NULL, 0, "%llu", unum); + + u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), len + num_len); + memcpy(new_buf, buf, idx); + + snprintf(new_buf + idx, num_len, "%llu", unum); + memcpy(new_buf + idx + num_len, buf_8 + old_len, len - idx - old_len); + + if (unlikely(its_fuzz(afl, new_buf, len, status))) { return 1; } + + } + + if (SHAPE_BYTES(h->shape) >= 8 && *status != 1) { if (its_len >= 8 && *buf_64 == pattern && *o_buf_64 == o_pattern) { @@ -290,7 +391,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } // reverse encoding - if (do_reverse) { + if (do_reverse && *status != 1) { if (unlikely(cmp_extend_encoding(afl, h, SWAP64(pattern), SWAP64(repl), SWAP64(o_pattern), idx, orig_buf, buf, @@ -304,7 +405,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - if (SHAPE_BYTES(h->shape) == 4 || *status == 2) { + if (SHAPE_BYTES(h->shape) >= 4 && *status != 1) { if (its_len >= 4 && *buf_32 == (u32)pattern && *o_buf_32 == (u32)o_pattern) { @@ -316,7 +417,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } // reverse encoding - if (do_reverse) { + if (do_reverse && *status != 1) { if (unlikely(cmp_extend_encoding(afl, h, SWAP32(pattern), SWAP32(repl), SWAP32(o_pattern), idx, orig_buf, buf, @@ -330,7 +431,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - if (SHAPE_BYTES(h->shape) == 2 || *status == 2) { + if (SHAPE_BYTES(h->shape) >= 2 && *status != 1) { if (its_len >= 2 && *buf_16 == (u16)pattern && *o_buf_16 == (u16)o_pattern) { @@ -342,7 +443,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } // reverse encoding - if (do_reverse) { + if (do_reverse && *status != 1) { if (unlikely(cmp_extend_encoding(afl, h, SWAP16(pattern), SWAP16(repl), SWAP16(o_pattern), idx, orig_buf, buf, @@ -356,7 +457,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - if (SHAPE_BYTES(h->shape) == 1 || *status == 2) { + if (SHAPE_BYTES(h->shape) >= 1 && *status != 1) { if (its_len >= 1 && *buf_8 == (u8)pattern && *o_buf_8 == (u8)o_pattern) { @@ -482,6 +583,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { for (idx = 0; idx < len && fails < 8; ++idx) { + status = 0; if (unlikely(cmp_extend_encoding(afl, h, o->v0, o->v1, orig_o->v0, idx, orig_buf, buf, len, 1, &status))) { @@ -499,6 +601,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) { } + status = 0; if (unlikely(cmp_extend_encoding(afl, h, o->v1, o->v0, orig_o->v1, idx, orig_buf, buf, len, 1, &status))) { @@ -570,14 +673,15 @@ static u8 rtn_extend_encoding(afl_state_t *afl, struct cmp_header *h, for (i = 0; i < its_len; ++i) { - if (pattern[idx + i] != buf[idx + i] || - o_pattern[idx + i] != orig_buf[idx + i] || *status == 1) { + if (pattern[i] != buf[idx + i] || o_pattern[i] != orig_buf[idx + i] || + *status == 1) { break; } - buf[idx + i] = repl[idx + i]; + buf[idx + i] = repl[i]; + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } } |