diff options
author | Andrea Fioraldi <andreafioraldi@gmail.com> | 2019-09-02 18:49:43 +0200 |
---|---|---|
committer | Andrea Fioraldi <andreafioraldi@gmail.com> | 2019-09-02 18:49:43 +0200 |
commit | b24639d0113e15933e749ea0f96abe3f25a134a0 (patch) | |
tree | 4272020625c80c0d6982d3787bebc573c0da01b8 /src/afl-fuzz.c | |
parent | 2ae4ca91b48407add0e940ee13bd8b385e319a7a (diff) | |
download | afl++-b24639d0113e15933e749ea0f96abe3f25a134a0.tar.gz |
run code formatter
Diffstat (limited to 'src/afl-fuzz.c')
-rw-r--r-- | src/afl-fuzz.c | 609 |
1 files changed, 361 insertions, 248 deletions
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 2242dd6b..685840c6 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -27,53 +27,62 @@ static void usage(u8* argv0) { #ifdef USE_PYTHON -#define PHYTON_SUPPORT \ - "Compiled with Python 2.7 module support, see docs/python_mutators.txt\n" +# define PHYTON_SUPPORT\ + "Compiled with Python 2.7 module support, see docs/python_mutators.txt\n" #else -#define PHYTON_SUPPORT "" +# define PHYTON_SUPPORT "" #endif - SAYF("\n%s [ options ] -- /path/to/fuzzed_app [ ... ]\n\n" - - "Required parameters:\n" - " -i dir - input directory with test cases\n" - " -o dir - output directory for fuzzer findings\n\n" - - "Execution control settings:\n" - " -p schedule - power schedules recompute a seed's performance score.\n" - " <explore (default), fast, coe, lin, quad, or exploit>\n" - " see docs/power_schedules.txt\n" - " -f file - location read by the fuzzed program (stdin)\n" - " -t msec - timeout for each run (auto-scaled, 50-%d ms)\n" - " -m megs - memory limit for child process (%d MB)\n" - " -Q - use binary-only instrumentation (QEMU mode)\n" - " -U - use Unicorn-based instrumentation (Unicorn mode)\n\n" - " -L minutes - use MOpt(imize) mode and set the limit time for entering the\n" - " pacemaker mode (minutes of no new paths, 0 = immediately).\n" - " a recommended value is 10-60. see docs/README.MOpt\n\n" - - "Fuzzing behavior settings:\n" - " -d - quick & dirty mode (skips deterministic steps)\n" - " -n - fuzz without instrumentation (dumb mode)\n" - " -x dir - optional fuzzer dictionary (see README)\n\n" - - "Testing settings:\n" - " -s seed - use a fixed seed for the RNG\n" - " -V seconds - fuzz for a maximum total time of seconds then terminate\n" - " -E execs - fuzz for a maximum number of total executions then terminate\n\n" - - "Other stuff:\n" - " -T text - text banner to show on the screen\n" - " -M / -S id - distributed mode (see parallel_fuzzing.txt)\n" - " -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap file\n" - " -C - crash exploration mode (the peruvian rabbit thing)\n" - " -e ext - File extension for the temporarily generated test case\n\n" - - PHYTON_SUPPORT - - "For additional tips, please consult %s/README\n\n", - - argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path); + SAYF( + "\n%s [ options ] -- /path/to/fuzzed_app [ ... ]\n\n" + + "Required parameters:\n" + " -i dir - input directory with test cases\n" + " -o dir - output directory for fuzzer findings\n\n" + + "Execution control settings:\n" + " -p schedule - power schedules recompute a seed's performance " + "score.\n" + " <explore (default), fast, coe, lin, quad, or " + "exploit>\n" + " see docs/power_schedules.txt\n" + " -f file - location read by the fuzzed program (stdin)\n" + " -t msec - timeout for each run (auto-scaled, 50-%d ms)\n" + " -m megs - memory limit for child process (%d MB)\n" + " -Q - use binary-only instrumentation (QEMU mode)\n" + " -U - use Unicorn-based instrumentation (Unicorn mode)\n\n" + " -L minutes - use MOpt(imize) mode and set the limit time for " + "entering the\n" + " pacemaker mode (minutes of no new paths, 0 = " + "immediately).\n" + " a recommended value is 10-60. see docs/README.MOpt\n\n" + + "Fuzzing behavior settings:\n" + " -d - quick & dirty mode (skips deterministic steps)\n" + " -n - fuzz without instrumentation (dumb mode)\n" + " -x dir - optional fuzzer dictionary (see README)\n\n" + + "Testing settings:\n" + " -s seed - use a fixed seed for the RNG\n" + " -V seconds - fuzz for a maximum total time of seconds then " + "terminate\n" + " -E execs - fuzz for a maximum number of total executions then " + "terminate\n\n" + + "Other stuff:\n" + " -T text - text banner to show on the screen\n" + " -M / -S id - distributed mode (see parallel_fuzzing.txt)\n" + " -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap " + "file\n" + " -C - crash exploration mode (the peruvian rabbit thing)\n" + " -e ext - File extension for the temporarily generated test " + "case\n\n" + + PHYTON_SUPPORT + + "For additional tips, please consult %s/README\n\n", + + argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path); exit(1); #undef PHYTON_SUPPORT @@ -82,65 +91,90 @@ static void usage(u8* argv0) { #ifndef AFL_LIB -static int stricmp(char const *a, char const *b) { +static int stricmp(char const* a, char const* b) { + for (;; ++a, ++b) { + int d; d = tolower(*a) - tolower(*b); - if (d != 0 || !*a) - return d; + if (d != 0 || !*a) return d; + } + } /* Main entry point */ int main(int argc, char** argv) { - s32 opt; - u64 prev_queued = 0; - u32 sync_interval_cnt = 0, seek_to; - u8 *extras_dir = 0; - u8 mem_limit_given = 0; - u8 exit_1 = !!getenv("AFL_BENCH_JUST_ONE"); + s32 opt; + u64 prev_queued = 0; + u32 sync_interval_cnt = 0, seek_to; + u8* extras_dir = 0; + u8 mem_limit_given = 0; + u8 exit_1 = !!getenv("AFL_BENCH_JUST_ONE"); char** use_argv; - s64 init_seed; + s64 init_seed; - struct timeval tv; + struct timeval tv; struct timezone tz; - SAYF(cCYA "afl-fuzz" VERSION cRST " based on afl by <lcamtuf@google.com> and a big online community\n"); + SAYF(cCYA + "afl-fuzz" VERSION cRST + " based on afl by <lcamtuf@google.com> and a big online community\n"); doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH; gettimeofday(&tv, &tz); init_seed = tv.tv_sec ^ tv.tv_usec ^ getpid(); - while ((opt = getopt(argc, argv, "+i:o:f:m:t:T:dnCB:S:M:x:QUe:p:s:V:E:L:")) > 0) + while ((opt = getopt(argc, argv, "+i:o:f:m:t:T:dnCB:S:M:x:QUe:p:s:V:E:L:")) > + 0) switch (opt) { case 's': { + init_seed = strtoul(optarg, 0L, 10); fixed_seed = 1; break; + } - case 'p': /* Power schedule */ + case 'p': /* Power schedule */ if (!stricmp(optarg, "fast")) { + schedule = FAST; + } else if (!stricmp(optarg, "coe")) { + schedule = COE; + } else if (!stricmp(optarg, "exploit")) { + schedule = EXPLOIT; + } else if (!stricmp(optarg, "lin")) { + schedule = LIN; + } else if (!stricmp(optarg, "quad")) { + schedule = QUAD; - } else if (!stricmp(optarg, "explore") || !stricmp(optarg, "default") || !stricmp(optarg, "normal") || !stricmp(optarg, "afl")) { + + } else if (!stricmp(optarg, "explore") || !stricmp(optarg, "default") || + + !stricmp(optarg, "normal") || !stricmp(optarg, "afl")) { + schedule = EXPLORE; + } else { + FATAL("Unknown -p power schedule"); + } + break; case 'e': @@ -151,7 +185,7 @@ int main(int argc, char** argv) { break; - case 'i': /* input dir */ + case 'i': /* input dir */ if (in_dir) FATAL("Multiple -i options not supported"); in_dir = optarg; @@ -160,115 +194,121 @@ int main(int argc, char** argv) { break; - case 'o': /* output dir */ + case 'o': /* output dir */ if (out_dir) FATAL("Multiple -o options not supported"); out_dir = optarg; break; - case 'M': { /* master sync ID */ + case 'M': { /* master sync ID */ - u8* c; + u8* c; - if (sync_id) FATAL("Multiple -S or -M options not supported"); - sync_id = ck_strdup(optarg); + if (sync_id) FATAL("Multiple -S or -M options not supported"); + sync_id = ck_strdup(optarg); - if ((c = strchr(sync_id, ':'))) { + if ((c = strchr(sync_id, ':'))) { - *c = 0; + *c = 0; - if (sscanf(c + 1, "%u/%u", &master_id, &master_max) != 2 || - !master_id || !master_max || master_id > master_max || - master_max > 1000000) FATAL("Bogus master ID passed to -M"); + if (sscanf(c + 1, "%u/%u", &master_id, &master_max) != 2 || + !master_id || !master_max || master_id > master_max || + master_max > 1000000) + FATAL("Bogus master ID passed to -M"); - } + } - force_deterministic = 1; + force_deterministic = 1; - } + } - break; + break; - case 'S': + case 'S': if (sync_id) FATAL("Multiple -S or -M options not supported"); sync_id = ck_strdup(optarg); break; - case 'f': /* target file */ + case 'f': /* target file */ if (out_file) FATAL("Multiple -f options not supported"); out_file = optarg; break; - case 'x': /* dictionary */ + case 'x': /* dictionary */ if (extras_dir) FATAL("Multiple -x options not supported"); extras_dir = optarg; break; - case 't': { /* timeout */ + case 't': { /* timeout */ - u8 suffix = 0; + u8 suffix = 0; - if (timeout_given) FATAL("Multiple -t options not supported"); + if (timeout_given) FATAL("Multiple -t options not supported"); - if (sscanf(optarg, "%u%c", &exec_tmout, &suffix) < 1 || - optarg[0] == '-') FATAL("Bad syntax used for -t"); + if (sscanf(optarg, "%u%c", &exec_tmout, &suffix) < 1 || + optarg[0] == '-') + FATAL("Bad syntax used for -t"); - if (exec_tmout < 5) FATAL("Dangerously low value of -t"); + if (exec_tmout < 5) FATAL("Dangerously low value of -t"); - if (suffix == '+') timeout_given = 2; else timeout_given = 1; + if (suffix == '+') + timeout_given = 2; + else + timeout_given = 1; - break; + break; } - case 'm': { /* mem limit */ + case 'm': { /* mem limit */ - u8 suffix = 'M'; + u8 suffix = 'M'; - if (mem_limit_given) FATAL("Multiple -m options not supported"); - mem_limit_given = 1; + if (mem_limit_given) FATAL("Multiple -m options not supported"); + mem_limit_given = 1; - if (!strcmp(optarg, "none")) { + if (!strcmp(optarg, "none")) { - mem_limit = 0; - break; + mem_limit = 0; + break; - } + } - if (sscanf(optarg, "%llu%c", &mem_limit, &suffix) < 1 || - optarg[0] == '-') FATAL("Bad syntax used for -m"); + if (sscanf(optarg, "%llu%c", &mem_limit, &suffix) < 1 || + optarg[0] == '-') + FATAL("Bad syntax used for -m"); - switch (suffix) { + switch (suffix) { - case 'T': mem_limit *= 1024 * 1024; break; - case 'G': mem_limit *= 1024; break; - case 'k': mem_limit /= 1024; break; - case 'M': break; + case 'T': mem_limit *= 1024 * 1024; break; + case 'G': mem_limit *= 1024; break; + case 'k': mem_limit /= 1024; break; + case 'M': break; - default: FATAL("Unsupported suffix or bad syntax for -m"); + default: FATAL("Unsupported suffix or bad syntax for -m"); - } + } - if (mem_limit < 5) FATAL("Dangerously low value of -m"); + if (mem_limit < 5) FATAL("Dangerously low value of -m"); - if (sizeof(rlim_t) == 4 && mem_limit > 2000) - FATAL("Value of -m out of range on 32-bit systems"); + if (sizeof(rlim_t) == 4 && mem_limit > 2000) + FATAL("Value of -m out of range on 32-bit systems"); - } + } - break; + break; - case 'd': /* skip deterministic */ + case 'd': /* skip deterministic */ if (skip_deterministic) FATAL("Multiple -d options not supported"); skip_deterministic = 1; use_splicing = 1; break; - case 'B': /* load bitmap */ + case 'B': /* load bitmap */ /* This is a secret undocumented option! It is useful if you find an interesting test case during a normal fuzzing process, and want @@ -287,26 +327,29 @@ int main(int argc, char** argv) { read_bitmap(in_bitmap); break; - case 'C': /* crash mode */ + case 'C': /* crash mode */ if (crash_mode) FATAL("Multiple -C options not supported"); crash_mode = FAULT_CRASH; break; - case 'n': /* dumb mode */ + case 'n': /* dumb mode */ if (dumb_mode) FATAL("Multiple -n options not supported"); - if (getenv("AFL_DUMB_FORKSRV")) dumb_mode = 2; else dumb_mode = 1; + if (getenv("AFL_DUMB_FORKSRV")) + dumb_mode = 2; + else + dumb_mode = 1; break; - case 'T': /* banner */ + case 'T': /* banner */ if (use_banner) FATAL("Multiple -T options not supported"); use_banner = optarg; break; - case 'Q': /* QEMU mode */ + case 'Q': /* QEMU mode */ if (qemu_mode) FATAL("Multiple -Q options not supported"); qemu_mode = 1; @@ -315,7 +358,7 @@ int main(int argc, char** argv) { break; - case 'U': /* Unicorn mode */ + case 'U': /* Unicorn mode */ if (unicorn_mode) FATAL("Multiple -U options not supported"); unicorn_mode = 1; @@ -325,115 +368,132 @@ int main(int argc, char** argv) { break; case 'V': { - most_time_key = 1; - if (sscanf(optarg, "%llu", &most_time) < 1 || optarg[0] == '-') - FATAL("Bad syntax used for -V"); - } - break; + + most_time_key = 1; + if (sscanf(optarg, "%llu", &most_time) < 1 || optarg[0] == '-') + FATAL("Bad syntax used for -V"); + + } break; case 'E': { - most_execs_key = 1; - if (sscanf(optarg, "%llu", &most_execs) < 1 || optarg[0] == '-') - FATAL("Bad syntax used for -E"); - } - break; - case 'L': { /* MOpt mode */ + most_execs_key = 1; + if (sscanf(optarg, "%llu", &most_execs) < 1 || optarg[0] == '-') + FATAL("Bad syntax used for -E"); - if (limit_time_sig) FATAL("Multiple -L options not supported"); - limit_time_sig = 1; - havoc_max_mult = HAVOC_MAX_MULT_MOPT; + } break; - if (sscanf(optarg, "%llu", &limit_time_puppet) < 1 || - optarg[0] == '-') FATAL("Bad syntax used for -L"); + case 'L': { /* MOpt mode */ - u64 limit_time_puppet2 = limit_time_puppet * 60 * 1000; + if (limit_time_sig) FATAL("Multiple -L options not supported"); + limit_time_sig = 1; + havoc_max_mult = HAVOC_MAX_MULT_MOPT; - if (limit_time_puppet2 < limit_time_puppet ) FATAL("limit_time overflow"); - limit_time_puppet = limit_time_puppet2; + if (sscanf(optarg, "%llu", &limit_time_puppet) < 1 || optarg[0] == '-') + FATAL("Bad syntax used for -L"); - SAYF("limit_time_puppet %llu\n",limit_time_puppet); - swarm_now = 0; + u64 limit_time_puppet2 = limit_time_puppet * 60 * 1000; - if (limit_time_puppet == 0 ) - key_puppet = 1; + if (limit_time_puppet2 < limit_time_puppet) + FATAL("limit_time overflow"); + limit_time_puppet = limit_time_puppet2; - int i; - int tmp_swarm = 0; + SAYF("limit_time_puppet %llu\n", limit_time_puppet); + swarm_now = 0; - if (g_now > g_max) g_now = 0; - w_now = (w_init - w_end)*(g_max - g_now) / (g_max)+w_end; + if (limit_time_puppet == 0) key_puppet = 1; - for (tmp_swarm = 0; tmp_swarm < swarm_num; ++tmp_swarm) { - double total_puppet_temp = 0.0; - swarm_fitness[tmp_swarm] = 0.0; + int i; + int tmp_swarm = 0; - for (i = 0; i < operator_num; ++i) { - stage_finds_puppet[tmp_swarm][i] = 0; - probability_now[tmp_swarm][i] = 0.0; - x_now[tmp_swarm][i] = ((double)(random() % 7000)*0.0001 + 0.1); - total_puppet_temp += x_now[tmp_swarm][i]; - v_now[tmp_swarm][i] = 0.1; - L_best[tmp_swarm][i] = 0.5; - G_best[i] = 0.5; - eff_best[tmp_swarm][i] = 0.0; + if (g_now > g_max) g_now = 0; + w_now = (w_init - w_end) * (g_max - g_now) / (g_max) + w_end; - } + for (tmp_swarm = 0; tmp_swarm < swarm_num; ++tmp_swarm) { - for (i = 0; i < operator_num; ++i) { - stage_cycles_puppet_v2[tmp_swarm][i] = stage_cycles_puppet[tmp_swarm][i]; - stage_finds_puppet_v2[tmp_swarm][i] = stage_finds_puppet[tmp_swarm][i]; - x_now[tmp_swarm][i] = x_now[tmp_swarm][i] / total_puppet_temp; - } + double total_puppet_temp = 0.0; + swarm_fitness[tmp_swarm] = 0.0; - double x_temp = 0.0; + for (i = 0; i < operator_num; ++i) { - for (i = 0; i < operator_num; ++i) { - probability_now[tmp_swarm][i] = 0.0; - v_now[tmp_swarm][i] = w_now * v_now[tmp_swarm][i] + RAND_C * (L_best[tmp_swarm][i] - x_now[tmp_swarm][i]) + RAND_C * (G_best[i] - x_now[tmp_swarm][i]); + stage_finds_puppet[tmp_swarm][i] = 0; + probability_now[tmp_swarm][i] = 0.0; + x_now[tmp_swarm][i] = ((double)(random() % 7000) * 0.0001 + 0.1); + total_puppet_temp += x_now[tmp_swarm][i]; + v_now[tmp_swarm][i] = 0.1; + L_best[tmp_swarm][i] = 0.5; + G_best[i] = 0.5; + eff_best[tmp_swarm][i] = 0.0; - x_now[tmp_swarm][i] += v_now[tmp_swarm][i]; + } + + for (i = 0; i < operator_num; ++i) { + + stage_cycles_puppet_v2[tmp_swarm][i] = + stage_cycles_puppet[tmp_swarm][i]; + stage_finds_puppet_v2[tmp_swarm][i] = + stage_finds_puppet[tmp_swarm][i]; + x_now[tmp_swarm][i] = x_now[tmp_swarm][i] / total_puppet_temp; + + } + + double x_temp = 0.0; + + for (i = 0; i < operator_num; ++i) { - if (x_now[tmp_swarm][i] > v_max) - x_now[tmp_swarm][i] = v_max; - else if (x_now[tmp_swarm][i] < v_min) - x_now[tmp_swarm][i] = v_min; + probability_now[tmp_swarm][i] = 0.0; + v_now[tmp_swarm][i] = + w_now * v_now[tmp_swarm][i] + + RAND_C * (L_best[tmp_swarm][i] - x_now[tmp_swarm][i]) + + RAND_C * (G_best[i] - x_now[tmp_swarm][i]); - x_temp += x_now[tmp_swarm][i]; - } + x_now[tmp_swarm][i] += v_now[tmp_swarm][i]; - for (i = 0; i < operator_num; ++i) { - x_now[tmp_swarm][i] = x_now[tmp_swarm][i] / x_temp; - if (likely(i != 0)) - probability_now[tmp_swarm][i] = probability_now[tmp_swarm][i - 1] + x_now[tmp_swarm][i]; - else - probability_now[tmp_swarm][i] = x_now[tmp_swarm][i]; - } - if (probability_now[tmp_swarm][operator_num - 1] < 0.99 || probability_now[tmp_swarm][operator_num - 1] > 1.01) - FATAL("ERROR probability"); - } + if (x_now[tmp_swarm][i] > v_max) + x_now[tmp_swarm][i] = v_max; + else if (x_now[tmp_swarm][i] < v_min) + x_now[tmp_swarm][i] = v_min; + + x_temp += x_now[tmp_swarm][i]; + + } + + for (i = 0; i < operator_num; ++i) { + + x_now[tmp_swarm][i] = x_now[tmp_swarm][i] / x_temp; + if (likely(i != 0)) + probability_now[tmp_swarm][i] = + probability_now[tmp_swarm][i - 1] + x_now[tmp_swarm][i]; + else + probability_now[tmp_swarm][i] = x_now[tmp_swarm][i]; + + } - for (i = 0; i < operator_num; ++i) { - core_operator_finds_puppet[i] = 0; - core_operator_finds_puppet_v2[i] = 0; - core_operator_cycles_puppet[i] = 0; - core_operator_cycles_puppet_v2[i] = 0; - core_operator_cycles_puppet_v3[i] = 0; - } + if (probability_now[tmp_swarm][operator_num - 1] < 0.99 || + probability_now[tmp_swarm][operator_num - 1] > 1.01) + FATAL("ERROR probability"); + + } + + for (i = 0; i < operator_num; ++i) { + + core_operator_finds_puppet[i] = 0; + core_operator_finds_puppet_v2[i] = 0; + core_operator_cycles_puppet[i] = 0; + core_operator_cycles_puppet_v2[i] = 0; + core_operator_cycles_puppet_v3[i] = 0; } - break; - default: + } break; - usage(argv[0]); + default: usage(argv[0]); } if (optind == argc || !in_dir || !out_dir) usage(argv[0]); - if (fixed_seed) - OKF("Running with fixed seed: %u", (u32)init_seed); + if (fixed_seed) OKF("Running with fixed seed: %u", (u32)init_seed); srandom((u32)init_seed); setup_signal_handlers(); check_asan_opts(); @@ -446,28 +506,39 @@ int main(int argc, char** argv) { FATAL("Input and output directories can't be the same"); if ((tmp_dir = getenv("AFL_TMPDIR")) != NULL) { + char tmpfile[strlen(tmp_dir + 16)]; sprintf(tmpfile, "%s/%s", tmp_dir, ".cur_input"); - if (access(tmpfile, F_OK) != -1) // there is still a race condition here, but well ... - FATAL("TMP_DIR already has an existing temporary input file: %s", tmpfile); + if (access(tmpfile, F_OK) != + -1) // there is still a race condition here, but well ... + FATAL("TMP_DIR already has an existing temporary input file: %s", + tmpfile); + } else + tmp_dir = out_dir; if (dumb_mode) { if (crash_mode) FATAL("-C and -n are mutually exclusive"); - if (qemu_mode) FATAL("-Q and -n are mutually exclusive"); + if (qemu_mode) FATAL("-Q and -n are mutually exclusive"); if (unicorn_mode) FATAL("-U and -n are mutually exclusive"); } - + if (getenv("AFL_NO_UI") && getenv("AFL_FORCE_UI")) FATAL("AFL_NO_UI and AFL_FORCE_UI are mutually exclusive"); - - if (strchr(argv[optind], '/') == NULL) WARNF(cLRD "Target binary called without a prefixed path, make sure you are fuzzing the right binary: " cRST "%s", argv[optind]); - OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" Eissfeldt and Andrea Fioraldi"); - OKF("afl++ is open source, get it at https://github.com/vanhauser-thc/AFLplusplus"); + if (strchr(argv[optind], '/') == NULL) + WARNF(cLRD + "Target binary called without a prefixed path, make sure you are " + "fuzzing the right binary: " cRST "%s", + argv[optind]); + + OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" " + "Eissfeldt and Andrea Fioraldi"); + OKF("afl++ is open source, get it at " + "https://github.com/vanhauser-thc/AFLplusplus"); OKF("Power schedules from github.com/mboehme/aflfast"); OKF("Python Mutator and llvm_mode whitelisting from github.com/choller/afl"); OKF("afl-tmin fork server patch from github.com/nccgroup/TriforceAFL"); @@ -475,32 +546,42 @@ int main(int argc, char** argv) { ACTF("Getting to work..."); switch (schedule) { - case FAST: OKF ("Using exponential power schedule (FAST)"); break; - case COE: OKF ("Using cut-off exponential power schedule (COE)"); break; - case EXPLOIT: OKF ("Using exploitation-based constant power schedule (EXPLOIT)"); break; - case LIN: OKF ("Using linear power schedule (LIN)"); break; - case QUAD: OKF ("Using quadratic power schedule (QUAD)"); break; - case EXPLORE: OKF ("Using exploration-based constant power schedule (EXPLORE)"); break; - default : FATAL ("Unknown power schedule"); break; + + case FAST: OKF("Using exponential power schedule (FAST)"); break; + case COE: OKF("Using cut-off exponential power schedule (COE)"); break; + case EXPLOIT: + OKF("Using exploitation-based constant power schedule (EXPLOIT)"); + break; + case LIN: OKF("Using linear power schedule (LIN)"); break; + case QUAD: OKF("Using quadratic power schedule (QUAD)"); break; + case EXPLORE: + OKF("Using exploration-based constant power schedule (EXPLORE)"); + break; + default: FATAL("Unknown power schedule"); break; + } - if (getenv("AFL_NO_FORKSRV")) no_forkserver = 1; - if (getenv("AFL_NO_CPU_RED")) no_cpu_meter_red = 1; - if (getenv("AFL_NO_ARITH")) no_arith = 1; - if (getenv("AFL_SHUFFLE_QUEUE")) shuffle_queue = 1; - if (getenv("AFL_FAST_CAL")) fast_cal = 1; + if (getenv("AFL_NO_FORKSRV")) no_forkserver = 1; + if (getenv("AFL_NO_CPU_RED")) no_cpu_meter_red = 1; + if (getenv("AFL_NO_ARITH")) no_arith = 1; + if (getenv("AFL_SHUFFLE_QUEUE")) shuffle_queue = 1; + if (getenv("AFL_FAST_CAL")) fast_cal = 1; if (getenv("AFL_HANG_TMOUT")) { + hang_tmout = atoi(getenv("AFL_HANG_TMOUT")); if (!hang_tmout) FATAL("Invalid value of AFL_HANG_TMOUT"); + } if (dumb_mode == 2 && no_forkserver) FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive"); if (getenv("AFL_PRELOAD")) { + setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1); setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1); + } if (getenv("AFL_LD_PRELOAD")) @@ -511,31 +592,33 @@ int main(int argc, char** argv) { fix_up_banner(argv[optind]); check_if_tty(); - if (getenv("AFL_FORCE_UI")) - not_on_tty = 0; + if (getenv("AFL_FORCE_UI")) not_on_tty = 0; if (getenv("AFL_CAL_FAST")) { + /* Use less calibration cycles, for slow applications */ cal_cycles = 3; cal_cycles_long = 5; + } - if (getenv("AFL_DEBUG")) - debug = 1; + if (getenv("AFL_DEBUG")) debug = 1; if (getenv("AFL_PYTHON_ONLY")) { + /* This ensures we don't proceed to havoc/splice */ python_only = 1; /* Ensure we also skip all deterministic steps */ skip_deterministic = 1; + } get_core_count(); -#ifdef HAVE_AFFINITY +# ifdef HAVE_AFFINITY bind_to_free_cpu(); -#endif /* HAVE_AFFINITY */ +# endif /* HAVE_AFFINITY */ check_crash_handling(); check_cpu_governor(); @@ -552,13 +635,12 @@ int main(int argc, char** argv) { setup_dirs_fds(); -#ifdef USE_PYTHON - if (init_py()) - FATAL("Failed to initialize Python module"); -#else +# ifdef USE_PYTHON + if (init_py()) FATAL("Failed to initialize Python module"); +# else if (getenv("AFL_PYTHON_MODULE")) - FATAL("Your AFL binary was built without Python support"); -#endif + FATAL("Your AFL binary was built without Python support"); +# endif setup_cmdline_file(argv + optind); @@ -574,24 +656,33 @@ int main(int argc, char** argv) { /* If we don't have a file name chosen yet, use a safe default. */ if (!out_file) { + u32 i = optind + 1; while (argv[i]) { u8* aa_loc = strstr(argv[i], "@@"); if (aa_loc && !out_file) { + if (file_extension) { + out_file = alloc_printf("%s/.cur_input.%s", out_dir, file_extension); + } else { + out_file = alloc_printf("%s/.cur_input", out_dir); + } + detect_file_args(argv + optind + 1, out_file); - break; + break; + } ++i; } + } if (!out_file) setup_stdio_file(); @@ -621,9 +712,11 @@ int main(int argc, char** argv) { /* Woop woop woop */ if (!not_on_tty) { + sleep(4); start_time += 4000; if (stop_soon) goto stop_fuzzing; + } // real start time, we reset, so this works correctly with -V @@ -638,21 +731,25 @@ int main(int argc, char** argv) { if (!queue_cur) { ++queue_cycle; - current_entry = 0; + current_entry = 0; cur_skipped_paths = 0; - queue_cur = queue; + queue_cur = queue; while (seek_to) { + ++current_entry; --seek_to; queue_cur = queue_cur->next; + } show_stats(); if (not_on_tty) { + ACTF("Entering queue cycle %llu.", queue_cycle); fflush(stdout); + } /* If we had a full queue cycle with no new finds, try @@ -660,9 +757,14 @@ int main(int argc, char** argv) { if (queued_paths == prev_queued) { - if (use_splicing) ++cycles_wo_finds; else use_splicing = 1; + if (use_splicing) + ++cycles_wo_finds; + else + use_splicing = 1; - } else cycles_wo_finds = 0; + } else + + cycles_wo_finds = 0; prev_queued = queued_paths; @@ -674,9 +776,8 @@ int main(int argc, char** argv) { skipped_fuzz = fuzz_one(use_argv); if (!stop_soon && sync_id && !skipped_fuzz) { - - if (!(sync_interval_cnt++ % SYNC_INTERVAL)) - sync_fuzzers(use_argv); + + if (!(sync_interval_cnt++ % SYNC_INTERVAL)) sync_fuzzers(use_argv); } @@ -688,18 +789,28 @@ int main(int argc, char** argv) { ++current_entry; if (most_time_key == 1) { + u64 cur_ms_lv = get_cur_time(); - if (most_time * 1000 < cur_ms_lv - start_time) { + if (most_time * 1000 < cur_ms_lv - start_time) { + most_time_key = 2; break; + } + } + if (most_execs_key == 1) { + if (most_execs <= total_execs) { + most_execs_key = 2; break; + } + } + } if (queue_cur) show_stats(); @@ -708,19 +819,20 @@ int main(int argc, char** argv) { * ATTENTION - the following 10 lines were copied from a PR to Google's afl * repository - and slightly fixed. * These lines have nothing to do with the purpose of original PR though. - * Looks like when an exit condition was completed (AFL_BENCH_JUST_ONE, + * Looks like when an exit condition was completed (AFL_BENCH_JUST_ONE, * AFL_EXIT_WHEN_DONE or AFL_BENCH_UNTIL_CRASH) the child and forkserver * where not killed? */ - /* if we stopped programmatically, we kill the forkserver and the current runner. - if we stopped manually, this is done by the signal handler */ - if (stop_soon == 2){ + /* if we stopped programmatically, we kill the forkserver and the current + runner. if we stopped manually, this is done by the signal handler */ + if (stop_soon == 2) { + if (child_pid > 0) kill(child_pid, SIGKILL); if (forksrv_pid > 0) kill(forksrv_pid, SIGKILL); - /* Now that we've killed the forkserver, we wait for it to be able to get rusage stats. */ - if (waitpid(forksrv_pid, NULL, 0) <= 0) { - WARNF("error waitpid\n"); - } + /* Now that we've killed the forkserver, we wait for it to be able to get + * rusage stats. */ + if (waitpid(forksrv_pid, NULL, 0) <= 0) { WARNF("error waitpid\n"); } + } write_bitmap(); @@ -732,8 +844,7 @@ stop_fuzzing: SAYF(CURSOR_SHOW cLRD "\n\n+++ Testing aborted %s +++\n" cRST, stop_soon == 2 ? "programmatically" : "by user"); - if (most_time_key == 2) - SAYF(cYEL "[!] " cRST "Time limit was reached\n"); + if (most_time_key == 2) SAYF(cYEL "[!] " cRST "Time limit was reached\n"); if (most_execs_key == 2) SAYF(cYEL "[!] " cRST "Execution limit was reached\n"); @@ -742,8 +853,9 @@ stop_fuzzing: if (queue_cycle == 1 && get_cur_time() - start_time > 30 * 60 * 1000) { SAYF("\n" cYEL "[!] " cRST - "Stopped during the first cycle, results may be incomplete.\n" - " (For info on resuming, see %s/README)\n", doc_path); + "Stopped during the first cycle, results may be incomplete.\n" + " (For info on resuming, see %s/README)\n", + doc_path); } @@ -755,9 +867,9 @@ stop_fuzzing: alloc_report(); -#ifdef USE_PYTHON +# ifdef USE_PYTHON finalize_py(); -#endif +# endif OKF("We're done here. Have a nice day!\n"); @@ -766,3 +878,4 @@ stop_fuzzing: } #endif /* !AFL_LIB */ + |