update mutation strategy

This commit is contained in:
vanhauser-thc
2023-06-29 16:57:20 +02:00
parent 15fc47a62c
commit 3e1d794107
5 changed files with 95 additions and 66 deletions

View File

@ -8,7 +8,8 @@
- new mutation engine: mutations that favor discovery more paths are - new mutation engine: mutations that favor discovery more paths are
prefered until no new finds for 10 minutes then switching to mutations prefered until no new finds for 10 minutes then switching to mutations
that favor triggering crashes. Modes and switch time can be configured that favor triggering crashes. Modes and switch time can be configured
with `-P`. with `-P`. Also input mode for the target can be defined with `-a` to
be `text` or `binary` (defaults to `generic`)
- new custom mutator that has the new afl++ engine (so it can easily - new custom mutator that has the new afl++ engine (so it can easily
incorporated into new custom mutators), and also comes with a standalone incorporated into new custom mutators), and also comes with a standalone
command line tool! See custom_mutators/aflpp/standalone/ command line tool! See custom_mutators/aflpp/standalone/
@ -23,6 +24,7 @@
Thanks to @amykweon for spotting and fixing! Thanks to @amykweon for spotting and fixing!
- @toka fixed a bug in laf-intel signed integer comparison splitting, - @toka fixed a bug in laf-intel signed integer comparison splitting,
thanks a lot!! thanks a lot!!
- more LLVM compatability
- frida_mode: - frida_mode:
- support for long form instrumentation on x86_x64 and arm64 - support for long form instrumentation on x86_x64 and arm64

View File

@ -505,36 +505,37 @@ typedef struct afl_state {
is_main_node, /* if this is the main node */ is_main_node, /* if this is the main node */
is_secondary_node, /* if this is a secondary instance */ is_secondary_node, /* if this is a secondary instance */
pizza_is_served, /* pizza mode */ pizza_is_served, /* pizza mode */
text_input, /* target wants text inputs */ input_mode, /* target wants text inputs */
fuzz_mode, /* current mode: coverage/exploration or crash/exploitation */ fuzz_mode, /* coverage/exploration or crash/exploitation mode */
schedule, /* Power schedule (default: EXPLORE)*/ schedule, /* Power schedule (default: EXPLORE)*/
havoc_max_mult, skip_deterministic, /* Skip deterministic stages? */ havoc_max_mult, /* havoc multiplier */
use_splicing, /* Recombine input files? */ skip_deterministic, /* Skip deterministic stages? */
non_instrumented_mode, /* Run in non-instrumented mode? */ use_splicing, /* Recombine input files? */
score_changed, /* Scoring for favorites changed? */ non_instrumented_mode, /* Run in non-instrumented mode? */
resuming_fuzz, /* Resuming an older fuzzing job? */ score_changed, /* Scoring for favorites changed? */
timeout_given, /* Specific timeout given? */ resuming_fuzz, /* Resuming an older fuzzing job? */
not_on_tty, /* stdout is not a tty */ timeout_given, /* Specific timeout given? */
term_too_small, /* terminal dimensions too small */ not_on_tty, /* stdout is not a tty */
no_forkserver, /* Disable forkserver? */ term_too_small, /* terminal dimensions too small */
crash_mode, /* Crash mode! Yeah! */ no_forkserver, /* Disable forkserver? */
in_place_resume, /* Attempt in-place resume? */ crash_mode, /* Crash mode! Yeah! */
autoresume, /* Resume if afl->out_dir exists? */ in_place_resume, /* Attempt in-place resume? */
auto_changed, /* Auto-generated tokens changed? */ autoresume, /* Resume if afl->out_dir exists? */
no_cpu_meter_red, /* Feng shui on the status screen */ auto_changed, /* Auto-generated tokens changed? */
no_arith, /* Skip most arithmetic ops */ no_cpu_meter_red, /* Feng shui on the status screen */
shuffle_queue, /* Shuffle input queue? */ no_arith, /* Skip most arithmetic ops */
bitmap_changed, /* Time to update bitmap? */ shuffle_queue, /* Shuffle input queue? */
unicorn_mode, /* Running in Unicorn mode? */ bitmap_changed, /* Time to update bitmap? */
use_wine, /* Use WINE with QEMU mode */ unicorn_mode, /* Running in Unicorn mode? */
skip_requested, /* Skip request, via SIGUSR1 */ use_wine, /* Use WINE with QEMU mode */
run_over10m, /* Run time over 10 minutes? */ skip_requested, /* Skip request, via SIGUSR1 */
persistent_mode, /* Running in persistent mode? */ run_over10m, /* Run time over 10 minutes? */
deferred_mode, /* Deferred forkserver mode? */ persistent_mode, /* Running in persistent mode? */
fixed_seed, /* do not reseed */ deferred_mode, /* Deferred forkserver mode? */
fast_cal, /* Try to calibrate faster? */ fixed_seed, /* do not reseed */
disable_trim, /* Never trim in fuzz_one */ fast_cal, /* Try to calibrate faster? */
shmem_testcase_mode, /* If sharedmem testcases are used */ disable_trim, /* Never trim in fuzz_one */
shmem_testcase_mode, /* If sharedmem testcases are used */
expand_havoc, /* perform expensive havoc after no find */ expand_havoc, /* perform expensive havoc after no find */
cycle_schedules, /* cycle power schedules? */ cycle_schedules, /* cycle power schedules? */
old_seed_selection, /* use vanilla afl seed selection */ old_seed_selection, /* use vanilla afl seed selection */

View File

@ -14,14 +14,14 @@
Parameters: Parameters:
afl_state_t *afl - the *afl state pointer afl_state_t *afl - the *afl state pointer
u8 *buf - the input buffer to mutate which will be mutated into. u8 *buf - the input buffer to mutate which will be mutated into.
NOTE: must be able to contain a size of at least max_len (see below)! NOTE: must be able to contain a size of at least max_len!! (see below)
u32 len - the length of the input u32 len - the length of the input
u32 steps - how many mutations to perform on the input u32 steps - how many mutations to perform on the input
bool is_text - is the target expecting text inputs bool is_text - is the target expecting text inputs
bool is_exploration - mutate for exploration mode (instead of exploitation) bool is_exploration - mutate for exploration mode (instead of exploitation)
splice_buf - a buffer from another corpus item to splice with. splice_buf - a buffer from another corpus item to splice with.
If NULL then no splicing If NULL then no splicing is done (obviously).
splice_len - the length of the splice buffer. If 0 then no splicing splice_len - the length of the splice buffer. If 0 then no splicing.
u32 max_len - the maximum size the mutated buffer may grow to u32 max_len - the maximum size the mutated buffer may grow to
*/ */

View File

@ -2085,47 +2085,57 @@ havoc_stage:
u32 *mutation_array; u32 *mutation_array;
u32 stack_max, rand_max; // stack_max_pow = afl->havoc_stack_pow2; u32 stack_max, rand_max; // stack_max_pow = afl->havoc_stack_pow2;
/* switch (afl->input_mode) {
if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) { case 1: { // TEXT
mutation_array = full_splice_array; if (likely(afl->fuzz_mode == 0)) { // is exploration?
rand_max = MUT_SPLICE_ARRAY_SIZE; mutation_array = (unsigned int *)&binary_array;
rand_max = MUT_BIN_ARRAY_SIZE;
} else { } else { // exploitation mode
mutation_array = normal_splice_array; mutation_array = (unsigned int *)&mutation_strategy_exploitation_text;
rand_max = MUT_NORMAL_ARRAY_SIZE; rand_max = MUT_STRATEGY_ARRAY_SIZE;
} }
*/ break;
if (unlikely(afl->text_input)) { // is text?
if (likely(afl->fuzz_mode == 0)) { // is exploration?
mutation_array = (unsigned int *)&text_array;
rand_max = MUT_TXT_ARRAY_SIZE;
} else { // is exploitation!
mutation_array = (unsigned int *)&mutation_strategy_exploitation_text;
rand_max = MUT_STRATEGY_ARRAY_SIZE;
} }
} else { // is binary! case 2: { // BINARY
if (likely(afl->fuzz_mode == 0)) { // is exploration? if (likely(afl->fuzz_mode == 0)) { // is exploration?
mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;
rand_max = MUT_STRATEGY_ARRAY_SIZE;
mutation_array = (unsigned int *)&binary_array; } else { // exploitation mode
rand_max = MUT_BIN_ARRAY_SIZE;
} else { // is exploitation! mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
rand_max = MUT_STRATEGY_ARRAY_SIZE;
mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary; }
rand_max = MUT_STRATEGY_ARRAY_SIZE;
break;
}
default: { // DEFAULT/GENERIC
if (likely(afl->fuzz_mode == 0)) { // is exploration?
mutation_array = (unsigned int *)&binary_array;
rand_max = MUT_BIN_ARRAY_SIZE;
} else { // exploitation mode
// this will need to be changed I guess
mutation_array = (unsigned int *)&mutation_strategy_exploration_text;
rand_max = MUT_STRATEGY_ARRAY_SIZE;
}
break;
} }

View File

@ -125,7 +125,8 @@ static void usage(u8 *argv0, int more_help) {
"Required parameters:\n" "Required parameters:\n"
" -i dir - input directory with test cases (or '-' to resume, " " -i dir - input directory with test cases (or '-' to resume, "
"also see AFL_AUTORESUME)\n" "also see \n"
" AFL_AUTORESUME)\n"
" -o dir - output directory for fuzzer findings\n\n" " -o dir - output directory for fuzzer findings\n\n"
"Execution control settings:\n" "Execution control settings:\n"
@ -164,8 +165,8 @@ static void usage(u8 *argv0, int more_help) {
"\n" "\n"
"Mutator settings:\n" "Mutator settings:\n"
" -a - target expects ascii text input (prefer text " " -a - target input format, \"text\" or \"binary\" (default: "
"mutators)\n" "generic)\n"
" -g minlength - set min length of generated fuzz input (default: 1)\n" " -g minlength - set min length of generated fuzz input (default: 1)\n"
" -G maxlength - set max length of generated fuzz input (default: " " -G maxlength - set max length of generated fuzz input (default: "
"%lu)\n" "%lu)\n"
@ -506,13 +507,28 @@ int main(int argc, char **argv_orig, char **envp) {
// still available: HjJkKqruvwz // still available: HjJkKqruvwz
while ((opt = getopt(argc, argv, while ((opt = getopt(argc, argv,
"+aAb:B:c:CdDe:E:f:F:g:G:hi:I:l:L:m:M:nNo:Op:P:QRs:S:t:" "+a:Ab:B:c:CdDe:E:f:F:g:G:hi:I:l:L:m:M:nNo:Op:P:QRs:S:t:"
"T:UV:WXx:YZ")) > 0) { "T:UV:WXx:YZ")) > 0) {
switch (opt) { switch (opt) {
case 'a': case 'a':
afl->text_input = 1;
if (!stricmp(optarg, "text") || !stricmp(optarg, "ascii") ||
!stricmp(optarg, "txt") || !stricmp(optarg, "asc")) {
afl->input_mode = 1;
} else if (!stricmp(optarg, "bin") || !stricmp(optarg, "binary")) {
afl->input_mode = 2;
} else {
FATAL("-a input mode needs to be \"text\" or \"binary\".");
}
break; break;
case 'P': case 'P':