mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-13 02:28:09 +00:00
added andrea's splicing, added cycle_schedules
This commit is contained in:
@ -455,7 +455,7 @@ code-format:
|
|||||||
./.custom-format.py -i llvm_mode/*.h
|
./.custom-format.py -i llvm_mode/*.h
|
||||||
./.custom-format.py -i llvm_mode/*.cc
|
./.custom-format.py -i llvm_mode/*.cc
|
||||||
./.custom-format.py -i gcc_plugin/*.c
|
./.custom-format.py -i gcc_plugin/*.c
|
||||||
#./.custom-format.py -i gcc_plugin/*.h
|
@#./.custom-format.py -i gcc_plugin/*.h
|
||||||
./.custom-format.py -i gcc_plugin/*.cc
|
./.custom-format.py -i gcc_plugin/*.cc
|
||||||
./.custom-format.py -i custom_mutators/*/*.c
|
./.custom-format.py -i custom_mutators/*/*.c
|
||||||
./.custom-format.py -i custom_mutators/*/*.h
|
./.custom-format.py -i custom_mutators/*/*.h
|
||||||
|
@ -139,7 +139,8 @@ struct queue_entry {
|
|||||||
var_behavior, /* Variable behavior? */
|
var_behavior, /* Variable behavior? */
|
||||||
favored, /* Currently favored? */
|
favored, /* Currently favored? */
|
||||||
fs_redundant, /* Marked as redundant in the fs? */
|
fs_redundant, /* Marked as redundant in the fs? */
|
||||||
fully_colorized; /* Do not run redqueen stage again */
|
fully_colorized, /* Do not run redqueen stage again */
|
||||||
|
is_ascii; /* Is the input just ascii text? */
|
||||||
|
|
||||||
u32 bitmap_size, /* Number of bits set in bitmap */
|
u32 bitmap_size, /* Number of bits set in bitmap */
|
||||||
fuzz_level; /* Number of fuzzing iterations */
|
fuzz_level; /* Number of fuzzing iterations */
|
||||||
@ -333,7 +334,7 @@ typedef struct afl_env_vars {
|
|||||||
afl_dumb_forksrv, afl_import_first, afl_custom_mutator_only, afl_no_ui,
|
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_force_ui, afl_i_dont_care_about_missing_crashes, afl_bench_just_one,
|
||||||
afl_bench_until_crash, afl_debug_child_output, afl_autoresume,
|
afl_bench_until_crash, afl_debug_child_output, afl_autoresume,
|
||||||
afl_cal_fast;
|
afl_cal_fast, afl_cycle_schedules;
|
||||||
|
|
||||||
u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path,
|
u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path,
|
||||||
*afl_hang_tmout, *afl_skip_crashes, *afl_preload;
|
*afl_hang_tmout, *afl_skip_crashes, *afl_preload;
|
||||||
@ -454,7 +455,9 @@ typedef struct afl_state {
|
|||||||
fixed_seed, /* do not reseed */
|
fixed_seed, /* do not reseed */
|
||||||
fast_cal, /* Try to calibrate faster? */
|
fast_cal, /* Try to calibrate faster? */
|
||||||
disable_trim, /* Never trim in fuzz_one */
|
disable_trim, /* Never trim in fuzz_one */
|
||||||
shmem_testcase_mode; /* If sharedmem testcases are used */
|
shmem_testcase_mode, /* If sharedmem testcases are used */
|
||||||
|
expand_havoc, /* perform expensive havoc after no find */
|
||||||
|
cycle_schedules; /* cycle power schedules ? */
|
||||||
|
|
||||||
u8 *virgin_bits, /* Regions yet untouched by fuzzing */
|
u8 *virgin_bits, /* Regions yet untouched by fuzzing */
|
||||||
*virgin_tmout, /* Bits we haven't seen in tmouts */
|
*virgin_tmout, /* Bits we haven't seen in tmouts */
|
||||||
@ -548,7 +551,7 @@ typedef struct afl_state {
|
|||||||
|
|
||||||
// growing buf
|
// growing buf
|
||||||
struct queue_entry **queue_buf;
|
struct queue_entry **queue_buf;
|
||||||
size_t queue_size;
|
size_t queue_size;
|
||||||
|
|
||||||
struct queue_entry **top_rated; /* Top entries for bitmap bytes */
|
struct queue_entry **top_rated; /* Top entries for bitmap bytes */
|
||||||
|
|
||||||
|
@ -401,5 +401,29 @@
|
|||||||
|
|
||||||
// #define IGNORE_FINDS
|
// #define IGNORE_FINDS
|
||||||
|
|
||||||
|
/* Text mutations */
|
||||||
|
|
||||||
|
/* What is the 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
|
||||||
|
|
||||||
|
/* How often to perform ASCII mutations 0 = disable, 1-8 are good values */
|
||||||
|
|
||||||
|
#define AFL_TXT_BIAS 6
|
||||||
|
|
||||||
|
/* Maximum length of a string to tamper with */
|
||||||
|
|
||||||
|
#define AFL_TXT_STRING_MAX_LEN 1024
|
||||||
|
|
||||||
|
/* Maximum mutations on a string */
|
||||||
|
|
||||||
|
#define AFL_TXT_STRING_MAX_MUTATIONS 8
|
||||||
|
|
||||||
#endif /* ! _HAVE_CONFIG_H */
|
#endif /* ! _HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ static char *afl_environment_variables[] = {
|
|||||||
"AFL_CUSTOM_MUTATOR_LIBRARY",
|
"AFL_CUSTOM_MUTATOR_LIBRARY",
|
||||||
"AFL_CUSTOM_MUTATOR_ONLY",
|
"AFL_CUSTOM_MUTATOR_ONLY",
|
||||||
"AFL_CXX",
|
"AFL_CXX",
|
||||||
|
"AFL_CYCLE_SCHEDULES",
|
||||||
"AFL_DEBUG",
|
"AFL_DEBUG",
|
||||||
"AFL_DEBUG_CHILD_OUTPUT",
|
"AFL_DEBUG_CHILD_OUTPUT",
|
||||||
"AFL_DEBUG_GDB",
|
"AFL_DEBUG_GDB",
|
||||||
|
@ -24,6 +24,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "afl-fuzz.h"
|
#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 */
|
/* MOpt */
|
||||||
|
|
||||||
@ -362,6 +367,450 @@ static void locate_diffs(u8 *ptr1, u8 *ptr2, u32 len, s32 *first, s32 *last) {
|
|||||||
|
|
||||||
#endif /* !IGNORE_FINDS */
|
#endif /* !IGNORE_FINDS */
|
||||||
|
|
||||||
|
#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size
|
||||||
|
|
||||||
|
/* search a string */
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* replace a string */
|
||||||
|
|
||||||
|
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", "#");
|
||||||
|
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, " ", "|");
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
yes += string_replace(out_buf, &temp_len, pos, " ", "$");
|
||||||
|
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, " ", "`");
|
||||||
|
break;
|
||||||
|
case 39:
|
||||||
|
yes += string_replace(out_buf, &temp_len, pos, " ", "\"");
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
yes += string_replace(out_buf, &temp_len, pos, ";", " ");
|
||||||
|
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
|
/* 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
|
function is a tad too long... returns 0 if fuzzed successfully, 1 if
|
||||||
skipped or bailed out. */
|
skipped or bailed out. */
|
||||||
@ -1854,6 +2303,22 @@ 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. */
|
||||||
|
|
||||||
|
u32 r_max, r;
|
||||||
|
|
||||||
|
if (unlikely(afl->expand_havoc)) {
|
||||||
|
|
||||||
|
/* add expensive havoc cases here, they are activated after a full
|
||||||
|
cycle without finds happened */
|
||||||
|
|
||||||
|
r_max = 16 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0) +
|
||||||
|
(afl->queue_cur->is_ascii ? AFL_TXT_BIAS : 0);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
r_max = 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
|
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 use_stacking = 1 << (1 + rand_below(afl, HAVOC_STACK_POW2));
|
||||||
@ -1896,8 +2361,9 @@ havoc_stage:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (rand_below(
|
retry_havoc:
|
||||||
afl, 16 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0))) {
|
|
||||||
|
switch ((r = rand_below(afl, r_max))) {
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
|
|
||||||
@ -2191,176 +2657,203 @@ havoc_stage:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 15: {
|
|
||||||
|
|
||||||
/* Overwrite bytes with a randomly selected chunk from another
|
default:
|
||||||
testcase or insert that chunk. */
|
|
||||||
|
|
||||||
if (afl->queued_paths < 2) break;
|
if (likely(r <= 16 && (afl->extras_cnt || afl->a_extras_cnt))) {
|
||||||
|
|
||||||
/* Pick a random queue entry and seek to it. */
|
/* Values 15 and 16 can be selected only if there are any extras
|
||||||
|
present in the dictionaries. */
|
||||||
|
|
||||||
u32 tid;
|
if (r == 15) {
|
||||||
do
|
|
||||||
tid = rand_below(afl, afl->queued_paths);
|
|
||||||
while (tid == afl->current_entry);
|
|
||||||
|
|
||||||
struct queue_entry* target = afl->queue_buf[tid];
|
/* Overwrite bytes with an extra. */
|
||||||
|
|
||||||
/* Make sure that the target has a reasonable length. */
|
if (!afl->extras_cnt ||
|
||||||
|
(afl->a_extras_cnt && rand_below(afl, 2))) {
|
||||||
|
|
||||||
while (target && (target->len < 2 || target == afl->queue_cur))
|
/* No user-specified extras or odds in our favor. Let's use an
|
||||||
target = target->next;
|
auto-detected one. */
|
||||||
|
|
||||||
if (!target) break;
|
u32 use_extra = rand_below(afl, afl->a_extras_cnt);
|
||||||
|
u32 extra_len = afl->a_extras[use_extra].len;
|
||||||
|
u32 insert_at;
|
||||||
|
|
||||||
/* Read the testcase into a new buffer. */
|
if (extra_len > temp_len) { break; }
|
||||||
|
|
||||||
fd = open(target->fname, O_RDONLY);
|
insert_at = rand_below(afl, temp_len - extra_len + 1);
|
||||||
|
memcpy(out_buf + insert_at, afl->a_extras[use_extra].data,
|
||||||
|
extra_len);
|
||||||
|
|
||||||
if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); }
|
} else {
|
||||||
|
|
||||||
u32 new_len = target->len;
|
/* No auto extras or odds in our favor. Use the dictionary. */
|
||||||
u8 * new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), new_len);
|
|
||||||
|
|
||||||
ck_read(fd, new_buf, new_len, target->fname);
|
u32 use_extra = rand_below(afl, afl->extras_cnt);
|
||||||
|
u32 extra_len = afl->extras[use_extra].len;
|
||||||
|
u32 insert_at;
|
||||||
|
|
||||||
close(fd);
|
if (extra_len > temp_len) { break; }
|
||||||
|
|
||||||
u8 overwrite = 0;
|
insert_at = rand_below(afl, temp_len - extra_len + 1);
|
||||||
if (temp_len >= 2 && rand_below(afl, 2))
|
memcpy(out_buf + insert_at, afl->extras[use_extra].data,
|
||||||
overwrite = 1;
|
extra_len);
|
||||||
else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) {
|
|
||||||
if (temp_len >= 2) overwrite = 1;
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overwrite) {
|
}
|
||||||
|
|
||||||
u32 copy_from, copy_to, copy_len;
|
break;
|
||||||
|
|
||||||
copy_len = choose_block_len(afl, new_len - 1);
|
} else { // case 16
|
||||||
if (copy_len > temp_len) copy_len = temp_len;
|
|
||||||
|
|
||||||
copy_from = rand_below(afl, new_len - copy_len + 1);
|
u32 use_extra, extra_len,
|
||||||
copy_to = rand_below(afl, temp_len - copy_len + 1);
|
insert_at = rand_below(afl, temp_len + 1);
|
||||||
|
u8 *ptr;
|
||||||
|
|
||||||
memmove(out_buf + copy_to, new_buf + copy_from, copy_len);
|
/* Insert an extra. Do the same dice-rolling stuff as for the
|
||||||
|
previous case. */
|
||||||
|
|
||||||
} else {
|
if (!afl->extras_cnt ||
|
||||||
|
(afl->a_extras_cnt && rand_below(afl, 2))) {
|
||||||
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);
|
|
||||||
|
|
||||||
u8 * temp_buf =
|
use_extra = rand_below(afl, afl->a_extras_cnt);
|
||||||
ck_maybe_grow(BUF_PARAMS(out_scratch), temp_len + clone_len);
|
extra_len = afl->a_extras[use_extra].len;
|
||||||
|
ptr = afl->a_extras[use_extra].data;
|
||||||
|
|
||||||
/* Head */
|
} else {
|
||||||
|
|
||||||
memcpy(temp_buf, out_buf, clone_to);
|
use_extra = rand_below(afl, afl->extras_cnt);
|
||||||
|
extra_len = afl->extras[use_extra].len;
|
||||||
|
ptr = afl->extras[use_extra].data;
|
||||||
|
|
||||||
/* Inserted part */
|
}
|
||||||
|
|
||||||
memcpy(temp_buf + clone_to, new_buf + clone_from, clone_len);
|
if (temp_len + extra_len >= MAX_FILE) { break; }
|
||||||
|
|
||||||
/* Tail */
|
out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len);
|
||||||
memcpy(temp_buf + clone_to + clone_len, out_buf + clone_to,
|
|
||||||
temp_len - clone_to);
|
|
||||||
|
|
||||||
swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch));
|
/* Tail */
|
||||||
out_buf = temp_buf;
|
memmove(out_buf + insert_at + extra_len, out_buf + insert_at,
|
||||||
temp_len += clone_len;
|
temp_len - insert_at);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
/* Inserted part */
|
||||||
|
memcpy(out_buf + insert_at, ptr, extra_len);
|
||||||
|
|
||||||
}
|
temp_len += extra_len;
|
||||||
|
|
||||||
/* Values 15 and 16 can be selected only if there are any extras
|
break;
|
||||||
present in the dictionaries. */
|
|
||||||
|
|
||||||
case 16: {
|
}
|
||||||
|
|
||||||
/* Overwrite bytes with an extra. */
|
} else
|
||||||
|
|
||||||
if (!afl->extras_cnt || (afl->a_extras_cnt && rand_below(afl, 2))) {
|
switch (r) {
|
||||||
|
|
||||||
/* No user-specified extras or odds in our favor. Let's use an
|
case 15: // fall through
|
||||||
auto-detected one. */
|
case 17: {
|
||||||
|
|
||||||
u32 use_extra = rand_below(afl, afl->a_extras_cnt);
|
/* Overwrite bytes with a randomly selected chunk from another
|
||||||
u32 extra_len = afl->a_extras[use_extra].len;
|
testcase or insert that chunk. */
|
||||||
u32 insert_at;
|
|
||||||
|
|
||||||
if (extra_len > temp_len) { break; }
|
if (afl->queued_paths < 2) break;
|
||||||
|
|
||||||
insert_at = rand_below(afl, temp_len - extra_len + 1);
|
/* Pick a random queue entry and seek to it. */
|
||||||
memcpy(out_buf + insert_at, afl->a_extras[use_extra].data,
|
|
||||||
extra_len);
|
|
||||||
|
|
||||||
} else {
|
u32 tid;
|
||||||
|
do
|
||||||
|
tid = rand_below(afl, afl->queued_paths);
|
||||||
|
while (tid == afl->current_entry);
|
||||||
|
|
||||||
/* No auto extras or odds in our favor. Use the dictionary. */
|
struct queue_entry *target = afl->queue_buf[tid];
|
||||||
|
|
||||||
u32 use_extra = rand_below(afl, afl->extras_cnt);
|
/* Make sure that the target has a reasonable length. */
|
||||||
u32 extra_len = afl->extras[use_extra].len;
|
|
||||||
u32 insert_at;
|
|
||||||
|
|
||||||
if (extra_len > temp_len) { break; }
|
while (target && (target->len < 2 || target == afl->queue_cur))
|
||||||
|
target = target->next;
|
||||||
|
|
||||||
insert_at = rand_below(afl, temp_len - extra_len + 1);
|
if (!target) break;
|
||||||
memcpy(out_buf + insert_at, afl->extras[use_extra].data, extra_len);
|
|
||||||
|
|
||||||
}
|
/* Read the testcase into a new buffer. */
|
||||||
|
|
||||||
break;
|
fd = open(target->fname, O_RDONLY);
|
||||||
|
|
||||||
}
|
if (unlikely(fd < 0)) {
|
||||||
|
|
||||||
case 17: {
|
PFATAL("Unable to open '%s'", target->fname);
|
||||||
|
|
||||||
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
|
u32 new_len = target->len;
|
||||||
previous case. */
|
u8 *new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), new_len);
|
||||||
|
|
||||||
if (!afl->extras_cnt || (afl->a_extras_cnt && rand_below(afl, 2))) {
|
ck_read(fd, new_buf, new_len, target->fname);
|
||||||
|
|
||||||
use_extra = rand_below(afl, afl->a_extras_cnt);
|
close(fd);
|
||||||
extra_len = afl->a_extras[use_extra].len;
|
|
||||||
ptr = afl->a_extras[use_extra].data;
|
|
||||||
|
|
||||||
} else {
|
u8 overwrite = 0;
|
||||||
|
if (temp_len >= 2 && rand_below(afl, 2))
|
||||||
|
overwrite = 1;
|
||||||
|
else if (temp_len + HAVOC_BLK_XL >= MAX_FILE) {
|
||||||
|
|
||||||
use_extra = rand_below(afl, afl->extras_cnt);
|
if (temp_len >= 2)
|
||||||
extra_len = afl->extras[use_extra].len;
|
overwrite = 1;
|
||||||
ptr = afl->extras[use_extra].data;
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temp_len + extra_len >= MAX_FILE) { break; }
|
if (overwrite) {
|
||||||
|
|
||||||
out_buf = ck_maybe_grow(BUF_PARAMS(out), temp_len + extra_len);
|
u32 copy_from, copy_to, copy_len;
|
||||||
|
|
||||||
/* Tail */
|
copy_len = choose_block_len(afl, new_len - 1);
|
||||||
memmove(out_buf + insert_at + extra_len, out_buf + insert_at,
|
if (copy_len > temp_len) copy_len = temp_len;
|
||||||
temp_len - insert_at);
|
|
||||||
|
|
||||||
/* Inserted part */
|
copy_from = rand_below(afl, new_len - copy_len + 1);
|
||||||
memcpy(out_buf + insert_at, ptr, extra_len);
|
copy_to = rand_below(afl, temp_len - copy_len + 1);
|
||||||
|
|
||||||
temp_len += extra_len;
|
memmove(out_buf + copy_to, new_buf + copy_from, copy_len);
|
||||||
|
|
||||||
break;
|
} else {
|
||||||
|
|
||||||
}
|
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);
|
||||||
|
|
||||||
|
u8 *temp_buf = ck_maybe_grow(BUF_PARAMS(out_scratch),
|
||||||
|
temp_len + clone_len);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch));
|
||||||
|
out_buf = temp_buf;
|
||||||
|
temp_len += clone_len;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
// perform ascii mutations
|
||||||
|
if (text_mutation(afl, &out_buf, &temp_len) == 0)
|
||||||
|
goto retry_havoc;
|
||||||
|
|
||||||
|
} // end default: switch(r)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4827,7 +5320,7 @@ u8 fuzz_one(afl_state_t *afl) {
|
|||||||
|
|
||||||
return (key_val_lv_1 | key_val_lv_2);
|
return (key_val_lv_1 | key_val_lv_2);
|
||||||
|
|
||||||
#undef BUF_PARAMS
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef BUF_PARAMS
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "afl-fuzz.h"
|
#include "afl-fuzz.h"
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size
|
#define BUF_PARAMS(name) (void **)&afl->name##_buf, &afl->name##_size
|
||||||
|
|
||||||
@ -102,6 +103,108 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check if ascii or UTF-8 */
|
||||||
|
|
||||||
|
static u8 check_if_text(struct queue_entry *q) {
|
||||||
|
|
||||||
|
if (q->len < AFL_TXT_MIN_LEN) return 0;
|
||||||
|
|
||||||
|
u8 buf[MAX_FILE];
|
||||||
|
s32 fd, len = q->len, offset = 0, ascii = 0, utf8 = 0, comp;
|
||||||
|
|
||||||
|
if ((fd = open(q->fname, O_RDONLY)) < 0) return 0;
|
||||||
|
if ((comp = read(fd, buf, len)) != len) return 0;
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
while (offset < len) {
|
||||||
|
|
||||||
|
// ASCII: <= 0x7F to allow ASCII control characters
|
||||||
|
if ((buf[offset + 0] == 0x09 || buf[offset + 0] == 0x0A ||
|
||||||
|
buf[offset + 0] == 0x0D ||
|
||||||
|
(0x20 <= buf[offset + 0] && buf[offset + 0] <= 0x7E))) {
|
||||||
|
|
||||||
|
offset++;
|
||||||
|
utf8++;
|
||||||
|
ascii++;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isascii((int)buf[offset]) || isprint((int)buf[offset])) {
|
||||||
|
|
||||||
|
ascii++;
|
||||||
|
// we continue though as it can also be a valid utf8
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// non-overlong 2-byte
|
||||||
|
if (((0xC2 <= buf[offset + 0] && buf[offset + 0] <= 0xDF) &&
|
||||||
|
(0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF))) {
|
||||||
|
|
||||||
|
offset += 2;
|
||||||
|
utf8++;
|
||||||
|
comp--;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// excluding overlongs
|
||||||
|
if ((buf[offset + 0] == 0xE0 &&
|
||||||
|
(0xA0 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) &&
|
||||||
|
(0x80 <= buf[offset + 2] &&
|
||||||
|
buf[offset + 2] <= 0xBF)) || // straight 3-byte
|
||||||
|
(((0xE1 <= buf[offset + 0] && buf[offset + 0] <= 0xEC) ||
|
||||||
|
buf[offset + 0] == 0xEE || buf[offset + 0] == 0xEF) &&
|
||||||
|
(0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) &&
|
||||||
|
(0x80 <= buf[offset + 2] &&
|
||||||
|
buf[offset + 2] <= 0xBF)) || // excluding surrogates
|
||||||
|
(buf[offset + 0] == 0xED &&
|
||||||
|
(0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x9F) &&
|
||||||
|
(0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF))) {
|
||||||
|
|
||||||
|
offset += 3;
|
||||||
|
utf8++;
|
||||||
|
comp -= 2;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// planes 1-3
|
||||||
|
if ((buf[offset + 0] == 0xF0 &&
|
||||||
|
(0x90 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) &&
|
||||||
|
(0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) &&
|
||||||
|
(0x80 <= buf[offset + 3] &&
|
||||||
|
buf[offset + 3] <= 0xBF)) || // planes 4-15
|
||||||
|
((0xF1 <= buf[offset + 0] && buf[offset + 0] <= 0xF3) &&
|
||||||
|
(0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) &&
|
||||||
|
(0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) &&
|
||||||
|
(0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF)) || // plane 16
|
||||||
|
(buf[offset + 0] == 0xF4 &&
|
||||||
|
(0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x8F) &&
|
||||||
|
(0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) &&
|
||||||
|
(0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF))) {
|
||||||
|
|
||||||
|
offset += 4;
|
||||||
|
utf8++;
|
||||||
|
comp -= 3;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
offset++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 percent_utf8 = (utf8 * 100) / comp;
|
||||||
|
u32 percent_ascii = (ascii * 100) / len;
|
||||||
|
|
||||||
|
if (percent_utf8 >= percent_ascii && percent_utf8 >= AFL_TXT_MIN_PERCENT)
|
||||||
|
return 2;
|
||||||
|
if (percent_ascii >= AFL_TXT_MIN_PERCENT) return 1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Append new test case to the queue. */
|
/* Append new test case to the queue. */
|
||||||
|
|
||||||
void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
|
void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
|
||||||
@ -139,9 +242,10 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
|
|||||||
afl->q_prev100 = q;
|
afl->q_prev100 = q;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct queue_entry** queue_buf = ck_maybe_grow(BUF_PARAMS(queue), afl->queued_paths * sizeof(struct queue_entry*));
|
struct queue_entry **queue_buf = ck_maybe_grow(
|
||||||
queue_buf[afl->queued_paths -1] = q;
|
BUF_PARAMS(queue), afl->queued_paths * sizeof(struct queue_entry *));
|
||||||
|
queue_buf[afl->queued_paths - 1] = q;
|
||||||
|
|
||||||
afl->last_path_time = get_cur_time();
|
afl->last_path_time = get_cur_time();
|
||||||
|
|
||||||
@ -164,6 +268,8 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
q->is_ascii = check_if_text(q);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Destroy the entire queue. */
|
/* Destroy the entire queue. */
|
||||||
|
@ -293,6 +293,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
|
|||||||
afl->afl_env.afl_autoresume =
|
afl->afl_env.afl_autoresume =
|
||||||
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
|
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
|
||||||
|
|
||||||
|
} else if (!strncmp(env, "AFL_CYCLE_SCHEDULES",
|
||||||
|
|
||||||
|
afl_environment_variable_len)) {
|
||||||
|
|
||||||
|
afl->cycle_schedules = afl->afl_env.afl_cycle_schedules =
|
||||||
|
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
|
||||||
|
|
||||||
} else if (!strncmp(env, "AFL_CAL_FAST",
|
} else if (!strncmp(env, "AFL_CAL_FAST",
|
||||||
|
|
||||||
afl_environment_variable_len)) {
|
afl_environment_variable_len)) {
|
||||||
|
@ -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
|
/* If we had a full queue cycle with no new finds, try
|
||||||
recombination strategies next. */
|
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) {
|
if (afl->use_splicing) {
|
||||||
|
|
||||||
++afl->cycles_wo_finds;
|
++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 {
|
} 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;
|
prev_queued = afl->queued_paths;
|
||||||
|
|
||||||
if (afl->sync_id && afl->queue_cycle == 1 &&
|
if (afl->sync_id && afl->queue_cycle == 1 &&
|
||||||
|
Reference in New Issue
Block a user