mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-08 16:21:32 +00:00
restructure havoc
This commit is contained in:
parent
5ee2dd6bbd
commit
eda1ee0807
@ -1997,16 +1997,19 @@ havoc_stage:
|
|||||||
/* We essentially just do several thousand runs (depending on perf_score)
|
/* We essentially just do several thousand runs (depending on perf_score)
|
||||||
where we take the input file and make random stacked tweaks. */
|
where we take the input file and make random stacked tweaks. */
|
||||||
|
|
||||||
|
#define MAX_HAVOC_ENTRY 59 /* 55 to 60 */
|
||||||
|
|
||||||
u32 r_max, r;
|
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)) {
|
if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) {
|
||||||
|
|
||||||
/* add expensive havoc cases here, they are activated after a full
|
/* add expensive havoc cases here, they are activated after a full
|
||||||
cycle without finds happened */
|
cycle without finds happened */
|
||||||
|
|
||||||
r_max++;
|
r_max += 4;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2015,7 +2018,7 @@ havoc_stage:
|
|||||||
|
|
||||||
/* add expensive havoc cases here if there is no findings in the last 5s */
|
/* add expensive havoc cases here if there is no findings in the last 5s */
|
||||||
|
|
||||||
r_max++;
|
r_max += 4;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2069,7 +2072,7 @@ havoc_stage:
|
|||||||
|
|
||||||
switch ((r = rand_below(afl, r_max))) {
|
switch ((r = rand_below(afl, r_max))) {
|
||||||
|
|
||||||
case 0:
|
case 0 ... 3: {
|
||||||
|
|
||||||
/* Flip a single bit somewhere. Spooky! */
|
/* Flip a single bit somewhere. Spooky! */
|
||||||
|
|
||||||
@ -2080,7 +2083,9 @@ havoc_stage:
|
|||||||
FLIP_BIT(out_buf, rand_below(afl, temp_len << 3));
|
FLIP_BIT(out_buf, rand_below(afl, temp_len << 3));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
}
|
||||||
|
|
||||||
|
case 4 ... 7: {
|
||||||
|
|
||||||
/* Set byte to interesting value. */
|
/* Set byte to interesting value. */
|
||||||
|
|
||||||
@ -2092,14 +2097,14 @@ havoc_stage:
|
|||||||
interesting_8[rand_below(afl, sizeof(interesting_8))];
|
interesting_8[rand_below(afl, sizeof(interesting_8))];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
}
|
||||||
|
|
||||||
|
case 8 ... 9: {
|
||||||
|
|
||||||
/* Set word to interesting value, randomly choosing endian. */
|
/* Set word to interesting value, randomly choosing endian. */
|
||||||
|
|
||||||
if (temp_len < 2) { break; }
|
if (temp_len < 2) { break; }
|
||||||
|
|
||||||
if (rand_below(afl, 2)) {
|
|
||||||
|
|
||||||
#ifdef INTROSPECTION
|
#ifdef INTROSPECTION
|
||||||
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16");
|
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16");
|
||||||
strcat(afl->mutation, afl->m_tmp);
|
strcat(afl->mutation, afl->m_tmp);
|
||||||
@ -2107,7 +2112,15 @@ havoc_stage:
|
|||||||
*(u16 *)(out_buf + rand_below(afl, temp_len - 1)) =
|
*(u16 *)(out_buf + rand_below(afl, temp_len - 1)) =
|
||||||
interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)];
|
interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)];
|
||||||
|
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case 10 ... 11: {
|
||||||
|
|
||||||
|
/* Set word to interesting value, randomly choosing endian. */
|
||||||
|
|
||||||
|
if (temp_len < 2) { break; }
|
||||||
|
|
||||||
#ifdef INTROSPECTION
|
#ifdef INTROSPECTION
|
||||||
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16BE");
|
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16BE");
|
||||||
@ -2116,18 +2129,16 @@ havoc_stage:
|
|||||||
*(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = SWAP16(
|
*(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = SWAP16(
|
||||||
interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]);
|
interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
}
|
||||||
|
|
||||||
|
case 12 ... 13: {
|
||||||
|
|
||||||
/* Set dword to interesting value, randomly choosing endian. */
|
/* Set dword to interesting value, randomly choosing endian. */
|
||||||
|
|
||||||
if (temp_len < 4) { break; }
|
if (temp_len < 4) { break; }
|
||||||
|
|
||||||
if (rand_below(afl, 2)) {
|
|
||||||
|
|
||||||
#ifdef INTROSPECTION
|
#ifdef INTROSPECTION
|
||||||
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32");
|
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32");
|
||||||
strcat(afl->mutation, afl->m_tmp);
|
strcat(afl->mutation, afl->m_tmp);
|
||||||
@ -2135,7 +2146,15 @@ havoc_stage:
|
|||||||
*(u32 *)(out_buf + rand_below(afl, temp_len - 3)) =
|
*(u32 *)(out_buf + rand_below(afl, temp_len - 3)) =
|
||||||
interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)];
|
interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)];
|
||||||
|
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case 14 ... 15: {
|
||||||
|
|
||||||
|
/* Set dword to interesting value, randomly choosing endian. */
|
||||||
|
|
||||||
|
if (temp_len < 4) { break; }
|
||||||
|
|
||||||
#ifdef INTROSPECTION
|
#ifdef INTROSPECTION
|
||||||
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32BE");
|
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32BE");
|
||||||
@ -2144,11 +2163,11 @@ havoc_stage:
|
|||||||
*(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = SWAP32(
|
*(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = SWAP32(
|
||||||
interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]);
|
interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
}
|
||||||
|
|
||||||
|
case 16 ... 19: {
|
||||||
|
|
||||||
/* Randomly subtract from byte. */
|
/* Randomly subtract from byte. */
|
||||||
|
|
||||||
@ -2159,7 +2178,9 @@ havoc_stage:
|
|||||||
out_buf[rand_below(afl, temp_len)] -= 1 + rand_below(afl, ARITH_MAX);
|
out_buf[rand_below(afl, temp_len)] -= 1 + rand_below(afl, ARITH_MAX);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
}
|
||||||
|
|
||||||
|
case 20 ... 23: {
|
||||||
|
|
||||||
/* Randomly add to byte. */
|
/* Randomly add to byte. */
|
||||||
|
|
||||||
@ -2170,14 +2191,14 @@ havoc_stage:
|
|||||||
out_buf[rand_below(afl, temp_len)] += 1 + rand_below(afl, ARITH_MAX);
|
out_buf[rand_below(afl, temp_len)] += 1 + rand_below(afl, ARITH_MAX);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
}
|
||||||
|
|
||||||
/* Randomly subtract from word, random endian. */
|
case 24 ... 25: {
|
||||||
|
|
||||||
|
/* Randomly subtract from word, little endian. */
|
||||||
|
|
||||||
if (temp_len < 2) { break; }
|
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
|
#ifdef INTROSPECTION
|
||||||
@ -2186,7 +2207,15 @@ havoc_stage:
|
|||||||
#endif
|
#endif
|
||||||
*(u16 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX);
|
*(u16 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX);
|
||||||
|
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case 26 ... 27: {
|
||||||
|
|
||||||
|
/* Randomly subtract from word, big endian. */
|
||||||
|
|
||||||
|
if (temp_len < 2) { break; }
|
||||||
|
|
||||||
u32 pos = rand_below(afl, temp_len - 1);
|
u32 pos = rand_below(afl, temp_len - 1);
|
||||||
u16 num = 1 + rand_below(afl, ARITH_MAX);
|
u16 num = 1 + rand_below(afl, ARITH_MAX);
|
||||||
@ -2199,18 +2228,16 @@ havoc_stage:
|
|||||||
*(u16 *)(out_buf + pos) =
|
*(u16 *)(out_buf + pos) =
|
||||||
SWAP16(SWAP16(*(u16 *)(out_buf + pos)) - num);
|
SWAP16(SWAP16(*(u16 *)(out_buf + pos)) - num);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
}
|
||||||
|
|
||||||
/* Randomly add to word, random endian. */
|
case 28 ... 29: {
|
||||||
|
|
||||||
|
/* Randomly add to word, little endian. */
|
||||||
|
|
||||||
if (temp_len < 2) { break; }
|
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
|
#ifdef INTROSPECTION
|
||||||
@ -2219,7 +2246,15 @@ havoc_stage:
|
|||||||
#endif
|
#endif
|
||||||
*(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX);
|
*(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX);
|
||||||
|
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case 30 ... 31: {
|
||||||
|
|
||||||
|
/* Randomly add to word, big endian. */
|
||||||
|
|
||||||
|
if (temp_len < 2) { break; }
|
||||||
|
|
||||||
u32 pos = rand_below(afl, temp_len - 1);
|
u32 pos = rand_below(afl, temp_len - 1);
|
||||||
u16 num = 1 + rand_below(afl, ARITH_MAX);
|
u16 num = 1 + rand_below(afl, ARITH_MAX);
|
||||||
@ -2232,18 +2267,16 @@ havoc_stage:
|
|||||||
*(u16 *)(out_buf + pos) =
|
*(u16 *)(out_buf + pos) =
|
||||||
SWAP16(SWAP16(*(u16 *)(out_buf + pos)) + num);
|
SWAP16(SWAP16(*(u16 *)(out_buf + pos)) + num);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
}
|
||||||
|
|
||||||
/* Randomly subtract from dword, random endian. */
|
case 32 ... 33: {
|
||||||
|
|
||||||
|
/* Randomly subtract from dword, little endian. */
|
||||||
|
|
||||||
if (temp_len < 4) { break; }
|
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
|
#ifdef INTROSPECTION
|
||||||
@ -2252,7 +2285,15 @@ havoc_stage:
|
|||||||
#endif
|
#endif
|
||||||
*(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX);
|
*(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX);
|
||||||
|
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case 34 ... 35: {
|
||||||
|
|
||||||
|
/* Randomly subtract from dword, big endian. */
|
||||||
|
|
||||||
|
if (temp_len < 4) { break; }
|
||||||
|
|
||||||
u32 pos = rand_below(afl, temp_len - 3);
|
u32 pos = rand_below(afl, temp_len - 3);
|
||||||
u32 num = 1 + rand_below(afl, ARITH_MAX);
|
u32 num = 1 + rand_below(afl, ARITH_MAX);
|
||||||
@ -2265,18 +2306,16 @@ havoc_stage:
|
|||||||
*(u32 *)(out_buf + pos) =
|
*(u32 *)(out_buf + pos) =
|
||||||
SWAP32(SWAP32(*(u32 *)(out_buf + pos)) - num);
|
SWAP32(SWAP32(*(u32 *)(out_buf + pos)) - num);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9:
|
}
|
||||||
|
|
||||||
/* Randomly add to dword, random endian. */
|
case 36 ... 37: {
|
||||||
|
|
||||||
|
/* Randomly add to dword, little endian. */
|
||||||
|
|
||||||
if (temp_len < 4) { break; }
|
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
|
#ifdef INTROSPECTION
|
||||||
@ -2285,7 +2324,15 @@ havoc_stage:
|
|||||||
#endif
|
#endif
|
||||||
*(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX);
|
*(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX);
|
||||||
|
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case 38 ... 39: {
|
||||||
|
|
||||||
|
/* Randomly add to dword, big endian. */
|
||||||
|
|
||||||
|
if (temp_len < 4) { break; }
|
||||||
|
|
||||||
u32 pos = rand_below(afl, temp_len - 3);
|
u32 pos = rand_below(afl, temp_len - 3);
|
||||||
u32 num = 1 + rand_below(afl, ARITH_MAX);
|
u32 num = 1 + rand_below(afl, ARITH_MAX);
|
||||||
@ -2298,11 +2345,11 @@ havoc_stage:
|
|||||||
*(u32 *)(out_buf + pos) =
|
*(u32 *)(out_buf + pos) =
|
||||||
SWAP32(SWAP32(*(u32 *)(out_buf + pos)) + num);
|
SWAP32(SWAP32(*(u32 *)(out_buf + pos)) + num);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 10:
|
}
|
||||||
|
|
||||||
|
case 40 ... 43: {
|
||||||
|
|
||||||
/* Just set a random byte to a random value. Because,
|
/* Just set a random byte to a random value. Because,
|
||||||
why not. We use XOR with 1-255 to eliminate the
|
why not. We use XOR with 1-255 to eliminate the
|
||||||
@ -2315,21 +2362,155 @@ havoc_stage:
|
|||||||
out_buf[rand_below(afl, temp_len)] ^= 1 + rand_below(afl, 255);
|
out_buf[rand_below(afl, temp_len)] ^= 1 + rand_below(afl, 255);
|
||||||
break;
|
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
|
/* Delete bytes. We're making this a bit more likely
|
||||||
than insertion (the next option) in hopes of keeping
|
than insertion (the next option) in hopes of keeping
|
||||||
files reasonably small. */
|
files reasonably small. */
|
||||||
|
|
||||||
u32 del_from, del_len;
|
|
||||||
|
|
||||||
if (temp_len < 2) { break; }
|
if (temp_len < 2) { break; }
|
||||||
|
|
||||||
/* Don't delete too much. */
|
/* Don't delete too much. */
|
||||||
|
|
||||||
del_len = choose_block_len(afl, temp_len - 1);
|
u32 del_len = choose_block_len(afl, temp_len - 1);
|
||||||
|
u32 del_from = rand_below(afl, temp_len - del_len + 1);
|
||||||
del_from = rand_below(afl, temp_len - del_len + 1);
|
|
||||||
|
|
||||||
#ifdef INTROSPECTION
|
#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,
|
||||||
@ -2345,151 +2526,15 @@ havoc_stage:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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:
|
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
|
if (afl->extras_cnt) {
|
||||||
present in the dictionaries. */
|
|
||||||
|
|
||||||
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))) {
|
|
||||||
|
|
||||||
/* No user-specified extras or odds in our favor. Let's use an
|
|
||||||
auto-detected one. */
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* No auto extras or odds in our favor. Use the dictionary. */
|
|
||||||
|
|
||||||
u32 use_extra = rand_below(afl, afl->extras_cnt);
|
u32 use_extra = rand_below(afl, afl->extras_cnt);
|
||||||
u32 extra_len = afl->extras[use_extra].len;
|
u32 extra_len = afl->extras[use_extra].len;
|
||||||
@ -2498,53 +2543,29 @@ havoc_stage:
|
|||||||
|
|
||||||
u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
|
u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
|
||||||
#ifdef INTROSPECTION
|
#ifdef INTROSPECTION
|
||||||
snprintf(afl->m_tmp, sizeof(afl->m_tmp),
|
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " EXTRA_OVERWRITE-%u-%u",
|
||||||
" EXTRA_OVERWRITE-%u-%u", insert_at, extra_len);
|
insert_at, extra_len);
|
||||||
strcat(afl->mutation, afl->m_tmp);
|
strcat(afl->mutation, afl->m_tmp);
|
||||||
#endif
|
#endif
|
||||||
memcpy(out_buf + insert_at, afl->extras[use_extra].data,
|
memcpy(out_buf + insert_at, afl->extras[use_extra].data,
|
||||||
extra_len);
|
extra_len);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} else { // case 16
|
} else if (r < 4) {
|
||||||
|
|
||||||
u32 use_extra, extra_len,
|
u32 use_extra = rand_below(afl, afl->extras_cnt);
|
||||||
insert_at = rand_below(afl, temp_len + 1);
|
u32 extra_len = afl->extras[use_extra].len;
|
||||||
u8 *ptr;
|
if (temp_len + extra_len >= MAX_FILE) { break; }
|
||||||
|
|
||||||
/* Insert an extra. Do the same dice-rolling stuff as for the
|
u8 *ptr = afl->extras[use_extra].data;
|
||||||
previous case. */
|
u32 insert_at = rand_below(afl, temp_len + 1);
|
||||||
|
|
||||||
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
|
#ifdef INTROSPECTION
|
||||||
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " EXTRA_INSERT-%u-%u",
|
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " EXTRA_INSERT-%u-%u",
|
||||||
insert_at, extra_len);
|
insert_at, extra_len);
|
||||||
strcat(afl->mutation, afl->m_tmp);
|
strcat(afl->mutation, afl->m_tmp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (temp_len + extra_len >= MAX_FILE) { break; }
|
|
||||||
|
|
||||||
out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len);
|
out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len);
|
||||||
if (unlikely(!out_buf)) { PFATAL("alloc"); }
|
if (unlikely(!out_buf)) { PFATAL("alloc"); }
|
||||||
|
|
||||||
@ -2554,23 +2575,77 @@ havoc_stage:
|
|||||||
|
|
||||||
/* Inserted part */
|
/* Inserted part */
|
||||||
memcpy(out_buf + insert_at, ptr, extra_len);
|
memcpy(out_buf + insert_at, ptr, extra_len);
|
||||||
|
|
||||||
temp_len += extra_len;
|
temp_len += extra_len;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
r -= 4;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
} else {
|
||||||
|
|
||||||
/*
|
r -= 2;
|
||||||
switch (r) {
|
|
||||||
|
|
||||||
case 15: // fall through
|
}
|
||||||
case 16:
|
|
||||||
case 17: {*/
|
|
||||||
|
|
||||||
/* Overwrite bytes with a randomly selected chunk from another
|
}
|
||||||
|
|
||||||
|
/* Splicing otherwise if we are still here.
|
||||||
|
Overwrite bytes with a randomly selected chunk from another
|
||||||
testcase or insert that chunk. */
|
testcase or insert that chunk. */
|
||||||
|
|
||||||
/* Pick a random queue entry and seek to it. */
|
/* Pick a random queue entry and seek to it. */
|
||||||
@ -2587,8 +2662,7 @@ havoc_stage:
|
|||||||
u32 new_len = target->len;
|
u32 new_len = target->len;
|
||||||
u8 * new_buf = queue_testcase_get(afl, target);
|
u8 * new_buf = queue_testcase_get(afl, target);
|
||||||
|
|
||||||
if ((temp_len >= 2 && rand_below(afl, 2)) ||
|
if ((temp_len >= 2 && r % 2) || temp_len + HAVOC_BLK_XL >= MAX_FILE) {
|
||||||
temp_len + HAVOC_BLK_XL >= MAX_FILE) {
|
|
||||||
|
|
||||||
/* overwrite mode */
|
/* overwrite mode */
|
||||||
|
|
||||||
@ -2648,9 +2722,7 @@ havoc_stage:
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
// end of default
|
||||||
|
|
||||||
// end of default:
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user