mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 11:08:06 +00:00
first commit, looks good
This commit is contained in:
@ -24,6 +24,11 @@
|
||||
*/
|
||||
|
||||
#include "afl-fuzz.h"
|
||||
#include <string.h>
|
||||
|
||||
static u8 *strnstr(const u8 *s, const u8 *find, size_t slen);
|
||||
static u32 string_replace(u8 **out_buf, s32 *temp_len, u32 pos, u8 *from,
|
||||
u8 *to);
|
||||
|
||||
/* MOpt */
|
||||
|
||||
@ -362,6 +367,446 @@ static void locate_diffs(u8 *ptr1, u8 *ptr2, u32 len, s32 *first, s32 *last) {
|
||||
|
||||
#endif /* !IGNORE_FINDS */
|
||||
|
||||
/* Not pretty, but saves a lot of writing */
|
||||
#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size
|
||||
|
||||
static u8 *strnstr(const u8 *s, const u8 *find, size_t slen) {
|
||||
|
||||
char c, sc;
|
||||
size_t len;
|
||||
|
||||
if ((c = *find++) != '\0') {
|
||||
|
||||
len = strlen(find);
|
||||
do {
|
||||
|
||||
do {
|
||||
|
||||
if (slen-- < 1 || (sc = *s++) == '\0') return (NULL);
|
||||
|
||||
} while (sc != c);
|
||||
|
||||
if (len > slen) return (NULL);
|
||||
|
||||
} while (strncmp(s, find, len) != 0);
|
||||
|
||||
s--;
|
||||
|
||||
}
|
||||
|
||||
return ((u8 *)s);
|
||||
|
||||
}
|
||||
|
||||
/* replace between deliminators, if rep == NULL, then we will duplicate the
|
||||
* target */
|
||||
|
||||
static u32 delim_replace(u8 **out_buf, s32 *temp_len, size_t pos,
|
||||
const u8 *ldelim, const u8 *rdelim, u8 *rep) {
|
||||
|
||||
u8 *end_buf = *out_buf + *temp_len;
|
||||
u8 *ldelim_start = strnstr(*out_buf + pos, ldelim, *temp_len - pos);
|
||||
|
||||
if (ldelim_start != NULL) {
|
||||
|
||||
u32 max = (end_buf - ldelim_start - 1 > AFL_TXT_STRING_MAX_LEN ? AFL_TXT_STRING_MAX_LEN : end_buf - ldelim_start - 1);
|
||||
|
||||
if (max > 0) {
|
||||
|
||||
u8 *rdelim_end =
|
||||
strnstr(ldelim_start + 1, rdelim, max);
|
||||
|
||||
if (rdelim_end != NULL) {
|
||||
|
||||
u32 rep_len, delim_space_len = rdelim_end - ldelim_start - 1, xtra = 0;
|
||||
|
||||
if (rep != NULL) {
|
||||
|
||||
rep_len = (u32)strlen(rep);
|
||||
|
||||
} else { // NULL? then we copy the value in between the delimiters
|
||||
|
||||
rep_len = delim_space_len;
|
||||
delim_space_len = 0;
|
||||
rep = ldelim_start + 1;
|
||||
xtra = rep_len;
|
||||
|
||||
}
|
||||
|
||||
if (rep_len != delim_space_len) {
|
||||
|
||||
memmove(ldelim_start + rep_len + xtra + 1, rdelim_end,
|
||||
*temp_len - (rdelim_end - *out_buf));
|
||||
|
||||
}
|
||||
|
||||
memcpy(ldelim_start + 1, rep, rep_len);
|
||||
*temp_len = (*temp_len - delim_space_len + rep_len);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static u32 delim_swap(u8 **out_buf, s32 *temp_len, size_t pos, const u8 *ldelim,
|
||||
const u8 *mdelim, const u8 *rdelim) {
|
||||
|
||||
u8 *out_buf_end = *out_buf + *temp_len;
|
||||
u32 max = (*temp_len - pos > AFL_TXT_STRING_MAX_LEN ? AFL_TXT_STRING_MAX_LEN
|
||||
: *temp_len - pos);
|
||||
u8 *ldelim_start = strnstr(*out_buf + pos, ldelim, max);
|
||||
|
||||
if (ldelim_start != NULL) {
|
||||
|
||||
max = (out_buf_end - ldelim_start - 1 > AFL_TXT_STRING_MAX_LEN
|
||||
? AFL_TXT_STRING_MAX_LEN
|
||||
: out_buf_end - ldelim_start - 1);
|
||||
if (max > 1) {
|
||||
|
||||
u8 *mdelim_pos = strnstr(ldelim_start + 1, mdelim, max);
|
||||
|
||||
if (mdelim_pos != NULL) {
|
||||
|
||||
max = (out_buf_end - mdelim_pos - 1 > AFL_TXT_STRING_MAX_LEN
|
||||
? AFL_TXT_STRING_MAX_LEN
|
||||
: out_buf_end - mdelim_pos - 1);
|
||||
if (max > 0) {
|
||||
|
||||
u8 *rdelim_end = strnstr(mdelim + 1, rdelim, max);
|
||||
|
||||
if (rdelim_end != NULL) {
|
||||
|
||||
u32 first_len = mdelim_pos - ldelim_start - 1;
|
||||
u32 second_len = rdelim_end - mdelim_pos - 1;
|
||||
u8 scratch[AFL_TXT_STRING_MAX_LEN];
|
||||
|
||||
memcpy(scratch, ldelim_start + 1, first_len);
|
||||
|
||||
if (first_len != second_len) {
|
||||
|
||||
memmove(ldelim_start + second_len + 1, mdelim_pos,
|
||||
out_buf_end - mdelim_pos);
|
||||
|
||||
}
|
||||
|
||||
memcpy(ldelim_start + 1, mdelim_pos + 1, second_len);
|
||||
|
||||
if (first_len != second_len) {
|
||||
|
||||
memmove(mdelim_pos + first_len + 1, rdelim_end,
|
||||
out_buf_end - rdelim_end);
|
||||
|
||||
}
|
||||
|
||||
memcpy(mdelim_pos + 1, scratch, first_len);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static u32 string_replace(u8 **out_buf, s32 *temp_len, u32 pos, u8 *from,
|
||||
u8 *to) {
|
||||
|
||||
u8 *start = strnstr(*out_buf + pos, from, *temp_len - pos);
|
||||
|
||||
if (start) {
|
||||
|
||||
u32 from_len = strlen(from);
|
||||
u32 to_len = strlen(to);
|
||||
|
||||
if (from_len != to_len) {
|
||||
|
||||
memmove(start + to_len, start + from_len,
|
||||
*temp_len - from_len - (start - *out_buf));
|
||||
|
||||
}
|
||||
|
||||
memcpy(start, to, to_len);
|
||||
*temp_len = (*temp_len - from_len + to_len);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/* Returns 1 if a mutant was generated and placed in out_buf, 0 if none
|
||||
* generated. */
|
||||
|
||||
static int text_mutation(afl_state_t *afl, u8 **out_buf, s32 *orig_temp_len) {
|
||||
|
||||
s32 temp_len;
|
||||
u32 pos, yes = 0,
|
||||
mutations = rand_below(afl, AFL_TXT_STRING_MAX_MUTATIONS) + 1;
|
||||
u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch),
|
||||
*orig_temp_len + AFL_TXT_STRING_MAX_MUTATIONS);
|
||||
temp_len = *orig_temp_len;
|
||||
memcpy(new_buf, *out_buf, temp_len);
|
||||
|
||||
for (u32 i = 0; i < mutations; i++) {
|
||||
|
||||
if (temp_len < AFL_TXT_MIN_LEN) { return 0; }
|
||||
|
||||
pos = rand_below(afl, temp_len - 1);
|
||||
int choice = rand_below(afl, 72);
|
||||
switch (choice) {
|
||||
|
||||
case 0: /* Semantic statement deletion */
|
||||
yes += string_replace(out_buf, &temp_len, pos, "\n", "\nif (0==1)\n");
|
||||
break;
|
||||
case 1:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "(", "(!");
|
||||
break;
|
||||
case 2:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "==", "!=");
|
||||
break;
|
||||
case 3:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "!=", "==");
|
||||
break;
|
||||
case 4:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "==", "<");
|
||||
break;
|
||||
case 5:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "<", "==");
|
||||
break;
|
||||
case 6:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "==", ">");
|
||||
break;
|
||||
case 7:
|
||||
yes += string_replace(out_buf, &temp_len, pos, ">", "==");
|
||||
break;
|
||||
case 8:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "=", "<");
|
||||
break;
|
||||
case 9:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "=", ">");
|
||||
break;
|
||||
case 10:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "<", ">");
|
||||
break;
|
||||
case 11:
|
||||
yes += string_replace(out_buf, &temp_len, pos, ">", "<");
|
||||
break;
|
||||
case 12:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "++", "--");
|
||||
break;
|
||||
case 13:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "--", "++");
|
||||
break;
|
||||
case 14:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "+", "-");
|
||||
break;
|
||||
case 15:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "+", "*");
|
||||
break;
|
||||
case 16:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "+", "/");
|
||||
break;
|
||||
case 17:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "+", "%");
|
||||
break;
|
||||
case 18:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "*", "-");
|
||||
break;
|
||||
case 19:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "*", "+");
|
||||
break;
|
||||
case 20:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "*", "/");
|
||||
break;
|
||||
case 21:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "*", "%");
|
||||
break;
|
||||
case 22:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "-", "+");
|
||||
break;
|
||||
case 23:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "-", "*");
|
||||
break;
|
||||
case 24:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "-", "/");
|
||||
break;
|
||||
case 25:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "-", "%");
|
||||
break;
|
||||
case 26:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "/", "-");
|
||||
break;
|
||||
case 27:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "/", "*");
|
||||
break;
|
||||
case 28:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "/", "+");
|
||||
break;
|
||||
case 29:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "/", "%");
|
||||
break;
|
||||
case 30:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "%", "-");
|
||||
break;
|
||||
case 31:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "%", "*");
|
||||
break;
|
||||
case 32:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "%", "/");
|
||||
break;
|
||||
case 33:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "%", "+");
|
||||
break;
|
||||
case 34:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "\n", "\nbreak;\n");
|
||||
break;
|
||||
case 35:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "\n", "\ncontinue;\n");
|
||||
break;
|
||||
case 36:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "0", "1");
|
||||
break;
|
||||
case 37:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "1", "0");
|
||||
break;
|
||||
case 38:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "if", "while");
|
||||
break;
|
||||
case 39:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "while", "if");
|
||||
break;
|
||||
case 40:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "\n", "\nwhile(1==1)\n");
|
||||
break;
|
||||
case 41:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "&&", "||");
|
||||
break;
|
||||
case 42:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "||", "&&");
|
||||
break;
|
||||
case 43:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "!", "");
|
||||
break;
|
||||
case 44:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "==", "=");
|
||||
break;
|
||||
case 45:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "--", "");
|
||||
break;
|
||||
case 46:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "<<", "<");
|
||||
break;
|
||||
case 47:
|
||||
yes += string_replace(out_buf, &temp_len, pos, ">>", ">");
|
||||
break;
|
||||
case 48:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "<", "<<");
|
||||
break;
|
||||
case 49:
|
||||
yes += string_replace(out_buf, &temp_len, pos, ">", ">>");
|
||||
break;
|
||||
case 50:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "\"", "'");
|
||||
break;
|
||||
case 51:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "'", "\"");
|
||||
break;
|
||||
case 52:
|
||||
yes += string_replace(out_buf, &temp_len, pos, "(", "\"");
|
||||
break;
|
||||
case 53: /* Remove a semicolon delimited statement after a semicolon */
|
||||
yes += delim_replace(out_buf, &temp_len, pos, ";", ";", ";");
|
||||
break;
|
||||
case 54: /* Remove a semicolon delimited statement after a left curly
|
||||
brace */
|
||||
yes += delim_replace(out_buf, &temp_len, pos, "}", ";", "}");
|
||||
break;
|
||||
case 55: /* Remove a curly brace construct */
|
||||
yes += delim_replace(out_buf, &temp_len, pos, "{", "}", "");
|
||||
break;
|
||||
case 56: /* Replace a curly brace construct with an empty one */
|
||||
yes += delim_replace(out_buf, &temp_len, pos, "{", "}", "{}");
|
||||
break;
|
||||
case 57:
|
||||
yes += delim_swap(out_buf, &temp_len, pos, ";", ";", ";");
|
||||
break;
|
||||
case 58:
|
||||
yes += delim_swap(out_buf, &temp_len, pos, "}", ";", ";");
|
||||
break;
|
||||
case 59: /* Swap comma delimited things case 1 */
|
||||
yes += delim_swap(out_buf, &temp_len, pos, "(", ",", ")");
|
||||
break;
|
||||
case 60: /* Swap comma delimited things case 2 */
|
||||
yes += delim_swap(out_buf, &temp_len, pos, "(", ",", ",");
|
||||
break;
|
||||
case 61: /* Swap comma delimited things case 3 */
|
||||
yes += delim_swap(out_buf, &temp_len, pos, ",", ",", ",");
|
||||
break;
|
||||
case 62: /* Swap comma delimited things case 4 */
|
||||
yes += delim_swap(out_buf, &temp_len, pos, ",", ",", ")");
|
||||
break;
|
||||
case 63: /* Just delete a line */
|
||||
yes += delim_replace(out_buf, &temp_len, pos, "\n", "\n", "");
|
||||
break;
|
||||
case 64: /* Delete something like "const" case 1 */
|
||||
yes += delim_replace(out_buf, &temp_len, pos, " ", " ", "");
|
||||
break;
|
||||
case 65: /* Delete something like "const" case 2 */
|
||||
yes += delim_replace(out_buf, &temp_len, pos, "\n", " ", "");
|
||||
break;
|
||||
case 66: /* Delete something like "const" case 3 */
|
||||
yes += delim_replace(out_buf, &temp_len, pos, "(", " ", "");
|
||||
break;
|
||||
case 67: /* Swap space delimited things case 1 */
|
||||
yes += delim_swap(out_buf, &temp_len, pos, " ", " ", " ");
|
||||
break;
|
||||
case 68: /* Swap space delimited things case 2 */
|
||||
yes += delim_swap(out_buf, &temp_len, pos, " ", " ", ")");
|
||||
break;
|
||||
case 69: /* Swap space delimited things case 3 */
|
||||
yes += delim_swap(out_buf, &temp_len, pos, "(", " ", " ");
|
||||
break;
|
||||
case 70: /* Swap space delimited things case 4 */
|
||||
yes += delim_swap(out_buf, &temp_len, pos, "(", " ", ")");
|
||||
break;
|
||||
case 71: /* Duplicate a single line of code */
|
||||
yes += delim_replace(out_buf, &temp_len, pos, "\n", "\n", NULL);
|
||||
break;
|
||||
case 72: /* Duplicate a construct (most often, a non-nested for loop */
|
||||
yes += delim_replace(out_buf, &temp_len, pos, "\n", "}", NULL);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (yes == 0 || temp_len <= 0) { return 0; }
|
||||
|
||||
swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch));
|
||||
*out_buf = new_buf;
|
||||
*orig_temp_len = temp_len;
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
/* Take the current entry from the queue, fuzz it for a while. This
|
||||
function is a tad too long... returns 0 if fuzzed successfully, 1 if
|
||||
skipped or bailed out. */
|
||||
@ -378,9 +823,6 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
||||
u8 a_collect[MAX_AUTO_EXTRA];
|
||||
u32 a_len = 0;
|
||||
|
||||
/* Not pretty, but saves a lot of writing */
|
||||
#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size
|
||||
|
||||
#ifdef IGNORE_FINDS
|
||||
|
||||
/* In IGNORE_FINDS mode, skip any entries that weren't in the
|
||||
@ -1853,9 +2295,12 @@ 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 = 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0) +
|
||||
(afl->queue_cur->is_ascii ? AFL_TXT_BIAS : 0);
|
||||
|
||||
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
|
||||
|
||||
u32 use_stacking = 1 << (1 + rand_below(afl, HAVOC_STACK_POW2));
|
||||
u32 r, use_stacking = 1 << (1 + rand_below(afl, HAVOC_STACK_POW2));
|
||||
|
||||
afl->stage_cur_val = use_stacking;
|
||||
|
||||
@ -1895,8 +2340,9 @@ havoc_stage:
|
||||
|
||||
}
|
||||
|
||||
switch (rand_below(
|
||||
afl, 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0))) {
|
||||
retry_havoc:
|
||||
|
||||
switch ((r = rand_below(afl, r_max))) {
|
||||
|
||||
case 0:
|
||||
|
||||
@ -2191,86 +2637,96 @@ havoc_stage:
|
||||
|
||||
}
|
||||
|
||||
/* Values 15 and 16 can be selected only if there are any extras
|
||||
present in the dictionaries. */
|
||||
// TODO: add splicing mutation here.
|
||||
// 15:
|
||||
// break;
|
||||
|
||||
case 15: {
|
||||
default:
|
||||
if (r == 15 && (afl->extras_cnt || afl->a_extras_cnt)) {
|
||||
|
||||
/* Overwrite bytes with an extra. */
|
||||
/* Values 15 and 16 can be selected only if there are any extras
|
||||
present in the dictionaries. */
|
||||
|
||||
if (!afl->extras_cnt || (afl->a_extras_cnt && rand_below(afl, 2))) {
|
||||
/* Overwrite bytes with an extra. */
|
||||
|
||||
/* No user-specified extras or odds in our favor. Let's use an
|
||||
auto-detected one. */
|
||||
if (!afl->extras_cnt || (afl->a_extras_cnt && rand_below(afl, 2))) {
|
||||
|
||||
u32 use_extra = rand_below(afl, afl->a_extras_cnt);
|
||||
u32 extra_len = afl->a_extras[use_extra].len;
|
||||
u32 insert_at;
|
||||
/* 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;
|
||||
u32 insert_at;
|
||||
|
||||
insert_at = rand_below(afl, temp_len - extra_len + 1);
|
||||
memcpy(out_buf + insert_at, afl->a_extras[use_extra].data,
|
||||
extra_len);
|
||||
if (extra_len > temp_len) { break; }
|
||||
|
||||
insert_at = rand_below(afl, temp_len - extra_len + 1);
|
||||
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;
|
||||
u32 insert_at;
|
||||
|
||||
if (extra_len > temp_len) { break; }
|
||||
|
||||
insert_at = rand_below(afl, temp_len - extra_len + 1);
|
||||
memcpy(out_buf + insert_at, afl->extras[use_extra].data,
|
||||
extra_len);
|
||||
|
||||
}
|
||||
|
||||
} else if (r == 16 && (afl->extras_cnt || afl->a_extras_cnt)) {
|
||||
|
||||
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;
|
||||
|
||||
} else {
|
||||
|
||||
use_extra = rand_below(afl, afl->extras_cnt);
|
||||
extra_len = afl->extras[use_extra].len;
|
||||
ptr = afl->extras[use_extra].data;
|
||||
|
||||
}
|
||||
|
||||
if (temp_len + extra_len >= MAX_FILE) { break; }
|
||||
|
||||
out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len);
|
||||
|
||||
/* 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;
|
||||
|
||||
} else {
|
||||
|
||||
/* No auto extras or odds in our favor. Use the dictionary. */
|
||||
// ascii mutations
|
||||
if (text_mutation(afl, &out_buf, &temp_len) == 0) goto retry_havoc;
|
||||
|
||||
u32 use_extra = rand_below(afl, afl->extras_cnt);
|
||||
u32 extra_len = afl->extras[use_extra].len;
|
||||
u32 insert_at;
|
||||
|
||||
if (extra_len > temp_len) { break; }
|
||||
|
||||
insert_at = rand_below(afl, temp_len - extra_len + 1);
|
||||
memcpy(out_buf + insert_at, afl->extras[use_extra].data, extra_len);
|
||||
//#ifdef _AFL_DOCUMENT_MUTATIONS
|
||||
// fprintf(stderr, "MUTATED: %s/mutations/%09u:*\n", afl->out_dir,
|
||||
// afl->document_counter);
|
||||
//#endif
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case 16: {
|
||||
|
||||
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;
|
||||
|
||||
} else {
|
||||
|
||||
use_extra = rand_below(afl, afl->extras_cnt);
|
||||
extra_len = afl->extras[use_extra].len;
|
||||
ptr = afl->extras[use_extra].data;
|
||||
|
||||
}
|
||||
|
||||
if (temp_len + extra_len >= MAX_FILE) { break; }
|
||||
|
||||
out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len);
|
||||
|
||||
/* 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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user