From ce9b4698fec5222e0af1b62d68c4105e6364771e Mon Sep 17 00:00:00 2001 From: van Hauser Date: Tue, 21 Jul 2020 20:53:51 +0200 Subject: added andrea's splicing, added cycle_schedules --- src/afl-fuzz.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) (limited to 'src/afl-fuzz.c') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index df2896d2..88f8e902 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1252,11 +1252,42 @@ int main(int argc, char **argv_orig, char **envp) { /* If we had a full queue cycle with no new finds, try recombination strategies next. */ - if (afl->queued_paths == prev_queued) { + if (afl->queued_paths == prev_queued && + (get_cur_time() - afl->start_time) >= 3600) { if (afl->use_splicing) { ++afl->cycles_wo_finds; + switch (afl->expand_havoc) { + + case 0: + afl->expand_havoc = 1; + break; + case 1: + if (afl->limit_time_sig == 0) { + + afl->limit_time_sig = -1; + afl->limit_time_puppet = 0; + + } + + afl->expand_havoc = 2; + break; + case 2: + afl->cycle_schedules = 1; + afl->expand_havoc = 3; + break; + case 3: + // nothing else currently + break; + + } + + if (afl->expand_havoc) { + + } else + + afl->expand_havoc = 1; } else { @@ -1270,6 +1301,53 @@ int main(int argc, char **argv_orig, char **envp) { } + if (afl->cycle_schedules) { + + /* we cannot mix non-AFLfast schedules with others */ + + switch (afl->schedule) { + + case EXPLORE: + afl->schedule = EXPLOIT; + break; + case EXPLOIT: + afl->schedule = MMOPT; + break; + case MMOPT: + afl->schedule = SEEK; + break; + case SEEK: + afl->schedule = EXPLORE; + break; + case FAST: + afl->schedule = COE; + break; + case COE: + afl->schedule = LIN; + break; + case LIN: + afl->schedule = QUAD; + break; + case QUAD: + afl->schedule = RARE; + break; + case RARE: + afl->schedule = FAST; + break; + + } + + struct queue_entry *q = afl->queue; + // we must recalculate the scores of all queue entries + while (q) { + + update_bitmap_score(afl, q); + q = q->next; + + } + + } + prev_queued = afl->queued_paths; if (afl->sync_id && afl->queue_cycle == 1 && -- cgit 1.4.1 From b015e4f07aabb39e1683406704f2aae1f7dcde4a Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Wed, 22 Jul 2020 16:15:16 +0200 Subject: epand havoc now env --- include/envs.h | 1 + src/afl-fuzz-one.c | 211 ++++++++++++++++++++++++++++++++++------------------- src/afl-fuzz.c | 1 + 3 files changed, 138 insertions(+), 75 deletions(-) (limited to 'src/afl-fuzz.c') diff --git a/include/envs.h b/include/envs.h index cb3c183e..c1c7d387 100644 --- a/include/envs.h +++ b/include/envs.h @@ -130,6 +130,7 @@ static char *afl_environment_variables[] = { "AFL_USE_CFISAN", "AFL_WINE_PATH", "AFL_NO_SNAPSHOT", + "AFL_EXPAND_HAVOC_NOW", NULL }; diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 250409da..a0ecb7a9 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -564,238 +564,299 @@ static int text_mutation(afl_state_t *afl, u8 **out_buf, s32 *orig_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); + *orig_temp_len + AFL_TXT_STRING_MAX_MUTATIONS +1); temp_len = *orig_temp_len; memcpy(new_buf, *out_buf, temp_len); + new_buf[temp_len] = 0; 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); + int choice = rand_below(afl, 80); switch (choice) { case 0: /* Semantic statement deletion */ - yes += string_replace(out_buf, &temp_len, pos, "\n", "#"); + yes += string_replace(&new_buf, &temp_len, pos, "\n", "#"); break; case 1: - yes += string_replace(out_buf, &temp_len, pos, "(", "(!"); + yes += string_replace(&new_buf, &temp_len, pos, "(", "(!"); break; case 2: - yes += string_replace(out_buf, &temp_len, pos, "==", "!="); + yes += string_replace(&new_buf, &temp_len, pos, "==", "!="); break; case 3: - yes += string_replace(out_buf, &temp_len, pos, "!=", "=="); + yes += string_replace(&new_buf, &temp_len, pos, "!=", "=="); break; case 4: - yes += string_replace(out_buf, &temp_len, pos, "==", "<"); + yes += string_replace(&new_buf, &temp_len, pos, "==", "<"); break; case 5: - yes += string_replace(out_buf, &temp_len, pos, "<", "=="); + yes += string_replace(&new_buf, &temp_len, pos, "<", "=="); break; case 6: - yes += string_replace(out_buf, &temp_len, pos, "==", ">"); + yes += string_replace(&new_buf, &temp_len, pos, "==", ">"); break; case 7: - yes += string_replace(out_buf, &temp_len, pos, ">", "=="); + yes += string_replace(&new_buf, &temp_len, pos, ">", "=="); break; case 8: - yes += string_replace(out_buf, &temp_len, pos, "=", "<"); + yes += string_replace(&new_buf, &temp_len, pos, "=", "<"); break; case 9: - yes += string_replace(out_buf, &temp_len, pos, "=", ">"); + yes += string_replace(&new_buf, &temp_len, pos, "=", ">"); break; case 10: - yes += string_replace(out_buf, &temp_len, pos, "<", ">"); + yes += string_replace(&new_buf, &temp_len, pos, "<", ">"); break; case 11: - yes += string_replace(out_buf, &temp_len, pos, ">", "<"); + yes += string_replace(&new_buf, &temp_len, pos, ">", "<"); break; case 12: - yes += string_replace(out_buf, &temp_len, pos, "++", "--"); + yes += string_replace(&new_buf, &temp_len, pos, "++", "--"); break; case 13: - yes += string_replace(out_buf, &temp_len, pos, "--", "++"); + yes += string_replace(&new_buf, &temp_len, pos, "--", "++"); break; case 14: - yes += string_replace(out_buf, &temp_len, pos, "+", "-"); + yes += string_replace(&new_buf, &temp_len, pos, "+", "-"); break; case 15: - yes += string_replace(out_buf, &temp_len, pos, "+", "*"); + yes += string_replace(&new_buf, &temp_len, pos, "+", "*"); break; case 16: - yes += string_replace(out_buf, &temp_len, pos, "+", "/"); + yes += string_replace(&new_buf, &temp_len, pos, "+", "/"); break; case 17: - yes += string_replace(out_buf, &temp_len, pos, "+", "%"); + yes += string_replace(&new_buf, &temp_len, pos, "+", "%"); break; case 18: - yes += string_replace(out_buf, &temp_len, pos, "*", "-"); + yes += string_replace(&new_buf, &temp_len, pos, "*", "-"); break; case 19: - yes += string_replace(out_buf, &temp_len, pos, "*", "+"); + yes += string_replace(&new_buf, &temp_len, pos, "*", "+"); break; case 20: - yes += string_replace(out_buf, &temp_len, pos, "*", "/"); + yes += string_replace(&new_buf, &temp_len, pos, "*", "/"); break; case 21: - yes += string_replace(out_buf, &temp_len, pos, "*", "%"); + yes += string_replace(&new_buf, &temp_len, pos, "*", "%"); break; case 22: - yes += string_replace(out_buf, &temp_len, pos, "-", "+"); + yes += string_replace(&new_buf, &temp_len, pos, "-", "+"); break; case 23: - yes += string_replace(out_buf, &temp_len, pos, "-", "*"); + yes += string_replace(&new_buf, &temp_len, pos, "-", "*"); break; case 24: - yes += string_replace(out_buf, &temp_len, pos, "-", "/"); + yes += string_replace(&new_buf, &temp_len, pos, "-", "/"); break; case 25: - yes += string_replace(out_buf, &temp_len, pos, "-", "%"); + yes += string_replace(&new_buf, &temp_len, pos, "-", "%"); break; case 26: - yes += string_replace(out_buf, &temp_len, pos, "/", "-"); + yes += string_replace(&new_buf, &temp_len, pos, "/", "-"); break; case 27: - yes += string_replace(out_buf, &temp_len, pos, "/", "*"); + yes += string_replace(&new_buf, &temp_len, pos, "/", "*"); break; case 28: - yes += string_replace(out_buf, &temp_len, pos, "/", "+"); + yes += string_replace(&new_buf, &temp_len, pos, "/", "+"); break; case 29: - yes += string_replace(out_buf, &temp_len, pos, "/", "%"); + yes += string_replace(&new_buf, &temp_len, pos, "/", "%"); break; case 30: - yes += string_replace(out_buf, &temp_len, pos, "%", "-"); + yes += string_replace(&new_buf, &temp_len, pos, "%", "-"); break; case 31: - yes += string_replace(out_buf, &temp_len, pos, "%", "*"); + yes += string_replace(&new_buf, &temp_len, pos, "%", "*"); break; case 32: - yes += string_replace(out_buf, &temp_len, pos, "%", "/"); + yes += string_replace(&new_buf, &temp_len, pos, "%", "/"); break; case 33: - yes += string_replace(out_buf, &temp_len, pos, "%", "+"); + yes += string_replace(&new_buf, &temp_len, pos, "%", "+"); break; case 34: - yes += string_replace(out_buf, &temp_len, pos, " ", "|"); + yes += string_replace(&new_buf, &temp_len, pos, " ", "|"); break; case 35: - yes += string_replace(out_buf, &temp_len, pos, " ", "$"); + yes += string_replace(&new_buf, &temp_len, pos, " ", "$"); break; case 36: - yes += string_replace(out_buf, &temp_len, pos, "0", "1"); + yes += string_replace(&new_buf, &temp_len, pos, "0", "1"); break; case 37: - yes += string_replace(out_buf, &temp_len, pos, "1", "0"); + yes += string_replace(&new_buf, &temp_len, pos, "1", "0"); break; case 38: - yes += string_replace(out_buf, &temp_len, pos, " ", "`"); + yes += string_replace(&new_buf, &temp_len, pos, " ", "`"); break; case 39: - yes += string_replace(out_buf, &temp_len, pos, " ", "\""); + yes += string_replace(&new_buf, &temp_len, pos, " ", "\""); break; case 40: - yes += string_replace(out_buf, &temp_len, pos, ";", " "); + yes += string_replace(&new_buf, &temp_len, pos, ";", " "); break; case 41: - yes += string_replace(out_buf, &temp_len, pos, "&&", "||"); + yes += string_replace(&new_buf, &temp_len, pos, "&&", "||"); break; case 42: - yes += string_replace(out_buf, &temp_len, pos, "||", "&&"); + yes += string_replace(&new_buf, &temp_len, pos, "||", "&&"); break; case 43: - yes += string_replace(out_buf, &temp_len, pos, "!", ""); + yes += string_replace(&new_buf, &temp_len, pos, "!", ""); break; case 44: - yes += string_replace(out_buf, &temp_len, pos, "==", "="); + yes += string_replace(&new_buf, &temp_len, pos, "==", "="); break; case 45: - yes += string_replace(out_buf, &temp_len, pos, "--", ""); + yes += string_replace(&new_buf, &temp_len, pos, "--", ""); break; case 46: - yes += string_replace(out_buf, &temp_len, pos, "<<", "<"); + yes += string_replace(&new_buf, &temp_len, pos, "<<", "<"); break; case 47: - yes += string_replace(out_buf, &temp_len, pos, ">>", ">"); + yes += string_replace(&new_buf, &temp_len, pos, ">>", ">"); break; case 48: - yes += string_replace(out_buf, &temp_len, pos, "<", "<<"); + yes += string_replace(&new_buf, &temp_len, pos, "<", "<<"); break; case 49: - yes += string_replace(out_buf, &temp_len, pos, ">", ">>"); + yes += string_replace(&new_buf, &temp_len, pos, ">", ">>"); break; case 50: - yes += string_replace(out_buf, &temp_len, pos, "\"", "'"); + yes += string_replace(&new_buf, &temp_len, pos, "\"", "'"); break; case 51: - yes += string_replace(out_buf, &temp_len, pos, "'", "\""); + yes += string_replace(&new_buf, &temp_len, pos, "'", "\""); break; case 52: - yes += string_replace(out_buf, &temp_len, pos, "(", "\""); + yes += string_replace(&new_buf, &temp_len, pos, "(", "\""); break; case 53: /* Remove a semicolon delimited statement after a semicolon */ - yes += delim_replace(out_buf, &temp_len, pos, ";", ";", ";"); + yes += delim_replace(&new_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, "}", ";", "}"); + yes += delim_replace(&new_buf, &temp_len, pos, "}", ";", "}"); break; case 55: /* Remove a curly brace construct */ - yes += delim_replace(out_buf, &temp_len, pos, "{", "}", ""); + yes += delim_replace(&new_buf, &temp_len, pos, "{", "}", ""); break; case 56: /* Replace a curly brace construct with an empty one */ - yes += delim_replace(out_buf, &temp_len, pos, "{", "}", "{}"); + yes += delim_replace(&new_buf, &temp_len, pos, "{", "}", "{}"); break; case 57: - yes += delim_swap(out_buf, &temp_len, pos, ";", ";", ";"); + yes += delim_swap(&new_buf, &temp_len, pos, ";", ";", ";"); break; case 58: - yes += delim_swap(out_buf, &temp_len, pos, "}", ";", ";"); + yes += delim_swap(&new_buf, &temp_len, pos, "}", ";", ";"); break; case 59: /* Swap comma delimited things case 1 */ - yes += delim_swap(out_buf, &temp_len, pos, "(", ",", ")"); + yes += delim_swap(&new_buf, &temp_len, pos, "(", ",", ")"); break; case 60: /* Swap comma delimited things case 2 */ - yes += delim_swap(out_buf, &temp_len, pos, "(", ",", ","); + yes += delim_swap(&new_buf, &temp_len, pos, "(", ",", ","); break; case 61: /* Swap comma delimited things case 3 */ - yes += delim_swap(out_buf, &temp_len, pos, ",", ",", ","); + yes += delim_swap(&new_buf, &temp_len, pos, ",", ",", ","); break; case 62: /* Swap comma delimited things case 4 */ - yes += delim_swap(out_buf, &temp_len, pos, ",", ",", ")"); + yes += delim_swap(&new_buf, &temp_len, pos, ",", ",", ")"); break; case 63: /* Just delete a line */ - yes += delim_replace(out_buf, &temp_len, pos, "\n", "\n", ""); + yes += delim_replace(&new_buf, &temp_len, pos, "\n", "\n", ""); break; case 64: /* Delete something like "const" case 1 */ - yes += delim_replace(out_buf, &temp_len, pos, " ", " ", ""); + yes += delim_replace(&new_buf, &temp_len, pos, " ", " ", ""); break; case 65: /* Delete something like "const" case 2 */ - yes += delim_replace(out_buf, &temp_len, pos, "\n", " ", ""); + yes += delim_replace(&new_buf, &temp_len, pos, "\n", " ", ""); break; case 66: /* Delete something like "const" case 3 */ - yes += delim_replace(out_buf, &temp_len, pos, "(", " ", ""); + yes += delim_replace(&new_buf, &temp_len, pos, "(", " ", ""); break; case 67: /* Swap space delimited things case 1 */ - yes += delim_swap(out_buf, &temp_len, pos, " ", " ", " "); + yes += delim_swap(&new_buf, &temp_len, pos, " ", " ", " "); break; case 68: /* Swap space delimited things case 2 */ - yes += delim_swap(out_buf, &temp_len, pos, " ", " ", ")"); + yes += delim_swap(&new_buf, &temp_len, pos, " ", " ", ")"); break; case 69: /* Swap space delimited things case 3 */ - yes += delim_swap(out_buf, &temp_len, pos, "(", " ", " "); + yes += delim_swap(&new_buf, &temp_len, pos, "(", " ", " "); break; case 70: /* Swap space delimited things case 4 */ - yes += delim_swap(out_buf, &temp_len, pos, "(", " ", ")"); + yes += delim_swap(&new_buf, &temp_len, pos, "(", " ", ")"); break; case 71: /* Duplicate a single line of code */ - yes += delim_replace(out_buf, &temp_len, pos, "\n", "\n", NULL); + yes += delim_replace(&new_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); + yes += delim_replace(&new_buf, &temp_len, pos, "\n", "}", NULL); break; + default: { + + for (u32 j = pos; j < temp_len; ++j) { + if (isdigit(new_buf[j])) { + + u8* endptr; + unsigned long long num = strtoull(new_buf +j, (char**)&endptr, 0); + + switch (rand_below(afl, 8)) { + case 0: + num = rand_below(afl, INT_MAX); + break; + case 1: + num = rand_next(afl); + break; + case 2: + num += 1 + rand_below(afl, 255); + break; + case 3: + num -= 1 + rand_below(afl, 255); + break; + case 4: + num *= 1 + rand_below(afl, 255); + break; + case 5: + num /= 1 + rand_below(afl, 255); + break; + case 6: + num /= 1 + rand_below(afl, 255); + break; + case 7: + num = ~num; + break; + } + + const char* fmt = "%llu"; + if (rand_below(afl, 5) == 0) // add - sign with 1/5 probability + fmt = "-%llu"; + + size_t num_len = snprintf(NULL, 0, fmt, num); + size_t old_len = endptr - (new_buf +j); + if (num_len < old_len) { + memmove(new_buf +j +num_len, endptr, temp_len - (endptr - new_buf)); + snprintf(new_buf +j, num_len, fmt, num); + temp_len -= old_len - num_len; + } else if (num_len == old_len) { + snprintf(new_buf +j, num_len, fmt, num); + } else { + new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + (num_len - old_len)); + memmove(new_buf +j +num_len, endptr, temp_len - (endptr - new_buf)); + snprintf(new_buf +j, num_len, fmt, num); + temp_len += num_len - old_len; + } + + yes += 1; + + } + } + + } } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 88f8e902..8220b41b 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -900,6 +900,7 @@ int main(int argc, char **argv_orig, char **envp) { if (get_afl_env("AFL_NO_ARITH")) { afl->no_arith = 1; } if (get_afl_env("AFL_SHUFFLE_QUEUE")) { afl->shuffle_queue = 1; } if (get_afl_env("AFL_FAST_CAL")) { afl->fast_cal = 1; } + if (get_afl_env("AFL_EXPAND_HAVOC_NOW")) { afl->expand_havoc = 1; } if (afl->afl_env.afl_autoresume) { -- cgit 1.4.1 From 3e04dbd5a1048ed3dd245c9db70d8a8d3b7d7135 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 23 Jul 2020 16:43:25 +0200 Subject: no cycle on expand --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/afl-fuzz.c') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 8220b41b..553300e9 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1275,7 +1275,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->expand_havoc = 2; break; case 2: - afl->cycle_schedules = 1; + //afl->cycle_schedules = 1; afl->expand_havoc = 3; break; case 3: -- cgit 1.4.1 From 30c09915432af7a9e98f9b4d8b09566731e0cca9 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Fri, 24 Jul 2020 13:26:07 +0200 Subject: better text mutation --- include/afl-fuzz.h | 2 +- include/config.h | 7 +- src/afl-fuzz-one.c | 341 +++++++++++++++++++++++++----------------------- src/afl-fuzz-redqueen.c | 142 ++++++++++---------- src/afl-fuzz-state.c | 7 + src/afl-fuzz.c | 2 +- 6 files changed, 261 insertions(+), 240 deletions(-) (limited to 'src/afl-fuzz.c') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 96d3d9f4..0e2b7458 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -334,7 +334,7 @@ typedef struct afl_env_vars { afl_dumb_forksrv, afl_import_first, afl_custom_mutator_only, afl_no_ui, afl_force_ui, afl_i_dont_care_about_missing_crashes, afl_bench_just_one, afl_bench_until_crash, afl_debug_child_output, afl_autoresume, - afl_cal_fast, afl_cycle_schedules; + afl_cal_fast, afl_cycle_schedules, afl_expand_havoc; u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, *afl_hang_tmout, *afl_skip_crashes, *afl_preload; diff --git a/include/config.h b/include/config.h index 9710cd1f..344a368f 100644 --- a/include/config.h +++ b/include/config.h @@ -403,15 +403,14 @@ /* Text mutations */ -/* What is the minimum length of a queue input to be evaluated for "is_ascii"? -+ */ +/* Minimum length of a queue input to be evaluated for "is_ascii"? */ #define AFL_TXT_MIN_LEN 12 /* What is the minimum percentage of ascii characters present to be classifed as "is_ascii"? */ -#define AFL_TXT_MIN_PERCENT 95 +#define AFL_TXT_MIN_PERCENT 94 /* How often to perform ASCII mutations 0 = disable, 1-8 are good values */ @@ -423,7 +422,7 @@ /* Maximum mutations on a string */ -#define AFL_TXT_STRING_MAX_MUTATIONS 8 +#define AFL_TXT_STRING_MAX_MUTATIONS 6 #endif /* ! _HAVE_CONFIG_H */ diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 7f96c2c6..dc19150d 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -559,13 +559,25 @@ static u32 string_replace(u8 **out_buf, s32 *temp_len, u32 pos, u8 *from, /* Returns 1 if a mutant was generated and placed in out_buf, 0 if none * generated. */ +static const uint8_t text_mutation_special_chars[] = { + + '\t', '\n', '\r', ' ', '!', '"', '$', '%', '&', '\'', '(', ')', '*', + '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', + '\\', ']', '^', '_', '`', '{', '|', '}', '~', ' ' // space is here twice + +}; + static int text_mutation(afl_state_t *afl, u8 **out_buf, s32 *orig_temp_len) { + if (*orig_temp_len < AFL_TXT_MIN_LEN) { return 0; } + 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 +1); + mutations = rand_below(afl, AFL_TXT_STRING_MAX_MUTATIONS) + 16; + u8 *new_buf = + ck_maybe_grow(BUF_PARAMS(out_scratch), + *orig_temp_len + AFL_TXT_STRING_MAX_MUTATIONS + 16); + u8 fromc[2] = {0, 0}, toc[2] = {0, 0}; temp_len = *orig_temp_len; memcpy(new_buf, *out_buf, temp_len); new_buf[temp_len] = 0; @@ -575,9 +587,12 @@ static int text_mutation(afl_state_t *afl, u8 **out_buf, s32 *orig_temp_len) { if (temp_len < AFL_TXT_MIN_LEN) { return 0; } pos = rand_below(afl, temp_len - 1); - int choice = rand_below(afl, 80); + int choice = rand_below(afl, 100); + switch (choice) { + /* 50% -> fixed replacements */ + case 0: /* Semantic statement deletion */ yes += string_replace(&new_buf, &temp_len, pos, "\n", "#"); break; @@ -624,246 +639,240 @@ static int text_mutation(afl_state_t *afl, u8 **out_buf, s32 *orig_temp_len) { yes += string_replace(&new_buf, &temp_len, pos, "+", "-"); break; case 15: - yes += string_replace(&new_buf, &temp_len, pos, "+", "*"); + yes += string_replace(&new_buf, &temp_len, pos, "-", "+"); break; case 16: - yes += string_replace(&new_buf, &temp_len, pos, "+", "/"); + yes += string_replace(&new_buf, &temp_len, pos, "0", "1"); break; case 17: - yes += string_replace(&new_buf, &temp_len, pos, "+", "%"); + yes += string_replace(&new_buf, &temp_len, pos, "1", "0"); break; case 18: - yes += string_replace(&new_buf, &temp_len, pos, "*", "-"); + yes += string_replace(&new_buf, &temp_len, pos, "&&", "||"); break; case 19: - yes += string_replace(&new_buf, &temp_len, pos, "*", "+"); + yes += string_replace(&new_buf, &temp_len, pos, "||", "&&"); break; case 20: - yes += string_replace(&new_buf, &temp_len, pos, "*", "/"); + yes += string_replace(&new_buf, &temp_len, pos, "!", ""); break; case 21: - yes += string_replace(&new_buf, &temp_len, pos, "*", "%"); + yes += string_replace(&new_buf, &temp_len, pos, "==", "="); break; case 22: - yes += string_replace(&new_buf, &temp_len, pos, "-", "+"); + yes += string_replace(&new_buf, &temp_len, pos, "=", "=="); break; case 23: - yes += string_replace(&new_buf, &temp_len, pos, "-", "*"); + yes += string_replace(&new_buf, &temp_len, pos, "--", ""); break; case 24: - yes += string_replace(&new_buf, &temp_len, pos, "-", "/"); + yes += string_replace(&new_buf, &temp_len, pos, "<<", "<"); break; case 25: - yes += string_replace(&new_buf, &temp_len, pos, "-", "%"); + yes += string_replace(&new_buf, &temp_len, pos, ">>", ">"); break; case 26: - yes += string_replace(&new_buf, &temp_len, pos, "/", "-"); + yes += string_replace(&new_buf, &temp_len, pos, "<", "<<"); break; case 27: - yes += string_replace(&new_buf, &temp_len, pos, "/", "*"); + yes += string_replace(&new_buf, &temp_len, pos, ">", ">>"); break; case 28: - yes += string_replace(&new_buf, &temp_len, pos, "/", "+"); + yes += string_replace(&new_buf, &temp_len, pos, "'", "\""); break; case 29: - yes += string_replace(&new_buf, &temp_len, pos, "/", "%"); - break; - case 30: - yes += string_replace(&new_buf, &temp_len, pos, "%", "-"); - break; - case 31: - yes += string_replace(&new_buf, &temp_len, pos, "%", "*"); - break; - case 32: - yes += string_replace(&new_buf, &temp_len, pos, "%", "/"); - break; - case 33: - yes += string_replace(&new_buf, &temp_len, pos, "%", "+"); - break; - case 34: - yes += string_replace(&new_buf, &temp_len, pos, " ", "|"); - break; - case 35: - yes += string_replace(&new_buf, &temp_len, pos, " ", "$"); - break; - case 36: - yes += string_replace(&new_buf, &temp_len, pos, "0", "1"); - break; - case 37: - yes += string_replace(&new_buf, &temp_len, pos, "1", "0"); - break; - case 38: - yes += string_replace(&new_buf, &temp_len, pos, " ", "`"); - break; - case 39: - yes += string_replace(&new_buf, &temp_len, pos, " ", "\""); - break; - case 40: - yes += string_replace(&new_buf, &temp_len, pos, ";", " "); - break; - case 41: - yes += string_replace(&new_buf, &temp_len, pos, "&&", "||"); - break; - case 42: - yes += string_replace(&new_buf, &temp_len, pos, "||", "&&"); - break; - case 43: - yes += string_replace(&new_buf, &temp_len, pos, "!", ""); - break; - case 44: - yes += string_replace(&new_buf, &temp_len, pos, "==", "="); - break; - case 45: - yes += string_replace(&new_buf, &temp_len, pos, "--", ""); - break; - case 46: - yes += string_replace(&new_buf, &temp_len, pos, "<<", "<"); - break; - case 47: - yes += string_replace(&new_buf, &temp_len, pos, ">>", ">"); - break; - case 48: - yes += string_replace(&new_buf, &temp_len, pos, "<", "<<"); - break; - case 49: - yes += string_replace(&new_buf, &temp_len, pos, ">", ">>"); - break; - case 50: yes += string_replace(&new_buf, &temp_len, pos, "\"", "'"); break; - case 51: - yes += string_replace(&new_buf, &temp_len, pos, "'", "\""); - break; - case 52: - yes += string_replace(&new_buf, &temp_len, pos, "(", "\""); - break; - case 53: /* Remove a semicolon delimited statement after a semicolon */ + case 30: /* Remove a semicolon delimited statement after a semicolon */ yes += delim_replace(&new_buf, &temp_len, pos, ";", ";", ";"); break; - case 54: /* Remove a semicolon delimited statement after a left curly + case 31: /* Remove a semicolon delimited statement after a left curly brace */ yes += delim_replace(&new_buf, &temp_len, pos, "}", ";", "}"); break; - case 55: /* Remove a curly brace construct */ + case 32: /* Remove a curly brace construct */ yes += delim_replace(&new_buf, &temp_len, pos, "{", "}", ""); break; - case 56: /* Replace a curly brace construct with an empty one */ + case 33: /* Replace a curly brace construct with an empty one */ yes += delim_replace(&new_buf, &temp_len, pos, "{", "}", "{}"); break; - case 57: + case 34: yes += delim_swap(&new_buf, &temp_len, pos, ";", ";", ";"); break; - case 58: + case 35: yes += delim_swap(&new_buf, &temp_len, pos, "}", ";", ";"); break; - case 59: /* Swap comma delimited things case 1 */ + case 36: /* Swap comma delimited things case 1 */ yes += delim_swap(&new_buf, &temp_len, pos, "(", ",", ")"); break; - case 60: /* Swap comma delimited things case 2 */ + case 37: /* Swap comma delimited things case 2 */ yes += delim_swap(&new_buf, &temp_len, pos, "(", ",", ","); break; - case 61: /* Swap comma delimited things case 3 */ + case 38: /* Swap comma delimited things case 3 */ yes += delim_swap(&new_buf, &temp_len, pos, ",", ",", ","); break; - case 62: /* Swap comma delimited things case 4 */ + case 39: /* Swap comma delimited things case 4 */ yes += delim_swap(&new_buf, &temp_len, pos, ",", ",", ")"); break; - case 63: /* Just delete a line */ + case 40: /* Just delete a line */ yes += delim_replace(&new_buf, &temp_len, pos, "\n", "\n", ""); break; - case 64: /* Delete something like "const" case 1 */ + case 41: /* Delete something like "const" case 1 */ yes += delim_replace(&new_buf, &temp_len, pos, " ", " ", ""); break; - case 65: /* Delete something like "const" case 2 */ + case 42: /* Delete something like "const" case 2 */ yes += delim_replace(&new_buf, &temp_len, pos, "\n", " ", ""); break; - case 66: /* Delete something like "const" case 3 */ + case 43: /* Delete something like "const" case 3 */ yes += delim_replace(&new_buf, &temp_len, pos, "(", " ", ""); break; - case 67: /* Swap space delimited things case 1 */ + case 44: /* Swap space delimited things case 1 */ yes += delim_swap(&new_buf, &temp_len, pos, " ", " ", " "); break; - case 68: /* Swap space delimited things case 2 */ + case 45: /* Swap space delimited things case 2 */ yes += delim_swap(&new_buf, &temp_len, pos, " ", " ", ")"); break; - case 69: /* Swap space delimited things case 3 */ + case 46: /* Swap space delimited things case 3 */ yes += delim_swap(&new_buf, &temp_len, pos, "(", " ", " "); break; - case 70: /* Swap space delimited things case 4 */ + case 47: /* Swap space delimited things case 4 */ yes += delim_swap(&new_buf, &temp_len, pos, "(", " ", ")"); break; - case 71: /* Duplicate a single line of code */ + case 48: /* Duplicate a single line of code */ yes += delim_replace(&new_buf, &temp_len, pos, "\n", "\n", NULL); break; - case 72: /* Duplicate a construct (most often, a non-nested for loop */ + case 49: /* Duplicate a construct (most often, a non-nested for loop */ yes += delim_replace(&new_buf, &temp_len, pos, "\n", "}", NULL); break; default: { - - for (u32 j = pos; j < temp_len; ++j) { - if (isdigit(new_buf[j])) { - - new_buf[temp_len] = 0; // should be safe thanks to the initial grow - - u8* endptr; - unsigned long long num = strtoull(new_buf +j, (char**)&endptr, 0); - - switch (rand_below(afl, 8)) { - case 0: - num = rand_below(afl, INT_MAX); - break; - case 1: - num = rand_next(afl); - break; - case 2: - num += 1 + rand_below(afl, 255); - break; - case 3: - num -= 1 + rand_below(afl, 255); - break; - case 4: - num *= 1 + rand_below(afl, 255); - break; - case 5: - num /= 1 + rand_below(afl, 255); - break; - case 6: - num /= 1 + rand_below(afl, 255); - break; - case 7: - num = ~num; - break; - } - - const char* fmt = "%llu"; - if (rand_below(afl, 5) == 0) // add - sign with 1/5 probability - fmt = "-%llu"; - - size_t num_len = snprintf(NULL, 0, fmt, num); - size_t old_len = endptr - (new_buf +j); - if (num_len < old_len) { - memmove(new_buf +j +num_len, new_buf +j +old_len, temp_len - (j + old_len)); - snprintf(new_buf +j, num_len, fmt, num); - temp_len -= old_len - num_len; - } else if (num_len == old_len) { - snprintf(new_buf +j, num_len, fmt, num); - } else { - new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + (num_len - old_len) + AFL_TXT_STRING_MAX_MUTATIONS +1); - memmove(new_buf +j +num_len, new_buf +j +old_len, temp_len - (j + old_len)); - snprintf(new_buf +j, num_len, fmt, num); - temp_len += num_len - old_len; + + /* 10% is transforming ascii numbers */ + + if (choice < 60) { + + for (u32 j = pos; j < temp_len; ++j) { + + if (isdigit(new_buf[j])) { + + new_buf[temp_len] = + 0; // should be safe thanks to the initial grow + + u8 * endptr; + unsigned long long num = + strtoull(new_buf + j, (char **)&endptr, 0); + + switch (rand_below(afl, 8)) { + + case 0: + num = rand_below(afl, INT_MAX); + break; + case 1: + num = rand_next(afl); + break; + case 2: + num += 1 + rand_below(afl, 255); + break; + case 3: + num -= 1 + rand_below(afl, 255); + break; + case 4: + num *= 1 + rand_below(afl, 255); + break; + case 5: + num /= 1 + rand_below(afl, 255); + break; + case 6: + num /= 1 + rand_below(afl, 255); + break; + case 7: + num = ~num; + break; + + } + + const char *fmt = "%llu"; + if (rand_below(afl, 5) == 0) // add - sign with 1/5 probability + fmt = "-%llu"; + + size_t num_len = snprintf(NULL, 0, fmt, num); + size_t old_len = endptr - (new_buf + j); + if (num_len < old_len) { + + memmove(new_buf + j + num_len, new_buf + j + old_len, + temp_len - (j + old_len)); + snprintf(new_buf + j, num_len, fmt, num); + temp_len -= old_len - num_len; + + } else if (num_len == old_len) { + + snprintf(new_buf + j, num_len, fmt, num); + + } else { + + new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), + temp_len + (num_len - old_len) + + AFL_TXT_STRING_MAX_MUTATIONS + 1); + memmove(new_buf + j + num_len, new_buf + j + old_len, + temp_len - (j + old_len)); + snprintf(new_buf + j, num_len, fmt, num); + temp_len += num_len - old_len; + + } + + yes += 1; + break; + } - yes += 1; - break; - } + + } else if (choice < 90) { + + /* 30% is special character transform */ + + fromc[0] = text_mutation_special_chars[rand_below( + afl, sizeof(text_mutation_special_chars))]; + + do { + + toc[0] = text_mutation_special_chars[rand_below( + afl, sizeof(text_mutation_special_chars))]; + + } while (toc[0] == fromc[0]); + + yes += string_replace(&new_buf, &temp_len, pos, fromc, toc); + break; + + } else { + + /* 10% is random text character transform */ + + u32 iter, cnt, loc, prev_loc = temp_len; + if (temp_len > 32) { + + cnt = 1 + rand_below(afl, 5); + + } else { + + cnt = rand_below(afl, 2); + + } + + for (iter = 0; iter <= cnt; iter++) { + + while ((loc = rand_below(afl, temp_len)) == prev_loc) + ; + new_buf[loc] = 32 + rand_below(afl, 'z' - ' ' + 1); + prev_loc = loc; + + } + } - + } } - + } if (yes == 0 || temp_len <= 0) { return 0; } @@ -871,7 +880,7 @@ static int text_mutation(afl_state_t *afl, u8 **out_buf, s32 *orig_temp_len) { swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch)); *out_buf = new_buf; *orig_temp_len = temp_len; - + return 1; } diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index de3adb2d..57e60c3d 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -264,49 +264,53 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) { } static long long strntoll(const char *str, size_t sz, char **end, int base) { - char buf[64]; - long long ret; - const char *beg = str; - - for (; beg && sz && *beg == ' '; beg++, sz--) - ; - - if (!sz || sz >= sizeof(buf)) { - if (end) - *end = (char *)str; - return 0; - } - - memcpy(buf, beg, sz); - buf[sz] = '\0'; - ret = strtoll(buf, end, base); - if (ret == LLONG_MIN || ret == LLONG_MAX) - return ret; - if (end) - *end = (char *)beg + (*end - buf); - return ret; + + char buf[64]; + long long ret; + const char *beg = str; + + for (; beg && sz && *beg == ' '; beg++, sz--) + ; + + if (!sz || sz >= sizeof(buf)) { + + if (end) *end = (char *)str; + return 0; + + } + + memcpy(buf, beg, sz); + buf[sz] = '\0'; + ret = strtoll(buf, end, base); + if (ret == LLONG_MIN || ret == LLONG_MAX) return ret; + if (end) *end = (char *)beg + (*end - buf); + return ret; + } -static unsigned long long strntoull(const char *str, size_t sz, char **end, int base) { - char buf[64]; - unsigned long long ret; - const char *beg = str; - - for (; beg && sz && *beg == ' '; beg++, sz--) - ; - - if (!sz || sz >= sizeof(buf)) { - if (end) - *end = (char *)str; - return 0; - } - - memcpy(buf, beg, sz); - buf[sz] = '\0'; - ret = strtoull(buf, end, base); - if (end) - *end = (char *)beg + (*end - buf); - return ret; +static unsigned long long strntoull(const char *str, size_t sz, char **end, + int base) { + + char buf[64]; + unsigned long long ret; + const char * beg = str; + + for (; beg && sz && *beg == ' '; beg++, sz--) + ; + + if (!sz || sz >= sizeof(buf)) { + + if (end) *end = (char *)str; + return 0; + + } + + memcpy(buf, beg, sz); + buf[sz] = '\0'; + ret = strtoull(buf, end, base); + if (end) *end = (char *)beg + (*end - buf); + return ret; + } #define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size @@ -328,49 +332,51 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u32 its_len = len - idx; // *status = 0; - u8 *endptr; - u8 use_num = 0, use_unum = 0; + u8 * endptr; + u8 use_num = 0, use_unum = 0; unsigned long long unum; - long long num; + long long num; if (afl->queue_cur->is_ascii) { - + endptr = buf_8; - num = strntoll(buf_8, len - idx, (char**)&endptr, 0); + num = strntoll(buf_8, len - idx, (char **)&endptr, 0); if (endptr == buf_8) { - unum = strntoull(buf_8, len - idx, (char**)&endptr, 0); - if (endptr == buf_8) - use_unum = 1; + + unum = strntoull(buf_8, len - idx, (char **)&endptr, 0); + if (endptr == buf_8) use_unum = 1; + } else + use_num = 1; - + } - + if (use_num && num == pattern) { - + size_t old_len = endptr - buf_8; size_t num_len = snprintf(NULL, 0, "%lld", num); - - u8* new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), len + num_len); + + u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), len + num_len); memcpy(new_buf, buf, idx); - - snprintf(new_buf +idx, num_len, "%lld", num); - memcpy(new_buf +idx +num_len, buf_8 + old_len, len - idx - old_len); - + + snprintf(new_buf + idx, num_len, "%lld", num); + memcpy(new_buf + idx + num_len, buf_8 + old_len, len - idx - old_len); + if (unlikely(its_fuzz(afl, new_buf, len, status))) { return 1; } - + } else if (use_unum && unum == pattern) { - + size_t old_len = endptr - buf_8; size_t num_len = snprintf(NULL, 0, "%llu", unum); - - u8* new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), len + num_len); + + u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), len + num_len); memcpy(new_buf, buf, idx); - - snprintf(new_buf +idx, num_len, "%llu", unum); - memcpy(new_buf +idx +num_len, buf_8 + old_len, len - idx - old_len); - + + snprintf(new_buf + idx, num_len, "%llu", unum); + memcpy(new_buf + idx + num_len, buf_8 + old_len, len - idx - old_len); + if (unlikely(its_fuzz(afl, new_buf, len, status))) { return 1; } - + } if (SHAPE_BYTES(h->shape) >= 8 && *status != 1) { @@ -382,7 +388,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, *buf_64 = pattern; } - + // reverse encoding if (do_reverse && *status != 1) { diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index f68a79e8..66280ed1 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -300,6 +300,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->cycle_schedules = afl->afl_env.afl_cycle_schedules = get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_EXPAND_HAVOC_NOW", + + afl_environment_variable_len)) { + + afl->expand_havoc = afl->afl_env.afl_expand_havoc = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_CAL_FAST", afl_environment_variable_len)) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 553300e9..c014035e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1275,7 +1275,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->expand_havoc = 2; break; case 2: - //afl->cycle_schedules = 1; + // afl->cycle_schedules = 1; afl->expand_havoc = 3; break; case 3: -- cgit 1.4.1