about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvanhauser-thc <vh@thc.org>2023-04-04 19:44:12 +0200
committervanhauser-thc <vh@thc.org>2023-04-04 19:44:12 +0200
commit3ab18d286142e2e19e37850c051e0b07b9d7b296 (patch)
tree0d717ef99fab4e30bb31e7a1af0623f929037509
parent2bff92c603463410fa0f97e7c4db7eb14c45e5ed (diff)
downloadafl++-3ab18d286142e2e19e37850c051e0b07b9d7b296.tar.gz
mode switch
-rw-r--r--include/afl-fuzz.h69
-rw-r--r--include/afl-mutations.h259
-rw-r--r--include/config.h6
-rw-r--r--src/afl-fuzz-one.c6
-rw-r--r--src/afl-fuzz-state.c1
-rw-r--r--src/afl-fuzz-stats.c5
-rw-r--r--src/afl-fuzz.c51
7 files changed, 351 insertions, 46 deletions
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 58d02af5..6573eabf 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -490,7 +490,9 @@ typedef struct afl_state {
       *orig_cmdline,                    /* Original command line            */
       *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                 */
       no_unlink,                        /* do not unlink cur_input          */
@@ -499,40 +501,37 @@ typedef struct afl_state {
       custom_splice_optout,             /* Custom mutator no splice buffer  */
       is_main_node,                     /* if this is the main node         */
       is_secondary_node,                /* if this is a secondary instance  */
-      pizza_is_served;                  /* pizza mode                       */
-
-  u32 stats_update_freq;                /* Stats update frequency (execs)   */
-
-  u8 schedule;                          /* Power schedule (default: EXPLORE)*/
-  u8 havoc_max_mult;
-
-  u8 skip_deterministic,                /* Skip deterministic stages?       */
-      use_splicing,                     /* Recombine input files?           */
-      non_instrumented_mode,            /* Run in non-instrumented mode?    */
-      score_changed,                    /* Scoring for favorites changed?   */
-      resuming_fuzz,                    /* Resuming an older fuzzing job?   */
-      timeout_given,                    /* Specific timeout given?          */
-      not_on_tty,                       /* stdout is not a tty              */
-      term_too_small,                   /* terminal dimensions too small    */
-      no_forkserver,                    /* Disable forkserver?              */
-      crash_mode,                       /* Crash mode! Yeah!                */
-      in_place_resume,                  /* Attempt in-place resume?         */
-      autoresume,                       /* Resume if afl->out_dir exists?   */
-      auto_changed,                     /* Auto-generated tokens changed?   */
-      no_cpu_meter_red,                 /* Feng shui on the status screen   */
-      no_arith,                         /* Skip most arithmetic ops         */
-      shuffle_queue,                    /* Shuffle input queue?             */
-      bitmap_changed,                   /* Time to update bitmap?           */
-      unicorn_mode,                     /* Running in Unicorn mode?         */
-      use_wine,                         /* Use WINE with QEMU mode          */
-      skip_requested,                   /* Skip request, via SIGUSR1        */
-      run_over10m,                      /* Run time over 10 minutes?        */
-      persistent_mode,                  /* Running in persistent mode?      */
-      deferred_mode,                    /* Deferred forkserver mode?        */
-      fixed_seed,                       /* do not reseed                    */
-      fast_cal,                         /* Try to calibrate faster?         */
-      disable_trim,                     /* Never trim in fuzz_one           */
-      shmem_testcase_mode,              /* If sharedmem testcases are used  */
+      pizza_is_served,                  /* pizza mode                       */
+      text_input,                       /* target wants text inputs         */
+      fuzz_mode, /* current mode: coverage/exploration or crash/exploitation */
+      schedule,                         /* Power schedule (default: EXPLORE)*/
+      havoc_max_mult, skip_deterministic, /* Skip deterministic stages?       */
+      use_splicing,                       /* Recombine input files?           */
+      non_instrumented_mode,              /* Run in non-instrumented mode?    */
+      score_changed,                      /* Scoring for favorites changed?   */
+      resuming_fuzz,                      /* Resuming an older fuzzing job?   */
+      timeout_given,                      /* Specific timeout given?          */
+      not_on_tty,                         /* stdout is not a tty              */
+      term_too_small,                     /* terminal dimensions too small    */
+      no_forkserver,                      /* Disable forkserver?              */
+      crash_mode,                         /* Crash mode! Yeah!                */
+      in_place_resume,                    /* Attempt in-place resume?         */
+      autoresume,                         /* Resume if afl->out_dir exists?   */
+      auto_changed,                       /* Auto-generated tokens changed?   */
+      no_cpu_meter_red,                   /* Feng shui on the status screen   */
+      no_arith,                           /* Skip most arithmetic ops         */
+      shuffle_queue,                      /* Shuffle input queue?             */
+      bitmap_changed,                     /* Time to update bitmap?           */
+      unicorn_mode,                       /* Running in Unicorn mode?         */
+      use_wine,                           /* Use WINE with QEMU mode          */
+      skip_requested,                     /* Skip request, via SIGUSR1        */
+      run_over10m,                        /* Run time over 10 minutes?        */
+      persistent_mode,                    /* Running in persistent mode?      */
+      deferred_mode,                      /* Deferred forkserver mode?        */
+      fixed_seed,                         /* do not reseed                    */
+      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 */
       cycle_schedules,                  /* cycle power schedules?           */
       old_seed_selection,               /* use vanilla afl seed selection   */
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index 707db799..5a1b6356 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -81,7 +81,264 @@ enum {
 u32 mutation_strategy_exploration_text[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_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 choose_block_len(afl_state_t *, u32);
diff --git a/include/config.h b/include/config.h
index e46f515a..c1297bdd 100644
--- a/include/config.h
+++ b/include/config.h
@@ -43,6 +43,12 @@
    Default: 8MB (defined in bytes) */
 #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) */
 #define DEFAULT_PERMISSION 0600
 
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 226fb40e..e6b58713 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2078,9 +2078,9 @@ havoc_stage:
   u32 *mutation_array;
   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;
 
@@ -2092,7 +2092,7 @@ havoc_stage:
 
   } else {  // is binary!
 
-    if (1) {  // is exploration?
+    if (likely(afl->fuzz_mode == 0)) {  // is exploration?
 
       mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;
 
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index f9aa5cfe..907861e9 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -108,6 +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;
 #ifndef NO_SPLICING
   afl->use_splicing = 1;
 #endif
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 25ebe987..de48e10a 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -1282,7 +1282,10 @@ void show_stats_normal(afl_state_t *afl) {
   }
 
   /* 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
 
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;