From 3ab18d286142e2e19e37850c051e0b07b9d7b296 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 4 Apr 2023 19:44:12 +0200 Subject: mode switch --- src/afl-fuzz.c | 51 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-) (limited to 'src/afl-fuzz.c') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 3380fd90..315107d7 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -128,6 +128,13 @@ static void usage(u8 *argv0, int more_help) { " -o dir - output directory for fuzzer findings\n\n" "Execution control settings:\n" + " -P strategy - set fix mutation strategy: explore (focus on new " + "coverage),\n" + " exploit (focus on triggering crashes). You can also " + "set a\n" + " number of seconds after without any finds it switches " + "to\n" + " exploit mode, and back on new coverage (default: %u)\n" " -p schedule - power schedules compute a seed's performance score:\n" " fast(default), explore, exploit, seek, rare, mmopt, " "coe, lin\n" @@ -156,6 +163,7 @@ static void usage(u8 *argv0, int more_help) { "\n" "Mutator settings:\n" + " -a - target expects ascii text input\n" " -g minlength - set min length of generated fuzz input (default: 1)\n" " -G maxlength - set max length of generated fuzz input (default: " "%lu)\n" @@ -212,7 +220,8 @@ static void usage(u8 *argv0, int more_help) { " -e ext - file extension for the fuzz test input file (if " "needed)\n" "\n", - argv0, EXEC_TIMEOUT, MEM_LIMIT, MAX_FILE, FOREIGN_SYNCS_MAX); + argv0, STRATEGY_SWITCH_TIME, EXEC_TIMEOUT, MEM_LIMIT, MAX_FILE, + FOREIGN_SYNCS_MAX); if (more_help > 1) { @@ -553,14 +562,44 @@ int main(int argc, char **argv_orig, char **envp) { afl->shmem_testcase_mode = 1; // we always try to perform shmem fuzzing - while ( - (opt = getopt( - argc, argv, - "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YZ")) > - 0) { + // still available: aHjJkKPqruvwz + 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:" + "T:UV:WXx:YZ")) > 0) { switch (opt) { + case 'a': + afl->text_input = 1; + break; + + case 'P': + if (!stricmp(optarg, "explore") || !stricmp(optarg, "exploration")) { + + afl->fuzz_mode = 0; + afl->switch_fuzz_mode = 1; + + } else if (!stricmp(optarg, "exploit") || + + !stricmp(optarg, "exploitation")) { + + afl->fuzz_mode = 1; + afl->switch_fuzz_mode = 0; + + } else { + + if ((s32)(afl->switch_fuzz_mode = (u32)atoi(optarg)) < 1) { + + FATAL( + "Parameter for option -P must be \"explore\", \"exploit\" or a " + "number!"); + + } + + } + + break; + case 'g': afl->min_length = atoi(optarg); break; -- cgit 1.4.1 From a74561b0e7434282ad214ca634b5c19c2f345e8e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 5 Apr 2023 12:12:05 +0200 Subject: implement switch mode --- include/afl-fuzz.h | 6 +++--- src/afl-fuzz-bitmap.c | 12 ++++++++++++ src/afl-fuzz-state.c | 2 +- src/afl-fuzz.c | 30 ++++++++++++++++++++++++++---- 4 files changed, 42 insertions(+), 8 deletions(-) (limited to 'src/afl-fuzz.c') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 6573eabf..23a04f42 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -491,8 +491,7 @@ typedef struct afl_state { *infoexec; /* Command to execute on a new crash */ u32 hang_tmout, /* Timeout used for hang det (ms) */ - stats_update_freq, /* Stats update frequency (execs) */ - switch_fuzz_mode; /* auto or fixed fuzz mode */ + stats_update_freq; /* Stats update frequency (execs) */ u8 havoc_stack_pow2, /* HAVOC_STACK_POW2 */ no_unlink, /* do not unlink cur_input */ @@ -592,7 +591,8 @@ typedef struct afl_state { last_hang_time, /* Time for most recent hang (ms) */ longest_find_time, /* Longest time taken for a find */ exit_on_time, /* Delay to exit if no new paths */ - sync_time; /* Sync time (ms) */ + sync_time, /* Sync time (ms) */ + switch_fuzz_mode; /* auto or fixed fuzz mode */ u32 slowest_exec_ms, /* Slowest testcase non hang in ms */ subseq_tmouts; /* Number of timeouts in a row */ diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index d9c792d1..a937c96d 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -529,6 +529,18 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { close(fd); add_to_queue(afl, queue_fn, len, 0); + if (unlikely(afl->fuzz_mode) && likely(afl->switch_fuzz_mode)) { + + if (afl->afl_env.afl_no_ui) { + + ACTF("New coverage found, switching back to exploration mode."); + + } + + afl->fuzz_mode = 0; + + } + #ifdef INTROSPECTION if (afl->custom_mutators_count && afl->current_custom_fuzz) { diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 907861e9..9dc258b1 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -108,7 +108,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->cmplog_lvl = 2; afl->min_length = 1; afl->max_length = MAX_FILE; - afl->switch_fuzz_mode = STRATEGY_SWITCH_TIME; + afl->switch_fuzz_mode = STRATEGY_SWITCH_TIME * 1000; #ifndef NO_SPLICING afl->use_splicing = 1; #endif diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 315107d7..c50b271b 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -577,7 +577,7 @@ int main(int argc, char **argv_orig, char **envp) { if (!stricmp(optarg, "explore") || !stricmp(optarg, "exploration")) { afl->fuzz_mode = 0; - afl->switch_fuzz_mode = 1; + afl->switch_fuzz_mode = 0; } else if (!stricmp(optarg, "exploit") || @@ -588,12 +588,16 @@ int main(int argc, char **argv_orig, char **envp) { } else { - if ((s32)(afl->switch_fuzz_mode = (u32)atoi(optarg)) < 1) { + if ((afl->switch_fuzz_mode = (u32)atoi(optarg)) > INT_MAX) { FATAL( "Parameter for option -P must be \"explore\", \"exploit\" or a " "number!"); + } else { + + afl->switch_fuzz_mode *= 1000; + } } @@ -2689,13 +2693,31 @@ int main(int argc, char **argv_orig, char **envp) { } while (skipped_fuzz && afl->queue_cur && !afl->stop_soon); + u64 cur_time = get_cur_time(); + + if (likely(afl->switch_fuzz_mode && afl->fuzz_mode == 0) && + unlikely(cur_time > afl->last_find_time + afl->switch_fuzz_mode)) { + + if (afl->afl_env.afl_no_ui) { + + ACTF( + "No new coverage found for %llu seconds, switching to exploitation " + "strategy.", + afl->switch_fuzz_mode / 1000); + + } + + afl->fuzz_mode = 1; + + } + if (likely(!afl->stop_soon && afl->sync_id)) { if (likely(afl->skip_deterministic)) { if (unlikely(afl->is_main_node)) { - if (unlikely(get_cur_time() > + if (unlikely(cur_time > (afl->sync_time >> 1) + afl->last_sync_time)) { if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) { @@ -2708,7 +2730,7 @@ int main(int argc, char **argv_orig, char **envp) { } else { - if (unlikely(get_cur_time() > afl->sync_time + afl->last_sync_time)) { + if (unlikely(cur_time > afl->sync_time + afl->last_sync_time)) { if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); } -- cgit 1.4.1 From fcb5eda5d0eb38b1a9678ee75890f2fccf936bd9 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 5 Apr 2023 16:34:08 +0200 Subject: nit --- 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 c50b271b..bc44367a 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -562,7 +562,7 @@ int main(int argc, char **argv_orig, char **envp) { afl->shmem_testcase_mode = 1; // we always try to perform shmem fuzzing - // still available: aHjJkKPqruvwz + // still available: HjJkKqruvwz 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:" "T:UV:WXx:YZ")) > 0) { -- cgit 1.4.1