From 5218c0b187dfeb2c722c41e3e0b3180d671c85ca Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 29 Mar 2023 22:53:15 +0200 Subject: all mutation strategies --- src/afl-fuzz-one.c | 571 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 368 insertions(+), 203 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 070669c5..3eed2b70 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2118,39 +2118,17 @@ havoc_stage: /* We essentially just do several thousand runs (depending on perf_score) where we take the input file and make random stacked tweaks. */ -#define MAX_HAVOC_ENTRY 64 -#define MUTATE_ASCII_DICT 64 +#define MAX_HAVOC_ENTRY 31 +#define MUTATE_ASCII_DICT 0 u32 r_max, r; - r_max = (MAX_HAVOC_ENTRY + 1) + (afl->extras_cnt ? 4 : 0) + - (afl->a_extras_cnt - ? (unlikely(afl->cmplog_binary && afl->queue_cur->is_ascii) - ? MUTATE_ASCII_DICT - : 4) - : 0); - - if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) { - - /* add expensive havoc cases here, they are activated after a full - cycle without finds happened */ - - r_max += 4; - - } - - if (unlikely(get_cur_time() - afl->last_find_time > 5000 /* 5 seconds */ && - afl->ready_for_splicing_count > 1)) { - - /* add expensive havoc cases here if there is no findings in the last 5s */ - - r_max += 4; - - } + r_max = (MAX_HAVOC_ENTRY + 1) + (afl->extras_cnt ? 2 : 0) + + (afl->a_extras_cnt ? 2 : 0); for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { - u32 use_stacking = 1 << (1 + rand_below(afl, afl->havoc_stack_pow2)); + u32 use_stacking = 2 + rand_below(afl, 15), item; afl->stage_cur_val = use_stacking; @@ -2198,146 +2176,157 @@ havoc_stage: switch ((r = rand_below(afl, r_max))) { - case 0 ... 3: { + case 0: { /* Flip a single bit somewhere. Spooky! */ + u8 bit = rand_below(afl, 8); + u32 off = rand_below(afl, temp_len); + out_buf[off] ^= 1 << bit; #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP_BIT1"); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP-BIT_%u", bit); strcat(afl->mutation, afl->m_tmp); #endif - FLIP_BIT(out_buf, rand_below(afl, temp_len << 3)); break; } - case 4 ... 7: { + case 1: { /* Set byte to interesting value. */ + item = rand_below(afl, sizeof(interesting_8)); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING8"); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING8_%u", item); strcat(afl->mutation, afl->m_tmp); #endif - out_buf[rand_below(afl, temp_len)] = - interesting_8[rand_below(afl, sizeof(interesting_8))]; + out_buf[rand_below(afl, temp_len)] = interesting_8[item]; break; } - case 8 ... 9: { + case 2: { /* Set word to interesting value, little endian. */ if (temp_len < 2) { break; } + item = rand_below(afl, sizeof(interesting_16) >> 1); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16"); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16_%u", item); strcat(afl->mutation, afl->m_tmp); #endif + *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = - interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]; + interesting_16[item]; break; } - case 10 ... 11: { + case 3: { /* Set word to interesting value, big endian. */ if (temp_len < 2) { break; } + item = rand_below(afl, sizeof(interesting_16) >> 1); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16BE"); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16BE_%u", item); strcat(afl->mutation, afl->m_tmp); #endif - *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = SWAP16( - interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]); + *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = + SWAP16(interesting_16[item]); break; } - case 12 ... 13: { + case 4: { /* Set dword to interesting value, little endian. */ if (temp_len < 4) { break; } + item = rand_below(afl, sizeof(interesting_32) >> 2); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32"); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32_%u", item); strcat(afl->mutation, afl->m_tmp); #endif + *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = - interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]; + interesting_32[item]; break; } - case 14 ... 15: { + case 5: { /* Set dword to interesting value, big endian. */ if (temp_len < 4) { break; } + item = rand_below(afl, sizeof(interesting_32) >> 2); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32BE"); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32BE_%u", item); strcat(afl->mutation, afl->m_tmp); #endif - *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = SWAP32( - interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]); + *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = + SWAP32(interesting_32[item]); break; } - case 16 ... 19: { + case 6: { /* Randomly subtract from byte. */ + item = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH8_"); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH8-_%u", item); strcat(afl->mutation, afl->m_tmp); #endif - out_buf[rand_below(afl, temp_len)] -= 1 + rand_below(afl, ARITH_MAX); + out_buf[rand_below(afl, temp_len)] -= item; break; } - case 20 ... 23: { + case 7: { /* Randomly add to byte. */ + item = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH8+"); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH8+_%u", item); strcat(afl->mutation, afl->m_tmp); #endif - out_buf[rand_below(afl, temp_len)] += 1 + rand_below(afl, ARITH_MAX); + out_buf[rand_below(afl, temp_len)] += item; break; } - case 24 ... 25: { + case 8: { /* Randomly subtract from word, little endian. */ if (temp_len < 2) { break; } u32 pos = rand_below(afl, temp_len - 1); + item = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16_-%u", pos); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16-_%u", item); strcat(afl->mutation, afl->m_tmp); #endif - *(u16 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); + *(u16 *)(out_buf + pos) -= item; break; } - case 26 ... 27: { + case 9: { /* Randomly subtract from word, big endian. */ @@ -2347,8 +2336,7 @@ havoc_stage: u16 num = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16_BE-%u_%u", pos, - num); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16BE-_%u", num); strcat(afl->mutation, afl->m_tmp); #endif *(u16 *)(out_buf + pos) = @@ -2358,25 +2346,26 @@ havoc_stage: } - case 28 ... 29: { + case 10: { /* Randomly add to word, little endian. */ if (temp_len < 2) { break; } u32 pos = rand_below(afl, temp_len - 1); + item = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+-%u", pos); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+_%u", item); strcat(afl->mutation, afl->m_tmp); #endif - *(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); + *(u16 *)(out_buf + pos) += item; break; } - case 30 ... 31: { + case 11: { /* Randomly add to word, big endian. */ @@ -2386,8 +2375,7 @@ havoc_stage: u16 num = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+BE-%u_%u", pos, - num); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16BE+__%u", num); strcat(afl->mutation, afl->m_tmp); #endif *(u16 *)(out_buf + pos) = @@ -2397,25 +2385,26 @@ havoc_stage: } - case 32 ... 33: { + case 12: { /* Randomly subtract from dword, little endian. */ if (temp_len < 4) { break; } u32 pos = rand_below(afl, temp_len - 3); + item = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32_-%u", pos); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32-_%u", item); strcat(afl->mutation, afl->m_tmp); #endif - *(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX); + *(u32 *)(out_buf + pos) -= item; break; } - case 34 ... 35: { + case 13: { /* Randomly subtract from dword, big endian. */ @@ -2425,8 +2414,7 @@ havoc_stage: u32 num = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32_BE-%u-%u", pos, - num); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32BE-_%u", num); strcat(afl->mutation, afl->m_tmp); #endif *(u32 *)(out_buf + pos) = @@ -2436,25 +2424,26 @@ havoc_stage: } - case 36 ... 37: { + case 14: { /* Randomly add to dword, little endian. */ if (temp_len < 4) { break; } u32 pos = rand_below(afl, temp_len - 3); + item = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+-%u", pos); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+_%u", item); strcat(afl->mutation, afl->m_tmp); #endif - *(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX); + *(u32 *)(out_buf + pos) += item; break; } - case 38 ... 39: { + case 15: { /* Randomly add to dword, big endian. */ @@ -2464,8 +2453,7 @@ havoc_stage: u32 num = 1 + rand_below(afl, ARITH_MAX); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+BE-%u-%u", pos, - num); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32BE+_%u", num); strcat(afl->mutation, afl->m_tmp); #endif *(u32 *)(out_buf + pos) = @@ -2475,22 +2463,25 @@ havoc_stage: } - case 40 ... 43: { + case 16: { /* Just set a random byte to a random value. Because, why not. We use XOR with 1-255 to eliminate the possibility of a no-op. */ + u32 pos = rand_below(afl, temp_len); + item = 1 + rand_below(afl, 255); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " RAND8"); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " RAND8_%u", + out_buf[pos] ^ item); strcat(afl->mutation, afl->m_tmp); #endif - out_buf[rand_below(afl, temp_len)] ^= 1 + rand_below(afl, 255); + out_buf[pos] ^= item; break; } - case 44 ... 46: { + case 17: { if (temp_len + HAVOC_BLK_XL < MAX_FILE) { @@ -2501,8 +2492,8 @@ havoc_stage: u32 clone_to = rand_below(afl, temp_len); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s-%u-%u-%u", - "clone", clone_from, clone_to, clone_len); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s_%u_%u_%u", + "overwrite", clone_from, clone_to, clone_len); strcat(afl->mutation, afl->m_tmp); #endif u8 *new_buf = @@ -2531,7 +2522,7 @@ havoc_stage: } - case 47: { + case 18: { if (temp_len + HAVOC_BLK_XL < MAX_FILE) { @@ -2539,10 +2530,13 @@ havoc_stage: u32 clone_len = choose_block_len(afl, HAVOC_BLK_XL); u32 clone_to = rand_below(afl, temp_len); + u32 strat = rand_below(afl, 2); + u32 clone_from = clone_to ? clone_to - 1 : 0; + item = strat ? rand_below(afl, 256) : out_buf[clone_from]; #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s-%u-%u", - "insert", clone_to, clone_len); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s_%u_%u_%u", + "insert", strat, clone_to, clone_len); strcat(afl->mutation, afl->m_tmp); #endif u8 *new_buf = @@ -2555,10 +2549,7 @@ havoc_stage: /* Inserted part */ - memset(new_buf + clone_to, - rand_below(afl, 2) ? rand_below(afl, 256) - : out_buf[rand_below(afl, temp_len)], - clone_len); + memset(new_buf + clone_to, item, clone_len); /* Tail */ memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, @@ -2574,7 +2565,7 @@ havoc_stage: } - case 48 ... 50: { + case 19: { /* Overwrite bytes with a randomly selected chunk bytes. */ @@ -2587,7 +2578,7 @@ havoc_stage: if (likely(copy_from != copy_to)) { #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " OVERWRITE_COPY-%u-%u-%u", + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " OVERWRITE-COPY_%u_%u_%u", copy_from, copy_to, copy_len); strcat(afl->mutation, afl->m_tmp); #endif @@ -2599,7 +2590,7 @@ havoc_stage: } - case 51: { + case 20: { /* Overwrite bytes with fixed bytes. */ @@ -2607,27 +2598,28 @@ havoc_stage: u32 copy_len = choose_block_len(afl, temp_len - 1); u32 copy_to = rand_below(afl, temp_len - copy_len + 1); + u32 strat = rand_below(afl, 2); + u32 copy_from = copy_to ? copy_to - 1 : 0; + item = strat ? rand_below(afl, 256) : out_buf[copy_from]; #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " OVERWRITE_FIXED-%u-%u", - copy_to, copy_len); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " OVERWRITE-FIXED_%u_%u_%u-%u", strat, item, copy_to, + copy_len); strcat(afl->mutation, afl->m_tmp); #endif - memset(out_buf + copy_to, - rand_below(afl, 2) ? rand_below(afl, 256) - : out_buf[rand_below(afl, temp_len)], - copy_len); + memset(out_buf + copy_to, item, copy_len); break; } - case 52: { + case 21: { /* Increase byte by 1. */ #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ADDBYTE_"); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " BYTEADD_"); strcat(afl->mutation, afl->m_tmp); #endif out_buf[rand_below(afl, temp_len)]++; @@ -2635,12 +2627,12 @@ havoc_stage: } - case 53: { + case 22: { /* Decrease byte by 1. */ #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " SUBBYTE_"); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " BYTESUB_"); strcat(afl->mutation, afl->m_tmp); #endif out_buf[rand_below(afl, temp_len)]--; @@ -2648,7 +2640,7 @@ havoc_stage: } - case 54: { + case 23: { /* Flip byte. */ @@ -2661,7 +2653,7 @@ havoc_stage: } - case 55 ... 56: { + case 24: { if (temp_len < 4) { break; } @@ -2690,7 +2682,7 @@ havoc_stage: switch_len = choose_block_len(afl, MIN(switch_len, to_end)); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " SWITCH-%s-%u-%u-%u", + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " SWITCH-%s_%u_%u_%u", "switch", switch_from, switch_to, switch_len); strcat(afl->mutation, afl->m_tmp); #endif @@ -2714,7 +2706,7 @@ havoc_stage: } // MAX_HAVOC_ENTRY = 64 - case 57 ... MAX_HAVOC_ENTRY: { + case 25: { /* Delete bytes. */ @@ -2726,7 +2718,7 @@ havoc_stage: u32 del_from = rand_below(afl, temp_len - del_len + 1); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " DEL-%u-%u", del_from, + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " DEL_%u_%u", del_from, del_len); strcat(afl->mutation, afl->m_tmp); #endif @@ -2739,13 +2731,274 @@ havoc_stage: } + case 26: { + + /* Shuffle bytes. */ + + if (temp_len < 4) { break; } + + u32 len = choose_block_len(afl, temp_len - 1); + u32 off = rand_below(afl, temp_len - len + 1); + +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " SHUFFLE_%u", len); + strcat(afl->mutation, afl->m_tmp); +#endif + + for (u32 i = len - 1; i > 0; i--) { + + u32 j; + do { + + j = rand_below(afl, i + 1); + + } while (i == j); + + unsigned char temp = out_buf[off + i]; + out_buf[off + i] = out_buf[off + j]; + out_buf[off + j] = temp; + + } + + break; + + } + + case 27: { + + /* Delete bytes. */ + + if (temp_len < 2) { break; } + + /* Don't delete too much. */ + + u32 del_len = 1; + u32 del_from = rand_below(afl, temp_len - del_len + 1); + +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " DELONE_%u", del_from); + strcat(afl->mutation, afl->m_tmp); +#endif + memmove(out_buf + del_from, out_buf + del_from + del_len, + temp_len - del_from - del_len); + + temp_len -= del_len; + + break; + + } + + case 28: { + + u32 clone_len = 1; + u32 clone_to = rand_below(afl, temp_len); + u32 strat = rand_below(afl, 2); + u32 clone_from = clone_to ? clone_to - 1 : 0; + item = strat ? rand_below(afl, 256) : out_buf[clone_from]; + +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INSERTONE_%u_%u", strat, + clone_to); + strcat(afl->mutation, afl->m_tmp); +#endif + u8 *new_buf = + afl_realloc(AFL_BUF_PARAM(out_scratch), temp_len + clone_len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } + + /* Head */ + + memcpy(new_buf, out_buf, clone_to); + + /* Inserted part */ + + memset(new_buf + clone_to, item, clone_len); + + /* Tail */ + memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, + temp_len - clone_to); + + out_buf = new_buf; + afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); + temp_len += clone_len; + + break; + + } + + case 29: { + + if (temp_len < 4) { break; } + + u32 off = rand_below(afl, temp_len), off2 = off, cnt = 0; + + while (off2 + cnt < temp_len && !isdigit(out_buf[off2 + cnt])) { + + ++cnt; + + } + + // none found, wrap + if (off2 + cnt == temp_len) { + + off2 = 0; + cnt = 0; + + while (cnt < off && !isdigit(out_buf[off2 + cnt])) { + + ++cnt; + + } + + if (cnt == off) { break; } + + } + + off = off2 + cnt; + off2 = off + 1; + + while (off2 < temp_len && isdigit(out_buf[off2])) { + + ++off2; + + } + + s64 val = out_buf[off] - '0'; + for (u32 i = off + 1; i < off2; ++i) { + + val = (val * 10) + out_buf[i] - '0'; + + } + + if (off && out_buf[off - 1] == '-') { val = -val; } + + u32 strat = rand_below(afl, 8); + switch (strat) { + + case 0: + val++; + break; + case 1: + val--; + break; + case 2: + val *= 2; + break; + case 3: + val /= 2; + break; + case 4: + if (val) { + + val = rand_next(afl) % (val * 10); + + } else { + + val = rand_below(afl, 256); + + } + + break; + case 5: + val += rand_below(afl, 256); + break; + case 6: + val -= rand_below(afl, 256); + break; + case 7: + val = ~(val); + break; + + } + +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ASCIINUM_%u_%u_%u", + afl->queue_cur->is_ascii, strat, off); + strcat(afl->mutation, afl->m_tmp); +#endif + // fprintf(stderr, "val: %u-%u = %ld\n", off, off2, val); + + char buf[20]; + snprintf(buf, sizeof(buf), "%ld", val); + + // fprintf(stderr, "BEFORE: %s\n", out_buf); + + u32 old_len = off2 - off; + u32 new_len = strlen(buf); + + if (old_len == new_len) { + + memcpy(out_buf + off, buf, new_len); + + } else { + + u8 *new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), + temp_len + new_len - old_len); + if (unlikely(!new_buf)) { PFATAL("alloc"); } + + /* Head */ + + memcpy(new_buf, out_buf, off); + + /* Inserted part */ + + memcpy(new_buf + off, buf, new_len); + + /* Tail */ + memcpy(new_buf + off + new_len, out_buf + off2, temp_len - off2); + + out_buf = new_buf; + afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); + temp_len += (new_len - old_len); + + } + + // fprintf(stderr, "AFTER : %s\n", out_buf); + break; + + } + + case 30: { + + /* Neg byte. */ + +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " NEG_"); + strcat(afl->mutation, afl->m_tmp); +#endif + item = rand_below(afl, temp_len); + + out_buf[item] = ~out_buf[item]; + break; + + } + + case 31: { + + u32 len = 1 + rand_below(afl, 8); + u32 pos = rand_below(afl, temp_len); + /* Insert ascii number. */ + if (temp_len < pos + len) { break; } + +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INSERTASCIINUM_"); + strcat(afl->mutation, afl->m_tmp); +#endif + u64 val = rand_next(afl); + char buf[20]; + snprintf(buf, sizeof(buf), "%llu", val); + memcpy(out_buf + pos, buf, len); + + break; + + } + default: r -= (MAX_HAVOC_ENTRY + 1); if (afl->extras_cnt) { - if (r < 2) { + if (r < 1) { /* Use the dictionary. */ @@ -2765,7 +3018,7 @@ havoc_stage: break; - } else if (r < 4) { + } else if (r < 2) { u32 use_extra = rand_below(afl, afl->extras_cnt); u32 extra_len = afl->extras[use_extra].len; @@ -2794,7 +3047,7 @@ havoc_stage: } else { - r -= 4; + r -= 2; } @@ -2802,15 +3055,7 @@ havoc_stage: if (afl->a_extras_cnt) { - u32 r_cmp = 2; - - if (unlikely(afl->cmplog_binary && afl->queue_cur->is_ascii)) { - - r_cmp = MUTATE_ASCII_DICT >> 1; - - } - - if (r < r_cmp) { + if (r < 1) { /* Use the dictionary. */ @@ -2830,7 +3075,7 @@ havoc_stage: break; - } else if (r < (r_cmp << 1)) { + } else if (r < 2) { u32 use_extra = rand_below(afl, afl->a_extras_cnt); u32 extra_len = afl->a_extras[use_extra].len; @@ -2859,92 +3104,12 @@ havoc_stage: } else { - r -= (r_cmp << 1); + r -= 2; } } - /* Splicing otherwise if we are still here. - Overwrite bytes with a randomly selected chunk from another - testcase or insert that chunk. */ - - /* Pick a random queue entry and seek to it. */ - - u32 tid; - do { - - tid = rand_below(afl, afl->queued_items); - - } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4); - - /* Get the testcase for splicing. */ - struct queue_entry *target = afl->queue_buf[tid]; - u32 new_len = target->len; - u8 *new_buf = queue_testcase_get(afl, target); - - if ((temp_len >= 2 && r % 2) || temp_len + HAVOC_BLK_XL >= MAX_FILE) { - - /* overwrite mode */ - - u32 copy_from, copy_to, copy_len; - - copy_len = choose_block_len(afl, new_len - 1); - if (copy_len > temp_len) copy_len = temp_len; - - copy_from = rand_below(afl, new_len - copy_len + 1); - copy_to = rand_below(afl, temp_len - copy_len + 1); - -#ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " SPLICE_OVERWRITE-%u-%u-%u-%s", copy_from, copy_to, - copy_len, target->fname); - strcat(afl->mutation, afl->m_tmp); -#endif - memmove(out_buf + copy_to, new_buf + copy_from, copy_len); - - } else { - - /* insert mode */ - - u32 clone_from, clone_to, clone_len; - - clone_len = choose_block_len(afl, new_len); - clone_from = rand_below(afl, new_len - clone_len + 1); - clone_to = rand_below(afl, temp_len + 1); - - u8 *temp_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), - temp_len + clone_len + 1); - if (unlikely(!temp_buf)) { PFATAL("alloc"); } - -#ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " SPLICE_INSERT-%u-%u-%u-%s", clone_from, clone_to, - clone_len, target->fname); - strcat(afl->mutation, afl->m_tmp); -#endif - /* Head */ - - memcpy(temp_buf, out_buf, clone_to); - - /* Inserted part */ - - memcpy(temp_buf + clone_to, new_buf + clone_from, clone_len); - - /* Tail */ - memcpy(temp_buf + clone_to + clone_len, out_buf + clone_to, - temp_len - clone_to); - - out_buf = temp_buf; - afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); - temp_len += clone_len; - - } - - break; - - // end of default - } } -- cgit 1.4.1 From 7893347e13d99b7e39ec4ebb95fbb5356bdd7f2b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 29 Mar 2023 22:56:12 +0200 Subject: final touches --- src/afl-fuzz-one.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 3eed2b70..e3ec8267 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2133,8 +2133,8 @@ havoc_stage: afl->stage_cur_val = use_stacking; #ifdef INTROSPECTION - snprintf(afl->mutation, sizeof(afl->mutation), "%s HAVOC-%u", - afl->queue_cur->fname, use_stacking); + snprintf(afl->mutation, sizeof(afl->mutation), "%s HAVOC-%u-%u", + afl->queue_cur->fname, afl->queue_cur->is_ascii, use_stacking); #endif for (i = 0; i < use_stacking; ++i) { -- cgit 1.4.1 From 145748a7e0b85c34660d0fe72ef1d4499ace2933 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 30 Mar 2023 14:00:45 +0200 Subject: prepare new mutation strategies --- src/afl-fuzz-one.c | 178 ++++++++++++++++++++++++++++------------------------- 1 file changed, 94 insertions(+), 84 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index e3ec8267..b1c38572 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -28,6 +28,21 @@ #include #include "cmplog.h" +static u32 mutation_array_explore[] = { + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; +// static u32 mutation_array_exploit[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, +// 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, +// 31 }; static u32 mutation_array_txt_explore[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, +// 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, +// 28, 29, 30, 31 }; static u32 mutation_array_txt_exploit[] = { 0, 1, 2, 3, 4, +// 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, +// 25, 26, 27, 28, 29, 30, 31 }; + +// what about more splicing? +// what about -x and cmplog learn? + /* MOpt */ static int select_algorithm(afl_state_t *afl, u32 max_algorithm) { @@ -2121,10 +2136,15 @@ havoc_stage: #define MAX_HAVOC_ENTRY 31 #define MUTATE_ASCII_DICT 0 - u32 r_max, r; + u32 r_max, mutation_array_len; + u32 **mutation_array; - r_max = (MAX_HAVOC_ENTRY + 1) + (afl->extras_cnt ? 2 : 0) + - (afl->a_extras_cnt ? 2 : 0); + // if ( ... ) + mutation_array = (u32 **)&mutation_array_explore; + mutation_array_len = sizeof(mutation_array_explore) + 1; + + r_max = mutation_array_len; + // + (afl->extras_cnt ? 2 : 0) + (afl->a_extras_cnt ? 2 : 0); for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { @@ -2174,7 +2194,7 @@ havoc_stage: } - switch ((r = rand_below(afl, r_max))) { + switch (*mutation_array[rand_below(afl, r_max)]) { case 0: { @@ -2992,123 +3012,113 @@ havoc_stage: } - default: - - r -= (MAX_HAVOC_ENTRY + 1); - - if (afl->extras_cnt) { + case 32: { - if (r < 1) { + if (!afl->extras_cnt) { break; } - /* Use the dictionary. */ + /* Use the dictionary. */ - u32 use_extra = rand_below(afl, afl->extras_cnt); - u32 extra_len = afl->extras[use_extra].len; + u32 use_extra = rand_below(afl, afl->extras_cnt); + u32 extra_len = afl->extras[use_extra].len; - if (extra_len > temp_len) { break; } + if (extra_len > temp_len) { break; } - u32 insert_at = rand_below(afl, temp_len - extra_len + 1); + u32 insert_at = rand_below(afl, temp_len - extra_len + 1); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " EXTRA_OVERWRITE-%u-%u", - insert_at, extra_len); - strcat(afl->mutation, afl->m_tmp); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " EXTRA-OVERWRITE_%u_%u", + insert_at, extra_len); + strcat(afl->mutation, afl->m_tmp); #endif - memcpy(out_buf + insert_at, afl->extras[use_extra].data, - extra_len); + memcpy(out_buf + insert_at, afl->extras[use_extra].data, extra_len); - break; + break; - } else if (r < 2) { + } - u32 use_extra = rand_below(afl, afl->extras_cnt); - u32 extra_len = afl->extras[use_extra].len; - if (temp_len + extra_len >= MAX_FILE) { break; } + case 33: { - u8 *ptr = afl->extras[use_extra].data; - u32 insert_at = rand_below(afl, temp_len + 1); -#ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " EXTRA_INSERT-%u-%u", - insert_at, extra_len); - strcat(afl->mutation, afl->m_tmp); -#endif + if (!afl->extras_cnt) { break; } - out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len); - if (unlikely(!out_buf)) { PFATAL("alloc"); } + u32 use_extra = rand_below(afl, afl->extras_cnt); + u32 extra_len = afl->extras[use_extra].len; + if (temp_len + extra_len >= MAX_FILE) { break; } - /* Tail */ - memmove(out_buf + insert_at + extra_len, out_buf + insert_at, - temp_len - insert_at); + u8 *ptr = afl->extras[use_extra].data; + u32 insert_at = rand_below(afl, temp_len + 1); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " EXTRA-INSERT_%u_%u", + insert_at, extra_len); + strcat(afl->mutation, afl->m_tmp); +#endif - /* Inserted part */ - memcpy(out_buf + insert_at, ptr, extra_len); - temp_len += extra_len; + out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len); + if (unlikely(!out_buf)) { PFATAL("alloc"); } - break; - - } else { + /* Tail */ + memmove(out_buf + insert_at + extra_len, out_buf + insert_at, + temp_len - insert_at); - r -= 2; + /* Inserted part */ + memcpy(out_buf + insert_at, ptr, extra_len); + temp_len += extra_len; - } + break; - } + } - if (afl->a_extras_cnt) { + case 34: { - if (r < 1) { + if (!afl->a_extras_cnt) { break; } - /* Use the dictionary. */ + /* Use the dictionary. */ - u32 use_extra = rand_below(afl, afl->a_extras_cnt); - u32 extra_len = afl->a_extras[use_extra].len; + u32 use_extra = rand_below(afl, afl->a_extras_cnt); + u32 extra_len = afl->a_extras[use_extra].len; - if (extra_len > temp_len) { break; } + if (extra_len > temp_len) { break; } - u32 insert_at = rand_below(afl, temp_len - extra_len + 1); + u32 insert_at = rand_below(afl, temp_len - extra_len + 1); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " AUTO_EXTRA_OVERWRITE-%u-%u", insert_at, extra_len); - strcat(afl->mutation, afl->m_tmp); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " AUTO-EXTRA-OVERWRITE_%u_%u", insert_at, extra_len); + strcat(afl->mutation, afl->m_tmp); #endif - memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, - extra_len); + memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, extra_len); - break; - - } else if (r < 2) { + break; - u32 use_extra = rand_below(afl, afl->a_extras_cnt); - u32 extra_len = afl->a_extras[use_extra].len; - if (temp_len + extra_len >= MAX_FILE) { break; } + } - u8 *ptr = afl->a_extras[use_extra].data; - u32 insert_at = rand_below(afl, temp_len + 1); -#ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), - " AUTO_EXTRA_INSERT-%u-%u", insert_at, extra_len); - strcat(afl->mutation, afl->m_tmp); -#endif + case 35: { - out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len); - if (unlikely(!out_buf)) { PFATAL("alloc"); } + if (!afl->a_extras_cnt) { break; } - /* Tail */ - memmove(out_buf + insert_at + extra_len, out_buf + insert_at, - temp_len - insert_at); + u32 use_extra = rand_below(afl, afl->a_extras_cnt); + u32 extra_len = afl->a_extras[use_extra].len; + if (temp_len + extra_len >= MAX_FILE) { break; } - /* Inserted part */ - memcpy(out_buf + insert_at, ptr, extra_len); - temp_len += extra_len; + u8 *ptr = afl->a_extras[use_extra].data; + u32 insert_at = rand_below(afl, temp_len + 1); +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " AUTO-EXTRA-INSERT_%u_%u", + insert_at, extra_len); + strcat(afl->mutation, afl->m_tmp); +#endif - break; + out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len); + if (unlikely(!out_buf)) { PFATAL("alloc"); } - } else { + /* Tail */ + memmove(out_buf + insert_at + extra_len, out_buf + insert_at, + temp_len - insert_at); - r -= 2; + /* Inserted part */ + memcpy(out_buf + insert_at, ptr, extra_len); + temp_len += extra_len; - } + break; - } + } } -- cgit 1.4.1 From 506f6b134987d47da6c1a2e172f50b47559e7b4f Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 30 Mar 2023 19:28:59 +0200 Subject: nits --- src/afl-fuzz-one.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/afl-fuzz-queue.c | 2 +- 2 files changed, 99 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index b1c38572..36259d9b 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -30,8 +30,8 @@ static u32 mutation_array_explore[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37}; // static u32 mutation_array_exploit[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, // 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, // 31 }; static u32 mutation_array_txt_explore[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, @@ -2133,9 +2133,6 @@ havoc_stage: /* We essentially just do several thousand runs (depending on perf_score) where we take the input file and make random stacked tweaks. */ -#define MAX_HAVOC_ENTRY 31 -#define MUTATE_ASCII_DICT 0 - u32 r_max, mutation_array_len; u32 **mutation_array; @@ -2725,7 +2722,6 @@ havoc_stage: } - // MAX_HAVOC_ENTRY = 64 case 25: { /* Delete bytes. */ @@ -3120,6 +3116,102 @@ havoc_stage: } + case 36: { + + if (afl->ready_for_splicing_count <= 1) { break; } + + /* Pick a random queue entry and seek to it. */ + + u32 tid; + do { + + tid = rand_below(afl, afl->queued_items); + + } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4); + + /* Get the testcase for splicing. */ + struct queue_entry *target = afl->queue_buf[tid]; + u32 new_len = target->len; + u8 *new_buf = queue_testcase_get(afl, target); + + /* overwrite mode */ + + u32 copy_from, copy_to, copy_len; + + copy_len = choose_block_len(afl, new_len - 1); + if (copy_len > temp_len) copy_len = temp_len; + + copy_from = rand_below(afl, new_len - copy_len + 1); + copy_to = rand_below(afl, temp_len - copy_len + 1); + +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), + " SPLICE-OVERWRITE_%u_%u_%u_%s", copy_from, copy_to, + copy_len, target->fname); + strcat(afl->mutation, afl->m_tmp); +#endif + memmove(out_buf + copy_to, new_buf + copy_from, copy_len); + + break; + + } + + case 37: { + + if (afl->ready_for_splicing_count <= 1) { break; } + if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { break; } + + /* Pick a random queue entry and seek to it. */ + + u32 tid; + do { + + tid = rand_below(afl, afl->queued_items); + + } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4); + + /* Get the testcase for splicing. */ + struct queue_entry *target = afl->queue_buf[tid]; + u32 new_len = target->len; + u8 *new_buf = queue_testcase_get(afl, target); + + /* insert mode */ + + u32 clone_from, clone_to, clone_len; + + clone_len = choose_block_len(afl, new_len); + clone_from = rand_below(afl, new_len - clone_len + 1); + clone_to = rand_below(afl, temp_len + 1); + + u8 *temp_buf = + afl_realloc(AFL_BUF_PARAM(out_scratch), temp_len + clone_len + 1); + if (unlikely(!temp_buf)) { PFATAL("alloc"); } + +#ifdef INTROSPECTION + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " SPLICE-INSERT_%u_%u_%u_%s", + clone_from, clone_to, clone_len, target->fname); + strcat(afl->mutation, afl->m_tmp); +#endif + /* Head */ + + memcpy(temp_buf, out_buf, clone_to); + + /* Inserted part */ + + memcpy(temp_buf + clone_to, new_buf + clone_from, clone_len); + + /* Tail */ + memcpy(temp_buf + clone_to + clone_len, out_buf + clone_to, + temp_len - clone_to); + + out_buf = temp_buf; + afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); + temp_len += clone_len; + + break; + + } + } } diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 40184645..fff8db03 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -563,7 +563,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { } - if (likely(q->len > 4)) afl->ready_for_splicing_count++; + if (likely(q->len > 4)) { ++afl->ready_for_splicing_count; } ++afl->queued_items; ++afl->active_items; -- cgit 1.4.1 From 74baebd93e6ad65de297e812d53f06592166ef9a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 30 Mar 2023 20:02:59 +0200 Subject: fix --- src/afl-fuzz-one.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 36259d9b..fc37d493 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2134,11 +2134,11 @@ havoc_stage: where we take the input file and make random stacked tweaks. */ u32 r_max, mutation_array_len; - u32 **mutation_array; + u32 *mutation_array; // if ( ... ) mutation_array = (u32 **)&mutation_array_explore; - mutation_array_len = sizeof(mutation_array_explore) + 1; + mutation_array_len = sizeof(mutation_array_explore) / 4; r_max = mutation_array_len; // + (afl->extras_cnt ? 2 : 0) + (afl->a_extras_cnt ? 2 : 0); @@ -2191,7 +2191,8 @@ havoc_stage: } - switch (*mutation_array[rand_below(afl, r_max)]) { + u32 r = rand_below(afl, r_max); + switch (mutation_array[r]) { case 0: { -- cgit 1.4.1 From 8f17c816919301b870b9c7dad84e475370c87381 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 30 Mar 2023 22:41:02 +0200 Subject: less mutation --- src/afl-fuzz-one.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index fc37d493..b01814a3 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2145,7 +2145,7 @@ havoc_stage: for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { - u32 use_stacking = 2 + rand_below(afl, 15), item; + u32 use_stacking = 1 + rand_below(afl, 8), item; afl->stage_cur_val = use_stacking; -- cgit 1.4.1 From 9eed60d1055ada484798d6de51101043ecaf462d Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 31 Mar 2023 08:12:32 +0200 Subject: nit --- src/afl-fuzz-one.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index b01814a3..1a120733 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2137,7 +2137,7 @@ havoc_stage: u32 *mutation_array; // if ( ... ) - mutation_array = (u32 **)&mutation_array_explore; + mutation_array = (u32 *)&mutation_array_explore; mutation_array_len = sizeof(mutation_array_explore) / 4; r_max = mutation_array_len; @@ -2192,6 +2192,7 @@ havoc_stage: } u32 r = rand_below(afl, r_max); + switch (mutation_array[r]) { case 0: { -- cgit 1.4.1 From 21203c2ea6b0586d3c63f9d33190dfd364677b1a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 2 Apr 2023 12:39:02 +0200 Subject: fix --- src/afl-fuzz-one.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 1a120733..c550fbc2 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2905,7 +2905,7 @@ havoc_stage: val /= 2; break; case 4: - if (val) { + if (val && val < 0xfffffff) { val = rand_next(afl) % (val * 10); -- cgit 1.4.1 From 71e2aa5d2bb99bd7edc2efcebd52eee5736c35fd Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 2 Apr 2023 13:42:08 +0200 Subject: more fix --- src/afl-fuzz-one.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index c550fbc2..a52fb4c6 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2133,7 +2133,7 @@ havoc_stage: /* We essentially just do several thousand runs (depending on perf_score) where we take the input file and make random stacked tweaks. */ - u32 r_max, mutation_array_len; + u32 r_max, mutation_array_len; u32 *mutation_array; // if ( ... ) @@ -2905,9 +2905,9 @@ havoc_stage: val /= 2; break; case 4: - if (val && val < 0xfffffff) { + if (val && (u64)val < 0x19999999) { - val = rand_next(afl) % (val * 10); + val = (u64)rand_next(afl) % (u64)((u64)val * 10); } else { -- cgit 1.4.1 From 635da39bd135b7db3529a4b3b059b85260ce14a5 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 3 Apr 2023 14:41:52 +0200 Subject: preparation for mutation arrays --- src/afl-fuzz-one.c | 176 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 131 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index a52fb4c6..1636c323 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2133,19 +2133,35 @@ havoc_stage: /* We essentially just do several thousand runs (depending on perf_score) where we take the input file and make random stacked tweaks. */ - u32 r_max, mutation_array_len; u32 *mutation_array; + u32 stack_max; // if ( ... ) mutation_array = (u32 *)&mutation_array_explore; - mutation_array_len = sizeof(mutation_array_explore) / 4; - r_max = mutation_array_len; + if (temp_len < 64) { + + stack_max = 4; + + } else if (temp_len < 512) { + + stack_max = 8; + + } else if (temp_len < 8096) { + + stack_max = 16; + + } else { + + stack_max = 32; + + } + // + (afl->extras_cnt ? 2 : 0) + (afl->a_extras_cnt ? 2 : 0); for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { - u32 use_stacking = 1 + rand_below(afl, 8), item; + u32 use_stacking = 1 + rand_below(afl, stack_max); afl->stage_cur_val = use_stacking; @@ -2191,7 +2207,8 @@ havoc_stage: } - u32 r = rand_below(afl, r_max); + retry_havoc_step: + u32 r = rand_below(afl, 256), item; switch (mutation_array[r]) { @@ -2228,7 +2245,7 @@ havoc_stage: /* Set word to interesting value, little endian. */ - if (temp_len < 2) { break; } + if (unlikely(temp_len < 2)) { break; } // no retry item = rand_below(afl, sizeof(interesting_16) >> 1); #ifdef INTROSPECTION @@ -2247,7 +2264,7 @@ havoc_stage: /* Set word to interesting value, big endian. */ - if (temp_len < 2) { break; } + if (unlikely(temp_len < 2)) { break; } // no retry item = rand_below(afl, sizeof(interesting_16) >> 1); #ifdef INTROSPECTION @@ -2265,7 +2282,7 @@ havoc_stage: /* Set dword to interesting value, little endian. */ - if (temp_len < 4) { break; } + if (unlikely(temp_len < 4)) { break; } // no retry item = rand_below(afl, sizeof(interesting_32) >> 2); #ifdef INTROSPECTION @@ -2284,7 +2301,7 @@ havoc_stage: /* Set dword to interesting value, big endian. */ - if (temp_len < 4) { break; } + if (unlikely(temp_len < 4)) { break; } // no retry item = rand_below(afl, sizeof(interesting_32) >> 2); #ifdef INTROSPECTION @@ -2330,7 +2347,7 @@ havoc_stage: /* Randomly subtract from word, little endian. */ - if (temp_len < 2) { break; } + if (unlikely(temp_len < 2)) { break; } // no retry u32 pos = rand_below(afl, temp_len - 1); item = 1 + rand_below(afl, ARITH_MAX); @@ -2349,7 +2366,7 @@ havoc_stage: /* Randomly subtract from word, big endian. */ - if (temp_len < 2) { break; } + if (unlikely(temp_len < 2)) { break; } // no retry u32 pos = rand_below(afl, temp_len - 1); u16 num = 1 + rand_below(afl, ARITH_MAX); @@ -2369,7 +2386,7 @@ havoc_stage: /* Randomly add to word, little endian. */ - if (temp_len < 2) { break; } + if (unlikely(temp_len < 2)) { break; } // no retry u32 pos = rand_below(afl, temp_len - 1); item = 1 + rand_below(afl, ARITH_MAX); @@ -2388,7 +2405,7 @@ havoc_stage: /* Randomly add to word, big endian. */ - if (temp_len < 2) { break; } + if (unlikely(temp_len < 2)) { break; } // no retry u32 pos = rand_below(afl, temp_len - 1); u16 num = 1 + rand_below(afl, ARITH_MAX); @@ -2408,7 +2425,7 @@ havoc_stage: /* Randomly subtract from dword, little endian. */ - if (temp_len < 4) { break; } + if (unlikely(temp_len < 4)) { break; } // no retry u32 pos = rand_below(afl, temp_len - 3); item = 1 + rand_below(afl, ARITH_MAX); @@ -2427,7 +2444,7 @@ havoc_stage: /* Randomly subtract from dword, big endian. */ - if (temp_len < 4) { break; } + if (unlikely(temp_len < 4)) { break; } // no retry u32 pos = rand_below(afl, temp_len - 3); u32 num = 1 + rand_below(afl, ARITH_MAX); @@ -2447,7 +2464,7 @@ havoc_stage: /* Randomly add to dword, little endian. */ - if (temp_len < 4) { break; } + if (unlikely(temp_len < 4)) { break; } // no retry u32 pos = rand_below(afl, temp_len - 3); item = 1 + rand_below(afl, ARITH_MAX); @@ -2466,7 +2483,7 @@ havoc_stage: /* Randomly add to dword, big endian. */ - if (temp_len < 4) { break; } + if (unlikely(temp_len < 4)) { break; } // no retry u32 pos = rand_below(afl, temp_len - 3); u32 num = 1 + rand_below(afl, ARITH_MAX); @@ -2502,7 +2519,7 @@ havoc_stage: case 17: { - if (temp_len + HAVOC_BLK_XL < MAX_FILE) { + if (likely(temp_len + HAVOC_BLK_XL < MAX_FILE)) { /* Clone bytes. */ @@ -2535,6 +2552,14 @@ havoc_stage: afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); temp_len += clone_len; + } else if (unlikely(temp_len < 8)) { + + break; + + } else { + + goto retry_havoc_step; + } break; @@ -2543,7 +2568,7 @@ havoc_stage: case 18: { - if (temp_len + HAVOC_BLK_XL < MAX_FILE) { + if (likely(temp_len + HAVOC_BLK_XL < MAX_FILE)) { /* Insert a block of constant bytes (25%). */ @@ -2578,6 +2603,14 @@ havoc_stage: afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch)); temp_len += clone_len; + } else if (unlikely(temp_len < 8)) { + + break; + + } else { + + goto retry_havoc_step; + } break; @@ -2588,7 +2621,7 @@ havoc_stage: /* Overwrite bytes with a randomly selected chunk bytes. */ - if (temp_len < 2) { break; } + if (unlikely(temp_len < 2)) { break; } // no retry u32 copy_len = choose_block_len(afl, temp_len - 1); u32 copy_from = rand_below(afl, temp_len - copy_len + 1); @@ -2613,7 +2646,7 @@ havoc_stage: /* Overwrite bytes with fixed bytes. */ - if (temp_len < 2) { break; } + if (unlikely(temp_len < 2)) { break; } // no retry u32 copy_len = choose_block_len(afl, temp_len - 1); u32 copy_to = rand_below(afl, temp_len - copy_len + 1); @@ -2674,7 +2707,7 @@ havoc_stage: case 24: { - if (temp_len < 4) { break; } + if (unlikely(temp_len < 4)) { break; } // no retry /* Switch bytes. */ @@ -2684,7 +2717,7 @@ havoc_stage: switch_to = rand_below(afl, temp_len); - } while (switch_from == switch_to); + } while (unlikely(switch_from == switch_to)); if (switch_from < switch_to) { @@ -2728,7 +2761,7 @@ havoc_stage: /* Delete bytes. */ - if (temp_len < 2) { break; } + if (unlikely(temp_len < 2)) { break; } // no retry /* Don't delete too much. */ @@ -2753,7 +2786,7 @@ havoc_stage: /* Shuffle bytes. */ - if (temp_len < 4) { break; } + if (unlikely(temp_len < 4)) { break; } // no retry u32 len = choose_block_len(afl, temp_len - 1); u32 off = rand_below(afl, temp_len - len + 1); @@ -2770,7 +2803,7 @@ havoc_stage: j = rand_below(afl, i + 1); - } while (i == j); + } while (unlikely(i == j)); unsigned char temp = out_buf[off + i]; out_buf[off + i] = out_buf[off + j]; @@ -2786,7 +2819,7 @@ havoc_stage: /* Delete bytes. */ - if (temp_len < 2) { break; } + if (unlikely(temp_len < 2)) { break; } // no retry /* Don't delete too much. */ @@ -2808,6 +2841,8 @@ havoc_stage: case 28: { + if (unlikely(temp_len < 2)) { break; } // no retry + u32 clone_len = 1; u32 clone_to = rand_below(afl, temp_len); u32 strat = rand_below(afl, 2); @@ -2845,7 +2880,7 @@ havoc_stage: case 29: { - if (temp_len < 4) { break; } + if (unlikely(temp_len < 4)) { break; } // no retry u32 off = rand_below(afl, temp_len), off2 = off, cnt = 0; @@ -2867,7 +2902,19 @@ havoc_stage: } - if (cnt == off) { break; } + if (cnt == off) { + + if (temp_len < 8) { + + break; + + } else { + + goto retry_havoc_step; + + } + + } } @@ -2905,7 +2952,7 @@ havoc_stage: val /= 2; break; case 4: - if (val && (u64)val < 0x19999999) { + if (likely(val && (u64)val < 0x19999999)) { val = (u64)rand_next(afl) % (u64)((u64)val * 10); @@ -2995,7 +3042,19 @@ havoc_stage: u32 len = 1 + rand_below(afl, 8); u32 pos = rand_below(afl, temp_len); /* Insert ascii number. */ - if (temp_len < pos + len) { break; } + if (unlikely(temp_len < pos + len)) { + + if (unlikely(temp_len < 8)) { + + break; + + } else { + + goto retry_havoc_step; + + } + + } #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INSERTASCIINUM_"); @@ -3012,14 +3071,14 @@ havoc_stage: case 32: { - if (!afl->extras_cnt) { break; } + if (unlikely(!afl->extras_cnt)) { goto retry_havoc_step; } /* Use the dictionary. */ u32 use_extra = rand_below(afl, afl->extras_cnt); u32 extra_len = afl->extras[use_extra].len; - if (extra_len > temp_len) { break; } + if (unlikely(extra_len > temp_len)) { goto retry_havoc_step; } u32 insert_at = rand_below(afl, temp_len - extra_len + 1); #ifdef INTROSPECTION @@ -3035,11 +3094,15 @@ havoc_stage: case 33: { - if (!afl->extras_cnt) { break; } + if (unlikely(!afl->extras_cnt)) { goto retry_havoc_step; } u32 use_extra = rand_below(afl, afl->extras_cnt); u32 extra_len = afl->extras[use_extra].len; - if (temp_len + extra_len >= MAX_FILE) { break; } + if (unlikely(temp_len + extra_len >= MAX_FILE)) { + + goto retry_havoc_step; + + } u8 *ptr = afl->extras[use_extra].data; u32 insert_at = rand_below(afl, temp_len + 1); @@ -3066,14 +3129,14 @@ havoc_stage: case 34: { - if (!afl->a_extras_cnt) { break; } + if (unlikely(!afl->a_extras_cnt)) { goto retry_havoc_step; } /* Use the dictionary. */ u32 use_extra = rand_below(afl, afl->a_extras_cnt); u32 extra_len = afl->a_extras[use_extra].len; - if (extra_len > temp_len) { break; } + if (unlikely(extra_len > temp_len)) { goto retry_havoc_step; } u32 insert_at = rand_below(afl, temp_len - extra_len + 1); #ifdef INTROSPECTION @@ -3089,11 +3152,15 @@ havoc_stage: case 35: { - if (!afl->a_extras_cnt) { break; } + if (unlikely(!afl->a_extras_cnt)) { goto retry_havoc_step; } u32 use_extra = rand_below(afl, afl->a_extras_cnt); u32 extra_len = afl->a_extras[use_extra].len; - if (temp_len + extra_len >= MAX_FILE) { break; } + if (unlikely(temp_len + extra_len >= MAX_FILE)) { + + goto retry_havoc_step; + + } u8 *ptr = afl->a_extras[use_extra].data; u32 insert_at = rand_below(afl, temp_len + 1); @@ -3120,7 +3187,11 @@ havoc_stage: case 36: { - if (afl->ready_for_splicing_count <= 1) { break; } + if (unlikely(afl->ready_for_splicing_count <= 1)) { + + goto retry_havoc_step; + + } /* Pick a random queue entry and seek to it. */ @@ -3129,7 +3200,9 @@ havoc_stage: tid = rand_below(afl, afl->queued_items); - } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4); + } while (unlikely(tid == afl->current_entry || + + afl->queue_buf[tid]->len < 4)); /* Get the testcase for splicing. */ struct queue_entry *target = afl->queue_buf[tid]; @@ -3160,8 +3233,17 @@ havoc_stage: case 37: { - if (afl->ready_for_splicing_count <= 1) { break; } - if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { break; } + if (unlikely(afl->ready_for_splicing_count <= 1)) { + + goto retry_havoc_step; + + } + + if (unlikely(temp_len + HAVOC_BLK_XL >= MAX_FILE)) { + + goto retry_havoc_step; + + } /* Pick a random queue entry and seek to it. */ @@ -3170,7 +3252,9 @@ havoc_stage: tid = rand_below(afl, afl->queued_items); - } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4); + } while (unlikely(tid == afl->current_entry || + + afl->queue_buf[tid]->len < 4)); /* Get the testcase for splicing. */ struct queue_entry *target = afl->queue_buf[tid]; @@ -3303,7 +3387,9 @@ retry_splicing: tid = rand_below(afl, afl->queued_items); - } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4); + } while ( + + unlikely(tid == afl->current_entry || afl->queue_buf[tid]->len < 4)); /* Get the testcase */ afl->splicing_with = tid; -- cgit 1.4.1 From fcd21256780fd21c55e72e9338b3992c60db22dc Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 4 Apr 2023 15:47:53 +0200 Subject: prepare for strategies --- custom_mutators/aflpp/Makefile | 10 + custom_mutators/aflpp/README.md | 8 + custom_mutators/aflpp/aflpp.c | 68 +++ include/afl-mutations.h | 992 ++++++++++++++++++++++++++++++++++++++++ src/afl-fuzz-one.c | 165 +++---- 5 files changed, 1143 insertions(+), 100 deletions(-) create mode 100644 custom_mutators/aflpp/Makefile create mode 100644 custom_mutators/aflpp/README.md create mode 100644 custom_mutators/aflpp/aflpp.c create mode 100644 include/afl-mutations.h (limited to 'src') diff --git a/custom_mutators/aflpp/Makefile b/custom_mutators/aflpp/Makefile new file mode 100644 index 00000000..8efdf3e4 --- /dev/null +++ b/custom_mutators/aflpp/Makefile @@ -0,0 +1,10 @@ + +CFLAGS = -O3 -funroll-loops -fPIC -Wl,-Bsymbolic + +all: aflpp-mutator.so + +aflpp-mutator.so: aflpp.c + $(CC) $(CFLAGS) -I../../include -I. -shared -o aflpp-mutator.so aflpp.c ../../src/afl-performance.c + +clean: + rm -f *.o *~ *.so core diff --git a/custom_mutators/aflpp/README.md b/custom_mutators/aflpp/README.md new file mode 100644 index 00000000..04d605c1 --- /dev/null +++ b/custom_mutators/aflpp/README.md @@ -0,0 +1,8 @@ +# custum mutator: AFL++ + +this is the AFL++ havoc mutator as a custom mutator module for AFL++. + +just type `make` to build + +```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/aflpp/aflpp-mutator.so afl-fuzz ...``` + diff --git a/custom_mutators/aflpp/aflpp.c b/custom_mutators/aflpp/aflpp.c new file mode 100644 index 00000000..2b69ad9c --- /dev/null +++ b/custom_mutators/aflpp/aflpp.c @@ -0,0 +1,68 @@ +#include "afl-mutations.h" + +typedef struct my_mutator { + + afl_state_t *afl; + u8 *buf; + +} my_mutator_t; + +my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { + + (void)seed; + + my_mutator_t *data = calloc(1, sizeof(my_mutator_t)); + if (!data) { + + perror("afl_custom_init alloc"); + return NULL; + + } + + data->buf = malloc(MAX_FILE); + if (!data->buf) { + + perror("afl_custom_init alloc"); + return NULL; + + } + + data->afl = afl; + + return data; + +} + +/* here we run the AFL++ mutator, which is the best! */ + +size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, + u8 **out_buf, uint8_t *add_buf, size_t add_buf_size, + size_t max_size) { + + u32 havoc_steps = 1 + rand_below(data->afl, 16); + + /* set everything up, costly ... :( */ + memcpy(data->buf, buf, buf_size); + + /* the mutation */ + u32 out_buf_len = afl_mutate(data->afl, data->buf, buf_size, havoc_steps, + false, true, add_buf, add_buf_size); + + /* return size of mutated data */ + *out_buf = data->buf; + return out_buf_len; + +} + +/** + * Deinitialize everything + * + * @param data The data ptr from afl_custom_init + */ +void afl_custom_deinit(my_mutator_t *data) { + + free(data->buf); + free(data); + +} + diff --git a/include/afl-mutations.h b/include/afl-mutations.h new file mode 100644 index 00000000..43b7927d --- /dev/null +++ b/include/afl-mutations.h @@ -0,0 +1,992 @@ +/* Implementation of afl havoc mutation to be used in AFL++ custom mutators and + partially in afl-fuzz itself. + + How to use: + + #include "afl-mutations.h" // needs afl-fuzz.h + + u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32t steps, bool is_text, + bool is_exploration, u8 *splice_buf, u32 splice_len); + + Returns: + u32 - the length of the mutated data return in *buf. 0 = error + Parameters: + afl_state_t *afl - the *afl state pointer + u8 *buf - the input buffer to mutate which will be mutated into. + NOTE: must be of MAX_FILE size! + u32 len - the length of the input + u32 steps - how many mutations to perform on the input + bool is_text - is the target expecting text inputs + bool is_exploration - mutate for exploration mode (instead of exploitation) + splice_buf - a buffer from another corpus item to splice with. + If NULL then no splicing + splice_len - the length of the splice buffer. If 0 then no splicing +*/ + +#ifndef _ANDROID_ASHMEM_H + #define AFL_MUTATIONS_H + + #include + #include "afl-fuzz.h" + + #define MUT_STRATEGY_ARRAY_SIZE 256 + +enum { + + /* 00 */ MUT_FLIPBIT, + /* 01 */ MUT_INTERESTING8, + /* 02 */ MUT_INTERESTING16, + /* 03 */ MUT_INTERESTING16BE, + /* 04 */ MUT_INTERESTING32, + /* 05 */ MUT_INTERESTING32BE, + /* 06 */ MUT_ARITH8_, + /* 07 */ MUT_ARITH8, + /* 08 */ MUT_ARITH16_, + /* 09 */ MUT_ARITH16BE_, + /* 10 */ MUT_ARITH16, + /* 11 */ MUT_ARITH16BE, + /* 12 */ MUT_ARITH32_, + /* 13 */ MUT_ARITH32BE_, + /* 14 */ MUT_ARITH32, + /* 15 */ MUT_ARITH32BE, + /* 16 */ MUT_RAND8, + /* 17 */ MUT_CLONE_OVERWRITE, + /* 18 */ MUT_CLONE_INSERT, + /* 19 */ MUT_OVERWRITE_COPY, + /* 20 */ MUT_OVERWRITE_FIXED, + /* 21 */ MUT_BYTEADD, + /* 22 */ MUT_BYTESUB, + /* 23 */ MUT_FLIP8, + /* 24 */ MUT_SWITCH, + /* 25 */ MUT_DEL, + /* 26 */ MUT_SHUFFLE, + /* 27 */ MUT_DELONE, + /* 28 */ MUT_INSERTONE, + /* 29 */ MUT_ASCIINUM, + /* 30 */ MUT_NEG, + /* 31 */ MUT_INSERTASCIINUM, + /* 32 */ MUT_EXTRA_OVERWRITE, + /* 33 */ MUT_EXTRA_INSERT, + /* 34 */ MUT_AUTO_EXTRA_OVERWRITE, + /* 35 */ MUT_AUTO_EXTRA_INSERT, + /* 36 */ MUT_SPLICE_OVERWRITE, + /* 37 */ MUT_SPLICE_INSERT, + + MUT_MAX + +}; + +unsigned int mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {}; +unsigned int mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {}; +unsigned int mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {}; +unsigned int mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = + {}; + +unsigned int afl_mutate(afl_state_t *, unsigned char *, unsigned int, + unsigned int, bool, bool, unsigned char *, + unsigned int); +u32 choose_block_len(afl_state_t *, u32); + +/* Helper to choose random block len for block operations in fuzz_one(). + Doesn't return zero, provided that max_len is > 0. */ + +inline u32 choose_block_len(afl_state_t *afl, u32 limit) { + + u32 min_value, max_value; + u32 rlim = MIN(afl->queue_cycle, (u32)3); + + if (unlikely(!afl->run_over10m)) { rlim = 1; } + + switch (rand_below(afl, rlim)) { + + case 0: + min_value = 1; + max_value = HAVOC_BLK_SMALL; + break; + + case 1: + min_value = HAVOC_BLK_SMALL; + max_value = HAVOC_BLK_MEDIUM; + break; + + default: + + if (likely(rand_below(afl, 10))) { + + min_value = HAVOC_BLK_MEDIUM; + max_value = HAVOC_BLK_LARGE; + + } else { + + min_value = HAVOC_BLK_LARGE; + max_value = HAVOC_BLK_XL; + + } + + } + + if (min_value >= limit) { min_value = 1; } + + return min_value + rand_below(afl, MIN(max_value, limit) - min_value + 1); + +} + +unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, + unsigned int steps, bool is_text, bool is_exploration, + unsigned char *splice_buf, unsigned int splice_len) { + + if (!buf || !len) { return 0; } + + u32 *mutation_array; + static unsigned char *tmp_buf = NULL; + + if (!tmp_buf) { + + if ((tmp_buf = malloc(MAX_FILE)) == NULL) { return 0; } + + } + + if (is_text) { + + if (is_exploration) { + + mutation_array = (unsigned int *)&mutation_strategy_exploration_text; + + } else { + + mutation_array = (unsigned int *)&mutation_strategy_exploitation_text; + + } + + } else { + + if (is_exploration) { + + mutation_array = (unsigned int *)&mutation_strategy_exploration_binary; + + } else { + + mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary; + + } + + } + + for (unsigned int step = 0; step < steps; ++step) { + + retry_havoc_step: + + u32 r = rand_below(afl, MUT_STRATEGY_ARRAY_SIZE), item; + + switch (mutation_array[r]) { + + case MUT_FLIPBIT: { + + /* Flip a single bit somewhere. Spooky! */ + u8 bit = rand_below(afl, 8); + u32 off = rand_below(afl, len); + buf[off] ^= 1 << bit; + + break; + + } + + case MUT_INTERESTING8: { + + /* Set byte to interesting value. */ + + item = rand_below(afl, sizeof(interesting_8)); + buf[rand_below(afl, len)] = interesting_8[item]; + break; + + } + + case MUT_INTERESTING16: { + + /* Set word to interesting value, little endian. */ + + if (unlikely(len < 2)) { break; } // no retry + + item = rand_below(afl, sizeof(interesting_16) >> 1); + *(u16 *)(buf + rand_below(afl, len - 1)) = interesting_16[item]; + + break; + + } + + case MUT_INTERESTING16BE: { + + /* Set word to interesting value, big endian. */ + + if (unlikely(len < 2)) { break; } // no retry + + item = rand_below(afl, sizeof(interesting_16) >> 1); + *(u16 *)(buf + rand_below(afl, len - 1)) = SWAP16(interesting_16[item]); + + break; + + } + + case MUT_INTERESTING32: { + + /* Set dword to interesting value, little endian. */ + + if (unlikely(len < 4)) { break; } // no retry + + item = rand_below(afl, sizeof(interesting_32) >> 2); + *(u32 *)(buf + rand_below(afl, len - 3)) = interesting_32[item]; + + break; + + } + + case MUT_INTERESTING32BE: { + + /* Set dword to interesting value, big endian. */ + + if (unlikely(len < 4)) { break; } // no retry + + item = rand_below(afl, sizeof(interesting_32) >> 2); + *(u32 *)(buf + rand_below(afl, len - 3)) = SWAP32(interesting_32[item]); + + break; + + } + + case MUT_ARITH8_: { + + /* Randomly subtract from byte. */ + + item = 1 + rand_below(afl, ARITH_MAX); + buf[rand_below(afl, len)] -= item; + break; + + } + + case MUT_ARITH8: { + + /* Randomly add to byte. */ + + item = 1 + rand_below(afl, ARITH_MAX); + buf[rand_below(afl, len)] += item; + break; + + } + + case MUT_ARITH16_: { + + /* Randomly subtract from word, little endian. */ + + if (unlikely(len < 2)) { break; } // no retry + + u32 pos = rand_below(afl, len - 1); + item = 1 + rand_below(afl, ARITH_MAX); + *(u16 *)(buf + pos) -= item; + + break; + + } + + case MUT_ARITH16BE_: { + + /* Randomly subtract from word, big endian. */ + + if (unlikely(len < 2)) { break; } // no retry + + u32 pos = rand_below(afl, len - 1); + u16 num = 1 + rand_below(afl, ARITH_MAX); + *(u16 *)(buf + pos) = SWAP16(SWAP16(*(u16 *)(buf + pos)) - num); + + break; + + } + + case MUT_ARITH16: { + + /* Randomly add to word, little endian. */ + + if (unlikely(len < 2)) { break; } // no retry + + u32 pos = rand_below(afl, len - 1); + item = 1 + rand_below(afl, ARITH_MAX); + *(u16 *)(buf + pos) += item; + + break; + + } + + case MUT_ARITH16BE: { + + /* Randomly add to word, big endian. */ + + if (unlikely(len < 2)) { break; } // no retry + + u32 pos = rand_below(afl, len - 1); + u16 num = 1 + rand_below(afl, ARITH_MAX); + *(u16 *)(buf + pos) = SWAP16(SWAP16(*(u16 *)(buf + pos)) + num); + + break; + + } + + case MUT_ARITH32_: { + + /* Randomly subtract from dword, little endian. */ + + if (unlikely(len < 4)) { break; } // no retry + + u32 pos = rand_below(afl, len - 3); + item = 1 + rand_below(afl, ARITH_MAX); + *(u32 *)(buf + pos) -= item; + + break; + + } + + case MUT_ARITH32BE_: { + + /* Randomly subtract from dword, big endian. */ + + if (unlikely(len < 4)) { break; } // no retry + + u32 pos = rand_below(afl, len - 3); + u32 num = 1 + rand_below(afl, ARITH_MAX); + *(u32 *)(buf + pos) = SWAP32(SWAP32(*(u32 *)(buf + pos)) - num); + + break; + + } + + case MUT_ARITH32: { + + /* Randomly add to dword, little endian. */ + + if (unlikely(len < 4)) { break; } // no retry + + u32 pos = rand_below(afl, len - 3); + item = 1 + rand_below(afl, ARITH_MAX); + *(u32 *)(buf + pos) += item; + + break; + + } + + case MUT_ARITH32BE: { + + /* Randomly add to dword, big endian. */ + + if (unlikely(len < 4)) { break; } // no retry + + u32 pos = rand_below(afl, len - 3); + u32 num = 1 + rand_below(afl, ARITH_MAX); + *(u32 *)(buf + pos) = SWAP32(SWAP32(*(u32 *)(buf + pos)) + num); + + break; + + } + + case MUT_RAND8: { + + /* Just set a random byte to a random value. Because, + why not. We use XOR with 1-255 to eliminate the + possibility of a no-op. */ + + u32 pos = rand_below(afl, len); + item = 1 + rand_below(afl, 255); + buf[pos] ^= item; + break; + + } + + case MUT_CLONE_OVERWRITE: { + + if (likely(len + HAVOC_BLK_XL < MAX_FILE)) { + + /* Clone bytes. */ + + u32 clone_len = choose_block_len(afl, len); + u32 clone_from = rand_below(afl, len - clone_len + 1); + u32 clone_to = rand_below(afl, len); + + /* Head */ + + memcpy(tmp_buf, buf, clone_to); + + /* Inserted part */ + + memcpy(tmp_buf + clone_to, buf + clone_from, clone_len); + + /* Tail */ + memcpy(tmp_buf + clone_to + clone_len, buf + clone_to, + len - clone_to); + + len += clone_len; + memcpy(buf, tmp_buf, len); + + } else if (unlikely(len < 8)) { + + break; + + } else { + + goto retry_havoc_step; + + } + + break; + + } + + case MUT_CLONE_INSERT: { + + if (likely(len + HAVOC_BLK_XL < MAX_FILE)) { + + /* Insert a block of constant bytes (25%). */ + + u32 clone_len = choose_block_len(afl, HAVOC_BLK_XL); + u32 clone_to = rand_below(afl, len); + u32 strat = rand_below(afl, 2); + u32 clone_from = clone_to ? clone_to - 1 : 0; + item = strat ? rand_below(afl, 256) : buf[clone_from]; + + /* Head */ + + memcpy(tmp_buf, buf, clone_to); + + /* Inserted part */ + + memset(tmp_buf + clone_to, item, clone_len); + + /* Tail */ + memcpy(tmp_buf + clone_to + clone_len, buf + clone_to, + len - clone_to); + + len += clone_len; + memcpy(buf, tmp_buf, len); + + } else if (unlikely(len < 8)) { + + break; + + } else { + + goto retry_havoc_step; + + } + + break; + + } + + case MUT_OVERWRITE_COPY: { + + /* Overwrite bytes with a randomly selected chunk bytes. */ + + if (unlikely(len < 2)) { break; } // no retry + + u32 copy_len = choose_block_len(afl, len - 1); + u32 copy_from = rand_below(afl, len - copy_len + 1); + u32 copy_to = rand_below(afl, len - copy_len + 1); + + if (likely(copy_from != copy_to)) { + + memmove(buf + copy_to, buf + copy_from, copy_len); + + } + + break; + + } + + case MUT_OVERWRITE_FIXED: { + + /* Overwrite bytes with fixed bytes. */ + + if (unlikely(len < 2)) { break; } // no retry + + u32 copy_len = choose_block_len(afl, len - 1); + u32 copy_to = rand_below(afl, len - copy_len + 1); + u32 strat = rand_below(afl, 2); + u32 copy_from = copy_to ? copy_to - 1 : 0; + item = strat ? rand_below(afl, 256) : buf[copy_from]; + memset(buf + copy_to, item, copy_len); + + break; + + } + + case MUT_BYTEADD: { + + /* Increase byte by 1. */ + + buf[rand_below(afl, len)]++; + break; + + } + + case MUT_BYTESUB: { + + /* Decrease byte by 1. */ + + buf[rand_below(afl, len)]--; + break; + + } + + case MUT_FLIP8: { + + /* Flip byte. */ + + buf[rand_below(afl, len)] ^= 0xff; + break; + + } + + case MUT_SWITCH: { + + if (unlikely(len < 4)) { break; } // no retry + + /* Switch bytes. */ + + u32 to_end, switch_to, switch_len, switch_from; + switch_from = rand_below(afl, len); + do { + + switch_to = rand_below(afl, len); + + } while (unlikely(switch_from == switch_to)); + + if (switch_from < switch_to) { + + switch_len = switch_to - switch_from; + to_end = len - switch_to; + + } else { + + switch_len = switch_from - switch_to; + to_end = len - switch_from; + + } + + switch_len = choose_block_len(afl, MIN(switch_len, to_end)); + + /* Backup */ + + memcpy(tmp_buf, buf + switch_from, switch_len); + + /* Switch 1 */ + + memcpy(buf + switch_from, buf + switch_to, switch_len); + + /* Switch 2 */ + + memcpy(buf + switch_to, tmp_buf, switch_len); + + break; + + } + + case MUT_DEL: { + + /* Delete bytes. */ + + if (unlikely(len < 2)) { break; } // no retry + + /* Don't delete too much. */ + + u32 del_len = choose_block_len(afl, len - 1); + u32 del_from = rand_below(afl, len - del_len + 1); + memmove(buf + del_from, buf + del_from + del_len, + len - del_from - del_len); + len -= del_len; + + break; + + } + + case MUT_SHUFFLE: { + + /* Shuffle bytes. */ + + if (unlikely(len < 4)) { break; } // no retry + + u32 len = choose_block_len(afl, len - 1); + u32 off = rand_below(afl, len - len + 1); + + for (u32 i = len - 1; i > 0; i--) { + + u32 j; + do { + + j = rand_below(afl, i + 1); + + } while (unlikely(i == j)); + + unsigned char temp = buf[off + i]; + buf[off + i] = buf[off + j]; + buf[off + j] = temp; + + } + + break; + + } + + case MUT_DELONE: { + + /* Delete bytes. */ + + if (unlikely(len < 2)) { break; } // no retry + + /* Don't delete too much. */ + + u32 del_len = 1; + u32 del_from = rand_below(afl, len - del_len + 1); + memmove(buf + del_from, buf + del_from + del_len, + len - del_from - del_len); + + len -= del_len; + + break; + + } + + case MUT_INSERTONE: { + + if (unlikely(len < 2)) { break; } // no retry + + u32 clone_len = 1; + u32 clone_to = rand_below(afl, len); + u32 strat = rand_below(afl, 2); + u32 clone_from = clone_to ? clone_to - 1 : 0; + item = strat ? rand_below(afl, 256) : buf[clone_from]; + + /* Head */ + + memcpy(tmp_buf, buf, clone_to); + + /* Inserted part */ + + memset(tmp_buf + clone_to, item, clone_len); + + /* Tail */ + memcpy(tmp_buf + clone_to + clone_len, buf + clone_to, len - clone_to); + + len += clone_len; + memcpy(buf, tmp_buf, len); + + break; + + } + + case MUT_ASCIINUM: { + + if (unlikely(len < 4)) { break; } // no retry + + u32 off = rand_below(afl, len), off2 = off, cnt = 0; + + while (off2 + cnt < len && !isdigit(buf[off2 + cnt])) { + + ++cnt; + + } + + // none found, wrap + if (off2 + cnt == len) { + + off2 = 0; + cnt = 0; + + while (cnt < off && !isdigit(buf[off2 + cnt])) { + + ++cnt; + + } + + if (cnt == off) { + + if (len < 8) { + + break; + + } else { + + goto retry_havoc_step; + + } + + } + + } + + off = off2 + cnt; + off2 = off + 1; + + while (off2 < len && isdigit(buf[off2])) { + + ++off2; + + } + + s64 val = buf[off] - '0'; + for (u32 i = off + 1; i < off2; ++i) { + + val = (val * 10) + buf[i] - '0'; + + } + + if (off && buf[off - 1] == '-') { val = -val; } + + u32 strat = rand_below(afl, 8); + switch (strat) { + + case 0: + val++; + break; + case 1: + val--; + break; + case 2: + val *= 2; + break; + case 3: + val /= 2; + break; + case 4: + if (likely(val && (u64)val < 0x19999999)) { + + val = (u64)rand_next(afl) % (u64)((u64)val * 10); + + } else { + + val = rand_below(afl, 256); + + } + + break; + case 5: + val += rand_below(afl, 256); + break; + case 6: + val -= rand_below(afl, 256); + break; + case 7: + val = ~(val); + break; + + } + + char buf[20]; + snprintf(buf, sizeof(buf), "%ld", val); + u32 old_len = off2 - off; + u32 new_len = strlen(buf); + + if (old_len == new_len) { + + memcpy(buf + off, buf, new_len); + + } else { + + /* Head */ + + memcpy(tmp_buf, buf, off); + + /* Inserted part */ + + memcpy(tmp_buf + off, buf, new_len); + + /* Tail */ + memcpy(tmp_buf + off + new_len, buf + off2, len - off2); + + len += (new_len - old_len); + memcpy(buf, tmp_buf, len); + + } + + // fprintf(stderr, "AFTER : %s\n", buf); + break; + + } + + case MUT_NEG: { + + /* Neg byte. */ + + item = rand_below(afl, len); + buf[item] = ~buf[item]; + + break; + + } + + case MUT_INSERTASCIINUM: { + + u32 len = 1 + rand_below(afl, 8); + u32 pos = rand_below(afl, len); + + /* Insert ascii number. */ + if (unlikely(len < pos + len)) { + + if (unlikely(len < 8)) { + + break; + + } else { + + goto retry_havoc_step; + + } + + } + + u64 val = rand_next(afl); + char buf[20]; + snprintf(buf, sizeof(buf), "%llu", val); + memcpy(buf + pos, buf, len); + + break; + + } + + case MUT_EXTRA_OVERWRITE: { + + if (unlikely(!afl->extras_cnt)) { goto retry_havoc_step; } + + /* Use the dictionary. */ + + u32 use_extra = rand_below(afl, afl->extras_cnt); + u32 extra_len = afl->extras[use_extra].len; + + if (unlikely(extra_len > len)) { goto retry_havoc_step; } + + u32 insert_at = rand_below(afl, len - extra_len + 1); + memcpy(buf + insert_at, afl->extras[use_extra].data, extra_len); + + break; + + } + + case MUT_EXTRA_INSERT: { + + if (unlikely(!afl->extras_cnt)) { goto retry_havoc_step; } + + u32 use_extra = rand_below(afl, afl->extras_cnt); + u32 extra_len = afl->extras[use_extra].len; + if (unlikely(len + extra_len >= MAX_FILE)) { goto retry_havoc_step; } + + u8 *ptr = afl->extras[use_extra].data; + u32 insert_at = rand_below(afl, len + 1); + + /* Tail */ + memmove(buf + insert_at + extra_len, buf + insert_at, len - insert_at); + + /* Inserted part */ + memcpy(buf + insert_at, ptr, extra_len); + len += extra_len; + + break; + + } + + case MUT_AUTO_EXTRA_OVERWRITE: { + + if (unlikely(!afl->a_extras_cnt)) { goto retry_havoc_step; } + + /* Use the dictionary. */ + + u32 use_extra = rand_below(afl, afl->a_extras_cnt); + u32 extra_len = afl->a_extras[use_extra].len; + + if (unlikely(extra_len > len)) { goto retry_havoc_step; } + + u32 insert_at = rand_below(afl, len - extra_len + 1); + memcpy(buf + insert_at, afl->a_extras[use_extra].data, extra_len); + + break; + + } + + case MUT_AUTO_EXTRA_INSERT: { + + if (unlikely(!afl->a_extras_cnt)) { goto retry_havoc_step; } + + u32 use_extra = rand_below(afl, afl->a_extras_cnt); + u32 extra_len = afl->a_extras[use_extra].len; + if (unlikely(len + extra_len >= MAX_FILE)) { goto retry_havoc_step; } + + u8 *ptr = afl->a_extras[use_extra].data; + u32 insert_at = rand_below(afl, len + 1); + + /* Tail */ + memmove(buf + insert_at + extra_len, buf + insert_at, len - insert_at); + + /* Inserted part */ + memcpy(buf + insert_at, ptr, extra_len); + len += extra_len; + + break; + + } + + case MUT_SPLICE_OVERWRITE: { + + if (unlikely(!splice_buf || !splice_len)) { goto retry_havoc_step; } + + /* overwrite mode */ + + u32 copy_from, copy_to, copy_len; + + copy_len = choose_block_len(afl, splice_len - 1); + + if (copy_len > len) copy_len = len; + + copy_from = rand_below(afl, splice_len - copy_len + 1); + copy_to = rand_below(afl, len - copy_len + 1); + memmove(buf + copy_to, splice_buf + copy_from, copy_len); + + break; + + } + + case MUT_SPLICE_INSERT: { + + if (unlikely(!splice_buf || !splice_len)) { goto retry_havoc_step; } + + if (unlikely(len + HAVOC_BLK_XL >= MAX_FILE)) { goto retry_havoc_step; } + + /* insert mode */ + + u32 clone_from, clone_to, clone_len; + + clone_len = choose_block_len(afl, splice_len); + clone_from = rand_below(afl, splice_len - clone_len + 1); + clone_to = rand_below(afl, len + 1); + + /* Head */ + + memcpy(tmp_buf, buf, clone_to); + + /* Inserted part */ + + memcpy(tmp_buf + clone_to, splice_buf + clone_from, clone_len); + + /* Tail */ + memcpy(tmp_buf + clone_to + clone_len, buf + clone_to, len - clone_to); + + len += clone_len; + memcpy(buf, tmp_buf, len); + + break; + + } + + } + + } + + return len; + +} + +#endif /* !AFL_MUTATIONS_H */ + diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 1636c323..226fb40e 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -27,21 +27,7 @@ #include #include #include "cmplog.h" - -static u32 mutation_array_explore[] = { - - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37}; -// static u32 mutation_array_exploit[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -// 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -// 31 }; static u32 mutation_array_txt_explore[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, -// 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, -// 28, 29, 30, 31 }; static u32 mutation_array_txt_exploit[] = { 0, 1, 2, 3, 4, -// 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, -// 25, 26, 27, 28, 29, 30, 31 }; - -// what about more splicing? -// what about -x and cmplog learn? +#include "afl-mutations.h" /* MOpt */ @@ -85,50 +71,6 @@ static int select_algorithm(afl_state_t *afl, u32 max_algorithm) { } -/* Helper to choose random block len for block operations in fuzz_one(). - Doesn't return zero, provided that max_len is > 0. */ - -static inline u32 choose_block_len(afl_state_t *afl, u32 limit) { - - u32 min_value, max_value; - u32 rlim = MIN(afl->queue_cycle, (u32)3); - - if (unlikely(!afl->run_over10m)) { rlim = 1; } - - switch (rand_below(afl, rlim)) { - - case 0: - min_value = 1; - max_value = HAVOC_BLK_SMALL; - break; - - case 1: - min_value = HAVOC_BLK_SMALL; - max_value = HAVOC_BLK_MEDIUM; - break; - - default: - - if (likely(rand_below(afl, 10))) { - - min_value = HAVOC_BLK_MEDIUM; - max_value = HAVOC_BLK_LARGE; - - } else { - - min_value = HAVOC_BLK_LARGE; - max_value = HAVOC_BLK_XL; - - } - - } - - if (min_value >= limit) { min_value = 1; } - - return min_value + rand_below(afl, MIN(max_value, limit) - min_value + 1); - -} - /* Helper function to see if a particular change (xor_val = old ^ new) could be a product of deterministic bit flips with the lengths and stepovers attempted by afl-fuzz. This is used to avoid dupes in some of the @@ -2136,8 +2078,31 @@ havoc_stage: u32 *mutation_array; u32 stack_max; - // if ( ... ) - mutation_array = (u32 *)&mutation_array_explore; + if (afl->queue_cur->is_ascii) { // is text? + + if (1) { // is exploration? + + mutation_array = (unsigned int *)&mutation_strategy_exploration_text; + + } else { // is exploitation! + + mutation_array = (unsigned int *)&mutation_strategy_exploitation_text; + + } + + } else { // is binary! + + if (1) { // is exploration? + + mutation_array = (unsigned int *)&mutation_strategy_exploration_binary; + + } else { // is exploitation! + + mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary; + + } + + } if (temp_len < 64) { @@ -2208,11 +2173,11 @@ havoc_stage: } retry_havoc_step: - u32 r = rand_below(afl, 256), item; + u32 r = rand_below(afl, MUT_STRATEGY_ARRAY_SIZE), item; switch (mutation_array[r]) { - case 0: { + case MUT_FLIPBIT: { /* Flip a single bit somewhere. Spooky! */ u8 bit = rand_below(afl, 8); @@ -2227,7 +2192,7 @@ havoc_stage: } - case 1: { + case MUT_INTERESTING8: { /* Set byte to interesting value. */ @@ -2241,7 +2206,7 @@ havoc_stage: } - case 2: { + case MUT_INTERESTING16: { /* Set word to interesting value, little endian. */ @@ -2260,7 +2225,7 @@ havoc_stage: } - case 3: { + case MUT_INTERESTING16BE: { /* Set word to interesting value, big endian. */ @@ -2278,7 +2243,7 @@ havoc_stage: } - case 4: { + case MUT_INTERESTING32: { /* Set dword to interesting value, little endian. */ @@ -2297,7 +2262,7 @@ havoc_stage: } - case 5: { + case MUT_INTERESTING32BE: { /* Set dword to interesting value, big endian. */ @@ -2315,7 +2280,7 @@ havoc_stage: } - case 6: { + case MUT_ARITH8_: { /* Randomly subtract from byte. */ @@ -2329,7 +2294,7 @@ havoc_stage: } - case 7: { + case MUT_ARITH8: { /* Randomly add to byte. */ @@ -2343,7 +2308,7 @@ havoc_stage: } - case 8: { + case MUT_ARITH16_: { /* Randomly subtract from word, little endian. */ @@ -2362,7 +2327,7 @@ havoc_stage: } - case 9: { + case MUT_ARITH16BE_: { /* Randomly subtract from word, big endian. */ @@ -2382,7 +2347,7 @@ havoc_stage: } - case 10: { + case MUT_ARITH16: { /* Randomly add to word, little endian. */ @@ -2401,7 +2366,7 @@ havoc_stage: } - case 11: { + case MUT_ARITH16BE: { /* Randomly add to word, big endian. */ @@ -2421,7 +2386,7 @@ havoc_stage: } - case 12: { + case MUT_ARITH32_: { /* Randomly subtract from dword, little endian. */ @@ -2440,7 +2405,7 @@ havoc_stage: } - case 13: { + case MUT_ARITH32BE_: { /* Randomly subtract from dword, big endian. */ @@ -2460,7 +2425,7 @@ havoc_stage: } - case 14: { + case MUT_ARITH32: { /* Randomly add to dword, little endian. */ @@ -2479,7 +2444,7 @@ havoc_stage: } - case 15: { + case MUT_ARITH32BE: { /* Randomly add to dword, big endian. */ @@ -2499,7 +2464,7 @@ havoc_stage: } - case 16: { + case MUT_RAND8: { /* Just set a random byte to a random value. Because, why not. We use XOR with 1-255 to eliminate the @@ -2517,7 +2482,7 @@ havoc_stage: } - case 17: { + case MUT_CLONE_OVERWRITE: { if (likely(temp_len + HAVOC_BLK_XL < MAX_FILE)) { @@ -2566,7 +2531,7 @@ havoc_stage: } - case 18: { + case MUT_CLONE_INSERT: { if (likely(temp_len + HAVOC_BLK_XL < MAX_FILE)) { @@ -2617,7 +2582,7 @@ havoc_stage: } - case 19: { + case MUT_OVERWRITE_COPY: { /* Overwrite bytes with a randomly selected chunk bytes. */ @@ -2642,7 +2607,7 @@ havoc_stage: } - case 20: { + case MUT_OVERWRITE_FIXED: { /* Overwrite bytes with fixed bytes. */ @@ -2666,7 +2631,7 @@ havoc_stage: } - case 21: { + case MUT_BYTEADD: { /* Increase byte by 1. */ @@ -2679,7 +2644,7 @@ havoc_stage: } - case 22: { + case MUT_BYTESUB: { /* Decrease byte by 1. */ @@ -2692,7 +2657,7 @@ havoc_stage: } - case 23: { + case MUT_FLIP8: { /* Flip byte. */ @@ -2705,7 +2670,7 @@ havoc_stage: } - case 24: { + case MUT_SWITCH: { if (unlikely(temp_len < 4)) { break; } // no retry @@ -2757,7 +2722,7 @@ havoc_stage: } - case 25: { + case MUT_DEL: { /* Delete bytes. */ @@ -2782,7 +2747,7 @@ havoc_stage: } - case 26: { + case MUT_SHUFFLE: { /* Shuffle bytes. */ @@ -2815,7 +2780,7 @@ havoc_stage: } - case 27: { + case MUT_DELONE: { /* Delete bytes. */ @@ -2839,7 +2804,7 @@ havoc_stage: } - case 28: { + case MUT_INSERTONE: { if (unlikely(temp_len < 2)) { break; } // no retry @@ -2878,7 +2843,7 @@ havoc_stage: } - case 29: { + case MUT_ASCIINUM: { if (unlikely(temp_len < 4)) { break; } // no retry @@ -3022,7 +2987,7 @@ havoc_stage: } - case 30: { + case MUT_NEG: { /* Neg byte. */ @@ -3037,7 +3002,7 @@ havoc_stage: } - case 31: { + case MUT_INSERTASCIINUM: { u32 len = 1 + rand_below(afl, 8); u32 pos = rand_below(afl, temp_len); @@ -3069,7 +3034,7 @@ havoc_stage: } - case 32: { + case MUT_EXTRA_OVERWRITE: { if (unlikely(!afl->extras_cnt)) { goto retry_havoc_step; } @@ -3092,7 +3057,7 @@ havoc_stage: } - case 33: { + case MUT_EXTRA_INSERT: { if (unlikely(!afl->extras_cnt)) { goto retry_havoc_step; } @@ -3127,7 +3092,7 @@ havoc_stage: } - case 34: { + case MUT_AUTO_EXTRA_OVERWRITE: { if (unlikely(!afl->a_extras_cnt)) { goto retry_havoc_step; } @@ -3150,7 +3115,7 @@ havoc_stage: } - case 35: { + case MUT_AUTO_EXTRA_INSERT: { if (unlikely(!afl->a_extras_cnt)) { goto retry_havoc_step; } @@ -3185,7 +3150,7 @@ havoc_stage: } - case 36: { + case MUT_SPLICE_OVERWRITE: { if (unlikely(afl->ready_for_splicing_count <= 1)) { @@ -3231,7 +3196,7 @@ havoc_stage: } - case 37: { + case MUT_SPLICE_INSERT: { if (unlikely(afl->ready_for_splicing_count <= 1)) { -- cgit 1.4.1 From 3ab18d286142e2e19e37850c051e0b07b9d7b296 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 4 Apr 2023 19:44:12 +0200 Subject: mode switch --- include/afl-fuzz.h | 69 +++++++------ include/afl-mutations.h | 259 +++++++++++++++++++++++++++++++++++++++++++++++- include/config.h | 6 ++ src/afl-fuzz-one.c | 6 +- src/afl-fuzz-state.c | 1 + src/afl-fuzz-stats.c | 5 +- src/afl-fuzz.c | 51 ++++++++-- 7 files changed, 351 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 58d02af5..6573eabf 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -490,7 +490,9 @@ typedef struct afl_state { *orig_cmdline, /* Original command line */ *infoexec; /* Command to execute on a new crash */ - u32 hang_tmout; /* Timeout used for hang det (ms) */ + u32 hang_tmout, /* Timeout used for hang det (ms) */ + stats_update_freq, /* Stats update frequency (execs) */ + switch_fuzz_mode; /* auto or fixed fuzz mode */ u8 havoc_stack_pow2, /* HAVOC_STACK_POW2 */ no_unlink, /* do not unlink cur_input */ @@ -499,40 +501,37 @@ typedef struct afl_state { custom_splice_optout, /* Custom mutator no splice buffer */ is_main_node, /* if this is the main node */ is_secondary_node, /* if this is a secondary instance */ - pizza_is_served; /* pizza mode */ - - u32 stats_update_freq; /* Stats update frequency (execs) */ - - u8 schedule; /* Power schedule (default: EXPLORE)*/ - u8 havoc_max_mult; - - u8 skip_deterministic, /* Skip deterministic stages? */ - use_splicing, /* Recombine input files? */ - non_instrumented_mode, /* Run in non-instrumented mode? */ - score_changed, /* Scoring for favorites changed? */ - resuming_fuzz, /* Resuming an older fuzzing job? */ - timeout_given, /* Specific timeout given? */ - not_on_tty, /* stdout is not a tty */ - term_too_small, /* terminal dimensions too small */ - no_forkserver, /* Disable forkserver? */ - crash_mode, /* Crash mode! Yeah! */ - in_place_resume, /* Attempt in-place resume? */ - autoresume, /* Resume if afl->out_dir exists? */ - auto_changed, /* Auto-generated tokens changed? */ - no_cpu_meter_red, /* Feng shui on the status screen */ - no_arith, /* Skip most arithmetic ops */ - shuffle_queue, /* Shuffle input queue? */ - bitmap_changed, /* Time to update bitmap? */ - unicorn_mode, /* Running in Unicorn mode? */ - use_wine, /* Use WINE with QEMU mode */ - skip_requested, /* Skip request, via SIGUSR1 */ - run_over10m, /* Run time over 10 minutes? */ - persistent_mode, /* Running in persistent mode? */ - deferred_mode, /* Deferred forkserver mode? */ - fixed_seed, /* do not reseed */ - fast_cal, /* Try to calibrate faster? */ - disable_trim, /* Never trim in fuzz_one */ - shmem_testcase_mode, /* If sharedmem testcases are used */ + pizza_is_served, /* pizza mode */ + text_input, /* target wants text inputs */ + fuzz_mode, /* current mode: coverage/exploration or crash/exploitation */ + schedule, /* Power schedule (default: EXPLORE)*/ + havoc_max_mult, skip_deterministic, /* Skip deterministic stages? */ + use_splicing, /* Recombine input files? */ + non_instrumented_mode, /* Run in non-instrumented mode? */ + score_changed, /* Scoring for favorites changed? */ + resuming_fuzz, /* Resuming an older fuzzing job? */ + timeout_given, /* Specific timeout given? */ + not_on_tty, /* stdout is not a tty */ + term_too_small, /* terminal dimensions too small */ + no_forkserver, /* Disable forkserver? */ + crash_mode, /* Crash mode! Yeah! */ + in_place_resume, /* Attempt in-place resume? */ + autoresume, /* Resume if afl->out_dir exists? */ + auto_changed, /* Auto-generated tokens changed? */ + no_cpu_meter_red, /* Feng shui on the status screen */ + no_arith, /* Skip most arithmetic ops */ + shuffle_queue, /* Shuffle input queue? */ + bitmap_changed, /* Time to update bitmap? */ + unicorn_mode, /* Running in Unicorn mode? */ + use_wine, /* Use WINE with QEMU mode */ + skip_requested, /* Skip request, via SIGUSR1 */ + run_over10m, /* Run time over 10 minutes? */ + persistent_mode, /* Running in persistent mode? */ + deferred_mode, /* Deferred forkserver mode? */ + fixed_seed, /* do not reseed */ + fast_cal, /* Try to calibrate faster? */ + disable_trim, /* Never trim in fuzz_one */ + shmem_testcase_mode, /* If sharedmem testcases are used */ expand_havoc, /* perform expensive havoc after no find */ cycle_schedules, /* cycle power schedules? */ old_seed_selection, /* use vanilla afl seed selection */ diff --git a/include/afl-mutations.h b/include/afl-mutations.h index 707db799..5a1b6356 100644 --- a/include/afl-mutations.h +++ b/include/afl-mutations.h @@ -81,7 +81,264 @@ enum { u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {}; u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {}; u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {}; -u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = {}; +u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = { + + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_CLONE_OVERWRITE, + MUT_CLONE_OVERWRITE, + MUT_CLONE_OVERWRITE, + MUT_CLONE_OVERWRITE, + MUT_CLONE_OVERWRITE, + MUT_CLONE_OVERWRITE, + MUT_CLONE_OVERWRITE, + MUT_CLONE_OVERWRITE, + MUT_CLONE_OVERWRITE, + MUT_CLONE_INSERT, + MUT_CLONE_INSERT, + MUT_CLONE_INSERT, + MUT_CLONE_INSERT, + MUT_CLONE_INSERT, + MUT_CLONE_INSERT, + MUT_CLONE_INSERT, + MUT_CLONE_INSERT, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_FIXED, + MUT_OVERWRITE_FIXED, + MUT_OVERWRITE_FIXED, + MUT_OVERWRITE_FIXED, + MUT_OVERWRITE_FIXED, + MUT_OVERWRITE_FIXED, + MUT_BYTEADD, + MUT_BYTEADD, + MUT_BYTEADD, + MUT_BYTEADD, + MUT_BYTEADD, + MUT_BYTEADD, + MUT_BYTEADD, + MUT_BYTESUB, + MUT_BYTESUB, + MUT_BYTESUB, + MUT_BYTESUB, + MUT_BYTESUB, + MUT_BYTESUB, + MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, + MUT_SWITCH, + MUT_SWITCH, + MUT_SWITCH, + MUT_SWITCH, + MUT_SWITCH, + MUT_SWITCH, + MUT_SWITCH, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_SHUFFLE, + MUT_SHUFFLE, + MUT_SHUFFLE, + MUT_SHUFFLE, + MUT_SHUFFLE, + MUT_SHUFFLE, + MUT_DELONE, + MUT_DELONE, + MUT_DELONE, + MUT_DELONE, + MUT_DELONE, + MUT_INSERTONE, + MUT_INSERTONE, + MUT_INSERTONE, + MUT_INSERTONE, + MUT_INSERTONE, + MUT_INSERTONE, + MUT_ASCIINUM, + MUT_ASCIINUM, + MUT_ASCIINUM, + MUT_ASCIINUM, + MUT_ASCIINUM, + MUT_NEG, + MUT_NEG, + MUT_NEG, + MUT_NEG, + MUT_NEG, + MUT_NEG, + MUT_INSERTASCIINUM, + MUT_INSERTASCIINUM, + MUT_INSERTASCIINUM, + MUT_INSERTASCIINUM, + MUT_INSERTASCIINUM, + MUT_INSERTASCIINUM, + MUT_INSERTASCIINUM, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT}; u32 afl_mutate(afl_state_t *, u8 *, u32, u32, bool, bool, u8 *, u32, u32); u32 choose_block_len(afl_state_t *, u32); diff --git a/include/config.h b/include/config.h index e46f515a..c1297bdd 100644 --- a/include/config.h +++ b/include/config.h @@ -43,6 +43,12 @@ Default: 8MB (defined in bytes) */ #define DEFAULT_SHMEM_SIZE (8 * 1024 * 1024) +/* Default time until when no more coverage finds are happening afl-fuzz + switches to exploitation mode. It automatically switches back when new + coverage is found. + Default: 300 (seconds) */ +#define STRATEGY_SWITCH_TIME 300 + /* Default file permission umode when creating files (default: 0600) */ #define DEFAULT_PERMISSION 0600 diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 226fb40e..e6b58713 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2078,9 +2078,9 @@ havoc_stage: u32 *mutation_array; u32 stack_max; - if (afl->queue_cur->is_ascii) { // is text? + if (unlikely(afl->text_input || afl->queue_cur->is_ascii)) { // is text? - if (1) { // is exploration? + if (likely(afl->fuzz_mode == 0)) { // is exploration? mutation_array = (unsigned int *)&mutation_strategy_exploration_text; @@ -2092,7 +2092,7 @@ havoc_stage: } else { // is binary! - if (1) { // is exploration? + if (likely(afl->fuzz_mode == 0)) { // is exploration? mutation_array = (unsigned int *)&mutation_strategy_exploration_binary; diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index f9aa5cfe..907861e9 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -108,6 +108,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->cmplog_lvl = 2; afl->min_length = 1; afl->max_length = MAX_FILE; + afl->switch_fuzz_mode = STRATEGY_SWITCH_TIME; #ifndef NO_SPLICING afl->use_splicing = 1; #endif diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 25ebe987..de48e10a 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -1282,7 +1282,10 @@ void show_stats_normal(afl_state_t *afl) { } /* Last line */ - SAYF(SET_G1 "\n" bSTG bLB bH30 bH20 bH2 bRB bSTOP cRST RESET_G1); + + SAYF(SET_G1 "\n" bSTG bLB bH cCYA bSTOP + " strategy:%s %s " bSTG bH20 bH10 bH2 bRB bSTOP cRST RESET_G1, + cPIN, afl->fuzz_mode == 0 ? "explore" : "exploit"); #undef IB diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 3380fd90..315107d7 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -128,6 +128,13 @@ static void usage(u8 *argv0, int more_help) { " -o dir - output directory for fuzzer findings\n\n" "Execution control settings:\n" + " -P strategy - set fix mutation strategy: explore (focus on new " + "coverage),\n" + " exploit (focus on triggering crashes). You can also " + "set a\n" + " number of seconds after without any finds it switches " + "to\n" + " exploit mode, and back on new coverage (default: %u)\n" " -p schedule - power schedules compute a seed's performance score:\n" " fast(default), explore, exploit, seek, rare, mmopt, " "coe, lin\n" @@ -156,6 +163,7 @@ static void usage(u8 *argv0, int more_help) { "\n" "Mutator settings:\n" + " -a - target expects ascii text input\n" " -g minlength - set min length of generated fuzz input (default: 1)\n" " -G maxlength - set max length of generated fuzz input (default: " "%lu)\n" @@ -212,7 +220,8 @@ static void usage(u8 *argv0, int more_help) { " -e ext - file extension for the fuzz test input file (if " "needed)\n" "\n", - argv0, EXEC_TIMEOUT, MEM_LIMIT, MAX_FILE, FOREIGN_SYNCS_MAX); + argv0, STRATEGY_SWITCH_TIME, EXEC_TIMEOUT, MEM_LIMIT, MAX_FILE, + FOREIGN_SYNCS_MAX); if (more_help > 1) { @@ -553,14 +562,44 @@ int main(int argc, char **argv_orig, char **envp) { afl->shmem_testcase_mode = 1; // we always try to perform shmem fuzzing - while ( - (opt = getopt( - argc, argv, - "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YZ")) > - 0) { + // still available: aHjJkKPqruvwz + while ((opt = getopt(argc, argv, + "+aAb:B:c:CdDe:E:f:F:g:G:hi:I:l:L:m:M:nNo:Op:P:QRs:S:t:" + "T:UV:WXx:YZ")) > 0) { switch (opt) { + case 'a': + afl->text_input = 1; + break; + + case 'P': + if (!stricmp(optarg, "explore") || !stricmp(optarg, "exploration")) { + + afl->fuzz_mode = 0; + afl->switch_fuzz_mode = 1; + + } else if (!stricmp(optarg, "exploit") || + + !stricmp(optarg, "exploitation")) { + + afl->fuzz_mode = 1; + afl->switch_fuzz_mode = 0; + + } else { + + if ((s32)(afl->switch_fuzz_mode = (u32)atoi(optarg)) < 1) { + + FATAL( + "Parameter for option -P must be \"explore\", \"exploit\" or a " + "number!"); + + } + + } + + break; + case 'g': afl->min_length = atoi(optarg); break; -- cgit 1.4.1 From 53b70ef104a334424fd5226c7504130b3bd45625 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 5 Apr 2023 09:33:09 +0200 Subject: mut changes --- include/afl-mutations.h | 83 +++++++++++++++++++++---------------------------- src/afl-fuzz-one.c | 17 +--------- 2 files changed, 37 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/include/afl-mutations.h b/include/afl-mutations.h index 31d0898a..9188a37f 100644 --- a/include/afl-mutations.h +++ b/include/afl-mutations.h @@ -65,14 +65,13 @@ enum { /* 27 */ MUT_DELONE, /* 28 */ MUT_INSERTONE, /* 29 */ MUT_ASCIINUM, - /* 30 */ MUT_NEG, - /* 31 */ MUT_INSERTASCIINUM, - /* 32 */ MUT_EXTRA_OVERWRITE, - /* 33 */ MUT_EXTRA_INSERT, - /* 34 */ MUT_AUTO_EXTRA_OVERWRITE, - /* 35 */ MUT_AUTO_EXTRA_INSERT, - /* 36 */ MUT_SPLICE_OVERWRITE, - /* 37 */ MUT_SPLICE_INSERT, + /* 30 */ MUT_INSERTASCIINUM, + /* 31 */ MUT_EXTRA_OVERWRITE, + /* 32 */ MUT_EXTRA_INSERT, + /* 33 */ MUT_AUTO_EXTRA_OVERWRITE, + /* 34 */ MUT_AUTO_EXTRA_INSERT, + /* 35 */ MUT_SPLICE_OVERWRITE, + /* 36 */ MUT_SPLICE_INSERT, MUT_MAX @@ -199,6 +198,7 @@ u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = { MUT_CLONE_INSERT, MUT_CLONE_INSERT, MUT_CLONE_INSERT, + MUT_CLONE_INSERT, MUT_OVERWRITE_COPY, MUT_OVERWRITE_COPY, MUT_OVERWRITE_COPY, @@ -233,6 +233,9 @@ u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = { MUT_FLIP8, MUT_FLIP8, MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, MUT_SWITCH, MUT_SWITCH, MUT_SWITCH, @@ -276,12 +279,8 @@ u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = { MUT_ASCIINUM, MUT_ASCIINUM, MUT_ASCIINUM, - MUT_NEG, - MUT_NEG, - MUT_NEG, - MUT_NEG, - MUT_NEG, - MUT_NEG, + MUT_ASCIINUM, + MUT_INSERTASCIINUM, MUT_INSERTASCIINUM, MUT_INSERTASCIINUM, MUT_INSERTASCIINUM, @@ -335,7 +334,7 @@ u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = { MUT_SPLICE_INSERT, MUT_SPLICE_INSERT, MUT_SPLICE_INSERT, - MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT }; @@ -468,6 +467,7 @@ u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = { MUT_CLONE_INSERT, MUT_CLONE_INSERT, MUT_CLONE_INSERT, + MUT_CLONE_INSERT, MUT_OVERWRITE_COPY, MUT_OVERWRITE_COPY, MUT_OVERWRITE_COPY, @@ -504,6 +504,10 @@ u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = { MUT_FLIP8, MUT_FLIP8, MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, MUT_SWITCH, MUT_SWITCH, MUT_SWITCH, @@ -541,12 +545,6 @@ u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = { MUT_ASCIINUM, MUT_ASCIINUM, MUT_ASCIINUM, - MUT_NEG, - MUT_NEG, - MUT_NEG, - MUT_NEG, - MUT_NEG, - MUT_NEG, MUT_INSERTASCIINUM, MUT_INSERTASCIINUM, MUT_INSERTASCIINUM, @@ -596,7 +594,7 @@ u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = { MUT_SPLICE_INSERT, MUT_SPLICE_INSERT, MUT_SPLICE_INSERT, - MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT }; @@ -766,6 +764,9 @@ u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = { MUT_FLIP8, MUT_FLIP8, MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, MUT_SWITCH, MUT_SWITCH, MUT_SWITCH, @@ -785,6 +786,7 @@ u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = { MUT_SHUFFLE, MUT_SHUFFLE, MUT_SHUFFLE, + MUT_SHUFFLE, MUT_DELONE, MUT_DELONE, MUT_DELONE, @@ -801,12 +803,8 @@ u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = { MUT_ASCIINUM, MUT_ASCIINUM, MUT_ASCIINUM, - MUT_NEG, - MUT_NEG, - MUT_NEG, - MUT_NEG, - MUT_NEG, - MUT_NEG, + MUT_ASCIINUM, + MUT_INSERTASCIINUM, MUT_INSERTASCIINUM, MUT_INSERTASCIINUM, MUT_INSERTASCIINUM, @@ -857,7 +855,7 @@ u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = { MUT_SPLICE_INSERT, MUT_SPLICE_INSERT, MUT_SPLICE_INSERT, - MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT }; @@ -959,6 +957,8 @@ u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = { MUT_ARITH32BE_, MUT_ARITH32BE_, MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32, MUT_ARITH32, MUT_ARITH32, MUT_ARITH32, @@ -1027,6 +1027,10 @@ u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = { MUT_FLIP8, MUT_FLIP8, MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, MUT_SWITCH, MUT_SWITCH, MUT_SWITCH, @@ -1062,12 +1066,6 @@ u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = { MUT_ASCIINUM, MUT_ASCIINUM, MUT_ASCIINUM, - MUT_NEG, - MUT_NEG, - MUT_NEG, - MUT_NEG, - MUT_NEG, - MUT_NEG, MUT_INSERTASCIINUM, MUT_INSERTASCIINUM, MUT_INSERTASCIINUM, @@ -1118,7 +1116,9 @@ u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = { MUT_SPLICE_INSERT, MUT_SPLICE_INSERT, MUT_SPLICE_INSERT, - MUT_SPLICE_INSERT}; + MUT_SPLICE_INSERT + +}; u32 afl_mutate(afl_state_t *, u8 *, u32, u32, bool, bool, u8 *, u32, u32); u32 choose_block_len(afl_state_t *, u32); @@ -1865,17 +1865,6 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps, } - case MUT_NEG: { - - /* Neg byte. */ - - item = rand_below(afl, len); - buf[item] = ~buf[item]; - - break; - - } - case MUT_INSERTASCIINUM: { u32 len = 1 + rand_below(afl, 8); diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index e6b58713..bc267b15 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2659,7 +2659,7 @@ havoc_stage: case MUT_FLIP8: { - /* Flip byte. */ + /* Flip byte with a XOR 0xff. This is the same as NEG. */ #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP8_"); @@ -2987,21 +2987,6 @@ havoc_stage: } - case MUT_NEG: { - - /* Neg byte. */ - -#ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " NEG_"); - strcat(afl->mutation, afl->m_tmp); -#endif - item = rand_below(afl, temp_len); - - out_buf[item] = ~out_buf[item]; - break; - - } - case MUT_INSERTASCIINUM: { u32 len = 1 + rand_below(afl, 8); -- cgit 1.4.1 From 1fc0731604c1ea1abb38ab345d9046a6f1e9b7de Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 5 Apr 2023 09:42:27 +0200 Subject: stack pow --- src/afl-fuzz-one.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index bc267b15..48aa6eb0 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2076,7 +2076,7 @@ havoc_stage: where we take the input file and make random stacked tweaks. */ u32 *mutation_array; - u32 stack_max; + u32 stack_max, stack_max_pow = afl->havoc_stack_pow2; if (unlikely(afl->text_input || afl->queue_cur->is_ascii)) { // is text? @@ -2106,22 +2106,20 @@ havoc_stage: if (temp_len < 64) { - stack_max = 4; + --stack_max_pow; - } else if (temp_len < 512) { + } else if (temp_len <= 8096) { - stack_max = 8; - - } else if (temp_len < 8096) { - - stack_max = 16; + ++stack_max_pow; } else { - stack_max = 32; + ++stack_max_pow; } + stack_max = 1 << stack_max_pow; + // + (afl->extras_cnt ? 2 : 0) + (afl->a_extras_cnt ? 2 : 0); for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { -- cgit 1.4.1 From e313180e4d3f7ba44b773e43af40d4af21088576 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 5 Apr 2023 10:32:37 +0200 Subject: fix for clang --- include/afl-mutations.h | 10 ++++++---- src/afl-fuzz-one.c | 9 ++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/include/afl-mutations.h b/include/afl-mutations.h index 9188a37f..cc913fb0 100644 --- a/include/afl-mutations.h +++ b/include/afl-mutations.h @@ -1231,7 +1231,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps, for (u32 step = 0; step < steps; ++step) { - retry_havoc_step: + retry_havoc_step : { u32 r = rand_below(afl, MUT_STRATEGY_ARRAY_SIZE), item; @@ -1667,10 +1667,10 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps, if (unlikely(len < 4)) { break; } // no retry - u32 len = choose_block_len(afl, len - 1); - u32 off = rand_below(afl, len - len + 1); + u32 blen = choose_block_len(afl, len - 1); + u32 off = rand_below(afl, len - blen + 1); - for (u32 i = len - 1; i > 0; i--) { + for (u32 i = blen - 1; i > 0; i--) { u32 j; do { @@ -2030,6 +2030,8 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps, } + } + return len; } diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 48aa6eb0..e6ff1d1a 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2139,8 +2139,8 @@ havoc_stage: LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { - if (el->stacked_custom && - rand_below(afl, 100) < el->stacked_custom_prob) { + if (unlikely(el->stacked_custom && + rand_below(afl, 100) < el->stacked_custom_prob)) { u8 *custom_havoc_buf = NULL; size_t new_len = el->afl_custom_havoc_mutation( @@ -2170,7 +2170,8 @@ havoc_stage: } - retry_havoc_step: + retry_havoc_step : { + u32 r = rand_below(afl, MUT_STRATEGY_ARRAY_SIZE), item; switch (mutation_array[r]) { @@ -3250,6 +3251,8 @@ havoc_stage: } + } + if (common_fuzz_stuff(afl, out_buf, temp_len)) { goto abandon_entry; } /* out_buf might have been mangled a bit, so let's restore it to its -- cgit 1.4.1 From a74561b0e7434282ad214ca634b5c19c2f345e8e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 5 Apr 2023 12:12:05 +0200 Subject: implement switch mode --- include/afl-fuzz.h | 6 +++--- src/afl-fuzz-bitmap.c | 12 ++++++++++++ src/afl-fuzz-state.c | 2 +- src/afl-fuzz.c | 30 ++++++++++++++++++++++++++---- 4 files changed, 42 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 6573eabf..23a04f42 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -491,8 +491,7 @@ typedef struct afl_state { *infoexec; /* Command to execute on a new crash */ u32 hang_tmout, /* Timeout used for hang det (ms) */ - stats_update_freq, /* Stats update frequency (execs) */ - switch_fuzz_mode; /* auto or fixed fuzz mode */ + stats_update_freq; /* Stats update frequency (execs) */ u8 havoc_stack_pow2, /* HAVOC_STACK_POW2 */ no_unlink, /* do not unlink cur_input */ @@ -592,7 +591,8 @@ typedef struct afl_state { last_hang_time, /* Time for most recent hang (ms) */ longest_find_time, /* Longest time taken for a find */ exit_on_time, /* Delay to exit if no new paths */ - sync_time; /* Sync time (ms) */ + sync_time, /* Sync time (ms) */ + switch_fuzz_mode; /* auto or fixed fuzz mode */ u32 slowest_exec_ms, /* Slowest testcase non hang in ms */ subseq_tmouts; /* Number of timeouts in a row */ diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index d9c792d1..a937c96d 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -529,6 +529,18 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { close(fd); add_to_queue(afl, queue_fn, len, 0); + if (unlikely(afl->fuzz_mode) && likely(afl->switch_fuzz_mode)) { + + if (afl->afl_env.afl_no_ui) { + + ACTF("New coverage found, switching back to exploration mode."); + + } + + afl->fuzz_mode = 0; + + } + #ifdef INTROSPECTION if (afl->custom_mutators_count && afl->current_custom_fuzz) { diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 907861e9..9dc258b1 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -108,7 +108,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->cmplog_lvl = 2; afl->min_length = 1; afl->max_length = MAX_FILE; - afl->switch_fuzz_mode = STRATEGY_SWITCH_TIME; + afl->switch_fuzz_mode = STRATEGY_SWITCH_TIME * 1000; #ifndef NO_SPLICING afl->use_splicing = 1; #endif diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 315107d7..c50b271b 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -577,7 +577,7 @@ int main(int argc, char **argv_orig, char **envp) { if (!stricmp(optarg, "explore") || !stricmp(optarg, "exploration")) { afl->fuzz_mode = 0; - afl->switch_fuzz_mode = 1; + afl->switch_fuzz_mode = 0; } else if (!stricmp(optarg, "exploit") || @@ -588,12 +588,16 @@ int main(int argc, char **argv_orig, char **envp) { } else { - if ((s32)(afl->switch_fuzz_mode = (u32)atoi(optarg)) < 1) { + if ((afl->switch_fuzz_mode = (u32)atoi(optarg)) > INT_MAX) { FATAL( "Parameter for option -P must be \"explore\", \"exploit\" or a " "number!"); + } else { + + afl->switch_fuzz_mode *= 1000; + } } @@ -2689,13 +2693,31 @@ int main(int argc, char **argv_orig, char **envp) { } while (skipped_fuzz && afl->queue_cur && !afl->stop_soon); + u64 cur_time = get_cur_time(); + + if (likely(afl->switch_fuzz_mode && afl->fuzz_mode == 0) && + unlikely(cur_time > afl->last_find_time + afl->switch_fuzz_mode)) { + + if (afl->afl_env.afl_no_ui) { + + ACTF( + "No new coverage found for %llu seconds, switching to exploitation " + "strategy.", + afl->switch_fuzz_mode / 1000); + + } + + afl->fuzz_mode = 1; + + } + if (likely(!afl->stop_soon && afl->sync_id)) { if (likely(afl->skip_deterministic)) { if (unlikely(afl->is_main_node)) { - if (unlikely(get_cur_time() > + if (unlikely(cur_time > (afl->sync_time >> 1) + afl->last_sync_time)) { if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) { @@ -2708,7 +2730,7 @@ int main(int argc, char **argv_orig, char **envp) { } else { - if (unlikely(get_cur_time() > afl->sync_time + afl->last_sync_time)) { + if (unlikely(cur_time > afl->sync_time + afl->last_sync_time)) { if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); } -- cgit 1.4.1 From fcb5eda5d0eb38b1a9678ee75890f2fccf936bd9 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 5 Apr 2023 16:34:08 +0200 Subject: nit --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index c50b271b..bc44367a 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -562,7 +562,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->shmem_testcase_mode = 1; // we always try to perform shmem fuzzing - // still available: aHjJkKPqruvwz + // still available: HjJkKqruvwz while ((opt = getopt(argc, argv, "+aAb:B:c:CdDe:E:f:F:g:G:hi:I:l:L:m:M:nNo:Op:P:QRs:S:t:" "T:UV:WXx:YZ")) > 0) { -- cgit 1.4.1 From 400c5e92cb5ed304a2c14a79597100850cf9f82c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 7 Apr 2023 09:41:22 +0200 Subject: renaming --- include/afl-mutations.h | 166 ++++++++++++++++++++++++------------------------ src/afl-fuzz-one.c | 30 +++++---- 2 files changed, 99 insertions(+), 97 deletions(-) (limited to 'src') diff --git a/include/afl-mutations.h b/include/afl-mutations.h index cc913fb0..8d40855d 100644 --- a/include/afl-mutations.h +++ b/include/afl-mutations.h @@ -52,8 +52,8 @@ enum { /* 14 */ MUT_ARITH32, /* 15 */ MUT_ARITH32BE, /* 16 */ MUT_RAND8, - /* 17 */ MUT_CLONE_OVERWRITE, - /* 18 */ MUT_CLONE_INSERT, + /* 17 */ MUT_CLONE_COPY, + /* 18 */ MUT_CLONE_FIXED, /* 19 */ MUT_OVERWRITE_COPY, /* 20 */ MUT_OVERWRITE_FIXED, /* 21 */ MUT_BYTEADD, @@ -176,29 +176,29 @@ u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = { MUT_RAND8, MUT_RAND8, MUT_RAND8, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, MUT_OVERWRITE_COPY, MUT_OVERWRITE_COPY, MUT_OVERWRITE_COPY, @@ -446,28 +446,28 @@ u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = { MUT_RAND8, MUT_RAND8, MUT_RAND8, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, MUT_OVERWRITE_COPY, MUT_OVERWRITE_COPY, MUT_OVERWRITE_COPY, @@ -716,23 +716,23 @@ u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = { MUT_RAND8, MUT_RAND8, MUT_RAND8, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, MUT_OVERWRITE_COPY, MUT_OVERWRITE_COPY, MUT_OVERWRITE_COPY, @@ -979,23 +979,23 @@ u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = { MUT_RAND8, MUT_RAND8, MUT_RAND8, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_OVERWRITE, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, - MUT_CLONE_INSERT, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, MUT_OVERWRITE_COPY, MUT_OVERWRITE_COPY, MUT_OVERWRITE_COPY, @@ -1455,7 +1455,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps, } - case MUT_CLONE_OVERWRITE: { + case MUT_CLONE_COPY: { if (likely(len + HAVOC_BLK_XL < max_len)) { @@ -1494,7 +1494,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps, } - case MUT_CLONE_INSERT: { + case MUT_CLONE_FIXED: { if (likely(len + HAVOC_BLK_XL < max_len)) { diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index e6ff1d1a..f5ddea0e 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2481,7 +2481,7 @@ havoc_stage: } - case MUT_CLONE_OVERWRITE: { + case MUT_CLONE_COPY: { if (likely(temp_len + HAVOC_BLK_XL < MAX_FILE)) { @@ -2493,7 +2493,7 @@ havoc_stage: #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s_%u_%u_%u", - "overwrite", clone_from, clone_to, clone_len); + "COPY", clone_from, clone_to, clone_len); strcat(afl->mutation, afl->m_tmp); #endif u8 *new_buf = @@ -2530,7 +2530,7 @@ havoc_stage: } - case MUT_CLONE_INSERT: { + case MUT_CLONE_FIXED: { if (likely(temp_len + HAVOC_BLK_XL < MAX_FILE)) { @@ -2544,7 +2544,7 @@ havoc_stage: #ifdef INTROSPECTION snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s_%u_%u_%u", - "insert", strat, clone_to, clone_len); + "FIXED", strat, clone_to, clone_len); strcat(afl->mutation, afl->m_tmp); #endif u8 *new_buf = @@ -2587,20 +2587,22 @@ havoc_stage: if (unlikely(temp_len < 2)) { break; } // no retry - u32 copy_len = choose_block_len(afl, temp_len - 1); - u32 copy_from = rand_below(afl, temp_len - copy_len + 1); - u32 copy_to = rand_below(afl, temp_len - copy_len + 1); + u32 copy_from, copy_to, + copy_len = choose_block_len(afl, temp_len - 1); + + do { - if (likely(copy_from != copy_to)) { + copy_from = rand_below(afl, temp_len - copy_len + 1); + copy_to = rand_below(afl, temp_len - copy_len + 1); + + } while (unlikely(copy_from == copy_to)); #ifdef INTROSPECTION - snprintf(afl->m_tmp, sizeof(afl->m_tmp), " OVERWRITE-COPY_%u_%u_%u", - copy_from, copy_to, copy_len); - strcat(afl->mutation, afl->m_tmp); + snprintf(afl->m_tmp, sizeof(afl->m_tmp), " OVERWRITE-COPY_%u_%u_%u", + copy_from, copy_to, copy_len); + strcat(afl->mutation, afl->m_tmp); #endif - memmove(out_buf + copy_to, out_buf + copy_from, copy_len); - - } + memmove(out_buf + copy_to, out_buf + copy_from, copy_len); break; -- cgit 1.4.1 From 8de7f6131d48e27d53e894b65bd11e0dc3817639 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 6 Jun 2023 13:12:31 +0200 Subject: add current mutation strategy to include --- include/afl-mutations.h | 161 ++++++++++++++++++++++++++++++++++++++++++++++++ src/afl-fuzz-one.c | 7 ++- 2 files changed, 166 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/include/afl-mutations.h b/include/afl-mutations.h index 8d40855d..08037b09 100644 --- a/include/afl-mutations.h +++ b/include/afl-mutations.h @@ -77,6 +77,167 @@ enum { }; + #define MUT_NORMAL_ARRAY_SIZE 77 +u32 normal_splice[MUT_NORMAL_ARRAY_SIZE] = {MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_FIXED, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_FIXED, + MUT_BYTEADD, + MUT_BYTESUB, + MUT_FLIP8, + MUT_SWITCH, + MUT_SWITCH, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT}; + #define MUT_SPLICE_ARRAY_SIZE 81 +u32 full_splice_array[MUT_SPLICE_ARRAY_SIZE] = {MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_FIXED, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_FIXED, + MUT_BYTEADD, + MUT_BYTESUB, + MUT_FLIP8, + MUT_SWITCH, + MUT_SWITCH, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT}; + u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = { MUT_FLIPBIT, diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index f5ddea0e..312e180d 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2076,7 +2076,7 @@ havoc_stage: where we take the input file and make random stacked tweaks. */ u32 *mutation_array; - u32 stack_max, stack_max_pow = afl->havoc_stack_pow2; + u32 stack_max; // stack_max_pow = afl->havoc_stack_pow2; if (unlikely(afl->text_input || afl->queue_cur->is_ascii)) { // is text? @@ -2104,6 +2104,7 @@ havoc_stage: } + /* if (temp_len < 64) { --stack_max_pow; @@ -2118,7 +2119,9 @@ havoc_stage: } - stack_max = 1 << stack_max_pow; + */ + + stack_max = 1 << (1 + rand_below(afl, afl->havoc_stack_pow2)); // + (afl->extras_cnt ? 2 : 0) + (afl->a_extras_cnt ? 2 : 0); -- cgit 1.4.1 From 14e25340fb7b9e13357a9059dd1c128a2d7d9d5b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 6 Jun 2023 16:55:32 +0200 Subject: comparison --- include/afl-mutations.h | 155 ++++++++++++++++++++++++------------------------ src/afl-fuzz-one.c | 43 +++++++++----- 2 files changed, 107 insertions(+), 91 deletions(-) (limited to 'src') diff --git a/include/afl-mutations.h b/include/afl-mutations.h index 08037b09..a3c9fd59 100644 --- a/include/afl-mutations.h +++ b/include/afl-mutations.h @@ -78,83 +78,84 @@ enum { }; #define MUT_NORMAL_ARRAY_SIZE 77 -u32 normal_splice[MUT_NORMAL_ARRAY_SIZE] = {MUT_FLIPBIT, - MUT_FLIPBIT, - MUT_FLIPBIT, - MUT_FLIPBIT, - MUT_INTERESTING8, - MUT_INTERESTING8, - MUT_INTERESTING8, - MUT_INTERESTING8, - MUT_INTERESTING16, - MUT_INTERESTING16, - MUT_INTERESTING16BE, - MUT_INTERESTING16BE, - MUT_INTERESTING32, - MUT_INTERESTING32, - MUT_INTERESTING32BE, - MUT_INTERESTING32BE, - MUT_ARITH8_, - MUT_ARITH8_, - MUT_ARITH8_, - MUT_ARITH8_, - MUT_ARITH8, - MUT_ARITH8, - MUT_ARITH8, - MUT_ARITH8, - MUT_ARITH16_, - MUT_ARITH16_, - MUT_ARITH16BE_, - MUT_ARITH16BE_, - MUT_ARITH16, - MUT_ARITH16, - MUT_ARITH16BE, - MUT_ARITH16BE, - MUT_ARITH32_, - MUT_ARITH32_, - MUT_ARITH32BE_, - MUT_ARITH32BE_, - MUT_ARITH32, - MUT_ARITH32, - MUT_ARITH32BE, - MUT_ARITH32BE, - MUT_RAND8, - MUT_RAND8, - MUT_RAND8, - MUT_RAND8, - MUT_CLONE_COPY, - MUT_CLONE_COPY, - MUT_CLONE_COPY, - MUT_CLONE_FIXED, - MUT_OVERWRITE_COPY, - MUT_OVERWRITE_COPY, - MUT_OVERWRITE_COPY, - MUT_OVERWRITE_FIXED, - MUT_BYTEADD, - MUT_BYTESUB, - MUT_FLIP8, - MUT_SWITCH, - MUT_SWITCH, - MUT_DEL, - MUT_DEL, - MUT_DEL, - MUT_DEL, - MUT_DEL, - MUT_DEL, - MUT_DEL, - MUT_DEL, - MUT_EXTRA_OVERWRITE, - MUT_EXTRA_OVERWRITE, - MUT_EXTRA_INSERT, - MUT_EXTRA_INSERT, - MUT_AUTO_EXTRA_OVERWRITE, - MUT_AUTO_EXTRA_OVERWRITE, - MUT_AUTO_EXTRA_INSERT, - MUT_AUTO_EXTRA_INSERT, - MUT_SPLICE_OVERWRITE, - MUT_SPLICE_OVERWRITE, - MUT_SPLICE_INSERT, - MUT_SPLICE_INSERT}; +u32 normal_splice_array[MUT_NORMAL_ARRAY_SIZE] = {MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_FIXED, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_FIXED, + MUT_BYTEADD, + MUT_BYTESUB, + MUT_FLIP8, + MUT_SWITCH, + MUT_SWITCH, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT}; + #define MUT_SPLICE_ARRAY_SIZE 81 u32 full_splice_array[MUT_SPLICE_ARRAY_SIZE] = {MUT_FLIPBIT, MUT_FLIPBIT, diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index ec348a95..9d4b366e 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2081,33 +2081,48 @@ havoc_stage: where we take the input file and make random stacked tweaks. */ u32 *mutation_array; - u32 stack_max; // stack_max_pow = afl->havoc_stack_pow2; + u32 stack_max, rand_max; // stack_max_pow = afl->havoc_stack_pow2; - if (unlikely(afl->text_input || afl->queue_cur->is_ascii)) { // is text? + if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) { - if (likely(afl->fuzz_mode == 0)) { // is exploration? + mutation_array = full_splice_array; + rand_max = MUT_SPLICE_ARRAY_SIZE; - mutation_array = (unsigned int *)&mutation_strategy_exploration_text; + } else { - } else { // is exploitation! + mutation_array = normal_splice_array; + rand_max = MUT_NORMAL_ARRAY_SIZE; - mutation_array = (unsigned int *)&mutation_strategy_exploitation_text; + } - } + /* + if (unlikely(afl->text_input || afl->queue_cur->is_ascii)) { // is text? + + if (likely(afl->fuzz_mode == 0)) { // is exploration? + + mutation_array = (unsigned int *)&mutation_strategy_exploration_text; + + } else { // is exploitation! - } else { // is binary! + mutation_array = (unsigned int *)&mutation_strategy_exploitation_text; - if (likely(afl->fuzz_mode == 0)) { // is exploration? + } + + } else { // is binary! - mutation_array = (unsigned int *)&mutation_strategy_exploration_binary; + if (likely(afl->fuzz_mode == 0)) { // is exploration? - } else { // is exploitation! + mutation_array = (unsigned int *)&mutation_strategy_exploration_binary; - mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary; + } else { // is exploitation! + + mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary; + + } } - } + */ /* if (temp_len < 64) { @@ -2180,7 +2195,7 @@ havoc_stage: retry_havoc_step : { - u32 r = rand_below(afl, MUT_STRATEGY_ARRAY_SIZE), item; + u32 r = rand_below(afl, rand_max), item; switch (mutation_array[r]) { -- cgit 1.4.1 From c7c6ad1a94810fc4c24fbf05bcdd7f9cf806646e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 6 Jun 2023 17:04:31 +0200 Subject: no_ui mode --- src/afl-fuzz-one.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index ec348a95..9685885b 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -402,10 +402,11 @@ u8 fuzz_one_original(afl_state_t *afl) { if (unlikely(afl->not_on_tty)) { ACTF( - "Fuzzing test case #%u (%u total, %llu crashes saved, " + "Fuzzing test case #%u (%u total, %llu crashes saved, mode=%s, " "perf_score=%0.0f, weight=%0.0f, favorite=%u, was_fuzzed=%u, " "exec_us=%llu, hits=%u, map=%u, ascii=%u)...", afl->current_entry, afl->queued_items, afl->saved_crashes, + afl->fuzz_mode ? "exploit" : "explore", afl->queue_cur->perf_score, afl->queue_cur->weight, afl->queue_cur->favored, afl->queue_cur->was_fuzzed, afl->queue_cur->exec_us, -- cgit 1.4.1 From c28779adc543ffd3c68696867eef0f719ecee9d4 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 8 Jun 2023 12:32:51 +0200 Subject: show fuzzing state --- include/afl-fuzz.h | 1 + src/afl-fuzz-one.c | 5 +++-- src/afl-fuzz-stats.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 47 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index e1359dc8..c6c45fbd 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -1202,6 +1202,7 @@ u8 check_if_text_buf(u8 *buf, u32 len); #ifndef AFL_SHOWMAP void setup_signal_handlers(void); #endif +char *get_fuzzing_state(afl_state_t *afl); /* CmpLog */ diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 9685885b..af5e57a0 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -402,11 +402,12 @@ u8 fuzz_one_original(afl_state_t *afl) { if (unlikely(afl->not_on_tty)) { ACTF( - "Fuzzing test case #%u (%u total, %llu crashes saved, mode=%s, " + "Fuzzing test case #%u (%u total, %llu crashes saved, state: %s, " + "mode=%s, " "perf_score=%0.0f, weight=%0.0f, favorite=%u, was_fuzzed=%u, " "exec_us=%llu, hits=%u, map=%u, ascii=%u)...", afl->current_entry, afl->queued_items, afl->saved_crashes, - afl->fuzz_mode ? "exploit" : "explore", + get_fuzzing_state(afl), afl->fuzz_mode ? "exploit" : "explore", afl->queue_cur->perf_score, afl->queue_cur->weight, afl->queue_cur->favored, afl->queue_cur->was_fuzzed, afl->queue_cur->exec_us, diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 4ffb2536..9a60fd47 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -27,6 +27,45 @@ #include "envs.h" #include +static char fuzzing_state[4][12] = {"started :-)", "in progress", "final phase", + "finished..."}; + +char *get_fuzzing_state(afl_state_t *afl) { + + u64 cur_ms = get_cur_time(); + u64 last_find = cur_ms - afl->last_find_time; + u64 cur_run_time = cur_ms - afl->start_time; + u64 cur_total_run_time = afl->prev_run_time + cur_run_time; + + if (unlikely(cur_run_time < 60 * 3 * 1000 || + cur_total_run_time < 60 * 5 * 1000)) { + + return fuzzing_state[0]; + + } else { + + u64 last_find_100 = 100 * last_find; + u64 percent_cur = last_find_100 / cur_run_time; + u64 percent_total = last_find_100 / cur_total_run_time; + + if (unlikely(percent_cur >= 90 && percent_total >= 90)) { + + return fuzzing_state[3]; + + } else if (unlikely(percent_cur >= 75 && percent_total >= 75)) { + + return fuzzing_state[2]; + + } else { + + return fuzzing_state[1]; + + } + + } + +} + /* Write fuzzer setup file */ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { @@ -1283,9 +1322,10 @@ void show_stats_normal(afl_state_t *afl) { /* Last line */ - SAYF(SET_G1 "\n" bSTG bLB bH cCYA bSTOP - " strategy:%s %s " bSTG bH20 bH10 bH2 bRB bSTOP cRST RESET_G1, - cPIN, afl->fuzz_mode == 0 ? "explore" : "exploit"); + SAYF(SET_G1 "\n" bSTG bLB bH cCYA bSTOP " strategy:" cPIN + " %s " bSTG bH10 cCYA bSTOP " state:" cPIN + " %s " bSTG bH2 bRB bSTOP cRST RESET_G1, + afl->fuzz_mode == 0 ? "explore" : "exploit", get_fuzzing_state(afl)); #undef IB -- cgit 1.4.1 From 6ec70fc0847a0624692e868743080bf4e6935523 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 9 Jun 2023 09:33:33 +0200 Subject: binary mutations --- src/afl-fuzz-one.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index e722f0c6..816384fd 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2085,6 +2085,8 @@ havoc_stage: u32 *mutation_array; u32 stack_max, rand_max; // stack_max_pow = afl->havoc_stack_pow2; + /* + if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) { mutation_array = full_splice_array; @@ -2097,6 +2099,8 @@ havoc_stage: } + */ + /* if (unlikely(afl->text_input || afl->queue_cur->is_ascii)) { // is text? @@ -2112,15 +2116,21 @@ havoc_stage: } else { // is binary! - if (likely(afl->fuzz_mode == 0)) { // is exploration? + */ - mutation_array = (unsigned int *)&mutation_strategy_exploration_binary; + rand_max = MUT_STRATEGY_ARRAY_SIZE; - } else { // is exploitation! + if (likely(afl->fuzz_mode == 0)) { // is exploration? - mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary; + mutation_array = (unsigned int *)&mutation_strategy_exploration_binary; - } + } else { // is exploitation! + + mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary; + + } + + /* } -- cgit 1.4.1 From 25eba95bbaf58539c65088fc8bc143ed30ad82b9 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 12 Jun 2023 08:43:30 +0200 Subject: update new feature config --- include/config.h | 2 +- src/afl-fuzz-stats.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/include/config.h b/include/config.h index b767d526..09d8620d 100644 --- a/include/config.h +++ b/include/config.h @@ -47,7 +47,7 @@ switches to exploitation mode. It automatically switches back when new coverage is found. Default: 300 (seconds) */ -#define STRATEGY_SWITCH_TIME 300 +#define STRATEGY_SWITCH_TIME 600 /* Default file permission umode when creating files (default: 0600) */ #define DEFAULT_PERMISSION 0600 diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 9a60fd47..1499a7e4 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -48,11 +48,11 @@ char *get_fuzzing_state(afl_state_t *afl) { u64 percent_cur = last_find_100 / cur_run_time; u64 percent_total = last_find_100 / cur_total_run_time; - if (unlikely(percent_cur >= 90 && percent_total >= 90)) { + if (unlikely(percent_cur >= 80 && percent_total >= 80)) { return fuzzing_state[3]; - } else if (unlikely(percent_cur >= 75 && percent_total >= 75)) { + } else if (unlikely(percent_cur >= 55 && percent_total >= 55)) { return fuzzing_state[2]; -- cgit 1.4.1 From ed97dbacef98c379d7028514a43c799c86050584 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 12 Jun 2023 09:13:24 +0200 Subject: enable text mode --- src/afl-fuzz-one.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 816384fd..4efc661e 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2101,40 +2101,33 @@ havoc_stage: */ - /* - if (unlikely(afl->text_input || afl->queue_cur->is_ascii)) { // is text? - - if (likely(afl->fuzz_mode == 0)) { // is exploration? + rand_max = MUT_STRATEGY_ARRAY_SIZE; - mutation_array = (unsigned int *)&mutation_strategy_exploration_text; + if (unlikely(afl->text_input /*|| afl->queue_cur->is_ascii*/)) { // is text? - } else { // is exploitation! + if (likely(afl->fuzz_mode == 0)) { // is exploration? - mutation_array = (unsigned int *)&mutation_strategy_exploitation_text; + mutation_array = (unsigned int *)&mutation_strategy_exploration_text; - } + } else { // is exploitation! - } else { // is binary! + mutation_array = (unsigned int *)&mutation_strategy_exploitation_text; - */ - - rand_max = MUT_STRATEGY_ARRAY_SIZE; - - if (likely(afl->fuzz_mode == 0)) { // is exploration? + } - mutation_array = (unsigned int *)&mutation_strategy_exploration_binary; + } else { // is binary! - } else { // is exploitation! + if (likely(afl->fuzz_mode == 0)) { // is exploration? - mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary; + mutation_array = (unsigned int *)&mutation_strategy_exploration_binary; - } + } else { // is exploitation! - /* + mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary; } - */ + } /* if (temp_len < 64) { -- cgit 1.4.1 From a36034424779d8c9769819ee525b321bfd64a26c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 14 Jun 2023 13:11:44 +0200 Subject: minor cmplog bugfix --- TODO.md | 1 - src/afl-fuzz-redqueen.c | 12 +++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/TODO.md b/TODO.md index 26e12cee..7968452e 100644 --- a/TODO.md +++ b/TODO.md @@ -3,7 +3,6 @@ ## Should - afl-crash-analysis - - show in the UI when fuzzing is "done" - test cmplog for less than 16bit - support persistent and deferred fork server in afl-showmap? - better autodetection of shifting runtime timeout values diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 41644cb9..73e188e7 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1988,10 +1988,10 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, if (l0 >= 0x80 || ol0 >= 0x80) { - l0 -= 0x80; - l1 -= 0x80; - ol0 -= 0x80; - ol1 -= 0x80; + if (l0 >= 0x80) { l0 -= 0x80; } + if (l1 >= 0x80) { l1 -= 0x80; } + if (ol0 >= 0x80) { ol0 -= 0x80; } + if (ol1 >= 0x80) { ol1 -= 0x80; } } @@ -2059,7 +2059,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, for (i = 0; i < its_len; ++i) { - if ((pattern[i] != buf[idx + i] && o_pattern[i] != orig_buf[idx + i]) || + if ((pattern[i] != buf[idx + i] || o_pattern[i] != orig_buf[idx + i]) || *status == 1) { break; @@ -2592,6 +2592,8 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, // shape_len), check_if_text_buf((u8 *)&o->v1, shape_len), v0_len, // o->v0, v1_len, o->v1); + // Note that this check differs from the line 1901, for RTN we are more + // opportunistic for adding to the dictionary than cmps if (!memcmp(o->v0, orig_o->v0, v0_len) || (!found_one || check_if_text_buf((u8 *)&o->v0, v0_len) == v0_len)) maybe_add_auto(afl, o->v0, v0_len); -- cgit 1.4.1 From 7b29f2cd244424c5385605d1302b68be44e432bc Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 20 Jun 2023 19:58:08 +0200 Subject: fix timeout for sessions restart and + usage --- docs/Changelog.md | 17 ++++++++++------- src/afl-fuzz-stats.c | 14 ++++++-------- src/afl-fuzz.c | 1 + 3 files changed, 17 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/docs/Changelog.md b/docs/Changelog.md index 70f38d05..4454456e 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -4,13 +4,16 @@ release of the tool. See README.md for the general instruction manual. ### Version ++4.08a (dev) - - new mutation engine: mutations that favor discovery more paths are prefered - until no new finds for 10 minutes then switching to mutations that favor - triggering crashes. Modes and switch time can be configured wie `-P`. - - new custom mutator that has the new afl++ engine (so it can easily - incorporated into new custom mutators), and also comes with a standalone - command line tool! See custom_mutators/aflpp/standalone/ - - display the state of the fuzzing run in the UI :-) + - afl-fuzz: + - new mutation engine: mutations that favor discovery more paths are + prefered until no new finds for 10 minutes then switching to mutations + that favor triggering crashes. Modes and switch time can be configured + with `-P`. + - new custom mutator that has the new afl++ engine (so it can easily + incorporated into new custom mutators), and also comes with a standalone + command line tool! See custom_mutators/aflpp/standalone/ + - display the state of the fuzzing run in the UI :-) + - fix timeout setting if '+' is used or a session is restarted ### Version ++4.07c (release) diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 1499a7e4..389b82fc 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -2303,7 +2303,12 @@ void show_init_stats(afl_state_t *afl) { stringify_int(IB(0), min_us), stringify_int(IB(1), max_us), stringify_int(IB(2), avg_us)); - if (afl->timeout_given != 1) { + if (afl->timeout_given == 3) { + + ACTF("Applying timeout settings from resumed session (%u ms).", + afl->fsrv.exec_tmout); + + } else if (afl->timeout_given != 1) { /* Figure out the appropriate timeout. The basic idea is: 5x average or 1x max, rounded up to EXEC_TM_ROUND ms and capped at 1 second. @@ -2345,13 +2350,6 @@ void show_init_stats(afl_state_t *afl) { afl->timeout_given = 1; - } else if (afl->timeout_given == 3) { - - ACTF("Applying timeout settings from resumed session (%u ms).", - afl->fsrv.exec_tmout); - - } else { - ACTF("-t option specified. We'll use an exec timeout of %u ms.", afl->fsrv.exec_tmout); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index d727fff5..9eabfae1 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -2362,6 +2362,7 @@ int main(int argc, char **argv_orig, char **envp) { max_ms = afl->queue_buf[entry]->exec_us; afl->fsrv.exec_tmout = max_ms; + afl->timeout_given = 1; } -- cgit 1.4.1 From 2366c00235692c9ae11921cf38e9f6fe3fb30142 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 21 Jun 2023 09:38:21 +0200 Subject: switch back to normal mutations --- src/afl-fuzz-one.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 4efc661e..32c05182 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2103,11 +2103,21 @@ havoc_stage: rand_max = MUT_STRATEGY_ARRAY_SIZE; - if (unlikely(afl->text_input /*|| afl->queue_cur->is_ascii*/)) { // is text? + if (unlikely(afl->text_input)) { // is text? if (likely(afl->fuzz_mode == 0)) { // is exploration? - mutation_array = (unsigned int *)&mutation_strategy_exploration_text; + if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) { + + mutation_array = full_splice_array; + rand_max = MUT_SPLICE_ARRAY_SIZE; + + } else { + + mutation_array = normal_splice_array; + rand_max = MUT_NORMAL_ARRAY_SIZE; + + } } else { // is exploitation! @@ -2119,7 +2129,17 @@ havoc_stage: if (likely(afl->fuzz_mode == 0)) { // is exploration? - mutation_array = (unsigned int *)&mutation_strategy_exploration_binary; + if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) { + + mutation_array = full_splice_array; + rand_max = MUT_SPLICE_ARRAY_SIZE; + + } else { + + mutation_array = normal_splice_array; + rand_max = MUT_NORMAL_ARRAY_SIZE; + + } } else { // is exploitation! -- cgit 1.4.1 From 936b6dcb5d7a93d2aa211d0812fd26ba0b2c7d3c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 21 Jun 2023 09:57:24 +0200 Subject: nits --- afl-cmin | 2 +- src/afl-fuzz-stats.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/afl-cmin b/afl-cmin index de76caf8..3e37dbdb 100755 --- a/afl-cmin +++ b/afl-cmin @@ -513,7 +513,7 @@ BEGIN { if (threads > 1) { - print "[*] Creating " threads " parallel tasks with about " inputsperfile " each." + print "[*] Creating " threads " parallel tasks with about " inputsperfile " items each." for (i = 1; i <= threads; i++) { if (!stdin_file) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 389b82fc..4013370d 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -2350,6 +2350,8 @@ void show_init_stats(afl_state_t *afl) { afl->timeout_given = 1; + } else { + ACTF("-t option specified. We'll use an exec timeout of %u ms.", afl->fsrv.exec_tmout); -- cgit 1.4.1 From 64b15a00f270f0ac9c00cf13e569481672227635 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 21 Jun 2023 12:20:10 +0200 Subject: fix afl-cmin* for old afl vanilla issue --- afl-cmin | 35 +++++++++++++++++++++++++++++------ afl-cmin.bash | 4 +++- docs/Changelog.md | 4 ++++ src/afl-showmap.c | 5 +++-- 4 files changed, 39 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/afl-cmin b/afl-cmin index 3e37dbdb..d0bbed2b 100755 --- a/afl-cmin +++ b/afl-cmin @@ -318,7 +318,9 @@ BEGIN { if (!nyx_mode && target_bin && !exists_and_is_executable(target_bin)) { - "command -v "target_bin" 2>/dev/null" | getline tnew + cmd = "command -v "target_bin" 2>/dev/null" + cmd | getline tnew + close(cmd) if (!tnew || !exists_and_is_executable(tnew)) { print "[-] Error: binary '"target_bin"' not found or not executable." > "/dev/stderr" exit 1 @@ -330,6 +332,7 @@ BEGIN { echo "[!] Trying to obtain the map size of the target ..." get_map_size = "AFL_DUMP_MAP_SIZE=1 " target_bin get_map_size | getline mapsize + close(get_map_size) if (mapsize && mapsize > 65535 && mapsize < 100000000) { AFL_MAP_SIZE = "AFL_MAP_SIZE="mapsize" " print "[+] Setting "AFL_MAP_SIZE @@ -359,14 +362,18 @@ BEGIN { system("rm -rf "trace_dir" 2>/dev/null"); system("rm "out_dir"/id[:_]* 2>/dev/null") - "ls "out_dir"/* 2>/dev/null | wc -l" | getline noofentries + cmd = "ls "out_dir"/* 2>/dev/null | wc -l" + cmd | getline noofentries + close(cmd) if (0 == system( "test -d "out_dir" -a "noofentries" -gt 0" )) { print "[-] Error: directory '"out_dir"' exists and is not empty - delete it first." > "/dev/stderr" exit 1 } if (threads) { - "nproc" | getline nproc + cmd = "nproc" + cmd | getline nproc + close(cmd) if (threads == "all") { threads = nproc } else { @@ -386,12 +393,14 @@ BEGIN { if (stdin_file) { # truncate input file printf "" > stdin_file - close( stdin_file ) + close(stdin_file) } # First we look in PATH if (0 == system("command -v afl-showmap >/dev/null 2>&1")) { - "command -v afl-showmap 2>/dev/null" | getline showmap + cmd = "command -v afl-showmap 2>/dev/null" + cmd | getline showmap + close(cmd) } else { # then we look in the current directory if (0 == system("test -x ./afl-showmap")) { @@ -413,7 +422,9 @@ BEGIN { # yuck, gnu stat is option incompatible to bsd stat # we use a heuristic to differentiate between # GNU stat and other stats - "stat --version 2>/dev/null" | getline statversion + cmd = "stat --version 2>/dev/null" + cmd | getline statversion + close(cmd) if (statversion ~ /GNU coreutils/) { stat_format = "-c '%s %n'" # GNU } else { @@ -432,6 +443,7 @@ BEGIN { infilesSmallToBigFullMap[infilesSmallToBigFull[i]] = infilesSmallToBig[i] i++ } + close(cmdline) in_count = i first_file = infilesSmallToBigFull[0] @@ -468,6 +480,7 @@ BEGIN { while ((getline < runtest) > 0) { ++first_count } + close(runtest) if (first_count) { print "[+] OK, "first_count" tuples recorded." @@ -582,6 +595,15 @@ BEGIN { else { print " Processing file "cur"/"in_count } # create path for the trace file from afl-showmap tracefile_path = trace_dir"/"fn + # ensure the file size is not zero + cmd = "du -b "tracefile_path + "ls -l "tracefile_path + cmd | getline output + close(cmd) + split(output, result, "\t") + if (result[1] == 0) { + print "[!] WARNING: file "fn" is crashing the target, ignoring..." + } # gather all keys, and count them while ((getline line < tracefile_path) > 0) { key = line @@ -643,6 +665,7 @@ BEGIN { } } close(sortedKeys) + print "" print "[+] Found "tuple_count" unique tuples across "in_count" files." if (out_count == 1) { diff --git a/afl-cmin.bash b/afl-cmin.bash index dc6d5342..1d080491 100755 --- a/afl-cmin.bash +++ b/afl-cmin.bash @@ -479,7 +479,7 @@ else echo "[+] all $THREADS running tasks completed." rm -f ${TMPFILE}* - echo trace dir files: $(ls $TRACE_DIR/*|wc -l) + #echo trace dir files: $(ls $TRACE_DIR/*|wc -l) fi @@ -523,6 +523,8 @@ ls -rS "$IN_DIR" | while read -r fn; do sed "s#\$# $fn#" "$TRACE_DIR/$fn" >>"$TRACE_DIR/.candidate_list" + test -s "$TRACE_DIR/$fn" || echo Warning: $fn is ignored because of crashing the target + done echo diff --git a/docs/Changelog.md b/docs/Changelog.md index 4454456e..246c3cac 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -14,6 +14,10 @@ command line tool! See custom_mutators/aflpp/standalone/ - display the state of the fuzzing run in the UI :-) - fix timeout setting if '+' is used or a session is restarted + - afl-cmin/afl-cmin.bash: + - fixed a bug inherited from vanilla AFL where a coverage of + map[123] = 11 would be the same as map[1123] = 1 + - warn on crashing inputs ### Version ++4.07c (release) diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 9c029035..13867fda 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -243,7 +243,8 @@ static void analyze_results(afl_forkserver_t *fsrv) { total += fsrv->trace_bits[i]; if (fsrv->trace_bits[i] > highest) highest = fsrv->trace_bits[i]; - if (!coverage_map[i]) { coverage_map[i] = 1; } + // if (!coverage_map[i]) { coverage_map[i] = 1; } + coverage_map[i] |= fsrv->trace_bits[i]; } @@ -328,7 +329,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { if (cmin_mode) { - fprintf(f, "%u%u\n", fsrv->trace_bits[i], i); + fprintf(f, "%u%03u\n", i, fsrv->trace_bits[i]); } else { -- cgit 1.4.1 From ec4ed66b1efd0953d42e6c7055a2b1cf766ff720 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 21 Jun 2023 13:51:02 +0200 Subject: nits --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 9eabfae1..8cf786af 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -164,7 +164,7 @@ static void usage(u8 *argv0, int more_help) { "\n" "Mutator settings:\n" - " -a - target expects ascii text input\n" + " -a - target expects ascii text input (prefer text mutators)\n" " -g minlength - set min length of generated fuzz input (default: 1)\n" " -G maxlength - set max length of generated fuzz input (default: " "%lu)\n" -- cgit 1.4.1 From 90f83c13d08f44fbf50036076a1772909c4d2c86 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 22 Jun 2023 09:24:00 +0200 Subject: remove dead code, code format --- .custom-format.py | 2 +- docs/Changelog.md | 3 ++ include/alloc-inl.h | 8 +++--- instrumentation/SanitizerCoveragePCGUARD.so.cc | 39 ++------------------------ qemu_mode/libqasan/dlmalloc.c | 2 +- src/afl-fuzz-init.c | 8 +++--- src/afl-fuzz.c | 3 +- utils/afl_network_proxy/afl-network-server.c | 2 +- 8 files changed, 19 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/.custom-format.py b/.custom-format.py index 1d5c8839..3521c05d 100755 --- a/.custom-format.py +++ b/.custom-format.py @@ -24,7 +24,7 @@ import importlib.metadata # string_re = re.compile('(\\"(\\\\.|[^"\\\\])*\\")') # TODO: for future use -CURRENT_LLVM = os.getenv('LLVM_VERSION', 15) +CURRENT_LLVM = os.getenv('LLVM_VERSION', 16) CLANG_FORMAT_BIN = os.getenv("CLANG_FORMAT_BIN", "") diff --git a/docs/Changelog.md b/docs/Changelog.md index 246c3cac..c850c43e 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -18,6 +18,9 @@ - fixed a bug inherited from vanilla AFL where a coverage of map[123] = 11 would be the same as map[1123] = 1 - warn on crashing inputs + - afl-cc + - fixed an off-by-one instrumentation of iselect, hurting coverage a bit. + Thanks to @amykweon for spotting and fixing! ### Version ++4.07c (release) diff --git a/include/alloc-inl.h b/include/alloc-inl.h index 1e9a192b..cff808b2 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -322,7 +322,7 @@ static inline void DFL_ck_free(void *mem) { static inline void *DFL_ck_realloc(void *orig, u32 size) { void *ret; - u32 old_size = 0; + u32 old_size = 0; if (!size) { @@ -392,7 +392,7 @@ static inline void *DFL_ck_realloc(void *orig, u32 size) { static inline u8 *DFL_ck_strdup(u8 *str) { void *ret; - u32 size; + u32 size; if (!str) return NULL; @@ -438,14 +438,14 @@ struct TRK_obj { void *ptr; char *file, *func; - u32 line; + u32 line; }; #ifdef AFL_MAIN struct TRK_obj *TRK[ALLOC_BUCKETS]; -u32 TRK_cnt[ALLOC_BUCKETS]; +u32 TRK_cnt[ALLOC_BUCKETS]; #define alloc_report() TRK_report() diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index d87af775..57b5d128 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -225,49 +225,18 @@ llvmGetPassPluginInfo() { } -#if LLVM_VERSION_MAJOR == 1 +#if LLVM_VERSION_MAJOR >= 16 PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M, ModuleAnalysisManager &MAM) { - ModuleSanitizerCoverageAFL ModuleSancov(Options); - auto &FAM = MAM.getResult(M).getManager(); - auto DTCallback = [&FAM](Function &F) -> const DominatorTree *{ - - return &FAM.getResult(F); - - }; - - auto PDTCallback = [&FAM](Function &F) -> const PostDominatorTree * { - - return &FAM.getResult(F); - - }; - - if (!ModuleSancov.instrumentModule(M, DTCallback, PDTCallback)) - return PreservedAnalyses::all(); - - PreservedAnalyses PA = PreservedAnalyses::none(); - // GlobalsAA is considered stateless and does not get invalidated unless - // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers - // make changes that require GlobalsAA to be invalidated. - PA.abandon(); - return PA; - -} - #else - #if LLVM_VERSION_MAJOR >= 16 -PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M, - ModuleAnalysisManager &MAM) { - - #else PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M, ModuleAnalysisManager &MAM) { - #endif +#endif ModuleSanitizerCoverageAFL ModuleSancov(Options); auto &FAM = MAM.getResult(M).getManager(); - auto DTCallback = [&FAM](Function &F) -> const DominatorTree * { + auto DTCallback = [&FAM](Function &F) -> const DominatorTree *{ return &FAM.getResult(F); @@ -285,8 +254,6 @@ PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M, } -#endif - std::pair ModuleSanitizerCoverageAFL::CreateSecStartEnd( Module &M, const char *Section, Type *Ty) { diff --git a/qemu_mode/libqasan/dlmalloc.c b/qemu_mode/libqasan/dlmalloc.c index 5d0b65ce..b459eb7b 100644 --- a/qemu_mode/libqasan/dlmalloc.c +++ b/qemu_mode/libqasan/dlmalloc.c @@ -1762,7 +1762,7 @@ static FORCEINLINE void *win32direct_mmap(size_t size) { static FORCEINLINE int win32munmap(void *ptr, size_t size) { MEMORY_BASIC_INFORMATION minfo; - char *cptr = (char *)ptr; + char *cptr = (char *)ptr; while (size) { diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 13802f40..24fd7077 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1542,8 +1542,8 @@ double get_runnable_processes(void) { processes well. */ FILE *f = fopen("/proc/stat", "r"); - u8 tmp[1024]; - u32 val = 0; + u8 tmp[1024]; + u32 val = 0; if (!f) { return 0; } @@ -2226,7 +2226,7 @@ void check_crash_handling(void) { *BSD, so we can just let it slide for now. */ s32 fd = open("/proc/sys/kernel/core_pattern", O_RDONLY); - u8 fchar; + u8 fchar; if (fd < 0) { return; } @@ -2365,7 +2365,7 @@ void check_cpu_governor(afl_state_t *afl) { FATAL("Suboptimal CPU scaling governor"); #elif defined __APPLE__ - u64 min = 0, max = 0; + u64 min = 0, max = 0; size_t mlen = sizeof(min); if (afl->afl_env.afl_skip_cpufreq) return; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 8cf786af..79b05da7 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -164,7 +164,8 @@ static void usage(u8 *argv0, int more_help) { "\n" "Mutator settings:\n" - " -a - target expects ascii text input (prefer text mutators)\n" + " -a - target expects ascii text input (prefer text " + "mutators)\n" " -g minlength - set min length of generated fuzz input (default: 1)\n" " -G maxlength - set max length of generated fuzz input (default: " "%lu)\n" diff --git a/utils/afl_network_proxy/afl-network-server.c b/utils/afl_network_proxy/afl-network-server.c index 7eb3d18e..95b0a551 100644 --- a/utils/afl_network_proxy/afl-network-server.c +++ b/utils/afl_network_proxy/afl-network-server.c @@ -173,7 +173,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) { } out_file = alloc_printf("%s/.afl-input-temp-%u", use_dir, getpid()); - fsrv->out_file = out_file; + fsrv->out_file = out_file; } -- cgit 1.4.1 From c2c27349c3d74f79ceb6cd3795862b21d90429ea Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 23 Jun 2023 17:08:21 +0200 Subject: new mutation weighting --- include/afl-mutations.h | 460 ++++++++++++++++++++++++++++++++++++++++++++++++ src/afl-fuzz-one.c | 30 +--- 2 files changed, 466 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/include/afl-mutations.h b/include/afl-mutations.h index a3c9fd59..cc4840c8 100644 --- a/include/afl-mutations.h +++ b/include/afl-mutations.h @@ -77,6 +77,466 @@ enum { }; + #define MUT_TXT_ARRAY_SIZE 200 +u32 text_array[MUT_TXT_ARRAY_SIZE] = {MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_FIXED, + MUT_OVERWRITE_FIXED, + MUT_OVERWRITE_FIXED, + MUT_OVERWRITE_FIXED, + MUT_OVERWRITE_FIXED, + MUT_BYTEADD, + MUT_BYTEADD, + MUT_BYTEADD, + MUT_BYTEADD, + MUT_BYTEADD, + MUT_BYTESUB, + MUT_BYTESUB, + MUT_BYTESUB, + MUT_BYTESUB, + MUT_BYTESUB, + MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, + MUT_SWITCH, + MUT_SWITCH, + MUT_SWITCH, + MUT_SWITCH, + MUT_SWITCH, + MUT_SWITCH, + MUT_SWITCH, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT}; + + #define MUT_BIN_ARRAY_SIZE 256 +u32 binary_array[MUT_BIN_ARRAY_SIZE] = {MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_INTERESTING32BE, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8_, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH8, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16BE_, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH16BE, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32BE_, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_ARITH32BE, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_RAND8, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_COPY, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_CLONE_FIXED, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_COPY, + MUT_OVERWRITE_FIXED, + MUT_OVERWRITE_FIXED, + MUT_OVERWRITE_FIXED, + MUT_OVERWRITE_FIXED, + MUT_OVERWRITE_FIXED, + MUT_BYTEADD, + MUT_BYTEADD, + MUT_BYTEADD, + MUT_BYTEADD, + MUT_BYTEADD, + MUT_BYTEADD, + MUT_BYTESUB, + MUT_BYTESUB, + MUT_BYTESUB, + MUT_BYTESUB, + MUT_BYTESUB, + MUT_BYTESUB, + MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, + MUT_FLIP8, + MUT_SWITCH, + MUT_SWITCH, + MUT_SWITCH, + MUT_SWITCH, + MUT_SWITCH, + MUT_SWITCH, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_DEL, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_OVERWRITE, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_EXTRA_INSERT, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_OVERWRITE, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_AUTO_EXTRA_INSERT, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_OVERWRITE, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT, + MUT_SPLICE_INSERT}; + #define MUT_NORMAL_ARRAY_SIZE 77 u32 normal_splice_array[MUT_NORMAL_ARRAY_SIZE] = {MUT_FLIPBIT, MUT_FLIPBIT, diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 32c05182..c6e49653 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2101,27 +2101,17 @@ havoc_stage: */ - rand_max = MUT_STRATEGY_ARRAY_SIZE; - if (unlikely(afl->text_input)) { // is text? if (likely(afl->fuzz_mode == 0)) { // is exploration? - if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) { - - mutation_array = full_splice_array; - rand_max = MUT_SPLICE_ARRAY_SIZE; - - } else { - - mutation_array = normal_splice_array; - rand_max = MUT_NORMAL_ARRAY_SIZE; - - } + mutation_array = (unsigned int *)&text_array; + rand_max = MUT_TXT_ARRAY_SIZE; } else { // is exploitation! mutation_array = (unsigned int *)&mutation_strategy_exploitation_text; + rand_max = MUT_STRATEGY_ARRAY_SIZE; } @@ -2129,21 +2119,13 @@ havoc_stage: if (likely(afl->fuzz_mode == 0)) { // is exploration? - if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) { - - mutation_array = full_splice_array; - rand_max = MUT_SPLICE_ARRAY_SIZE; - - } else { - - mutation_array = normal_splice_array; - rand_max = MUT_NORMAL_ARRAY_SIZE; - - } + mutation_array = (unsigned int *)&binary_array; + rand_max = MUT_BIN_ARRAY_SIZE; } else { // is exploitation! mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary; + rand_max = MUT_STRATEGY_ARRAY_SIZE; } -- cgit 1.4.1 From 32d5ccb92dd3f646db327d2b7c1ec5fa74b4d656 Mon Sep 17 00:00:00 2001 From: Siqi Chen Date: Tue, 27 Jun 2023 01:15:54 +0800 Subject: Increase the number of afl-cc supported params --- src/afl-cc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 9e56828c..58d44e5d 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -383,9 +383,11 @@ static u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0, have_o = 0, have_pic = 0, have_c = 0, partial_linking = 0, non_dash = 0; +#define MAX_PARAMS_NUM 2048 + static void process_params(u32 argc, char **argv) { - if (cc_par_cnt + argc >= 1024) { FATAL("Too many command line parameters"); } + if (cc_par_cnt + argc >= MAX_PARAMS_NUM) { FATAL("Too many command line parameters, please increase MAX_PARAMS_NUM."); } if (lto_mode && argc > 1) { @@ -679,7 +681,7 @@ static void process_params(u32 argc, char **argv) { static void edit_params(u32 argc, char **argv, char **envp) { - cc_params = ck_alloc(1024 * sizeof(u8 *)); + cc_params = ck_alloc(MAX_PARAMS_NUM * sizeof(u8 *)); if (lto_mode) { -- cgit 1.4.1 From 3e1d7941077b1457f702988063d6b9fdd9b80740 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 29 Jun 2023 16:57:20 +0200 Subject: update mutation strategy --- docs/Changelog.md | 4 +++- include/afl-fuzz.h | 59 +++++++++++++++++++++++++------------------------ include/afl-mutations.h | 6 ++--- src/afl-fuzz-one.c | 56 +++++++++++++++++++++++++++------------------- src/afl-fuzz.c | 26 +++++++++++++++++----- 5 files changed, 90 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/docs/Changelog.md b/docs/Changelog.md index e6b90d3d..ad58e99e 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -8,7 +8,8 @@ - new mutation engine: mutations that favor discovery more paths are prefered until no new finds for 10 minutes then switching to mutations that favor triggering crashes. Modes and switch time can be configured - with `-P`. + with `-P`. Also input mode for the target can be defined with `-a` to + be `text` or `binary` (defaults to `generic`) - new custom mutator that has the new afl++ engine (so it can easily incorporated into new custom mutators), and also comes with a standalone command line tool! See custom_mutators/aflpp/standalone/ @@ -23,6 +24,7 @@ Thanks to @amykweon for spotting and fixing! - @toka fixed a bug in laf-intel signed integer comparison splitting, thanks a lot!! + - more LLVM compatability - frida_mode: - support for long form instrumentation on x86_x64 and arm64 diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index c6c45fbd..9da5cc03 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -505,36 +505,37 @@ typedef struct afl_state { is_main_node, /* if this is the main node */ is_secondary_node, /* if this is a secondary instance */ pizza_is_served, /* pizza mode */ - text_input, /* target wants text inputs */ - fuzz_mode, /* current mode: coverage/exploration or crash/exploitation */ + input_mode, /* target wants text inputs */ + fuzz_mode, /* coverage/exploration or crash/exploitation mode */ schedule, /* Power schedule (default: EXPLORE)*/ - havoc_max_mult, skip_deterministic, /* Skip deterministic stages? */ - use_splicing, /* Recombine input files? */ - non_instrumented_mode, /* Run in non-instrumented mode? */ - score_changed, /* Scoring for favorites changed? */ - resuming_fuzz, /* Resuming an older fuzzing job? */ - timeout_given, /* Specific timeout given? */ - not_on_tty, /* stdout is not a tty */ - term_too_small, /* terminal dimensions too small */ - no_forkserver, /* Disable forkserver? */ - crash_mode, /* Crash mode! Yeah! */ - in_place_resume, /* Attempt in-place resume? */ - autoresume, /* Resume if afl->out_dir exists? */ - auto_changed, /* Auto-generated tokens changed? */ - no_cpu_meter_red, /* Feng shui on the status screen */ - no_arith, /* Skip most arithmetic ops */ - shuffle_queue, /* Shuffle input queue? */ - bitmap_changed, /* Time to update bitmap? */ - unicorn_mode, /* Running in Unicorn mode? */ - use_wine, /* Use WINE with QEMU mode */ - skip_requested, /* Skip request, via SIGUSR1 */ - run_over10m, /* Run time over 10 minutes? */ - persistent_mode, /* Running in persistent mode? */ - deferred_mode, /* Deferred forkserver mode? */ - fixed_seed, /* do not reseed */ - fast_cal, /* Try to calibrate faster? */ - disable_trim, /* Never trim in fuzz_one */ - shmem_testcase_mode, /* If sharedmem testcases are used */ + havoc_max_mult, /* havoc multiplier */ + skip_deterministic, /* Skip deterministic stages? */ + use_splicing, /* Recombine input files? */ + non_instrumented_mode, /* Run in non-instrumented mode? */ + score_changed, /* Scoring for favorites changed? */ + resuming_fuzz, /* Resuming an older fuzzing job? */ + timeout_given, /* Specific timeout given? */ + not_on_tty, /* stdout is not a tty */ + term_too_small, /* terminal dimensions too small */ + no_forkserver, /* Disable forkserver? */ + crash_mode, /* Crash mode! Yeah! */ + in_place_resume, /* Attempt in-place resume? */ + autoresume, /* Resume if afl->out_dir exists? */ + auto_changed, /* Auto-generated tokens changed? */ + no_cpu_meter_red, /* Feng shui on the status screen */ + no_arith, /* Skip most arithmetic ops */ + shuffle_queue, /* Shuffle input queue? */ + bitmap_changed, /* Time to update bitmap? */ + unicorn_mode, /* Running in Unicorn mode? */ + use_wine, /* Use WINE with QEMU mode */ + skip_requested, /* Skip request, via SIGUSR1 */ + run_over10m, /* Run time over 10 minutes? */ + persistent_mode, /* Running in persistent mode? */ + deferred_mode, /* Deferred forkserver mode? */ + fixed_seed, /* do not reseed */ + fast_cal, /* Try to calibrate faster? */ + disable_trim, /* Never trim in fuzz_one */ + shmem_testcase_mode, /* If sharedmem testcases are used */ expand_havoc, /* perform expensive havoc after no find */ cycle_schedules, /* cycle power schedules? */ old_seed_selection, /* use vanilla afl seed selection */ diff --git a/include/afl-mutations.h b/include/afl-mutations.h index cc4840c8..0a9bbbf4 100644 --- a/include/afl-mutations.h +++ b/include/afl-mutations.h @@ -14,14 +14,14 @@ Parameters: afl_state_t *afl - the *afl state pointer u8 *buf - the input buffer to mutate which will be mutated into. - NOTE: must be able to contain a size of at least max_len (see below)! + NOTE: must be able to contain a size of at least max_len!! (see below) u32 len - the length of the input u32 steps - how many mutations to perform on the input bool is_text - is the target expecting text inputs bool is_exploration - mutate for exploration mode (instead of exploitation) splice_buf - a buffer from another corpus item to splice with. - If NULL then no splicing - splice_len - the length of the splice buffer. If 0 then no splicing + If NULL then no splicing is done (obviously). + splice_len - the length of the splice buffer. If 0 then no splicing. u32 max_len - the maximum size the mutated buffer may grow to */ diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index c6e49653..0d3c29f2 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2085,47 +2085,57 @@ havoc_stage: u32 *mutation_array; u32 stack_max, rand_max; // stack_max_pow = afl->havoc_stack_pow2; - /* + switch (afl->input_mode) { - if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) { + case 1: { // TEXT - mutation_array = full_splice_array; - rand_max = MUT_SPLICE_ARRAY_SIZE; + if (likely(afl->fuzz_mode == 0)) { // is exploration? + mutation_array = (unsigned int *)&binary_array; + rand_max = MUT_BIN_ARRAY_SIZE; - } else { + } else { // exploitation mode - mutation_array = normal_splice_array; - rand_max = MUT_NORMAL_ARRAY_SIZE; + mutation_array = (unsigned int *)&mutation_strategy_exploitation_text; + rand_max = MUT_STRATEGY_ARRAY_SIZE; - } + } - */ + break; - if (unlikely(afl->text_input)) { // is text? + } - if (likely(afl->fuzz_mode == 0)) { // is exploration? + case 2: { // BINARY - mutation_array = (unsigned int *)&text_array; - rand_max = MUT_TXT_ARRAY_SIZE; + if (likely(afl->fuzz_mode == 0)) { // is exploration? + mutation_array = (unsigned int *)&mutation_strategy_exploration_binary; + rand_max = MUT_STRATEGY_ARRAY_SIZE; - } else { // is exploitation! + } else { // exploitation mode - mutation_array = (unsigned int *)&mutation_strategy_exploitation_text; - rand_max = MUT_STRATEGY_ARRAY_SIZE; + mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary; + rand_max = MUT_STRATEGY_ARRAY_SIZE; + + } + + break; } - } else { // is binary! + default: { // DEFAULT/GENERIC - if (likely(afl->fuzz_mode == 0)) { // is exploration? + if (likely(afl->fuzz_mode == 0)) { // is exploration? + mutation_array = (unsigned int *)&binary_array; + rand_max = MUT_BIN_ARRAY_SIZE; - mutation_array = (unsigned int *)&binary_array; - rand_max = MUT_BIN_ARRAY_SIZE; + } else { // exploitation mode - } else { // is exploitation! + // this will need to be changed I guess + mutation_array = (unsigned int *)&mutation_strategy_exploration_text; + rand_max = MUT_STRATEGY_ARRAY_SIZE; + + } - mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary; - rand_max = MUT_STRATEGY_ARRAY_SIZE; + break; } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 79b05da7..ab7d6534 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -125,7 +125,8 @@ static void usage(u8 *argv0, int more_help) { "Required parameters:\n" " -i dir - input directory with test cases (or '-' to resume, " - "also see AFL_AUTORESUME)\n" + "also see \n" + " AFL_AUTORESUME)\n" " -o dir - output directory for fuzzer findings\n\n" "Execution control settings:\n" @@ -164,8 +165,8 @@ static void usage(u8 *argv0, int more_help) { "\n" "Mutator settings:\n" - " -a - target expects ascii text input (prefer text " - "mutators)\n" + " -a - target input format, \"text\" or \"binary\" (default: " + "generic)\n" " -g minlength - set min length of generated fuzz input (default: 1)\n" " -G maxlength - set max length of generated fuzz input (default: " "%lu)\n" @@ -506,13 +507,28 @@ int main(int argc, char **argv_orig, char **envp) { // still available: HjJkKqruvwz while ((opt = getopt(argc, argv, - "+aAb:B:c:CdDe:E:f:F:g:G:hi:I:l:L:m:M:nNo:Op:P:QRs:S:t:" + "+a:Ab:B:c:CdDe:E:f:F:g:G:hi:I:l:L:m:M:nNo:Op:P:QRs:S:t:" "T:UV:WXx:YZ")) > 0) { switch (opt) { case 'a': - afl->text_input = 1; + + if (!stricmp(optarg, "text") || !stricmp(optarg, "ascii") || + !stricmp(optarg, "txt") || !stricmp(optarg, "asc")) { + + afl->input_mode = 1; + + } else if (!stricmp(optarg, "bin") || !stricmp(optarg, "binary")) { + + afl->input_mode = 2; + + } else { + + FATAL("-a input mode needs to be \"text\" or \"binary\"."); + + } + break; case 'P': -- cgit 1.4.1