about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvanhauser-thc <vh@thc.org>2021-02-21 17:53:09 +0100
committervanhauser-thc <vh@thc.org>2021-02-21 17:53:09 +0100
commit974aab6cf6aa4ae34ee73bdceed1bd44a212fc5e (patch)
treed671f2951cbe48ae48fc5b8643a29108ed88981f
parentb957218a3aad95af02a4da8207c7dabb893d4dc8 (diff)
downloadafl++-974aab6cf6aa4ae34ee73bdceed1bd44a212fc5e.tar.gz
cmplog config.h -> -l option
-rw-r--r--include/afl-fuzz.h1
-rw-r--r--include/config.h9
-rw-r--r--src/afl-common.c8
-rw-r--r--src/afl-fuzz-redqueen.c83
-rw-r--r--src/afl-fuzz.c46
5 files changed, 85 insertions, 62 deletions
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 1d5ec1f0..10d94fed 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -649,6 +649,7 @@ typedef struct afl_state {
   u32 cmplog_max_filesize;
   u32 cmplog_lvl;
   u32 colorize_success;
+  u8  cmplog_enable_arith, cmplog_enable_transform;
 
   struct afl_pass_stat *pass_stats;
   struct cmp_map *      orig_cmp_map;
diff --git a/include/config.h b/include/config.h
index 9f7db04d..535ce0d3 100644
--- a/include/config.h
+++ b/include/config.h
@@ -42,13 +42,8 @@
  *
  */
 
-/* Enable arithmetic compare solving for both branches */
-#define CMPLOG_SOLVE_ARITHMETIC
-
-/* Enable transform following (XOR/ADD/SUB manipulations, hex en/decoding) */
-#define CMPLOG_SOLVE_TRANSFORM
-
-/* if TRANSFORM is enabled, this additionally enables base64 en/decoding */
+/* if TRANSFORM is enabled with '-l T', this additionally enables base64
+   encoding/decoding */
 // #define CMPLOG_SOLVE_TRANSFORM_BASE64
 
 /* If a redqueen pass finds more than one solution, try to combine them? */
diff --git a/src/afl-common.c b/src/afl-common.c
index 531753c2..ce63c262 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -561,13 +561,13 @@ void print_suggested_envs(char *mispelled_env) {
   memcpy(env_name, mispelled_env + 4, env_name_len);
 
   char *seen = ck_alloc(sizeof(afl_environment_variables) / sizeof(char *));
-  int found = 0;
+  int   found = 0;
 
   int j;
   for (j = 0; afl_environment_variables[j] != NULL; ++j) {
 
     char *afl_env = afl_environment_variables[j] + 4;
-    int distance = string_distance_levenshtein(afl_env, env_name);
+    int   distance = string_distance_levenshtein(afl_env, env_name);
     if (distance < ENV_SIMILARITY_TRESHOLD && seen[j] == 0) {
 
       SAYF("Did you mean %s?\n", afl_environment_variables[j]);
@@ -575,14 +575,14 @@ void print_suggested_envs(char *mispelled_env) {
       found = 1;
 
     }
-  
+
   }
 
   if (found) goto cleanup;
 
   for (j = 0; afl_environment_variables[j] != NULL; ++j) {
 
-    char *afl_env = afl_environment_variables[j] + 4;
+    char * afl_env = afl_environment_variables[j] + 4;
     size_t afl_env_len = strlen(afl_env);
     char * reduced = ck_alloc(afl_env_len + 1);
 
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index d77baf25..1ab5f996 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -30,7 +30,6 @@
 
 //#define _DEBUG
 //#define CMPLOG_INTROSPECTION
-#define CMPLOG_COMBINE
 
 // CMP attribute enum
 enum {
@@ -523,7 +522,7 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) {
 
 }
 
-#ifdef CMPLOG_SOLVE_TRANSFORM
+//#ifdef CMPLOG_SOLVE_TRANSFORM
 static int strntoll(const char *str, size_t sz, char **end, int base,
                     long long *out) {
 
@@ -608,7 +607,7 @@ static int is_hex(const char *str) {
 
 }
 
-  #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
+#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
 // tests 4 bytes at location
 static int is_base64(const char *str) {
 
@@ -721,10 +720,10 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) {
 
 }
 
-  #endif
-
 #endif
 
+//#endif
+
 static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
                               u64 pattern, u64 repl, u64 o_pattern,
                               u64 changed_val, u8 attr, u32 idx, u32 taint_len,
@@ -748,9 +747,9 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
   //         o_pattern, pattern, repl, changed_val, idx, taint_len,
   //         h->shape + 1, attr);
 
-#ifdef CMPLOG_SOLVE_TRANSFORM
+  //#ifdef CMPLOG_SOLVE_TRANSFORM
   // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3
-  if (lvl & LVL3) {
+  if (afl->cmplog_enable_transform && (lvl & LVL3)) {
 
     u8 *               endptr;
     u8                 use_num = 0, use_unum = 0;
@@ -771,11 +770,11 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
 
     }
 
-  #ifdef _DEBUG
+#ifdef _DEBUG
     if (idx == 0)
       fprintf(stderr, "ASCII is=%u use_num=%u use_unum=%u idx=%u %llx==%llx\n",
               afl->queue_cur->is_ascii, use_num, use_unum, idx, num, pattern);
-  #endif
+#endif
 
     // num is likely not pattern as atoi("AAA") will be zero...
     if (use_num && ((u64)num == pattern || !num)) {
@@ -1060,7 +1059,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
 
   }
 
-#endif
+  //#endif
 
   // we only allow this for ascii2integer (above) so leave if this is the case
   if (unlikely(pattern == o_pattern)) { return 0; }
@@ -1215,8 +1214,12 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
   //       16 = modified float, 32 = modified integer (modified = wont match
   //                                                   in original buffer)
 
-#ifdef CMPLOG_SOLVE_ARITHMETIC
-  if (lvl < LVL3 || attr == IS_TRANSFORM) { return 0; }
+  //#ifdef CMPLOG_SOLVE_ARITHMETIC
+  if (!afl->cmplog_enable_arith || lvl < LVL3 || attr == IS_TRANSFORM) {
+
+    return 0;
+
+  }
 
   if (!(attr & (IS_GREATER | IS_LESSER)) || SHAPE_BYTES(h->shape) < 4) {
 
@@ -1321,11 +1324,11 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
       double *f = (double *)&repl;
       float   g = (float)*f;
       repl_new = 0;
-  #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
       memcpy((char *)&repl_new, (char *)&g, 4);
-  #else
+#else
       memcpy(((char *)&repl_new) + 4, (char *)&g, 4);
-  #endif
+#endif
       changed_val = repl_new;
       h->shape = 3;  // modify shape
 
@@ -1380,7 +1383,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
 
   }
 
-#endif                                           /* CMPLOG_SOLVE_ARITHMETIC */
+  //#endif                                           /* CMPLOG_SOLVE_ARITHMETIC
 
   return 0;
 
@@ -1539,7 +1542,7 @@ static void try_to_add_to_dictN(afl_state_t *afl, u128 v, u8 size) {
   for (k = 0; k < size; ++k) {
 
   #else
-  u32 off = 16 - size;
+  u32    off = 16 - size;
   for (k = 16 - size; k < 16; ++k) {
 
   #endif
@@ -1857,9 +1860,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
 #ifndef CMPLOG_COMBINE
   (void)(cbuf);
 #endif
-#ifndef CMPLOG_SOLVE_TRANSFORM
-  (void)(changed_val);
-#endif
+  //#ifndef CMPLOG_SOLVE_TRANSFORM
+  //  (void)(changed_val);
+  //#endif
 
   u8  save[40];
   u32 saved_idx = idx, pre, from = 0, to = 0, i, j;
@@ -1939,16 +1942,16 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
 
   }
 
-#ifdef CMPLOG_SOLVE_TRANSFORM
+  //#ifdef CMPLOG_SOLVE_TRANSFORM
 
   if (*status == 1) return 0;
 
-  if (lvl & LVL3) {
+  if (afl->cmplog_enable_transform && (lvl & LVL3)) {
 
     u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, fromhex = 0;
-  #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
+#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
     u32 tob64 = 0, fromb64 = 0;
-  #endif
+#endif
     u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_up = 0;
     u32 to_0 = 0, to_x = 0, to_slash = 0, to_up = 0;
     u8  xor_val[32], arith_val[32], tmp[48];
@@ -2044,7 +2047,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
 
       }
 
-  #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
+#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
       if (i % 3 == 2 && i < 24) {
 
         if (is_base64(repl + ((i / 3) << 2))) tob64 += 3;
@@ -2057,7 +2060,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
 
       }
 
-  #endif
+#endif
 
       if ((o_pattern[i] ^ orig_buf[idx + i]) == xor_val[i] && xor_val[i]) {
 
@@ -2085,20 +2088,20 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
 
       }
 
-  #ifdef _DEBUG
+#ifdef _DEBUG
       fprintf(stderr,
               "RTN idx=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u "
               "tohex=%u fromhex=%u to_0=%u to_slash=%u to_x=%u "
               "from_0=%u from_slash=%u from_x=%u\n",
               idx, i, xor, arith, tolower, toupper, tohex, fromhex, to_0,
               to_slash, to_x, from_0, from_slash, from_x);
-    #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
+  #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
       fprintf(stderr, "RTN idx=%u loop=%u tob64=%u from64=%u\n", tob64,
               fromb64);
-    #endif
   #endif
+#endif
 
-  #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
+#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
       // input is base64 and converted to binary? convert repl to base64!
       if ((i % 4) == 3 && i < 24 && fromb64 > i) {
 
@@ -2121,7 +2124,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
 
       }
 
-  #endif
+#endif
 
       // input is converted to hex? convert repl to binary!
       if (i < 16 && tohex > i) {
@@ -2250,16 +2253,16 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
 
       }
 
-  #ifdef CMPLOG_COMBINE
+#ifdef CMPLOG_COMBINE
       if (*status == 1) { memcpy(cbuf + idx, &buf[idx], i + 1); }
-  #endif
+#endif
 
       if ((i >= 7 &&
            (i >= xor&&i >= arith &&i >= tolower &&i >= toupper &&i > tohex &&i >
                 (fromhex + from_0 + from_x + from_slash + 1)
-  #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
+#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
             && i > tob64 + 3 && i > fromb64 + 4
-  #endif
+#endif
             )) ||
           repl[i] != changed_val[i] || *status == 1) {
 
@@ -2273,7 +2276,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
 
   }
 
-#endif
+  //#endif
 
   return 0;
 
@@ -2606,9 +2609,9 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
 
     } else if ((lvl & LVL1)
 
-#ifdef CMPLOG_SOLVE_TRANSFORM
-               || (lvl & LVL3)
-#endif
+               //#ifdef CMPLOG_SOLVE_TRANSFORM
+               || ((lvl & LVL3) && afl->cmplog_enable_transform)
+               //#endif
     ) {
 
       if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, lvl, taint))) {
@@ -2689,7 +2692,7 @@ exit_its:
   #else
     u32 *v = (u32 *)afl->virgin_bits;
     u32 *s = (u32 *)virgin_save;
-    u32 i;
+    u32  i;
     for (i = 0; i < (afl->shm.map_size >> 2); i++) {
 
       v[i] &= s[i];
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index e3e9007d..e2db029d 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -103,7 +103,8 @@ static void usage(u8 *argv0, int more_help) {
       "                  quad -- see docs/power_schedules.md\n"
       "  -f file       - location read by the fuzzed program (default: stdin "
       "or @@)\n"
-      "  -t msec       - timeout for each run (auto-scaled, 50-... ms, default %u ms)\n"
+      "  -t msec       - timeout for each run (auto-scaled, 50-... ms, default "
+      "%u ms)\n"
       "                  add a '+' to skip over seeds running longer.\n"
       "  -m megs       - memory limit for child process (%u MB, 0 = no limit "
       "[default])\n"
@@ -123,10 +124,10 @@ static void usage(u8 *argv0, int more_help) {
       "  -c program    - enable CmpLog by specifying a binary compiled for "
       "it.\n"
       "                  if using QEMU, just use -c 0.\n"
-      "  -l cmplog_level - set the complexity/intensivity of CmpLog.\n"
-      "                  Values: 1 (basic), 2 (larger files) and 3 "
-      "(transform)\n\n"
-
+      "  -l cmplog_opts - CmpLog configuration values (e.g. \"2AT\"):\n"
+      "                  1=small files (default), 2=larger files, 3=all "
+      "files,\n"
+      "                  A=arithmetic solving, T=tranformational solving.\n\n"
       "Fuzzing behavior settings:\n"
       "  -Z            - sequential queue selection instead of weighted "
       "random\n"
@@ -813,13 +814,36 @@ int main(int argc, char **argv_orig, char **envp) {
 
       case 'l': {
 
-        if (optarg) { afl->cmplog_lvl = atoi(optarg); }
-        if (afl->cmplog_lvl < 1 || afl->cmplog_lvl > CMPLOG_LVL_MAX) {
+        if (!optarg) { FATAL("missing parameter for 'l'"); }
+        char *c = optarg;
+        while (*c) {
 
-          FATAL(
-              "Bad complog level value, accepted values are 1 (default), 2 and "
-              "%u.",
-              CMPLOG_LVL_MAX);
+          switch (*c) {
+
+            case '0':
+            case '1':
+              afl->cmplog_lvl = 1;
+              break;
+            case '2':
+              afl->cmplog_lvl = 2;
+              break;
+            case '3':
+              afl->cmplog_lvl = 3;
+              break;
+            case 'a':
+            case 'A':
+              afl->cmplog_enable_arith = 1;
+              break;
+            case 't':
+            case 'T':
+              afl->cmplog_enable_transform = 1;
+              break;
+            default:
+              FATAL("Unknown option value '%c' in -l %s", *c, optarg);
+
+          }
+
+          ++c;
 
         }