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(-) 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(-) 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(-) 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(-) 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(-) 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(-) 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(-) 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(-) 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(-) 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(-) 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 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 32ffa2664cdfa2cc377df12cbf6efdcecbc2e78a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 4 Apr 2023 16:23:19 +0200 Subject: max_len support --- custom_mutators/aflpp/aflpp.c | 27 +++++++++++++-- include/afl-mutations.h | 76 +++++++++++++++++++++++++++---------------- 2 files changed, 72 insertions(+), 31 deletions(-) diff --git a/custom_mutators/aflpp/aflpp.c b/custom_mutators/aflpp/aflpp.c index 2b69ad9c..e15d0391 100644 --- a/custom_mutators/aflpp/aflpp.c +++ b/custom_mutators/aflpp/aflpp.c @@ -4,6 +4,7 @@ typedef struct my_mutator { afl_state_t *afl; u8 *buf; + u32 buf_size; } my_mutator_t; @@ -19,12 +20,15 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { } - data->buf = malloc(MAX_FILE); - if (!data->buf) { + if ((data->buf = malloc(MAX_FILE)) == NULL) { perror("afl_custom_init alloc"); return NULL; + } else { + + data->buf_size = MAX_FILE; + } data->afl = afl; @@ -39,6 +43,23 @@ 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) { + if (max_size > data->buf_size) { + + u8 *ptr = realloc(data->buf, max_size); + + if (ptr) { + + return 0; + + } else { + + data->buf = ptr; + data->buf_size = max_size; + + } + + } + u32 havoc_steps = 1 + rand_below(data->afl, 16); /* set everything up, costly ... :( */ @@ -46,7 +67,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t 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); + false, true, add_buf, add_buf_size, max_size); /* return size of mutated data */ *out_buf = data->buf; diff --git a/include/afl-mutations.h b/include/afl-mutations.h index 43b7927d..e3f69214 100644 --- a/include/afl-mutations.h +++ b/include/afl-mutations.h @@ -6,7 +6,8 @@ #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); + bool is_exploration, u8 *splice_buf, u32 splice_len, + u32 max_len); Returns: u32 - the length of the mutated data return in *buf. 0 = error @@ -21,6 +22,7 @@ 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 + u32 max_len - the maximum size the mutated buffer may grow to */ #ifndef _ANDROID_ASHMEM_H @@ -76,16 +78,13 @@ enum { }; -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] = - {}; +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] = {}; -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); +u32 afl_mutate(afl_state_t *, u8 *, u32, u32, bool, bool, u8 *, u32, u32); +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. */ @@ -131,18 +130,39 @@ inline u32 choose_block_len(afl_state_t *afl, u32 limit) { } -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) { +inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps, + bool is_text, bool is_exploration, u8 *splice_buf, + u32 splice_len, u32 max_len) { if (!buf || !len) { return 0; } - u32 *mutation_array; - static unsigned char *tmp_buf = NULL; + u32 *mutation_array; + static u8 *tmp_buf = NULL; + static u32 tmp_buf_size = 0; - if (!tmp_buf) { + if (max_len > tmp_buf_size) { - if ((tmp_buf = malloc(MAX_FILE)) == NULL) { return 0; } + if (tmp_buf) { + + u8 *ptr = realloc(tmp_buf, max_len); + + if (!ptr) { + + return 0; + + } else { + + tmp_buf = ptr; + + } + + } else { + + if ((tmp_buf = malloc(max_len)) == NULL) { return 0; } + + } + + tmp_buf_size = max_len; } @@ -150,11 +170,11 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, if (is_exploration) { - mutation_array = (unsigned int *)&mutation_strategy_exploration_text; + mutation_array = (u32 *)&mutation_strategy_exploration_text; } else { - mutation_array = (unsigned int *)&mutation_strategy_exploitation_text; + mutation_array = (u32 *)&mutation_strategy_exploitation_text; } @@ -162,17 +182,17 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, if (is_exploration) { - mutation_array = (unsigned int *)&mutation_strategy_exploration_binary; + mutation_array = (u32 *)&mutation_strategy_exploration_binary; } else { - mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary; + mutation_array = (u32 *)&mutation_strategy_exploitation_binary; } } - for (unsigned int step = 0; step < steps; ++step) { + for (u32 step = 0; step < steps; ++step) { retry_havoc_step: @@ -400,7 +420,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, case MUT_CLONE_OVERWRITE: { - if (likely(len + HAVOC_BLK_XL < MAX_FILE)) { + if (likely(len + HAVOC_BLK_XL < max_len)) { /* Clone bytes. */ @@ -439,7 +459,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, case MUT_CLONE_INSERT: { - if (likely(len + HAVOC_BLK_XL < MAX_FILE)) { + if (likely(len + HAVOC_BLK_XL < max_len)) { /* Insert a block of constant bytes (25%). */ @@ -622,7 +642,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, } while (unlikely(i == j)); - unsigned char temp = buf[off + i]; + u8 temp = buf[off + i]; buf[off + i] = buf[off + j]; buf[off + j] = temp; @@ -872,7 +892,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, 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; } + if (unlikely(len + extra_len >= max_len)) { goto retry_havoc_step; } u8 *ptr = afl->extras[use_extra].data; u32 insert_at = rand_below(afl, len + 1); @@ -912,7 +932,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, 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; } + if (unlikely(len + extra_len >= max_len)) { goto retry_havoc_step; } u8 *ptr = afl->a_extras[use_extra].data; u32 insert_at = rand_below(afl, len + 1); @@ -952,7 +972,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len, if (unlikely(!splice_buf || !splice_len)) { goto retry_havoc_step; } - if (unlikely(len + HAVOC_BLK_XL >= MAX_FILE)) { goto retry_havoc_step; } + if (unlikely(len + HAVOC_BLK_XL >= max_len)) { goto retry_havoc_step; } /* insert mode */ -- cgit 1.4.1 From 2bff92c603463410fa0f97e7c4db7eb14c45e5ed Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 4 Apr 2023 16:25:05 +0200 Subject: nit --- include/afl-mutations.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/afl-mutations.h b/include/afl-mutations.h index e3f69214..707db799 100644 --- a/include/afl-mutations.h +++ b/include/afl-mutations.h @@ -14,7 +14,7 @@ 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! + 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 -- 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(-) 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 41a452d4e8038461f730736439346eb8a7a3968f Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 4 Apr 2023 21:48:51 +0200 Subject: mutation lists --- include/afl-mutations.h | 786 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 783 insertions(+), 3 deletions(-) diff --git a/include/afl-mutations.h b/include/afl-mutations.h index 5a1b6356..31d0898a 100644 --- a/include/afl-mutations.h +++ b/include/afl-mutations.h @@ -78,9 +78,789 @@ 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_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = { + + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_FLIPBIT, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING8, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING16BE, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32, + MUT_INTERESTING32, + 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_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_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_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_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_FLIP8, + MUT_SWITCH, + 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_SHUFFLE, + MUT_SHUFFLE, + MUT_SHUFFLE, + MUT_SHUFFLE, + MUT_SHUFFLE, + MUT_SHUFFLE, + MUT_SHUFFLE, + MUT_SHUFFLE, + MUT_DELONE, + MUT_DELONE, + 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_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_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_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_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, + +}; + +u32 mutation_strategy_exploration_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_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_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_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_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_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_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_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_DELONE, + MUT_INSERTONE, + MUT_INSERTONE, + MUT_INSERTONE, + MUT_INSERTONE, + MUT_INSERTONE, + MUT_INSERTONE, + MUT_ASCIINUM, + 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_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_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_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, + +}; + +u32 mutation_strategy_exploitation_text[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 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = { MUT_FLIPBIT, -- 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(-) 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(-) 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(-) 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(-) 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(-) 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(-) 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 d1ec5dc089ff29e596083a90fa64dcd77060e6bc Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 15 May 2023 15:11:16 +0200 Subject: standalone mutator --- custom_mutators/aflpp/standalone/Makefile | 10 ++ custom_mutators/aflpp/standalone/README.md | 10 ++ .../aflpp/standalone/aflpp-standalone.c | 167 +++++++++++++++++++++ 3 files changed, 187 insertions(+) create mode 100644 custom_mutators/aflpp/standalone/Makefile create mode 100644 custom_mutators/aflpp/standalone/README.md create mode 100644 custom_mutators/aflpp/standalone/aflpp-standalone.c diff --git a/custom_mutators/aflpp/standalone/Makefile b/custom_mutators/aflpp/standalone/Makefile new file mode 100644 index 00000000..f1e99445 --- /dev/null +++ b/custom_mutators/aflpp/standalone/Makefile @@ -0,0 +1,10 @@ + +CFLAGS = -O3 -funroll-loops -fPIC + +all: aflpp-standalone + +aflpp-standalone: aflpp-standalone.c + $(CC) $(CFLAGS) -I../../../include -I. -o aflpp-standalone aflpp-standalone.c ../../../src/afl-performance.c + +clean: + rm -f *.o *~ aflpp-standalone core diff --git a/custom_mutators/aflpp/standalone/README.md b/custom_mutators/aflpp/standalone/README.md new file mode 100644 index 00000000..f5f94c5f --- /dev/null +++ b/custom_mutators/aflpp/standalone/README.md @@ -0,0 +1,10 @@ +# AFL++ standalone mutator + +this is the AFL++ havoc mutator as a standalone mutator + +just type `make` to build. + +``` +aflpp-standalone inputfile outputfile +``` + diff --git a/custom_mutators/aflpp/standalone/aflpp-standalone.c b/custom_mutators/aflpp/standalone/aflpp-standalone.c new file mode 100644 index 00000000..337b7937 --- /dev/null +++ b/custom_mutators/aflpp/standalone/aflpp-standalone.c @@ -0,0 +1,167 @@ +#include "afl-mutations.h" + +s8 interesting_8[] = {INTERESTING_8}; +s16 interesting_16[] = {INTERESTING_8, INTERESTING_16}; +s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32}; + +typedef struct my_mutator { + + afl_state_t *afl; + u8 *buf; + u32 buf_size; + +} 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; + + } + + if ((data->buf = malloc(1024*1024)) == NULL) { + + perror("afl_custom_init alloc"); + return NULL; + + } else { + + data->buf_size = 1024*1024; + + } + + /* fake AFL++ state */ + data->afl = calloc(1, sizeof(afl_state_t)); + data->afl->queue_cycle = 1; + data->afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY); + rand_set_seed(data->afl, getpid()); + + 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) { + + if (max_size > data->buf_size) { + + u8 *ptr = realloc(data->buf, max_size); + + if (ptr) { + + return 0; + + } else { + + data->buf = ptr; + data->buf_size = 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, max_size); + + /* return size of mutated data */ + *out_buf = data->buf; + return out_buf_len; + +} + +int main(int argc, char *argv[]) { + + if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) { + + printf("Syntax: $0 [-v] [inputfile [outputfile [splicefile]]]\n\n", argv[0]); + printf("Reads a testcase from stdin when no input file (or '-') is specified,\n"); + printf("mutates according to AFL++'s mutation engine, and write to stdout when '-' or\n"); + printf("no output filename is given. As an optional third parameter you can give a file\n"); + printf("for splicing. Maximum input and output length is 1MB.\n"); + printf("The -v verbose option prints debug output to stderr\n"); + return 0; + + } + + FILE *in = stdin, *out = stdout, *splice = NULL; + unsigned char *inbuf = malloc(1024 * 1024), *outbuf, *splicebuf = NULL; + int verbose = 0, splicelen = 0; + + if (argc > 1 && strcmp(argv[1], "-v") == 0) { + verbose = 1; + argc--; + argv++; + fprintf(stderr, "Verbose active\n"); + } + + my_mutator_t *data = afl_custom_init(NULL, 0); + + if (argc > 1 && strcmp(argv[1], "-") != 0) { + if ((in = fopen(argv[1], "r")) == NULL) { + perror(argv[1]); + return -1; + } + if (verbose) fprintf(stderr, "Input: %s\n", argv[1]); + } + + size_t inlen = fread(inbuf, 1, 1024*1024, in); + + if (!inlen) { + fprintf(stderr, "Error: empty file %s\n", argv[1] ? argv[1] : "stdin"); + return -1; + } + + if (argc > 2 && strcmp(argv[2], "-") != 0) { + if ((out = fopen(argv[2], "w")) == NULL) { + perror(argv[2]); + return -1; + } + if (verbose) fprintf(stderr, "Output: %s\n", argv[2]); + } + + if (argc > 3) { + if ((splice = fopen(argv[3], "r")) == NULL) { + perror(argv[3]); + return -1; + } + if (verbose) fprintf(stderr, "Splice: %s\n", argv[3]); + splicebuf = malloc(1024*1024); + size_t splicelen = fread(splicebuf, 1, 1024*1024, splice); + if (!splicelen) { + fprintf(stderr, "Error: empty file %s\n", argv[3]); + return -1; + } + if (verbose) fprintf(stderr, "Mutation splice length: %zu\n", splicelen); + } + + if (verbose) fprintf(stderr, "Mutation input length: %zu\n", inlen); + unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf, splicelen, 1024*1024); + + if (outlen == 0 || !outbuf) { + fprintf(stderr, "Error: no mutation data returned.\n"); + return -1; + } + + if (verbose) fprintf(stderr, "Mutation output length: %zu\n", outlen); + + if (fwrite(outbuf, 1, outlen, out) != outlen) { + fprintf(stderr, "Warning: incomplete write.\n"); + return -1; + } + + return 0; +} -- cgit 1.4.1 From ab148aeed81d755399e257c0c17fe4cbb9be3d48 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 15 May 2023 15:12:26 +0200 Subject: standalone mutator --- custom_mutators/aflpp/standalone/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_mutators/aflpp/standalone/README.md b/custom_mutators/aflpp/standalone/README.md index f5f94c5f..a1ffb5f9 100644 --- a/custom_mutators/aflpp/standalone/README.md +++ b/custom_mutators/aflpp/standalone/README.md @@ -5,6 +5,6 @@ this is the AFL++ havoc mutator as a standalone mutator just type `make` to build. ``` -aflpp-standalone inputfile outputfile +aflpp-standalone inputfile outputfile [splicefile] ``` -- cgit 1.4.1 From 9a55bbdb44c1508a0b08728db2dacaebc9c43277 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 15 May 2023 15:17:33 +0200 Subject: fix --- custom_mutators/aflpp/standalone/aflpp-standalone.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/custom_mutators/aflpp/standalone/aflpp-standalone.c b/custom_mutators/aflpp/standalone/aflpp-standalone.c index 337b7937..91bac4a8 100644 --- a/custom_mutators/aflpp/standalone/aflpp-standalone.c +++ b/custom_mutators/aflpp/standalone/aflpp-standalone.c @@ -86,15 +86,13 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, int main(int argc, char *argv[]) { if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) { - - printf("Syntax: $0 [-v] [inputfile [outputfile [splicefile]]]\n\n", argv[0]); + printf("Syntax: %s [-v] [inputfile [outputfile [splicefile]]]\n\n", argv[0]); printf("Reads a testcase from stdin when no input file (or '-') is specified,\n"); printf("mutates according to AFL++'s mutation engine, and write to stdout when '-' or\n"); printf("no output filename is given. As an optional third parameter you can give a file\n"); printf("for splicing. Maximum input and output length is 1MB.\n"); - printf("The -v verbose option prints debug output to stderr\n"); + printf("The -v verbose option prints debug output to stderr.\n"); return 0; - } FILE *in = stdin, *out = stdout, *splice = NULL; -- 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(-) 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 9b2c4a2a5a8e54a80bdb82fee39891fbe42544e8 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 6 Jun 2023 16:54:12 +0200 Subject: nit --- include/afl-mutations.h | 155 ++++++++++++++++++++++++------------------------ 1 file changed, 78 insertions(+), 77 deletions(-) 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, -- 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(-) 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(-) 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(-) 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(-) 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(-) 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(-) 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 61b6f4ed9e4dce15c39e4350278a95a41ea2522c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 12 Jun 2023 09:16:15 +0200 Subject: 4.08a init --- README.md | 2 +- docs/Changelog.md | 7 +++++++ include/config.h | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 97fd3997..05c662c1 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Release version: [4.07c](https://github.com/AFLplusplus/AFLplusplus/releases) -GitHub version: 4.07c +GitHub version: 4.08a Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) diff --git a/docs/Changelog.md b/docs/Changelog.md index c52ddd56..98d59527 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -3,6 +3,13 @@ This is the list of all noteworthy changes made in every public 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`. + - display the state of the fuzzing run in the UI :-) + + ### Version ++4.07c (release) - afl-fuzz: - reverse reading the seeds only on restarts (increases performance) diff --git a/include/config.h b/include/config.h index 53be8549..d8153a2c 100644 --- a/include/config.h +++ b/include/config.h @@ -26,7 +26,7 @@ /* Version string: */ // c = release, a = volatile github dev, e = experimental branch -#define VERSION "++4.07c" +#define VERSION "++4.08a" /****************************************************** * * -- cgit 1.4.1 From 3ad8e9856cc48a6f69aa701dafd0623f91f31c5c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 12 Jun 2023 09:23:57 +0200 Subject: update changelog --- docs/Changelog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 98d59527..70f38d05 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -7,6 +7,9 @@ - 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 :-) -- cgit 1.4.1 From 091d66fa92cd9e4caa5829d579b1b996c49db8c9 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 12 Jun 2023 13:05:35 +0200 Subject: increase strategy switch --- include/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/config.h b/include/config.h index 5100d88f..8585041e 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 600 +#define STRATEGY_SWITCH_TIME 1000 /* Default file permission umode when creating files (default: 0600) */ #define DEFAULT_PERMISSION 0600 -- cgit 1.4.1 From fc1e352965416fc9cc74db39c1fec25c95ef2a64 Mon Sep 17 00:00:00 2001 From: forky2 <63731115+forky2@users.noreply.github.com> Date: Wed, 14 Jun 2023 08:43:06 +0100 Subject: Fixes #1770: afl-cmin in -T mode doesn't correctly divide inputs among threads --- afl-cmin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/afl-cmin b/afl-cmin index ae723c1b..de76caf8 100755 --- a/afl-cmin +++ b/afl-cmin @@ -488,7 +488,7 @@ BEGIN { if (threads) { - inputsperfile = in_count / threads + inputsperfile = int(in_count / threads) if (in_count % threads) { inputsperfile++; } -- 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(-) 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 4231d33bc086895a15d8f449991ee3b160446d0a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 14 Jun 2023 13:18:44 +0200 Subject: improve afl-plot plots --- afl-plot | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/afl-plot b/afl-plot index 230d3bfe..f1f288a3 100755 --- a/afl-plot +++ b/afl-plot @@ -75,8 +75,17 @@ outputdir=`get_abs_path "$2"` if [ ! -f "$inputdir/plot_data" ]; then - echo "[-] Error: input directory is not valid (missing 'plot_data')." 1>&2 - exit 1 + if [ -f "$inputdir/default/plot_data" ]; then + + echo "[-] Error: input directory is not valid (missing 'plot_data'), likely you mean $inputdir/default?" 1>&2 + exit 1 + + else + + echo "[-] Error: input directory is not valid (missing 'plot_data')." 1>&2 + exit 1 + + fi fi @@ -141,7 +150,7 @@ set output '$outputdir/high_freq.png' $GNUPLOT_SETUP plot '$inputdir/plot_data' using 1:4 with filledcurve x1 title 'corpus count' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\ - '' using 1:3 with filledcurve x1 title 'current fuzz item' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\ + '' using 1:3 with filledcurve x1 title 'current item' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\ '' using 1:5 with lines title 'pending items' linecolor rgb '#0090ff' linewidth 3, \\ '' using 1:6 with lines title 'pending favs' linecolor rgb '#c00080' linewidth 3, \\ '' using 1:2 with lines title 'cycles done' linecolor rgb '#c000f0' linewidth 3 -- cgit 1.4.1 From 450e00446dfe23a74b08c4ad88b082d48e1f0b66 Mon Sep 17 00:00:00 2001 From: cuanduo Date: Fri, 16 Jun 2023 08:28:05 +0800 Subject: fix bug --- utils/afl_network_proxy/afl-network-server.c | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/afl_network_proxy/afl-network-server.c b/utils/afl_network_proxy/afl-network-server.c index 04309ada..7eb3d18e 100644 --- a/utils/afl_network_proxy/afl-network-server.c +++ b/utils/afl_network_proxy/afl-network-server.c @@ -173,6 +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; } -- cgit 1.4.1 From 420e36dcd3764921765d6aeb07989e701134513a Mon Sep 17 00:00:00 2001 From: Seoyoung Date: Fri, 16 Jun 2023 05:49:49 -0400 Subject: SanitizerCoveragePCGUARD: select counter off by one error --- instrumentation/SanitizerCoveragePCGUARD.so.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index 7171e7aa..d87af775 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -892,7 +892,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage( IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), ConstantInt::get( IntptrTy, - (cnt_cov + ++local_selects + AllBlocks.size()) * 4)), + (cnt_cov + local_selects++ + AllBlocks.size()) * 4)), Int32PtrTy); auto GuardPtr2 = IRB.CreateIntToPtr( @@ -900,7 +900,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage( IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), ConstantInt::get( IntptrTy, - (cnt_cov + ++local_selects + AllBlocks.size()) * 4)), + (cnt_cov + local_selects++ + AllBlocks.size()) * 4)), Int32PtrTy); result = IRB.CreateSelect(condition, GuardPtr1, GuardPtr2); @@ -937,7 +937,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage( IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), ConstantInt::get( IntptrTy, - (cnt_cov + ++local_selects + AllBlocks.size()) * 4)), + (cnt_cov + local_selects++ + AllBlocks.size()) * 4)), Int32PtrTy); x = IRB.CreateInsertElement(GuardPtr1, val1, (uint64_t)0); @@ -946,7 +946,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage( IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), ConstantInt::get( IntptrTy, - (cnt_cov + ++local_selects + AllBlocks.size()) * 4)), + (cnt_cov + local_selects++ + AllBlocks.size()) * 4)), Int32PtrTy); y = IRB.CreateInsertElement(GuardPtr2, val2, (uint64_t)0); @@ -955,7 +955,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage( val1 = IRB.CreateIntToPtr( IRB.CreateAdd( IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), - ConstantInt::get(IntptrTy, (cnt_cov + ++local_selects + + ConstantInt::get(IntptrTy, (cnt_cov + local_selects++ + AllBlocks.size()) * 4)), Int32PtrTy); @@ -964,7 +964,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage( val2 = IRB.CreateIntToPtr( IRB.CreateAdd( IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), - ConstantInt::get(IntptrTy, (cnt_cov + ++local_selects + + ConstantInt::get(IntptrTy, (cnt_cov + local_selects++ + AllBlocks.size()) * 4)), Int32PtrTy); -- 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(-) 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 51ab51ca278dafacfca1131fd339529e9d7dce08 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 21 Jun 2023 09:04:08 +0200 Subject: update tutorial list --- custom_mutators/README.md | 11 +++++++---- docs/tutorials.md | 5 +++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/custom_mutators/README.md b/custom_mutators/README.md index a5a572c0..2d1220b3 100644 --- a/custom_mutators/README.md +++ b/custom_mutators/README.md @@ -70,14 +70,17 @@ requires cmake (among other things): ### libprotobuf Mutators -There are two WIP protobuf projects, that require work to be working though: +There are three WIP protobuf projects, that require work to be working though: + +ASN.1 example: +[https://github.com/airbus-seclab/AFLplusplus-blogpost/tree/main/src/mutator](https://github.com/airbus-seclab/AFLplusplus-blogpost/tree/main/src/mutator) transforms protobuf raw: -https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator +[https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator](https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator) has a transform function you need to fill for your protobuf format, however needs to be ported to the updated AFL++ custom mutator API (not much work): -https://github.com/thebabush/afl-libprotobuf-mutator +[https://github.com/thebabush/afl-libprotobuf-mutator](https://github.com/thebabush/afl-libprotobuf-mutator) same as above but is for current AFL++: -https://github.com/P1umer/AFLplusplus-protobuf-mutator +[https://github.com/P1umer/AFLplusplus-protobuf-mutator](https://github.com/P1umer/AFLplusplus-protobuf-mutator) \ No newline at end of file diff --git a/docs/tutorials.md b/docs/tutorials.md index 342080fd..a5ee3322 100644 --- a/docs/tutorials.md +++ b/docs/tutorials.md @@ -8,6 +8,7 @@ Here are some good write-ups to show how to effectively use AFL++: * [https://aflplus.plus/docs/tutorials/libxml2_tutorial/](https://aflplus.plus/docs/tutorials/libxml2_tutorial/) * [https://bananamafia.dev/post/gb-fuzz/](https://bananamafia.dev/post/gb-fuzz/) +* [https://bushido-sec.com/index.php/2023/06/19/the-art-of-fuzzing/](https://bushido-sec.com/index.php/2023/06/19/the-art-of-fuzzing/) * [https://securitylab.github.com/research/fuzzing-challenges-solutions-1](https://securitylab.github.com/research/fuzzing-challenges-solutions-1) * [https://securitylab.github.com/research/fuzzing-software-2](https://securitylab.github.com/research/fuzzing-software-2) * [https://securitylab.github.com/research/fuzzing-sockets-FTP](https://securitylab.github.com/research/fuzzing-sockets-FTP) @@ -20,6 +21,10 @@ training, then we can highly recommend the following: * [https://github.com/antonio-morales/Fuzzing101](https://github.com/antonio-morales/Fuzzing101) +Here is a good forkflow description (and tutorial) for qemu_mode: + +* [https://airbus-seclab.github.io/AFLplusplus-blogpost/](https://airbus-seclab.github.io/AFLplusplus-blogpost/) + Here is good workflow description for frida_mode: * [https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html](https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html) -- 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(-) 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(-) 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(-) 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(-) 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 93362c6e672f1d2aba15636b6ba96a771aeb7ead Mon Sep 17 00:00:00 2001 From: mischa Date: Wed, 21 Jun 2023 16:39:05 +0200 Subject: updated llvm requirements --- GNUmakefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 55676d97..71011858 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -318,7 +318,7 @@ all: test_x86 test_shm test_python ready $(PROGS) afl-as llvm gcc_plugin test_bu @echo Build Summary: @test -e afl-fuzz && echo "[+] afl-fuzz and supporting tools successfully built" || echo "[-] afl-fuzz could not be built, please set CC to a working compiler" @test -e afl-llvm-pass.so && echo "[+] LLVM basic mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md" - @test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md" + @test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-13 and clang-13 or newer, see docs/INSTALL.md" @test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be built, it is optional, if you want it, please install LLVM and LLD 11+. More information at instrumentation/README.lto.md on how to build it" ifneq "$(SYS)" "Darwin" @test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this" @@ -740,7 +740,7 @@ endif @echo Build Summary: @test -e afl-fuzz && echo "[+] afl-fuzz and supporting tools successfully built" || echo "[-] afl-fuzz could not be built, please set CC to a working compiler" @test -e afl-llvm-pass.so && echo "[+] LLVM basic mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md" - @test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md" + @test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-13 and clang-13 or newer, see docs/INSTALL.md" @test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be built, it is optional, if you want it, please install LLVM 11-14. More information at instrumentation/README.lto.md on how to build it" ifneq "$(SYS)" "Darwin" test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this" -- 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(-) 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 9926f070822c35c312b5051ce0be0a40a471f253 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 22 Jun 2023 17:36:02 +0100 Subject: Support for long form instrumentation on x64 --- frida_mode/src/instrument/instrument_x64.c | 289 ++++++++++++++++++++++++----- 1 file changed, 242 insertions(+), 47 deletions(-) diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index 8338f8e7..3983c3ba 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -58,6 +58,7 @@ typedef union { } jcc_insn; static GHashTable *coverage_blocks = NULL; +static GHashTable *coverage_blocks_long = NULL; gboolean instrument_is_coverage_optimize_supported(void) { @@ -127,6 +128,64 @@ typedef struct { } afl_log_code_asm_t; +typedef struct { + + // cur_location = (block_address >> 4) ^ (block_address << 8); + // shared_mem[cur_location ^ prev_location]++; + // prev_location = cur_location >> 1; + + // mov QWORD PTR [rsp-0x88],rax + // lahf + // mov QWORD PTR [rsp-0x90],rax + // mov QWORD PTR [rsp-0x98],rbx + + // mov rax, 0xXXXXXXXXXXXXXXXXX /* p_prev_loc */ + // mov eax, dword ptr [rax] /* prev_loc */ + // xor eax,0x3f77 /* cur_loc */ + + // mov rbx, 0xXXXXXXXXXXXXXXXXX /* map */ + // add rax,rbx + + // mov bl,BYTE PTR [rax] + // add bl,0x1 + // adc bl,0x0 + // mov BYTE PTR [rax],bl + + // mov rax, 0xXXXXXXXXXXXXXXXXX /* p_prev_loc */ + // mov dword ptr [rax], 0xXXXXXXXXX /* prev_loc */ + + // mov rbx,QWORD PTR [rsp-0x98] + // mov rax,QWORD PTR [rsp-0x90] + // sahf + // mov rax,QWORD PTR [rsp-0x88] + + uint8_t mov_rax_rsp_88[8]; + uint8_t lahf; + uint8_t mov_rax_rsp_90[8]; + uint8_t mov_rbx_rsp_98[8]; + + uint8_t mov_rax_prev_loc_ptr1[10]; + uint8_t mov_eax_prev_loc[2]; + uint8_t xor_eax_curr_loc[5]; + + uint8_t mov_rbx_map_ptr[10]; + uint8_t add_rax_rbx[3]; + + uint8_t mov_rbx_ptr_rax[2]; + uint8_t add_bl_1[3]; + uint8_t adc_bl_0[3]; + uint8_t mov_ptr_rax_rbx[2]; + + uint8_t mov_rax_prev_loc_ptr2[10]; + uint8_t mov_prev_loc_curr_loc_shr1[6]; + + uint8_t mov_rsp_98_rbx[8]; + uint8_t mov_rsp_90_rax[8]; + uint8_t sahf; + uint8_t mov_rsp_88_rax[8]; + +} afl_log_code_asm_long_t; + #pragma pack(pop) static const afl_log_code_asm_t template = @@ -158,6 +217,41 @@ static const afl_log_code_asm_t template = ; +static const afl_log_code_asm_long_t template_long = + { + + .mov_rax_rsp_88 = {0x48, 0x89, 0x84, 0x24, 0x78, 0xFF, 0xFF, 0xFF}, + .lahf = 0x9f, + .mov_rax_rsp_90 = {0x48, 0x89, 0x84, 0x24, 0x70, 0xFF, 0xFF, 0xFF}, + .mov_rbx_rsp_98 = {0x48, 0x89, 0x9C, 0x24, 0x68, 0xFF, 0xFF, 0xFF}, + + .mov_rax_prev_loc_ptr1 = {0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF}, + .mov_eax_prev_loc = {0x8b, 0x00}, + .xor_eax_curr_loc = {0x35}, + + .mov_rbx_map_ptr = {0x48, 0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF}, + .add_rax_rbx = {0x48, 0x01, 0xd8}, + + .mov_rbx_ptr_rax = {0x8a, 0x18}, + .add_bl_1 = {0x80, 0xc3, 0x01}, + .adc_bl_0 = {0x80, 0xd3, 0x00}, + .mov_ptr_rax_rbx = {0x88, 0x18}, + + .mov_rax_prev_loc_ptr2 = {0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF}, + .mov_prev_loc_curr_loc_shr1 = {0xc7, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}, + + .mov_rsp_98_rbx = {0x48, 0x8B, 0x9C, 0x24, 0x68, 0xFF, 0xFF, 0xFF}, + .mov_rsp_90_rax = {0x48, 0x8B, 0x84, 0x24, 0x70, 0xFF, 0xFF, 0xFF}, + .sahf = 0x9e, + .mov_rsp_88_rax = {0x48, 0x8B, 0x84, 0x24, 0x78, 0xFF, 0xFF, 0xFF}, + +} + +; + typedef union { afl_log_code_asm_t code; @@ -165,6 +259,13 @@ typedef union { } afl_log_code; +typedef union { + + afl_log_code_asm_long_t code; + uint8_t bytes[0]; + +} afl_log_code_long; + void instrument_coverage_optimize_init(void) { FVERBOSE("__afl_area_ptr: %p", __afl_area_ptr); @@ -182,16 +283,19 @@ static void instrument_coverage_switch_insn(GumStalkerObserver *self, cs_x86 *x86; cs_x86_op *op; + bool is_short = false; + bool is_long = false; + if (from_insn == NULL) { return; } x86 = &from_insn->detail->x86; op = x86->operands; - if (!g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target))) { - - return; + is_short = g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target)); + is_long = + g_hash_table_contains(coverage_blocks_long, GSIZE_TO_POINTER(*target)); - } + if (!is_short && !is_long) { return; } switch (from_insn->id) { @@ -212,15 +316,41 @@ static void instrument_coverage_switch_insn(GumStalkerObserver *self, break; case X86_INS_RET: - instrument_cache_insert(start_address, - (guint8 *)*target + sizeof(afl_log_code)); + if (is_short) { + + instrument_cache_insert(start_address, + (guint8 *)*target + sizeof(afl_log_code)); + + } else if (is_long) { + + instrument_cache_insert(start_address, + (guint8 *)*target + sizeof(afl_log_code_long)); + + } else { + + FATAL("Something has gone wrong here!"); + + } + break; default: return; } - *target = (guint8 *)*target + sizeof(afl_log_code); + if (is_short) { + + *target = (guint8 *)*target + sizeof(afl_log_code); + + } else if (is_long) { + + *target = (guint8 *)*target + sizeof(afl_log_code_long); + + } else { + + FATAL("Something has gone wrong here!"); + + } } @@ -270,22 +400,22 @@ static void instrument_coverage_suppress_init(void) { } + coverage_blocks_long = g_hash_table_new(g_direct_hash, g_direct_equal); + if (coverage_blocks_long == NULL) { + + FATAL("Failed to g_hash_table_new, errno: %d", errno); + + } + } -static void instrument_coverage_write(GumAddress address, - GumStalkerOutput *output) { +bool instrument_write_inline(GumX86Writer *cw, GumAddress code_addr, + guint32 area_offset, guint32 area_offset_ror) { - afl_log_code code = {0}; - GumX86Writer *cw = output->writer.x86; - guint64 area_offset = instrument_get_offset_hash(address); - gsize map_size_pow2; - gsize area_offset_ror; - GumAddress code_addr = cw->pc; + afl_log_code code = {0}; code.code = template; - /* mov_prev_loc_curr_loc_shr1 */ - gssize prev_loc_value = GPOINTER_TO_SIZE(instrument_previous_pc_addr) - (code_addr + offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) + @@ -294,11 +424,7 @@ static void instrument_coverage_write(GumAddress address, offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) + sizeof(code.code.mov_prev_loc_curr_loc_shr1) - sizeof(gint) - sizeof(guint32); - if (!instrument_coverage_in_range(prev_loc_value)) { - - FATAL("Patch out of range (current_pc_value1): 0x%016lX", prev_loc_value); - - } + if (!instrument_coverage_in_range(prev_loc_value)) { return false; } *((gint *)&code.bytes[prev_loc_value_offset]) = (gint)prev_loc_value; @@ -311,11 +437,7 @@ static void instrument_coverage_write(GumAddress address, gssize prev_loc_value_offset2 = offsetof(afl_log_code, code.mov_eax_prev_loc) + sizeof(code.code.mov_eax_prev_loc) - sizeof(gint); - if (!instrument_coverage_in_range(prev_loc_value)) { - - FATAL("Patch out of range (current_pc_value1): 0x%016lX", prev_loc_value2); - - } + if (!instrument_coverage_in_range(prev_loc_value)) { return false; } *((gint *)&code.bytes[prev_loc_value_offset2]) = (gint)prev_loc_value2; @@ -338,12 +460,7 @@ static void instrument_coverage_write(GumAddress address, (code_addr + offsetof(afl_log_code, code.lea_rbx_area_ptr) + sizeof(code.code.lea_rbx_area_ptr))); - if (!instrument_coverage_in_range(lea_rbx_area_ptr_value)) { - - FATAL("Patch out of range (lea_rbx_area_ptr_value): 0x%016lX", - lea_rbx_area_ptr_value); - - } + if (!instrument_coverage_in_range(lea_rbx_area_ptr_value)) { return false; } *((guint32 *)&code.bytes[lea_rbx_area_ptr_offset]) = lea_rbx_area_ptr_value; @@ -353,12 +470,100 @@ static void instrument_coverage_write(GumAddress address, offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) + sizeof(code.code.mov_prev_loc_curr_loc_shr1) - sizeof(guint32); - map_size_pow2 = util_log2(__afl_map_size); - area_offset_ror = util_rotate(area_offset, 1, map_size_pow2); - *((guint32 *)&code.bytes[curr_loc_shr_1_offset]) = (guint32)(area_offset_ror); + if (instrument_suppress) { + + if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) { + + FATAL("Failed - g_hash_table_add"); + + } + + } + gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code)); + return true; + +} + +bool instrument_write_inline_long(GumX86Writer *cw, guint32 area_offset, + guint32 area_offset_ror) { + + afl_log_code_long code = {0}; + code.code = template_long; + + /* mov_rax_prev_loc_ptr1 */ + gssize mov_rax_prev_loc_ptr1_offset = + offsetof(afl_log_code_long, code.mov_rax_prev_loc_ptr1) + + sizeof(code.code.mov_rax_prev_loc_ptr1) - sizeof(gsize); + *((gsize *)&code.bytes[mov_rax_prev_loc_ptr1_offset]) = + GPOINTER_TO_SIZE(instrument_previous_pc_addr); + + /* xor_eax_curr_loc */ + gssize xor_eax_curr_loc_offset = + offsetof(afl_log_code_long, code.xor_eax_curr_loc) + + sizeof(code.code.xor_eax_curr_loc) - sizeof(guint32); + *((guint32 *)&code.bytes[xor_eax_curr_loc_offset]) = area_offset; + + /* mov_rbx_map_ptr */ + gsize mov_rbx_map_ptr_offset = + offsetof(afl_log_code_long, code.mov_rbx_map_ptr) + + sizeof(code.code.mov_rbx_map_ptr) - sizeof(gsize); + *((gsize *)&code.bytes[mov_rbx_map_ptr_offset]) = + GPOINTER_TO_SIZE(__afl_area_ptr); + + /* mov_rax_prev_loc_ptr2 */ + gssize mov_rax_prev_loc_ptr2_offset = + offsetof(afl_log_code_long, code.mov_rax_prev_loc_ptr2) + + sizeof(code.code.mov_rax_prev_loc_ptr2) - sizeof(gsize); + *((gsize *)&code.bytes[mov_rax_prev_loc_ptr2_offset]) = + GPOINTER_TO_SIZE(instrument_previous_pc_addr); + + /* mov_prev_loc_curr_loc_shr1 */ + gssize mov_prev_loc_curr_loc_shr1_offset = + offsetof(afl_log_code_long, code.mov_prev_loc_curr_loc_shr1) + + sizeof(code.code.mov_prev_loc_curr_loc_shr1) - sizeof(guint32); + *((guint32 *)&code.bytes[mov_prev_loc_curr_loc_shr1_offset]) = + (guint32)(area_offset_ror); + + if (instrument_suppress) { + + if (!g_hash_table_add(coverage_blocks_long, GSIZE_TO_POINTER(cw->code))) { + + FATAL("Failed - g_hash_table_add"); + + } + + } + + gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code_long)); + return true; + +} + +static void instrument_coverage_write(GumAddress address, + GumStalkerOutput *output) { + + GumX86Writer *cw = output->writer.x86; + guint64 area_offset = (guint32)instrument_get_offset_hash(address); + gsize map_size_pow2; + guint32 area_offset_ror; + GumAddress code_addr = cw->pc; + + map_size_pow2 = util_log2(__afl_map_size); + area_offset_ror = (guint32)util_rotate(instrument_get_offset_hash(address), 1, + map_size_pow2); + + if (!instrument_write_inline(cw, code_addr, area_offset, area_offset_ror)) { + + if (!instrument_write_inline_long(cw, area_offset, area_offset_ror)) { + + FATAL("Failed to write inline instrumentation"); + + } + + } } @@ -380,17 +585,7 @@ void instrument_coverage_optimize(const cs_insn *instr, } - if (instrument_suppress) { - - instrument_coverage_suppress_init(); - - if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) { - - FATAL("Failed - g_hash_table_add"); - - } - - } + if (instrument_suppress) { instrument_coverage_suppress_init(); } instrument_coverage_write(GUM_ADDRESS(instr->address), output); -- 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(-) 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 0616f368c83189ef5559f64d2053129d329aaefe Mon Sep 17 00:00:00 2001 From: "Dongjia \"toka\" Zhang" Date: Sat, 24 Jun 2023 00:21:45 +0200 Subject: fixing laf --- instrumentation/split-compares-pass.so.cc | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc index aec6758e..3cfd1964 100644 --- a/instrumentation/split-compares-pass.so.cc +++ b/instrumentation/split-compares-pass.so.cc @@ -463,8 +463,9 @@ bool SplitComparesTransform::simplifyOrEqualsCompare(CmpInst *IcmpInst, #else ReplaceInstWithInst(IcmpInst->getParent()->getInstList(), ii, PN); #endif - - worklist.push_back(icmp_np); + if (new_pred == CmpInst::ICMP_SGT || new_pred == CmpInst::ICMP_SLT) { + simplifySignedCompare(icmp_np, M, worklist); + } worklist.push_back(icmp_eq); return true; @@ -740,18 +741,22 @@ bool SplitComparesTransform::splitCompare(CmpInst *cmp_inst, Module &M, CmpInst *icmp_inv_cmp = nullptr; BasicBlock *inv_cmp_bb = BasicBlock::Create(C, "inv_cmp", end_bb->getParent(), end_bb); - if (pred == CmpInst::ICMP_UGT || pred == CmpInst::ICMP_SGT || - pred == CmpInst::ICMP_UGE || pred == CmpInst::ICMP_SGE) { + if (pred == CmpInst::ICMP_UGT) { icmp_inv_cmp = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, op0_high, op1_high); - } else { + } else if (pred == CmpInst::ICMP_ULT) { icmp_inv_cmp = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, op0_high, op1_high); } + else { + // Never gonna appen + if (!be_quiet) + fprintf(stderr, "Error: split-compare: Equals or signed not removed: %d\n", pred); + } #if LLVM_MAJOR >= 16 icmp_inv_cmp->insertInto(inv_cmp_bb, inv_cmp_bb->end()); -- cgit 1.4.1 From edd352612da1f58832cbe84d909a8998ce4fa690 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 24 Jun 2023 09:30:09 +0200 Subject: code format --- docs/Changelog.md | 6 +++++- instrumentation/split-compares-pass.so.cc | 12 +++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index c850c43e..e6b90d3d 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -18,9 +18,13 @@ - 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 + - afl-cc: - fixed an off-by-one instrumentation of iselect, hurting coverage a bit. Thanks to @amykweon for spotting and fixing! + - @toka fixed a bug in laf-intel signed integer comparison splitting, + thanks a lot!! + - frida_mode: + - support for long form instrumentation on x86_x64 and arm64 ### Version ++4.07c (release) diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc index 3cfd1964..6eafb332 100644 --- a/instrumentation/split-compares-pass.so.cc +++ b/instrumentation/split-compares-pass.so.cc @@ -464,8 +464,11 @@ bool SplitComparesTransform::simplifyOrEqualsCompare(CmpInst *IcmpInst, ReplaceInstWithInst(IcmpInst->getParent()->getInstList(), ii, PN); #endif if (new_pred == CmpInst::ICMP_SGT || new_pred == CmpInst::ICMP_SLT) { + simplifySignedCompare(icmp_np, M, worklist); + } + worklist.push_back(icmp_eq); return true; @@ -751,11 +754,14 @@ bool SplitComparesTransform::splitCompare(CmpInst *cmp_inst, Module &M, icmp_inv_cmp = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, op0_high, op1_high); - } - else { + } else { + // Never gonna appen if (!be_quiet) - fprintf(stderr, "Error: split-compare: Equals or signed not removed: %d\n", pred); + fprintf(stderr, + "Error: split-compare: Equals or signed not removed: %d\n", + pred); + } #if LLVM_MAJOR >= 16 -- cgit 1.4.1 From 1e3890ea7f32866af97614c657afdf970be7168b Mon Sep 17 00:00:00 2001 From: "Dongjia \"toka\" Zhang" Date: Sat, 24 Jun 2023 15:34:12 +0200 Subject: delete duplicate branches --- instrumentation/SanitizerCoveragePCGUARD.so.cc | 7 ------- 1 file changed, 7 deletions(-) diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index 57b5d128..7d614f43 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -225,15 +225,8 @@ llvmGetPassPluginInfo() { } -#if LLVM_VERSION_MAJOR >= 16 PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M, ModuleAnalysisManager &MAM) { - -#else -PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M, - ModuleAnalysisManager &MAM) { - -#endif ModuleSanitizerCoverageAFL ModuleSancov(Options); auto &FAM = MAM.getResult(M).getManager(); auto DTCallback = [&FAM](Function &F) -> const DominatorTree *{ -- cgit 1.4.1 From cac713ec304b40e815d54e0991adcb14290f8f30 Mon Sep 17 00:00:00 2001 From: "Dongjia \"toka\" Zhang" Date: Sat, 24 Jun 2023 15:48:23 +0200 Subject: llvm 15 --- instrumentation/SanitizerCoverageLTO.so.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 2d17ffd4..d7b03634 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -331,7 +331,7 @@ llvmGetPassPluginInfo() { #if LLVM_VERSION_MAJOR <= 13 using OptimizationLevel = typename PassBuilder::OptimizationLevel; #endif -#if LLVM_VERSION_MAJOR >= 16 +#if LLVM_VERSION_MAJOR >= 15 PB.registerFullLinkTimeOptimizationLastEPCallback( #else PB.registerOptimizerLastEPCallback( -- 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(-) 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(-) 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