mode switch

This commit is contained in:
vanhauser-thc
2023-04-04 19:44:12 +02:00
parent 2bff92c603
commit 3ab18d2861
7 changed files with 351 additions and 46 deletions

View File

@ -490,7 +490,9 @@ typedef struct afl_state {
*orig_cmdline, /* Original command line */ *orig_cmdline, /* Original command line */
*infoexec; /* Command to execute on a new crash */ *infoexec; /* Command to execute on a new crash */
u32 hang_tmout; /* Timeout used for hang det (ms) */ u32 hang_tmout, /* Timeout used for hang det (ms) */
stats_update_freq, /* Stats update frequency (execs) */
switch_fuzz_mode; /* auto or fixed fuzz mode */
u8 havoc_stack_pow2, /* HAVOC_STACK_POW2 */ u8 havoc_stack_pow2, /* HAVOC_STACK_POW2 */
no_unlink, /* do not unlink cur_input */ no_unlink, /* do not unlink cur_input */
@ -499,40 +501,37 @@ typedef struct afl_state {
custom_splice_optout, /* Custom mutator no splice buffer */ custom_splice_optout, /* Custom mutator no splice buffer */
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 */
u32 stats_update_freq; /* Stats update frequency (execs) */ fuzz_mode, /* current mode: coverage/exploration or crash/exploitation */
schedule, /* Power schedule (default: EXPLORE)*/
u8 schedule; /* Power schedule (default: EXPLORE)*/ havoc_max_mult, skip_deterministic, /* Skip deterministic stages? */
u8 havoc_max_mult; use_splicing, /* Recombine input files? */
non_instrumented_mode, /* Run in non-instrumented mode? */
u8 skip_deterministic, /* Skip deterministic stages? */ score_changed, /* Scoring for favorites changed? */
use_splicing, /* Recombine input files? */ resuming_fuzz, /* Resuming an older fuzzing job? */
non_instrumented_mode, /* Run in non-instrumented mode? */ timeout_given, /* Specific timeout given? */
score_changed, /* Scoring for favorites changed? */ not_on_tty, /* stdout is not a tty */
resuming_fuzz, /* Resuming an older fuzzing job? */ term_too_small, /* terminal dimensions too small */
timeout_given, /* Specific timeout given? */ no_forkserver, /* Disable forkserver? */
not_on_tty, /* stdout is not a tty */ crash_mode, /* Crash mode! Yeah! */
term_too_small, /* terminal dimensions too small */ in_place_resume, /* Attempt in-place resume? */
no_forkserver, /* Disable forkserver? */ autoresume, /* Resume if afl->out_dir exists? */
crash_mode, /* Crash mode! Yeah! */ auto_changed, /* Auto-generated tokens changed? */
in_place_resume, /* Attempt in-place resume? */ no_cpu_meter_red, /* Feng shui on the status screen */
autoresume, /* Resume if afl->out_dir exists? */ no_arith, /* Skip most arithmetic ops */
auto_changed, /* Auto-generated tokens changed? */ shuffle_queue, /* Shuffle input queue? */
no_cpu_meter_red, /* Feng shui on the status screen */ bitmap_changed, /* Time to update bitmap? */
no_arith, /* Skip most arithmetic ops */ unicorn_mode, /* Running in Unicorn mode? */
shuffle_queue, /* Shuffle input queue? */ use_wine, /* Use WINE with QEMU mode */
bitmap_changed, /* Time to update bitmap? */ skip_requested, /* Skip request, via SIGUSR1 */
unicorn_mode, /* Running in Unicorn mode? */ run_over10m, /* Run time over 10 minutes? */
use_wine, /* Use WINE with QEMU mode */ persistent_mode, /* Running in persistent mode? */
skip_requested, /* Skip request, via SIGUSR1 */ deferred_mode, /* Deferred forkserver mode? */
run_over10m, /* Run time over 10 minutes? */ fixed_seed, /* do not reseed */
persistent_mode, /* Running in persistent mode? */ fast_cal, /* Try to calibrate faster? */
deferred_mode, /* Deferred forkserver mode? */ disable_trim, /* Never trim in fuzz_one */
fixed_seed, /* do not reseed */ shmem_testcase_mode, /* If sharedmem testcases are used */
fast_cal, /* Try to calibrate faster? */
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

@ -81,7 +81,264 @@ enum {
u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {}; u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {};
u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {}; u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {};
u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {}; u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {};
u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = {}; u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_FLIPBIT,
MUT_FLIPBIT,
MUT_FLIPBIT,
MUT_FLIPBIT,
MUT_FLIPBIT,
MUT_FLIPBIT,
MUT_FLIPBIT,
MUT_INTERESTING8,
MUT_INTERESTING8,
MUT_INTERESTING8,
MUT_INTERESTING8,
MUT_INTERESTING8,
MUT_INTERESTING8,
MUT_INTERESTING8,
MUT_INTERESTING16,
MUT_INTERESTING16,
MUT_INTERESTING16,
MUT_INTERESTING16,
MUT_INTERESTING16,
MUT_INTERESTING16,
MUT_INTERESTING16,
MUT_INTERESTING16BE,
MUT_INTERESTING16BE,
MUT_INTERESTING16BE,
MUT_INTERESTING16BE,
MUT_INTERESTING16BE,
MUT_INTERESTING16BE,
MUT_INTERESTING16BE,
MUT_INTERESTING32,
MUT_INTERESTING32,
MUT_INTERESTING32,
MUT_INTERESTING32,
MUT_INTERESTING32,
MUT_INTERESTING32,
MUT_INTERESTING32,
MUT_INTERESTING32,
MUT_INTERESTING32BE,
MUT_INTERESTING32BE,
MUT_INTERESTING32BE,
MUT_INTERESTING32BE,
MUT_INTERESTING32BE,
MUT_INTERESTING32BE,
MUT_INTERESTING32BE,
MUT_INTERESTING32BE,
MUT_ARITH8_,
MUT_ARITH8_,
MUT_ARITH8_,
MUT_ARITH8_,
MUT_ARITH8_,
MUT_ARITH8_,
MUT_ARITH8,
MUT_ARITH8,
MUT_ARITH8,
MUT_ARITH8,
MUT_ARITH8,
MUT_ARITH8,
MUT_ARITH8,
MUT_ARITH16_,
MUT_ARITH16_,
MUT_ARITH16_,
MUT_ARITH16_,
MUT_ARITH16_,
MUT_ARITH16_,
MUT_ARITH16BE_,
MUT_ARITH16BE_,
MUT_ARITH16BE_,
MUT_ARITH16BE_,
MUT_ARITH16BE_,
MUT_ARITH16BE_,
MUT_ARITH16BE_,
MUT_ARITH16,
MUT_ARITH16,
MUT_ARITH16,
MUT_ARITH16,
MUT_ARITH16,
MUT_ARITH16,
MUT_ARITH16,
MUT_ARITH16BE,
MUT_ARITH16BE,
MUT_ARITH16BE,
MUT_ARITH16BE,
MUT_ARITH16BE,
MUT_ARITH16BE,
MUT_ARITH16BE,
MUT_ARITH32_,
MUT_ARITH32_,
MUT_ARITH32_,
MUT_ARITH32_,
MUT_ARITH32_,
MUT_ARITH32_,
MUT_ARITH32BE_,
MUT_ARITH32BE_,
MUT_ARITH32BE_,
MUT_ARITH32BE_,
MUT_ARITH32BE_,
MUT_ARITH32BE_,
MUT_ARITH32,
MUT_ARITH32,
MUT_ARITH32,
MUT_ARITH32,
MUT_ARITH32,
MUT_ARITH32,
MUT_ARITH32BE,
MUT_ARITH32BE,
MUT_ARITH32BE,
MUT_ARITH32BE,
MUT_ARITH32BE,
MUT_ARITH32BE,
MUT_ARITH32BE,
MUT_RAND8,
MUT_RAND8,
MUT_RAND8,
MUT_RAND8,
MUT_RAND8,
MUT_RAND8,
MUT_RAND8,
MUT_CLONE_OVERWRITE,
MUT_CLONE_OVERWRITE,
MUT_CLONE_OVERWRITE,
MUT_CLONE_OVERWRITE,
MUT_CLONE_OVERWRITE,
MUT_CLONE_OVERWRITE,
MUT_CLONE_OVERWRITE,
MUT_CLONE_OVERWRITE,
MUT_CLONE_OVERWRITE,
MUT_CLONE_INSERT,
MUT_CLONE_INSERT,
MUT_CLONE_INSERT,
MUT_CLONE_INSERT,
MUT_CLONE_INSERT,
MUT_CLONE_INSERT,
MUT_CLONE_INSERT,
MUT_CLONE_INSERT,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_FIXED,
MUT_OVERWRITE_FIXED,
MUT_OVERWRITE_FIXED,
MUT_OVERWRITE_FIXED,
MUT_OVERWRITE_FIXED,
MUT_OVERWRITE_FIXED,
MUT_BYTEADD,
MUT_BYTEADD,
MUT_BYTEADD,
MUT_BYTEADD,
MUT_BYTEADD,
MUT_BYTEADD,
MUT_BYTEADD,
MUT_BYTESUB,
MUT_BYTESUB,
MUT_BYTESUB,
MUT_BYTESUB,
MUT_BYTESUB,
MUT_BYTESUB,
MUT_FLIP8,
MUT_FLIP8,
MUT_FLIP8,
MUT_FLIP8,
MUT_FLIP8,
MUT_FLIP8,
MUT_SWITCH,
MUT_SWITCH,
MUT_SWITCH,
MUT_SWITCH,
MUT_SWITCH,
MUT_SWITCH,
MUT_SWITCH,
MUT_DEL,
MUT_DEL,
MUT_DEL,
MUT_DEL,
MUT_DEL,
MUT_DEL,
MUT_SHUFFLE,
MUT_SHUFFLE,
MUT_SHUFFLE,
MUT_SHUFFLE,
MUT_SHUFFLE,
MUT_SHUFFLE,
MUT_DELONE,
MUT_DELONE,
MUT_DELONE,
MUT_DELONE,
MUT_DELONE,
MUT_INSERTONE,
MUT_INSERTONE,
MUT_INSERTONE,
MUT_INSERTONE,
MUT_INSERTONE,
MUT_INSERTONE,
MUT_ASCIINUM,
MUT_ASCIINUM,
MUT_ASCIINUM,
MUT_ASCIINUM,
MUT_ASCIINUM,
MUT_NEG,
MUT_NEG,
MUT_NEG,
MUT_NEG,
MUT_NEG,
MUT_NEG,
MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
MUT_EXTRA_OVERWRITE,
MUT_EXTRA_OVERWRITE,
MUT_EXTRA_OVERWRITE,
MUT_EXTRA_OVERWRITE,
MUT_EXTRA_OVERWRITE,
MUT_EXTRA_OVERWRITE,
MUT_EXTRA_OVERWRITE,
MUT_EXTRA_INSERT,
MUT_EXTRA_INSERT,
MUT_EXTRA_INSERT,
MUT_EXTRA_INSERT,
MUT_EXTRA_INSERT,
MUT_EXTRA_INSERT,
MUT_EXTRA_INSERT,
MUT_AUTO_EXTRA_OVERWRITE,
MUT_AUTO_EXTRA_OVERWRITE,
MUT_AUTO_EXTRA_OVERWRITE,
MUT_AUTO_EXTRA_OVERWRITE,
MUT_AUTO_EXTRA_OVERWRITE,
MUT_AUTO_EXTRA_OVERWRITE,
MUT_AUTO_EXTRA_OVERWRITE,
MUT_AUTO_EXTRA_INSERT,
MUT_AUTO_EXTRA_INSERT,
MUT_AUTO_EXTRA_INSERT,
MUT_AUTO_EXTRA_INSERT,
MUT_AUTO_EXTRA_INSERT,
MUT_AUTO_EXTRA_INSERT,
MUT_AUTO_EXTRA_INSERT,
MUT_SPLICE_OVERWRITE,
MUT_SPLICE_OVERWRITE,
MUT_SPLICE_OVERWRITE,
MUT_SPLICE_OVERWRITE,
MUT_SPLICE_OVERWRITE,
MUT_SPLICE_OVERWRITE,
MUT_SPLICE_OVERWRITE,
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT};
u32 afl_mutate(afl_state_t *, u8 *, u32, u32, bool, bool, u8 *, u32, u32); u32 afl_mutate(afl_state_t *, u8 *, u32, u32, bool, bool, u8 *, u32, u32);
u32 choose_block_len(afl_state_t *, u32); u32 choose_block_len(afl_state_t *, u32);

View File

@ -43,6 +43,12 @@
Default: 8MB (defined in bytes) */ Default: 8MB (defined in bytes) */
#define DEFAULT_SHMEM_SIZE (8 * 1024 * 1024) #define DEFAULT_SHMEM_SIZE (8 * 1024 * 1024)
/* Default time until when no more coverage finds are happening afl-fuzz
switches to exploitation mode. It automatically switches back when new
coverage is found.
Default: 300 (seconds) */
#define STRATEGY_SWITCH_TIME 300
/* Default file permission umode when creating files (default: 0600) */ /* Default file permission umode when creating files (default: 0600) */
#define DEFAULT_PERMISSION 0600 #define DEFAULT_PERMISSION 0600

View File

@ -2078,9 +2078,9 @@ havoc_stage:
u32 *mutation_array; u32 *mutation_array;
u32 stack_max; u32 stack_max;
if (afl->queue_cur->is_ascii) { // is text? if (unlikely(afl->text_input || afl->queue_cur->is_ascii)) { // is text?
if (1) { // is exploration? if (likely(afl->fuzz_mode == 0)) { // is exploration?
mutation_array = (unsigned int *)&mutation_strategy_exploration_text; mutation_array = (unsigned int *)&mutation_strategy_exploration_text;
@ -2092,7 +2092,7 @@ havoc_stage:
} else { // is binary! } else { // is binary!
if (1) { // is exploration? if (likely(afl->fuzz_mode == 0)) { // is exploration?
mutation_array = (unsigned int *)&mutation_strategy_exploration_binary; mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;

View File

@ -108,6 +108,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
afl->cmplog_lvl = 2; afl->cmplog_lvl = 2;
afl->min_length = 1; afl->min_length = 1;
afl->max_length = MAX_FILE; afl->max_length = MAX_FILE;
afl->switch_fuzz_mode = STRATEGY_SWITCH_TIME;
#ifndef NO_SPLICING #ifndef NO_SPLICING
afl->use_splicing = 1; afl->use_splicing = 1;
#endif #endif

View File

@ -1282,7 +1282,10 @@ void show_stats_normal(afl_state_t *afl) {
} }
/* Last line */ /* Last line */
SAYF(SET_G1 "\n" bSTG bLB bH30 bH20 bH2 bRB bSTOP cRST RESET_G1);
SAYF(SET_G1 "\n" bSTG bLB bH cCYA bSTOP
" strategy:%s %s " bSTG bH20 bH10 bH2 bRB bSTOP cRST RESET_G1,
cPIN, afl->fuzz_mode == 0 ? "explore" : "exploit");
#undef IB #undef IB

View File

@ -128,6 +128,13 @@ static void usage(u8 *argv0, int more_help) {
" -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"
" -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" " -p schedule - power schedules compute a seed's performance score:\n"
" fast(default), explore, exploit, seek, rare, mmopt, " " fast(default), explore, exploit, seek, rare, mmopt, "
"coe, lin\n" "coe, lin\n"
@ -156,6 +163,7 @@ static void usage(u8 *argv0, int more_help) {
"\n" "\n"
"Mutator settings:\n" "Mutator settings:\n"
" -a - target expects ascii text input\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"
@ -212,7 +220,8 @@ static void usage(u8 *argv0, int more_help) {
" -e ext - file extension for the fuzz test input file (if " " -e ext - file extension for the fuzz test input file (if "
"needed)\n" "needed)\n"
"\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) { 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 afl->shmem_testcase_mode = 1; // we always try to perform shmem fuzzing
while ( // still available: aHjJkKPqruvwz
(opt = getopt( while ((opt = getopt(argc, argv,
argc, argv, "+aAb:B:c:CdDe:E:f:F:g:G:hi:I:l:L:m:M:nNo:Op:P:QRs:S:t:"
"+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YZ")) > "T:UV:WXx:YZ")) > 0) {
0) {
switch (opt) { 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': case 'g':
afl->min_length = atoi(optarg); afl->min_length = atoi(optarg);
break; break;