restructure havoc
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 4e8154c..e0d961b 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -1997,16 +1997,19 @@
/* 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 59 /* 55 to 60 */
+
u32 r_max, r;
- r_max = 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0);
+ r_max = (MAX_HAVOC_ENTRY + 1) + (afl->extras_cnt ? 4 : 0) +
+ (afl->a_extras_cnt ? 2 : 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++;
+ r_max += 4;
}
@@ -2015,7 +2018,7 @@
/* add expensive havoc cases here if there is no findings in the last 5s */
- r_max++;
+ r_max += 4;
}
@@ -2069,7 +2072,7 @@
switch ((r = rand_below(afl, r_max))) {
- case 0:
+ case 0 ... 3: {
/* Flip a single bit somewhere. Spooky! */
@@ -2080,7 +2083,9 @@
FLIP_BIT(out_buf, rand_below(afl, temp_len << 3));
break;
- case 1:
+ }
+
+ case 4 ... 7: {
/* Set byte to interesting value. */
@@ -2092,63 +2097,77 @@
interesting_8[rand_below(afl, sizeof(interesting_8))];
break;
- case 2:
+ }
+
+ case 8 ... 9: {
/* Set word to interesting value, randomly choosing endian. */
if (temp_len < 2) { break; }
- if (rand_below(afl, 2)) {
-
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16");
- strcat(afl->mutation, afl->m_tmp);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16");
+ 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)];
-
- } else {
-
-#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16BE");
- 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)) =
+ interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)];
break;
- case 3:
+ }
+
+ case 10 ... 11: {
+
+ /* Set word to interesting value, randomly choosing endian. */
+
+ if (temp_len < 2) { break; }
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16BE");
+ 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)]);
+
+ break;
+
+ }
+
+ case 12 ... 13: {
/* Set dword to interesting value, randomly choosing endian. */
if (temp_len < 4) { break; }
- if (rand_below(afl, 2)) {
-
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32");
- strcat(afl->mutation, afl->m_tmp);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32");
+ 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)];
-
- } else {
-
-#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32BE");
- 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)) =
+ interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)];
break;
- case 4:
+ }
+
+ case 14 ... 15: {
+
+ /* Set dword to interesting value, randomly choosing endian. */
+
+ if (temp_len < 4) { break; }
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32BE");
+ 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)]);
+
+ break;
+
+ }
+
+ case 16 ... 19: {
/* Randomly subtract from byte. */
@@ -2159,7 +2178,9 @@
out_buf[rand_below(afl, temp_len)] -= 1 + rand_below(afl, ARITH_MAX);
break;
- case 5:
+ }
+
+ case 20 ... 23: {
/* Randomly add to byte. */
@@ -2170,139 +2191,165 @@
out_buf[rand_below(afl, temp_len)] += 1 + rand_below(afl, ARITH_MAX);
break;
- case 6:
+ }
- /* Randomly subtract from word, random endian. */
+ case 24 ... 25: {
+
+ /* Randomly subtract from word, little endian. */
if (temp_len < 2) { break; }
- if (rand_below(afl, 2)) {
-
- u32 pos = rand_below(afl, temp_len - 1);
+ u32 pos = rand_below(afl, temp_len - 1);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16_-%u", pos);
- strcat(afl->mutation, afl->m_tmp);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16_-%u", pos);
+ strcat(afl->mutation, afl->m_tmp);
#endif
- *(u16 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX);
-
- } else {
-
- u32 pos = rand_below(afl, temp_len - 1);
- u16 num = 1 + rand_below(afl, ARITH_MAX);
-
-#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16_BE-%u_%u", pos,
- num);
- strcat(afl->mutation, afl->m_tmp);
-#endif
- *(u16 *)(out_buf + pos) =
- SWAP16(SWAP16(*(u16 *)(out_buf + pos)) - num);
-
- }
+ *(u16 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX);
break;
- case 7:
+ }
- /* Randomly add to word, random endian. */
+ case 26 ... 27: {
+
+ /* Randomly subtract from word, big endian. */
if (temp_len < 2) { break; }
- if (rand_below(afl, 2)) {
-
- u32 pos = rand_below(afl, temp_len - 1);
+ u32 pos = rand_below(afl, temp_len - 1);
+ u16 num = 1 + rand_below(afl, ARITH_MAX);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+-%u", pos);
- strcat(afl->mutation, afl->m_tmp);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16_BE-%u_%u", pos,
+ num);
+ strcat(afl->mutation, afl->m_tmp);
#endif
- *(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX);
-
- } else {
-
- u32 pos = rand_below(afl, temp_len - 1);
- u16 num = 1 + rand_below(afl, ARITH_MAX);
-
-#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+BE-%u_%u", pos,
- num);
- strcat(afl->mutation, afl->m_tmp);
-#endif
- *(u16 *)(out_buf + pos) =
- SWAP16(SWAP16(*(u16 *)(out_buf + pos)) + num);
-
- }
+ *(u16 *)(out_buf + pos) =
+ SWAP16(SWAP16(*(u16 *)(out_buf + pos)) - num);
break;
- case 8:
+ }
- /* Randomly subtract from dword, random endian. */
+ case 28 ... 29: {
+
+ /* Randomly add to word, little endian. */
+
+ if (temp_len < 2) { break; }
+
+ u32 pos = rand_below(afl, temp_len - 1);
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+-%u", pos);
+ strcat(afl->mutation, afl->m_tmp);
+#endif
+ *(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX);
+
+ break;
+
+ }
+
+ case 30 ... 31: {
+
+ /* Randomly add to word, big endian. */
+
+ if (temp_len < 2) { break; }
+
+ u32 pos = rand_below(afl, temp_len - 1);
+ u16 num = 1 + rand_below(afl, ARITH_MAX);
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+BE-%u_%u", pos,
+ num);
+ strcat(afl->mutation, afl->m_tmp);
+#endif
+ *(u16 *)(out_buf + pos) =
+ SWAP16(SWAP16(*(u16 *)(out_buf + pos)) + num);
+
+ break;
+
+ }
+
+ case 32 ... 33: {
+
+ /* Randomly subtract from dword, little endian. */
if (temp_len < 4) { break; }
- if (rand_below(afl, 2)) {
-
- u32 pos = rand_below(afl, temp_len - 3);
+ u32 pos = rand_below(afl, temp_len - 3);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32_-%u", pos);
- strcat(afl->mutation, afl->m_tmp);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32_-%u", pos);
+ strcat(afl->mutation, afl->m_tmp);
#endif
- *(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX);
-
- } else {
-
- u32 pos = rand_below(afl, temp_len - 3);
- u32 num = 1 + rand_below(afl, ARITH_MAX);
-
-#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32_BE-%u-%u", pos,
- num);
- strcat(afl->mutation, afl->m_tmp);
-#endif
- *(u32 *)(out_buf + pos) =
- SWAP32(SWAP32(*(u32 *)(out_buf + pos)) - num);
-
- }
+ *(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX);
break;
- case 9:
+ }
- /* Randomly add to dword, random endian. */
+ case 34 ... 35: {
+
+ /* Randomly subtract from dword, big endian. */
if (temp_len < 4) { break; }
- if (rand_below(afl, 2)) {
-
- u32 pos = rand_below(afl, temp_len - 3);
+ u32 pos = rand_below(afl, temp_len - 3);
+ u32 num = 1 + rand_below(afl, ARITH_MAX);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+-%u", pos);
- strcat(afl->mutation, afl->m_tmp);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32_BE-%u-%u", pos,
+ num);
+ strcat(afl->mutation, afl->m_tmp);
#endif
- *(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX);
-
- } else {
-
- u32 pos = rand_below(afl, temp_len - 3);
- u32 num = 1 + rand_below(afl, ARITH_MAX);
-
-#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+BE-%u-%u", pos,
- num);
- strcat(afl->mutation, afl->m_tmp);
-#endif
- *(u32 *)(out_buf + pos) =
- SWAP32(SWAP32(*(u32 *)(out_buf + pos)) + num);
-
- }
+ *(u32 *)(out_buf + pos) =
+ SWAP32(SWAP32(*(u32 *)(out_buf + pos)) - num);
break;
- case 10:
+ }
+
+ case 36 ... 37: {
+
+ /* Randomly add to dword, little endian. */
+
+ if (temp_len < 4) { break; }
+
+ u32 pos = rand_below(afl, temp_len - 3);
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+-%u", pos);
+ strcat(afl->mutation, afl->m_tmp);
+#endif
+ *(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX);
+
+ break;
+
+ }
+
+ case 38 ... 39: {
+
+ /* Randomly add to dword, big endian. */
+
+ if (temp_len < 4) { break; }
+
+ u32 pos = rand_below(afl, temp_len - 3);
+ u32 num = 1 + rand_below(afl, ARITH_MAX);
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+BE-%u-%u", pos,
+ num);
+ strcat(afl->mutation, afl->m_tmp);
+#endif
+ *(u32 *)(out_buf + pos) =
+ SWAP32(SWAP32(*(u32 *)(out_buf + pos)) + num);
+
+ break;
+
+ }
+
+ case 40 ... 43: {
/* Just set a random byte to a random value. Because,
why not. We use XOR with 1-255 to eliminate the
@@ -2315,21 +2362,155 @@
out_buf[rand_below(afl, temp_len)] ^= 1 + rand_below(afl, 255);
break;
- case 11 ... 12: {
+ }
+
+ case 44 ... 46: {
+
+ if (temp_len + HAVOC_BLK_XL < MAX_FILE) {
+
+ /* Clone bytes. */
+
+ u32 clone_len = choose_block_len(afl, temp_len);
+ u32 clone_from = rand_below(afl, temp_len - clone_len + 1);
+ u32 clone_to = rand_below(afl, temp_len);
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s-%u-%u-%u",
+ actually_clone ? "clone" : "insert", clone_from, clone_to,
+ clone_len);
+ 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 */
+
+ memcpy(new_buf + clone_to, out_buf + clone_from, 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 47: {
+
+ if (temp_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, temp_len);
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s-%u-%u-%u",
+ actually_clone ? "clone" : "insert", clone_from, clone_to,
+ clone_len);
+ 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,
+ rand_below(afl, 2) ? rand_below(afl, 256)
+ : out_buf[rand_below(afl, temp_len)],
+ 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 48 ... 50: {
+
+ /* Overwrite bytes with a randomly selected chunk bytes. */
+
+ if (temp_len < 2) { break; }
+
+ 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);
+
+ if (likely(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);
+#endif
+ memmove(out_buf + copy_to, out_buf + copy_from, copy_len);
+
+ }
+
+ break;
+
+ }
+
+ case 51: {
+
+ /* Overwrite bytes with fixed bytes. */
+
+ if (temp_len < 2) { break; }
+
+ u32 copy_len = choose_block_len(afl, temp_len - 1);
+ u32 copy_to = rand_below(afl, temp_len - copy_len + 1);
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " OVERWRITE_FIXED-%u-%u-%u",
+ copy_from, 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);
+
+ break;
+
+ }
+
+ // increase from 4 up to 8?
+ case 52 ... MAX_HAVOC_ENTRY: {
/* Delete bytes. We're making this a bit more likely
than insertion (the next option) in hopes of keeping
files reasonably small. */
- u32 del_from, del_len;
-
if (temp_len < 2) { break; }
/* Don't delete too much. */
- del_len = choose_block_len(afl, temp_len - 1);
-
- del_from = rand_below(afl, temp_len - del_len + 1);
+ u32 del_len = choose_block_len(afl, temp_len - 1);
+ 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,
@@ -2345,206 +2526,46 @@
}
- case 13:
-
- if (temp_len + HAVOC_BLK_XL < MAX_FILE) {
-
- /* Clone bytes (75%) or insert a block of constant bytes (25%). */
-
- u8 actually_clone = rand_below(afl, 4);
- u32 clone_from, clone_to, clone_len;
- u8 *new_buf;
-
- if (likely(actually_clone)) {
-
- clone_len = choose_block_len(afl, temp_len);
- clone_from = rand_below(afl, temp_len - clone_len + 1);
-
- } else {
-
- clone_len = choose_block_len(afl, HAVOC_BLK_XL);
- clone_from = 0;
-
- }
-
- clone_to = rand_below(afl, temp_len);
-
-#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s-%u-%u-%u",
- actually_clone ? "clone" : "insert", clone_from, clone_to,
- clone_len);
- strcat(afl->mutation, afl->m_tmp);
-#endif
- 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 */
-
- if (likely(actually_clone)) {
-
- memcpy(new_buf + clone_to, out_buf + clone_from, clone_len);
-
- } else {
-
- memset(new_buf + clone_to,
- rand_below(afl, 2) ? rand_below(afl, 256)
- : out_buf[rand_below(afl, temp_len)],
- 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 14: {
-
- /* Overwrite bytes with a randomly selected chunk (75%) or fixed
- bytes (25%). */
-
- u32 copy_from, copy_to, copy_len;
-
- if (temp_len < 2) { break; }
-
- copy_len = choose_block_len(afl, temp_len - 1);
-
- copy_from = rand_below(afl, temp_len - copy_len + 1);
- copy_to = rand_below(afl, temp_len - copy_len + 1);
-
- if (likely(rand_below(afl, 4))) {
-
- if (likely(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);
-#endif
- memmove(out_buf + copy_to, out_buf + copy_from, copy_len);
-
- }
-
- } else {
-
-#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp),
- " OVERWRITE_FIXED-%u-%u-%u", copy_from, 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);
-
- }
-
- break;
-
- }
-
default:
- if (likely(r <= 16 && (afl->extras_cnt || afl->a_extras_cnt))) {
+ r -= (MAX_HAVOC_ENTRY + 1);
- /* Values 15 and 16 can be selected only if there are any extras
- present in the dictionaries. */
+ if (afl->extras_cnt) {
- if (r == 15) {
+ if (r < 2) {
- /* Overwrite bytes with an extra. */
+ /* Use the dictionary. */
- if (!afl->extras_cnt ||
- (afl->a_extras_cnt && rand_below(afl, 2))) {
+ u32 use_extra = rand_below(afl, afl->extras_cnt);
+ u32 extra_len = afl->extras[use_extra].len;
- /* No user-specified extras or odds in our favor. Let's use an
- auto-detected one. */
+ if (extra_len > temp_len) { break; }
- 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; }
-
- 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), " 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);
-
- } else {
-
- /* No auto extras or odds in our favor. 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; }
-
- 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);
-#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;
- } else { // case 16
+ } else if (r < 4) {
- u32 use_extra, extra_len,
- insert_at = rand_below(afl, temp_len + 1);
- u8 *ptr;
-
- /* Insert an extra. Do the same dice-rolling stuff as for the
- previous case. */
-
- if (!afl->extras_cnt ||
- (afl->a_extras_cnt && rand_below(afl, 2))) {
-
- use_extra = rand_below(afl, afl->a_extras_cnt);
- extra_len = afl->a_extras[use_extra].len;
- ptr = afl->a_extras[use_extra].data;
-#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
-
- } else {
-
- use_extra = rand_below(afl, afl->extras_cnt);
- extra_len = afl->extras[use_extra].len;
- ptr = afl->extras[use_extra].data;
-#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
-
- }
-
+ 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; }
+ 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
+
out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len);
if (unlikely(!out_buf)) { PFATAL("alloc"); }
@@ -2554,103 +2575,154 @@
/* Inserted part */
memcpy(out_buf + insert_at, ptr, extra_len);
-
temp_len += extra_len;
break;
- }
-
- } else {
-
- /*
- switch (r) {
-
- case 15: // fall through
- case 16:
- case 17: {*/
-
- /* 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_paths);
-
- } 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 && rand_below(afl, 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;
+ r -= 4;
}
- break;
-
}
- // end of default:
+ if (afl->a_extras_cnt) {
+
+ if (r == 0) {
+
+ /* 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; }
+
+ 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);
+#endif
+ memcpy(out_buf + insert_at, afl->a_extras[use_extra].data,
+ extra_len);
+
+ break;
+
+ } else if (r == 1) {
+
+ 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
+
+ out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len);
+ if (unlikely(!out_buf)) { PFATAL("alloc"); }
+
+ /* Tail */
+ memmove(out_buf + insert_at + extra_len, out_buf + insert_at,
+ temp_len - insert_at);
+
+ /* Inserted part */
+ memcpy(out_buf + insert_at, ptr, extra_len);
+ temp_len += extra_len;
+
+ break;
+
+ } else {
+
+ 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_paths);
+
+ } 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
}