diff options
author | vanhauser-thc <vh@thc.org> | 2021-02-21 17:53:09 +0100 |
---|---|---|
committer | vanhauser-thc <vh@thc.org> | 2021-02-21 17:53:09 +0100 |
commit | 974aab6cf6aa4ae34ee73bdceed1bd44a212fc5e (patch) | |
tree | d671f2951cbe48ae48fc5b8643a29108ed88981f | |
parent | b957218a3aad95af02a4da8207c7dabb893d4dc8 (diff) | |
download | afl++-974aab6cf6aa4ae34ee73bdceed1bd44a212fc5e.tar.gz |
cmplog config.h -> -l option
-rw-r--r-- | include/afl-fuzz.h | 1 | ||||
-rw-r--r-- | include/config.h | 9 | ||||
-rw-r--r-- | src/afl-common.c | 8 | ||||
-rw-r--r-- | src/afl-fuzz-redqueen.c | 83 | ||||
-rw-r--r-- | src/afl-fuzz.c | 46 |
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; } |