aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKhaled Yakdan <yakdan@code-intelligence.de>2019-05-15 10:03:19 +0200
committerKhaled Yakdan <yakdan@code-intelligence.de>2019-07-01 17:53:41 +0200
commitfedbd543250fae64a988c283ad67d2362db6b8c8 (patch)
tree3271bbc8bbaf90ffe3c04d122434a73209c2c920
parentc0347c80b2191ec00caedd8cefed362804bd7093 (diff)
downloadafl++-fedbd543250fae64a988c283ad67d2362db6b8c8.tar.gz
Define AFLCustomMutator hook that can be implemented by implemented by external libraries and provided to AFL
-rw-r--r--afl-fuzz.c84
1 files changed, 58 insertions, 26 deletions
diff --git a/afl-fuzz.c b/afl-fuzz.c
index 6db99acf..8af110a5 100644
--- a/afl-fuzz.c
+++ b/afl-fuzz.c
@@ -304,6 +304,9 @@ static u32 a_extras_cnt; /* Total number of tokens available */
static u8* (*post_handler)(u8* buf, u32* len);
+/* A hook for the custom mutator function */
+extern size_t AFLCustomMutator(uint8_t *data, size_t size, size_t max_size, unsigned int seed) __attribute__((weak));
+
/* Interesting values, as per config.h */
static s8 interesting_8[] = { INTERESTING_8 };
@@ -330,7 +333,8 @@ enum {
/* 14 */ STAGE_EXTRAS_AO,
/* 15 */ STAGE_HAVOC,
/* 16 */ STAGE_SPLICE,
- /* 17 */ STAGE_PYTHON
+ /* 17 */ STAGE_PYTHON,
+ /* 18 */ STAGE_CUSTOM_MUTATOR
};
/* Stage value types */
@@ -1480,7 +1484,7 @@ static u64 next_p2(u64 val) {
while (val > ret) ret <<= 1;
return ret;
-}
+}
/* When we bump into a new path, we call this to see if the path appears
@@ -4127,7 +4131,7 @@ static void maybe_delete_out_dir(void) {
fn = alloc_printf("%s/plot_data", out_dir);
if (unlink(fn) && errno != ENOENT) goto dir_cleanup_failed;
ck_free(fn);
-
+
fn = alloc_printf("%s/cmdline", out_dir);
if (unlink(fn) && errno != ENOENT) goto dir_cleanup_failed;
ck_free(fn);
@@ -4185,7 +4189,7 @@ static void show_stats(void) {
/* Calculate smoothed exec speed stats. */
if (!last_execs) {
-
+
avg_exec = ((double)total_execs) * 1000 / (cur_ms - start_time);
} else {
@@ -4217,7 +4221,7 @@ static void show_stats(void) {
t_bytes = count_non_255_bytes(virgin_bits);
t_byte_ratio = ((double)t_bytes * 100) / MAP_SIZE;
- if (t_bytes)
+ if (t_bytes)
stab_ratio = 100 - ((double)var_byte_count) * 100 / t_bytes;
else
stab_ratio = 100;
@@ -4239,7 +4243,7 @@ static void show_stats(void) {
last_plot_ms = cur_ms;
maybe_update_plot_file(t_byte_ratio, avg_exec);
-
+
}
/* Honor AFL_EXIT_WHEN_DONE and AFL_BENCH_UNTIL_CRASH. */
@@ -4286,7 +4290,7 @@ static void show_stats(void) {
memset(tmp, ' ', banner_pad);
sprintf(tmp + banner_pad, "%s " cLCY VERSION cLGN
- " (%s) " cPIN "[%s]", crash_mode ? cPIN "peruvian were-rabbit" :
+ " (%s) " cPIN "[%s]", crash_mode ? cPIN "peruvian were-rabbit" :
cYEL "american fuzzy lop", use_banner, power_name);
SAYF("\n%s\n", tmp);
@@ -4348,7 +4352,7 @@ static void show_stats(void) {
if (dumb_mode)
- SAYF(bV bSTOP " last new path : " cPIN "n/a" cRST
+ SAYF(bV bSTOP " last new path : " cPIN "n/a" cRST
" (non-instrumented mode) ");
else
@@ -4375,7 +4379,7 @@ static void show_stats(void) {
sprintf(tmp, "%s%s", DI(unique_hangs),
(unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
- SAYF(bV bSTOP " last uniq hang : " cRST "%-33s " bSTG bV bSTOP
+ SAYF(bV bSTOP " last uniq hang : " cRST "%-33s " bSTG bV bSTOP
" uniq hangs : " cRST "%-6s" bSTG bV "\n",
DTD(cur_ms, last_hang_time), tmp);
@@ -4392,10 +4396,10 @@ static void show_stats(void) {
SAYF(bV bSTOP " now processing : " cRST "%-16s " bSTG bV bSTOP, tmp);
- sprintf(tmp, "%0.02f%% / %0.02f%%", ((double)queue_cur->bitmap_size) *
+ sprintf(tmp, "%0.02f%% / %0.02f%%", ((double)queue_cur->bitmap_size) *
100 / MAP_SIZE, t_byte_ratio);
- SAYF(" map density : %s%-21s" bSTG bV "\n", t_byte_ratio > 70 ? cLRD :
+ SAYF(" map density : %s%-21s" bSTG bV "\n", t_byte_ratio > 70 ? cLRD :
((t_bytes < 200 && !dumb_mode) ? cPIN : cRST), tmp);
sprintf(tmp, "%s (%0.02f%%)", DI(cur_skipped_paths),
@@ -4416,7 +4420,7 @@ static void show_stats(void) {
/* Yeah... it's still going on... halp? */
- SAYF(bV bSTOP " now trying : " cRST "%-20s " bSTG bV bSTOP
+ SAYF(bV bSTOP " now trying : " cRST "%-20s " bSTG bV bSTOP
" favored paths : " cRST "%-22s" bSTG bV "\n", stage_name, tmp);
if (!stage_max) {
@@ -4543,7 +4547,7 @@ static void show_stats(void) {
if (t_bytes) sprintf(tmp, "%0.02f%%", stab_ratio);
else strcpy(tmp, "n/a");
- SAYF(" stability : %s%-10s" bSTG bV "\n", (stab_ratio < 85 && var_byte_count > 40)
+ SAYF(" stability : %s%-10s" bSTG bV "\n", (stab_ratio < 85 && var_byte_count > 40)
? cLRD : ((queued_variable && (!persistent_mode || var_byte_count > 20))
? cMGN : cRST), tmp);
@@ -4577,9 +4581,14 @@ static void show_stats(void) {
strcat(tmp, tmp2);
}
-
- SAYF(bV bSTOP " trim : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n"
+ if (AFLCustomMutator) {
+ sprintf(tmp, "%s/%s", DI(stage_finds[STAGE_CUSTOM_MUTATOR]), DI(stage_cycles[STAGE_CUSTOM_MUTATOR]));
+ SAYF(bV bSTOP " custom mut. : " cRST "%-37s " bSTG bVR bH20 bH2 bH2 bRB "\n"
+ bLB bH30 bH20 bH2 bH bRB bSTOP cRST RESET_G1, tmp);
+ } else {
+ SAYF(bV bSTOP " trim : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n"
bLB bH30 bH20 bH2 bRB bSTOP cRST RESET_G1, tmp);
+ }
/* Provide some CPU utilization stats. */
@@ -5140,7 +5149,7 @@ static u32 calculate_score(struct queue_entry* q) {
switch (schedule) {
- case EXPLORE:
+ case EXPLORE:
break;
case EXPLOIT:
@@ -5151,7 +5160,7 @@ static u32 calculate_score(struct queue_entry* q) {
fuzz_total = 0;
n_paths = 0;
- struct queue_entry *queue_it = queue;
+ struct queue_entry *queue_it = queue;
while (queue_it) {
fuzz_total += queue_it->n_fuzz;
n_paths ++;
@@ -5162,22 +5171,22 @@ static u32 calculate_score(struct queue_entry* q) {
if (fuzz <= fuzz_mu) {
if (q->fuzz_level < 16)
factor = ((u32) (1 << q->fuzz_level));
- else
+ else
factor = MAX_FACTOR;
} else {
factor = 0;
}
break;
-
+
case FAST:
if (q->fuzz_level < 16) {
- factor = ((u32) (1 << q->fuzz_level)) / (fuzz == 0 ? 1 : fuzz);
+ factor = ((u32) (1 << q->fuzz_level)) / (fuzz == 0 ? 1 : fuzz);
} else
factor = MAX_FACTOR / (fuzz == 0 ? 1 : next_p2 (fuzz));
break;
case LIN:
- factor = q->fuzz_level / (fuzz == 0 ? 1 : fuzz);
+ factor = q->fuzz_level / (fuzz == 0 ? 1 : fuzz);
break;
case QUAD:
@@ -5187,7 +5196,7 @@ static u32 calculate_score(struct queue_entry* q) {
default:
PFATAL ("Unknown Power Schedule");
}
- if (factor > MAX_FACTOR)
+ if (factor > MAX_FACTOR)
factor = MAX_FACTOR;
perf_score *= factor / POWER_BETA;
@@ -5500,7 +5509,7 @@ static u8 fuzz_one(char** argv) {
* TRIMMING *
************/
- if (!dumb_mode && !queue_cur->trim_done) {
+ if (!dumb_mode && !queue_cur->trim_done && !AFLCustomMutator) {
u8 res = trim_case(argv, queue_cur, in_buf);
@@ -5530,16 +5539,39 @@ static u8 fuzz_one(char** argv) {
if (perf_score == 0) goto abandon_entry;
+ if (AFLCustomMutator) {
+ stage_short = "custom";
+ stage_name = "custom mutator";
+ stage_max = 1 << 16;
+ stage_val_type = STAGE_VAL_NONE;
+
+ orig_hit_cnt = queued_paths + unique_crashes;
+
+ for (stage_cur = 0 ; stage_cur < stage_max ; stage_cur++) {
+ size_t orig_size = (size_t) len;
+ size_t mutated_size = AFLCustomMutator(out_buf, orig_size, orig_size + 10000, UR(UINT32_MAX));
+ if (common_fuzz_stuff(argv, out_buf, (u32)mutated_size)) {
+ goto abandon_entry;
+ }
+ }
+ new_hit_cnt = queued_paths + unique_crashes;
+
+ stage_finds[STAGE_CUSTOM_MUTATOR] += new_hit_cnt - orig_hit_cnt;
+ stage_cycles[STAGE_CUSTOM_MUTATOR] += stage_max;
+ goto abandon_entry;
+ }
+
+
/* Skip right away if -d is given, if it has not been chosen sufficiently
often to warrant the expensive deterministic stage (fuzz_level), or
if it has gone through deterministic testing in earlier, resumed runs
(passed_det). */
- if (skip_deterministic
- || ((!queue_cur->passed_det)
+ if (skip_deterministic
+ || ((!queue_cur->passed_det)
&& perf_score < (
queue_cur->depth * 30 <= HAVOC_MAX_MULT * 100
- ? queue_cur->depth * 30
+ ? queue_cur->depth * 30
: HAVOC_MAX_MULT * 100))
|| queue_cur->passed_det)
#ifdef USE_PYTHON