aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-03-20 08:54:09 +0100
committervan Hauser <vh@thc.org>2020-03-20 08:54:09 +0100
commit29853549c3c12b4ebd4c2af4f0d728a13f30a727 (patch)
treed35e7d17a8156e0a206c19c8052c3db2a068b76e /src
parentd0b5cd64c3edd790c1405f0a2105033cf52f7c14 (diff)
downloadafl++-29853549c3c12b4ebd4c2af4f0d728a13f30a727.tar.gz
add RARE schedule. also fixes doc_path
Diffstat (limited to 'src')
-rw-r--r--src/afl-fuzz-globals.c5
-rw-r--r--src/afl-fuzz-queue.c49
-rw-r--r--src/afl-fuzz-stats.c25
-rw-r--r--src/afl-fuzz.c13
4 files changed, 63 insertions, 29 deletions
diff --git a/src/afl-fuzz-globals.c b/src/afl-fuzz-globals.c
index dbd8c835..88633a1b 100644
--- a/src/afl-fuzz-globals.c
+++ b/src/afl-fuzz-globals.c
@@ -30,8 +30,9 @@ s8 interesting_8[] = {INTERESTING_8};
s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
-char *power_names[POWER_SCHEDULES_NUM] = {"explore", "fast", "coe", "lin",
- "quad", "exploit", "mmopt"};
+char *power_names[POWER_SCHEDULES_NUM] = {
+
+ "explore", "fast", "coe", "lin", "quad", "exploit", "mmopt", "rare"};
u8 *doc_path = NULL; /* gath to documentation dir */
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index 8a995727..f49e1f1e 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -185,12 +185,16 @@ void destroy_queue(afl_state_t *afl) {
void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
u32 i;
- u64 fav_factor = q->exec_us * q->len;
+ u64 fav_factor;
u64 fuzz_p2 = next_p2(q->n_fuzz);
+ if (afl->schedule == MMOPT || afl->schedule == RARE)
+ fav_factor = q->len << 2;
+ else
+ fav_factor = q->exec_us * q->len;
+
/* For every byte set in afl->fsrv.trace_bits[], see if there is a previous
winner, and how it compares to us. */
-
for (i = 0; i < MAP_SIZE; ++i)
if (afl->fsrv.trace_bits[i]) {
@@ -198,20 +202,20 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
if (afl->top_rated[i]) {
/* Faster-executing or smaller test cases are favored. */
+ u64 top_rated_fav_factor;
u64 top_rated_fuzz_p2 = next_p2(afl->top_rated[i]->n_fuzz);
- u64 top_rated_fav_factor =
- afl->top_rated[i]->exec_us * afl->top_rated[i]->len;
- if (fuzz_p2 > top_rated_fuzz_p2) {
+ if (afl->schedule == MMOPT || afl->schedule == RARE)
+ top_rated_fav_factor = afl->top_rated[i]->len << 2;
+ else
+ top_rated_fav_factor =
+ afl->top_rated[i]->exec_us * afl->top_rated[i]->len;
+ if (fuzz_p2 > top_rated_fuzz_p2)
continue;
-
- } else if (fuzz_p2 == top_rated_fuzz_p2) {
-
+ else if (fuzz_p2 == top_rated_fuzz_p2)
if (fav_factor > top_rated_fav_factor) continue;
- }
-
if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len)
continue;
@@ -328,7 +332,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
// Longer execution time means longer work on the input, the deeper in
// coverage, the better the fuzzing, right? -mh
- if (afl->schedule != MMOPT) {
+ if (afl->schedule != MMOPT && afl->schedule != RARE) {
if (q->exec_us * 0.1 > avg_exec_us)
perf_score = 10;
@@ -448,8 +452,29 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
break;
case MMOPT:
+ /* -- this was a more complex setup, which is good, but competed with
+ -- rare. the simpler algo however is good when rare is not.
+ // the newer the entry, the higher the pref_score
+ perf_score *= (1 + (double)((double)q->depth /
+ (double)afl->queued_paths));
+ // with special focus on the last 8 entries
+ if (afl->max_depth - q->depth < 8) perf_score *= (1 + ((8 -
+ (afl->max_depth - q->depth)) / 5));
+ */
+ // put focus on the last 5 entries
+ if (afl->max_depth - q->depth < 5) perf_score *= 2;
+
+ break;
+
+ case RARE:
- if (afl->max_depth - q->depth < 5) perf_score *= 1.5;
+ // increase the score for every bitmap byte for which this entry
+ // is the top contender
+ perf_score += (q->tc_ref * 10);
+ // the more often fuzz result paths are equal to this queue entry,
+ // reduce its value
+ perf_score *=
+ (1 - (double)((double)q->n_fuzz / (double)afl->total_execs));
break;
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index dcd4f542..6ea6a8e9 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -32,9 +32,10 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
struct rusage rus;
- u8 * fn = alloc_printf("%s/fuzzer_stats", afl->out_dir);
- s32 fd;
- FILE *f;
+ unsigned long long int cur_time = get_cur_time();
+ u8 * fn = alloc_printf("%s/fuzzer_stats", afl->out_dir);
+ s32 fd;
+ FILE * f;
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
@@ -69,6 +70,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
f,
"start_time : %llu\n"
"last_update : %llu\n"
+ "run_time : %llu\n"
"fuzzer_pid : %d\n"
"cycles_done : %llu\n"
"execs_done : %llu\n"
@@ -99,7 +101,8 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
"\n"
"target_mode : %s%s%s%s%s%s%s%s\n"
"command_line : %s\n",
- afl->start_time / 1000, get_cur_time() / 1000, getpid(),
+ afl->start_time / 1000, cur_time / 1000,
+ (cur_time - afl->start_time) / 1000, getpid(),
afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->total_execs,
/*eps,*/ afl->total_execs /
((double)(get_cur_time() - afl->start_time) / 1000),
@@ -357,9 +360,9 @@ void show_stats(afl_state_t *afl) {
/* Lord, forgive me this. */
- SAYF(SET_G1 bSTG bLT bH bSTOP cCYA
+ SAYF(SET_G1 bSTG bLT bH bSTOP cCYA
" process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA
- " overall results " bSTG bH2 bH2 bRT "\n");
+ " overall results " bSTG bH2 bH2 bRT "\n");
if (afl->dumb_mode) {
@@ -441,9 +444,9 @@ void show_stats(afl_state_t *afl) {
" uniq hangs : " cRST "%-6s" bSTG bV "\n",
time_tmp, tmp);
- SAYF(bVR bH bSTOP cCYA
+ SAYF(bVR bH bSTOP cCYA
" cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA
- " map coverage " bSTG bH bHT bH20 bH2 bVL "\n");
+ " map coverage " bSTG bH bHT bH20 bH2 bVL "\n");
/* This gets funny because we want to print several variable-length variables
together, but then cram them into a fixed-width field - so we need to
@@ -472,9 +475,9 @@ void show_stats(afl_state_t *afl) {
SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp);
- SAYF(bVR bH bSTOP cCYA
+ SAYF(bVR bH bSTOP cCYA
" stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA
- " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n");
+ " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n");
sprintf(tmp, "%s (%0.02f%%)", DI(IB(0), afl->queued_favored),
((double)afl->queued_favored) * 100 / afl->queued_paths);
@@ -546,7 +549,7 @@ void show_stats(afl_state_t *afl) {
/* Aaaalmost there... hold on! */
- SAYF(bVR bH cCYA bSTOP
+ SAYF(bVR bH cCYA bSTOP
" fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA
" path geometry " bSTG bH5 bH2 bVL "\n");
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 10fee76c..15caa65f 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -96,8 +96,8 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
"Execution control settings:\n"
" -p schedule - power schedules recompute a seed's performance "
"score.\n"
- " <explore (default), fast, coe, lin, quad, exploit, "
- "mmopt>\n"
+ " <explore(default), fast, coe, lin, quad, exploit, "
+ "mmopt, rare>\n"
" see docs/power_schedules.md\n"
" -f file - location read by the fuzzed program (stdin)\n"
" -t msec - timeout for each run (auto-scaled, 50-%d ms)\n"
@@ -250,7 +250,7 @@ int main(int argc, char **argv_orig, char **envp) {
SAYF(cCYA "afl-fuzz" VERSION cRST
" based on afl by Michal Zalewski and a big online community\n");
- doc_path = access(DOC_PATH, F_OK) ? (u8 *)"docs" : doc_path;
+ doc_path = access(DOC_PATH, F_OK) != 0 ? (u8 *)"docs" : (u8 *)DOC_PATH;
gettimeofday(&tv, &tz);
afl->init_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
@@ -304,6 +304,10 @@ int main(int argc, char **argv_orig, char **envp) {
afl->schedule = MMOPT;
+ } else if (!stricmp(optarg, "rare")) {
+
+ afl->schedule = RARE;
+
} else if (!stricmp(optarg, "explore") || !stricmp(optarg, "default") ||
!stricmp(optarg, "normal") || !stricmp(optarg, "afl")) {
@@ -760,8 +764,9 @@ int main(int argc, char **argv_orig, char **envp) {
case LIN: OKF("Using linear power schedule (LIN)"); break;
case QUAD: OKF("Using quadratic power schedule (QUAD)"); break;
case MMOPT: OKF("Using modified MOpt power schedule (MMOPT)"); break;
+ case RARE: OKF("Using rare edge focus power schedule (RARE)"); break;
case EXPLORE:
- OKF("Using exploration-based constant power schedule (EXPLORE)");
+ OKF("Using exploration-based constant power schedule (EXPLORE, default)");
break;
default: FATAL("Unknown power schedule"); break;