aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-05-12 11:04:18 +0200
committerGitHub <noreply@github.com>2020-05-12 11:04:18 +0200
commit1317433a51a7f7336c82c80a592835ddda9ef60f (patch)
treee623506f1d0a8771c3fc266eed0a75b626a88724 /src
parentbdd2a412c476cbd5aea0fff67ef096305815953b (diff)
parenta578d719e1f556db07ca3c7e2fe38b7668c204d8 (diff)
downloadafl++-1317433a51a7f7336c82c80a592835ddda9ef60f.tar.gz
Merge pull request #359 from AFLplusplus/dev
push to master
Diffstat (limited to 'src')
-rw-r--r--src/afl-analyze.c2
-rw-r--r--src/afl-as.c2
-rw-r--r--src/afl-common.c18
-rw-r--r--src/afl-fuzz-bitmap.c4
-rw-r--r--src/afl-fuzz-mutators.c207
-rw-r--r--src/afl-fuzz-one.c197
-rw-r--r--src/afl-fuzz-python.c55
-rw-r--r--src/afl-fuzz-queue.c19
-rw-r--r--src/afl-fuzz-run.c77
-rw-r--r--src/afl-fuzz-stats.c6
-rw-r--r--src/afl-fuzz.c18
-rw-r--r--src/afl-showmap.c3
-rw-r--r--src/afl-tmin.c2
13 files changed, 351 insertions, 259 deletions
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index 8f48b1d0..4e973672 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -723,7 +723,7 @@ static void set_up_environment(void) {
}
- prog_in = alloc_printf("%s/.afl-analyze-temp-%u", use_dir, getpid());
+ prog_in = alloc_printf("%s/.afl-analyze-temp-%u", use_dir, (u32)getpid());
}
diff --git a/src/afl-as.c b/src/afl-as.c
index 486a6afa..cf7f8bb6 100644
--- a/src/afl-as.c
+++ b/src/afl-as.c
@@ -233,7 +233,7 @@ static void edit_params(int argc, char **argv) {
}
modified_file =
- alloc_printf("%s/.afl-%u-%u.s", tmp_dir, getpid(), (u32)time(NULL));
+ alloc_printf("%s/.afl-%u-%u.s", tmp_dir, (u32)getpid(), (u32)time(NULL));
wrap_things_up:
diff --git a/src/afl-common.c b/src/afl-common.c
index 54b2e790..d9d57863 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -64,15 +64,15 @@ char *afl_environment_variables[] = {
"AFL_LD_PRELOAD", "AFL_LD_VERBOSE", "AFL_LLVM_CMPLOG", "AFL_LLVM_INSTRIM",
"AFL_LLVM_CTX", "AFL_LLVM_INSTRUMENT", "AFL_LLVM_INSTRIM_LOOPHEAD",
"AFL_LLVM_LTO_AUTODICTIONARY", "AFL_LLVM_AUTODICTIONARY",
- "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK", "AFL_LLVM_LAF_SPLIT_COMPARES",
- "AFL_LLVM_LAF_SPLIT_COMPARES_BITW", "AFL_LLVM_LAF_SPLIT_FLOATS",
- "AFL_LLVM_LAF_SPLIT_SWITCHES", "AFL_LLVM_LAF_TRANSFORM_COMPARES",
- "AFL_LLVM_MAP_ADDR", "AFL_LLVM_MAP_DYNAMIC", "AFL_LLVM_NGRAM_SIZE",
- "AFL_NGRAM_SIZE", "AFL_LLVM_NOT_ZERO", "AFL_LLVM_WHITELIST",
- "AFL_LLVM_SKIP_NEVERZERO", "AFL_NO_AFFINITY", "AFL_LLVM_LTO_STARTID",
- "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN",
- "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", "AFL_NO_PYTHON",
- "AFL_UNTRACER_FILE",
+ "AFL_LLVM_SKIPSINGLEBLOCK", "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK",
+ "AFL_LLVM_LAF_SPLIT_COMPARES", "AFL_LLVM_LAF_SPLIT_COMPARES_BITW",
+ "AFL_LLVM_LAF_SPLIT_FLOATS", "AFL_LLVM_LAF_SPLIT_SWITCHES",
+ "AFL_LLVM_LAF_TRANSFORM_COMPARES", "AFL_LLVM_MAP_ADDR",
+ "AFL_LLVM_MAP_DYNAMIC", "AFL_LLVM_NGRAM_SIZE", "AFL_NGRAM_SIZE",
+ "AFL_LLVM_NOT_ZERO", "AFL_LLVM_WHITELIST", "AFL_LLVM_SKIP_NEVERZERO",
+ "AFL_NO_AFFINITY", "AFL_LLVM_LTO_STARTID", "AFL_LLVM_LTO_DONTWRITEID",
+ "AFL_NO_ARITH", "AFL_NO_BUILTIN", "AFL_NO_CPU_RED", "AFL_NO_FORKSRV",
+ "AFL_NO_UI", "AFL_NO_PYTHON", "AFL_UNTRACER_FILE",
"AFL_NO_X86", // not really an env but we dont want to warn on it
"AFL_MAP_SIZE", "AFL_MAPSIZE", "AFL_PATH", "AFL_PERFORMANCE_FILE",
//"AFL_PERSISTENT", // not implemented anymore, so warn additionally
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 2289183c..d4966889 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -437,13 +437,13 @@ u8 *describe_op(afl_state_t *afl, u8 hnb) {
sprintf(ret, "src:%06u", afl->current_entry);
- sprintf(ret + strlen(ret), ",time:%llu", get_cur_time() - afl->start_time);
-
if (afl->splicing_with >= 0) {
sprintf(ret + strlen(ret), "+%06d", afl->splicing_with);
}
+
+ sprintf(ret + strlen(ret), ",time:%llu", get_cur_time() - afl->start_time);
sprintf(ret + strlen(ret), ",op:%s", afl->stage_short);
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index beb89092..027add49 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -26,27 +26,55 @@
#include "afl-fuzz.h"
-void load_custom_mutator(afl_state_t *, const char *);
+struct custom_mutator *load_custom_mutator(afl_state_t *, const char *);
+#ifdef USE_PYTHON
+struct custom_mutator *load_custom_mutator_py(afl_state_t *, char *);
+#endif
-void setup_custom_mutator(afl_state_t *afl) {
+void setup_custom_mutators(afl_state_t *afl) {
/* Try mutator library first */
- u8 *fn = afl->afl_env.afl_custom_mutator_library;
+ struct custom_mutator *mutator;
+ u8 * fn = afl->afl_env.afl_custom_mutator_library;
+ u32 prev_mutator_count = 0;
if (fn) {
- if (afl->limit_time_sig) {
-
+ if (afl->limit_time_sig)
FATAL(
"MOpt and custom mutator are mutually exclusive. We accept pull "
"requests that integrates MOpt with the optional mutators "
- "(custom/radamsa/redquenn/...).");
+ "(custom/radamsa/redqueen/...).");
- }
+ u8 *fn_token = (u8 *)strsep((char **)&fn, ";:,");
+
+ if (likely(!fn_token)) {
- load_custom_mutator(afl, fn);
+ mutator = load_custom_mutator(afl, fn);
+ list_append(&afl->custom_mutator_list, mutator);
+ afl->custom_mutators_count++;
- return;
+ } else {
+
+ while (fn_token) {
+
+ if (*fn_token) { // strsep can be empty if ";;"
+
+ if (afl->not_on_tty && afl->debug)
+ SAYF("[Custom] Processing: %s\n", fn_token);
+ prev_mutator_count = afl->custom_mutators_count;
+ mutator = load_custom_mutator(afl, fn_token);
+ list_append(&afl->custom_mutator_list, mutator);
+ afl->custom_mutators_count++;
+ if (prev_mutator_count > afl->custom_mutators_count)
+ FATAL("Maximum Custom Mutator count reached.");
+ fn_token = (u8 *)strsep((char **)&fn, ";:,");
+
+ }
+
+ }
+
+ }
}
@@ -65,7 +93,9 @@ void setup_custom_mutator(afl_state_t *afl) {
}
- load_custom_mutator_py(afl, module_name);
+ struct custom_mutator *mutator = load_custom_mutator_py(afl, module_name);
+ afl->custom_mutators_count++;
+ list_append(&afl->custom_mutator_list, mutator);
}
@@ -80,114 +110,87 @@ void setup_custom_mutator(afl_state_t *afl) {
}
-void destroy_custom_mutator(afl_state_t *afl) {
+void destroy_custom_mutators(afl_state_t *afl) {
- if (afl->mutator) {
+ if (afl->custom_mutators_count) {
- afl->mutator->afl_custom_deinit(afl->mutator->data);
+ LIST_FOREACH_CLEAR(&afl->custom_mutator_list, struct custom_mutator, {
- if (afl->mutator->dh) { dlclose(afl->mutator->dh); }
+ if (!el->data) { FATAL("Deintializing NULL mutator"); }
+ el->afl_custom_deinit(el->data);
+ if (el->dh) dlclose(el->dh);
- if (afl->mutator->pre_save_buf) {
+ if (el->pre_save_buf) {
- ck_free(afl->mutator->pre_save_buf);
- afl->mutator->pre_save_buf = NULL;
- afl->mutator->pre_save_size = 0;
+ ck_free(el->pre_save_buf);
+ el->pre_save_buf = NULL;
+ el->pre_save_size = 0;
- }
+ }
- ck_free(afl->mutator);
- afl->mutator = NULL;
+ ck_free(el);
+
+ });
}
}
-void load_custom_mutator(afl_state_t *afl, const char *fn) {
+struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
- void *dh;
- afl->mutator = ck_alloc(sizeof(struct custom_mutator));
- afl->mutator->pre_save_buf = NULL;
- afl->mutator->pre_save_size = 0;
+ void * dh;
+ struct custom_mutator *mutator = ck_alloc(sizeof(struct custom_mutator));
- afl->mutator->name = fn;
+ mutator->name = fn;
ACTF("Loading custom mutator library from '%s'...", fn);
dh = dlopen(fn, RTLD_NOW);
- if (!dh) { FATAL("%s", dlerror()); }
- afl->mutator->dh = dh;
+ if (!dh) FATAL("%s", dlerror());
+ mutator->dh = dh;
/* Mutator */
- /* "afl_custom_init", required */
- afl->mutator->afl_custom_init = dlsym(dh, "afl_custom_init");
- if (!afl->mutator->afl_custom_init) {
-
- FATAL("Symbol 'afl_custom_init' not found.");
-
- }
-
- /* "afl_custom_deinit", required */
- afl->mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit");
- if (!afl->mutator->afl_custom_deinit) {
-
- FATAL("Symbol 'afl_custom_deinit' not found.");
-
- }
+ /* "afl_custom_init", optional for backward compatibility */
+ mutator->afl_custom_init = dlsym(dh, "afl_custom_init");
+ if (!mutator->afl_custom_init) WARNF("Symbol 'afl_custom_init' not found.");
/* "afl_custom_fuzz" or "afl_custom_mutator", required */
- afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz");
- if (!afl->mutator->afl_custom_fuzz) {
+ mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz");
+ if (!mutator->afl_custom_fuzz) {
/* Try "afl_custom_mutator" for backward compatibility */
WARNF("Symbol 'afl_custom_fuzz' not found. Try 'afl_custom_mutator'.");
- afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_mutator");
- if (!afl->mutator->afl_custom_fuzz) {
-
+ mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_mutator");
+ if (!mutator->afl_custom_fuzz)
FATAL("Symbol 'afl_custom_mutator' not found.");
- }
-
}
/* "afl_custom_pre_save", optional */
- afl->mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save");
- if (!afl->mutator->afl_custom_pre_save) {
-
+ mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save");
+ if (!mutator->afl_custom_pre_save)
WARNF("Symbol 'afl_custom_pre_save' not found.");
- }
-
u8 notrim = 0;
/* "afl_custom_init_trim", optional */
- afl->mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim");
- if (!afl->mutator->afl_custom_init_trim) {
-
+ mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim");
+ if (!mutator->afl_custom_init_trim)
WARNF("Symbol 'afl_custom_init_trim' not found.");
- }
-
/* "afl_custom_trim", optional */
- afl->mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim");
- if (!afl->mutator->afl_custom_trim) {
-
- WARNF("Symbol 'afl_custom_trim' not found.");
-
- }
+ mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim");
+ if (!mutator->afl_custom_trim) WARNF("Symbol 'afl_custom_trim' not found.");
/* "afl_custom_post_trim", optional */
- afl->mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim");
- if (!afl->mutator->afl_custom_post_trim) {
-
+ mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim");
+ if (!mutator->afl_custom_post_trim)
WARNF("Symbol 'afl_custom_post_trim' not found.");
- }
-
if (notrim) {
- afl->mutator->afl_custom_init_trim = NULL;
- afl->mutator->afl_custom_trim = NULL;
- afl->mutator->afl_custom_post_trim = NULL;
+ mutator->afl_custom_init_trim = NULL;
+ mutator->afl_custom_trim = NULL;
+ mutator->afl_custom_post_trim = NULL;
WARNF(
"Custom mutator does not implement all three trim APIs, standard "
"trimming will be used.");
@@ -195,53 +198,42 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
}
/* "afl_custom_havoc_mutation", optional */
- afl->mutator->afl_custom_havoc_mutation =
- dlsym(dh, "afl_custom_havoc_mutation");
- if (!afl->mutator->afl_custom_havoc_mutation) {
-
+ mutator->afl_custom_havoc_mutation = dlsym(dh, "afl_custom_havoc_mutation");
+ if (!mutator->afl_custom_havoc_mutation)
WARNF("Symbol 'afl_custom_havoc_mutation' not found.");
- }
-
/* "afl_custom_havoc_mutation", optional */
- afl->mutator->afl_custom_havoc_mutation_probability =
+ mutator->afl_custom_havoc_mutation_probability =
dlsym(dh, "afl_custom_havoc_mutation_probability");
- if (!afl->mutator->afl_custom_havoc_mutation_probability) {
-
+ if (!mutator->afl_custom_havoc_mutation_probability)
WARNF("Symbol 'afl_custom_havoc_mutation_probability' not found.");
- }
-
/* "afl_custom_queue_get", optional */
- afl->mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get");
- if (!afl->mutator->afl_custom_queue_get) {
-
+ mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get");
+ if (!mutator->afl_custom_queue_get)
WARNF("Symbol 'afl_custom_queue_get' not found.");
- }
-
/* "afl_custom_queue_new_entry", optional */
- afl->mutator->afl_custom_queue_new_entry =
- dlsym(dh, "afl_custom_queue_new_entry");
- if (!afl->mutator->afl_custom_queue_new_entry) {
-
+ mutator->afl_custom_queue_new_entry = dlsym(dh, "afl_custom_queue_new_entry");
+ if (!mutator->afl_custom_queue_new_entry)
WARNF("Symbol 'afl_custom_queue_new_entry' not found");
- }
-
OKF("Custom mutator '%s' installed successfully.", fn);
/* Initialize the custom mutator */
- if (afl->mutator->afl_custom_init) {
+ if (mutator->afl_custom_init)
+ mutator->data = mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF));
- afl->mutator->data =
- afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF));
+ mutator->stacked_custom = (mutator && mutator->afl_custom_havoc_mutation);
+ mutator->stacked_custom_prob =
+ 6; // like one of the default mutations in havoc
- }
+ return mutator;
}
-u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
+u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
+ struct custom_mutator *mutator) {
u8 needs_write = 0, fault = 0;
u32 trim_exec = 0;
@@ -254,8 +246,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
/* Initialize trimming in the custom mutator */
afl->stage_cur = 0;
- afl->stage_max =
- afl->mutator->afl_custom_init_trim(afl->mutator->data, in_buf, q->len);
+ afl->stage_max = mutator->afl_custom_init_trim(mutator->data, in_buf, q->len);
if (unlikely(afl->stage_max) < 0) {
FATAL("custom_init_trim error ret: %d", afl->stage_max);
@@ -278,7 +269,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
u32 cksum;
- size_t retlen = afl->mutator->afl_custom_trim(afl->mutator->data, &retbuf);
+ size_t retlen = mutator->afl_custom_trim(mutator->data, &retbuf);
if (unlikely(!retbuf)) {
@@ -318,8 +309,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
}
/* Tell the custom mutator that the trimming was successful */
- afl->stage_cur =
- afl->mutator->afl_custom_post_trim(afl->mutator->data, 1);
+ afl->stage_cur = mutator->afl_custom_post_trim(mutator->data, 1);
if (afl->not_on_tty && afl->debug) {
@@ -331,8 +321,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
} else {
/* Tell the custom mutator that the trimming was unsuccessful */
- afl->stage_cur =
- afl->mutator->afl_custom_post_trim(afl->mutator->data, 0);
+ afl->stage_cur = mutator->afl_custom_post_trim(mutator->data, 0);
if (unlikely(afl->stage_cur < 0)) {
FATAL("Error ret in custom_post_trim: %d", afl->stage_cur);
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 6d399a03..ddd15c84 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -384,16 +384,20 @@ u8 fuzz_one_original(afl_state_t *afl) {
#else
- if (unlikely(afl->mutator) && unlikely(afl->mutator->afl_custom_queue_get)) {
+ if (unlikely(afl->custom_mutators_count)) {
/* The custom mutator will decide to skip this test case or not. */
- if (!afl->mutator->afl_custom_queue_get(afl->mutator->data,
- afl->queue_cur->fname)) {
+ LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
- return 1;
+ if (el->afl_custom_queue_get &&
+ !el->afl_custom_queue_get(el->data, afl->queue_cur->fname)) {
- }
+ return 1;
+
+ }
+
+ });
}
@@ -1646,13 +1650,13 @@ custom_mutator_stage:
* CUSTOM MUTATORS *
*******************/
- if (likely(!afl->mutator)) { goto havoc_stage; }
- if (likely(!afl->mutator->afl_custom_fuzz)) { goto havoc_stage; }
+ if (likely(!afl->custom_mutators_count)) { goto havoc_stage; }
afl->stage_name = "custom mutator";
afl->stage_short = "custom";
afl->stage_max = HAVOC_CYCLES * perf_score / afl->havoc_div / 100;
afl->stage_val_type = STAGE_VAL_NONE;
+ bool has_custom_fuzz = false;
if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; }
@@ -1660,98 +1664,112 @@ custom_mutator_stage:
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
- for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
+ LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
- struct queue_entry *target;
- u32 tid;
- u8 * new_buf;
+ if (el->afl_custom_fuzz) {
- retry_external_pick:
- /* Pick a random other queue entry for passing to external API */
- do {
+ has_custom_fuzz = true;
- tid = rand_below(afl, afl->queued_paths);
+ for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max;
+ ++afl->stage_cur) {
- } while (tid == afl->current_entry && afl->queued_paths > 1);
+ struct queue_entry *target;
+ u32 tid;
+ u8 * new_buf;
- target = afl->queue;
+ retry_external_pick:
+ /* Pick a random other queue entry for passing to external API */
+ do {
- while (tid >= 100) {
+ tid = rand_below(afl, afl->queued_paths);
- target = target->next_100;
- tid -= 100;
+ } while (tid == afl->current_entry && afl->queued_paths > 1);
- }
+ target = afl->queue;
- while (tid--) {
+ while (tid >= 100) {
- target = target->next;
+ target = target->next_100;
+ tid -= 100;
- }
+ }
- /* Make sure that the target has a reasonable length. */
+ while (tid--) {
- while (target && (target->len < 2 || target == afl->queue_cur) &&
- afl->queued_paths > 1) {
+ target = target->next;
- target = target->next;
- ++afl->splicing_with;
+ }
- }
+ /* Make sure that the target has a reasonable length. */
- if (!target) { goto retry_external_pick; }
+ while (target && (target->len < 2 || target == afl->queue_cur) &&
+ afl->queued_paths > 1) {
- /* Read the additional testcase into a new buffer. */
- fd = open(target->fname, O_RDONLY);
- if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); }
+ target = target->next;
+ ++afl->splicing_with;
- new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), target->len);
- ck_read(fd, new_buf, target->len, target->fname);
- close(fd);
+ }
- u8 *mutated_buf = NULL;
+ if (!target) { goto retry_external_pick; }
- size_t mutated_size = afl->mutator->afl_custom_fuzz(
- afl->mutator->data, out_buf, len, &mutated_buf, new_buf, target->len,
- max_seed_size);
+ /* Read the additional testcase into a new buffer. */
+ fd = open(target->fname, O_RDONLY);
+ if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", target->fname); }
- if (unlikely(!mutated_buf)) {
+ new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), target->len);
+ ck_read(fd, new_buf, target->len, target->fname);
+ close(fd);
- FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size);
+ u8 *mutated_buf = NULL;
- }
+ size_t mutated_size =
+ el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf,
+ target->len, max_seed_size);
- if (mutated_size > 0) {
+ if (unlikely(!mutated_buf)) {
- if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) {
+ FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size);
- goto abandon_entry;
+ }
- }
+ if (mutated_size > 0) {
+
+ if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) {
+
+ goto abandon_entry;
+
+ }
- /* If we're finding new stuff, let's run for a bit longer, limits
- permitting. */
+ /* If we're finding new stuff, let's run for a bit longer, limits
+ permitting. */
- if (afl->queued_paths != havoc_queued) {
+ if (afl->queued_paths != havoc_queued) {
- if (perf_score <= afl->havoc_max_mult * 100) {
+ if (perf_score <= afl->havoc_max_mult * 100) {
- afl->stage_max *= 2;
- perf_score *= 2;
+ afl->stage_max *= 2;
+ perf_score *= 2;
+
+ }
+
+ havoc_queued = afl->queued_paths;
+
+ }
}
- havoc_queued = afl->queued_paths;
+ /* `(afl->)out_buf` may have been changed by the call to custom_fuzz */
+ /* TODO: Only do this when `mutated_buf` == `out_buf`? Branch vs Memcpy.
+ */
+ memcpy(out_buf, in_buf, len);
}
}
- /* `(afl->)out_buf` may have been changed by the call to custom_fuzz */
- /* TODO: Only do this when `mutated_buf` == `out_buf`? Branch vs Memcpy. */
- memcpy(out_buf, in_buf, len);
+ });
- }
+ if (!has_custom_fuzz) goto havoc_stage;
new_hit_cnt = afl->queued_paths + afl->unique_crashes;
@@ -1803,20 +1821,26 @@ havoc_stage:
havoc_queued = afl->queued_paths;
- u8 stacked_custom = (afl->mutator && afl->mutator->afl_custom_havoc_mutation);
- u8 stacked_custom_prob = 6; // like one of the default mutations in havoc
+ if (afl->custom_mutators_count) {
- if (stacked_custom && afl->mutator->afl_custom_havoc_mutation_probability) {
+ LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
- stacked_custom_prob =
- afl->mutator->afl_custom_havoc_mutation_probability(afl->mutator->data);
- if (stacked_custom_prob > 100) {
+ if (el->stacked_custom && el->afl_custom_havoc_mutation_probability) {
- FATAL(
- "The probability returned by afl_custom_havoc_mutation_propability "
- "has to be in the range 0-100.");
+ el->stacked_custom_prob =
+ el->afl_custom_havoc_mutation_probability(el->data);
+ if (el->stacked_custom_prob > 100) {
- }
+ FATAL(
+ "The probability returned by "
+ "afl_custom_havoc_mutation_propability "
+ "has to be in the range 0-100.");
+
+ }
+
+ }
+
+ });
}
@@ -1831,28 +1855,37 @@ havoc_stage:
for (i = 0; i < use_stacking; ++i) {
- if (stacked_custom && rand_below(afl, 100) < stacked_custom_prob) {
+ if (afl->custom_mutators_count) {
- u8 * custom_havoc_buf = NULL;
- size_t new_len = afl->mutator->afl_custom_havoc_mutation(
- afl->mutator->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE);
- if (unlikely(!custom_havoc_buf)) {
+ LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
- FATAL("Error in custom_havoc (return %zd)", new_len);
+ if (el->stacked_custom &&
+ rand_below(afl, 100) < el->stacked_custom_prob) {
- }
+ u8 * custom_havoc_buf = NULL;
+ size_t new_len = el->afl_custom_havoc_mutation(
+ el->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE);
+ if (unlikely(!custom_havoc_buf)) {
+
+ FATAL("Error in custom_havoc (return %zd)", new_len);
- if (likely(new_len > 0 && custom_havoc_buf)) {
+ }
- temp_len = new_len;
- if (out_buf != custom_havoc_buf) {
+ if (likely(new_len > 0 && custom_havoc_buf)) {
- ck_maybe_grow(BUF_PARAMS(out), temp_len);
- memcpy(out_buf, custom_havoc_buf, temp_len);
+ temp_len = new_len;
+ if (out_buf != custom_havoc_buf) {
+
+ ck_maybe_grow(BUF_PARAMS(out), temp_len);
+ memcpy(out_buf, custom_havoc_buf, temp_len);
+
+ }
+
+ }
}
- }
+ });
}
diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c
index 64cabcad..832dba06 100644
--- a/src/afl-fuzz-python.c
+++ b/src/afl-fuzz-python.c
@@ -71,7 +71,7 @@ static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf,
PyTuple_SetItem(py_args, 1, py_value);
- /* max_size */
+/* max_size */
#if PY_MAJOR_VERSION >= 3
py_value = PyLong_FromLong(max_size);
#else
@@ -295,80 +295,75 @@ void deinit_py(void *py_mutator) {
}
-void load_custom_mutator_py(afl_state_t *afl, char *module_name) {
+struct custom_mutator *load_custom_mutator_py(afl_state_t *afl,
+ char * module_name) {
- afl->mutator = ck_alloc(sizeof(struct custom_mutator));
- afl->mutator->pre_save_buf = NULL;
- afl->mutator->pre_save_size = 0;
+ struct custom_mutator *mutator;
- afl->mutator->name = module_name;
+ mutator = ck_alloc(sizeof(struct custom_mutator));
+ mutator->pre_save_buf = NULL;
+ mutator->pre_save_size = 0;
+
+ mutator->name = module_name;
ACTF("Loading Python mutator library from '%s'...", module_name);
py_mutator_t *py_mutator;
py_mutator = init_py_module(afl, module_name);
- afl->mutator->data = py_mutator;
+ mutator->data = py_mutator;
if (!py_mutator) { FATAL("Failed to load python mutator."); }
PyObject **py_functions = py_mutator->py_functions;
- if (py_functions[PY_FUNC_INIT]) {
-
- afl->mutator->afl_custom_init = unsupported;
-
- }
-
- if (py_functions[PY_FUNC_DEINIT]) {
-
- afl->mutator->afl_custom_deinit = deinit_py;
+ if (py_functions[PY_FUNC_INIT]) { mutator->afl_custom_init = unsupported; }
- }
+ if (py_functions[PY_FUNC_DEINIT]) { mutator->afl_custom_deinit = deinit_py; }
/* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator
is quite different from the custom mutator. */
- afl->mutator->afl_custom_fuzz = fuzz_py;
+ mutator->afl_custom_fuzz = fuzz_py;
if (py_functions[PY_FUNC_PRE_SAVE]) {
- afl->mutator->afl_custom_pre_save = pre_save_py;
+ mutator->afl_custom_pre_save = pre_save_py;
}
if (py_functions[PY_FUNC_INIT_TRIM]) {
- afl->mutator->afl_custom_init_trim = init_trim_py;
+ mutator->afl_custom_init_trim = init_trim_py;
}
if (py_functions[PY_FUNC_POST_TRIM]) {
- afl->mutator->afl_custom_post_trim = post_trim_py;
+ mutator->afl_custom_post_trim = post_trim_py;
}
- if (py_functions[PY_FUNC_TRIM]) { afl->mutator->afl_custom_trim = trim_py; }
+ if (py_functions[PY_FUNC_TRIM]) { mutator->afl_custom_trim = trim_py; }
if (py_functions[PY_FUNC_HAVOC_MUTATION]) {
- afl->mutator->afl_custom_havoc_mutation = havoc_mutation_py;
+ mutator->afl_custom_havoc_mutation = havoc_mutation_py;
}
if (py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY]) {
- afl->mutator->afl_custom_havoc_mutation_probability =
+ mutator->afl_custom_havoc_mutation_probability =
havoc_mutation_probability_py;
}
if (py_functions[PY_FUNC_QUEUE_GET]) {
- afl->mutator->afl_custom_queue_get = queue_get_py;
+ mutator->afl_custom_queue_get = queue_get_py;
}
if (py_functions[PY_FUNC_QUEUE_NEW_ENTRY]) {
- afl->mutator->afl_custom_queue_new_entry = queue_new_entry_py;
+ mutator->afl_custom_queue_new_entry = queue_new_entry_py;
}
@@ -377,6 +372,8 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) {
/* Initialize the custom mutator */
init_py(afl, py_mutator, rand_below(afl, 0xFFFFFFFF));
+ return mutator;
+
}
size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) {
@@ -545,7 +542,7 @@ size_t havoc_mutation_py(void *py_mutator, u8 *buf, size_t buf_size,
PyTuple_SetItem(py_args, 0, py_value);
- /* max_size */
+/* max_size */
#if PY_MAJOR_VERSION >= 3
py_value = PyLong_FromLong(max_size);
#else
@@ -627,7 +624,7 @@ u8 queue_get_py(void *py_mutator, const u8 *filename) {
py_args = PyTuple_New(1);
- // File name
+// File name
#if PY_MAJOR_VERSION >= 3
py_value = PyUnicode_FromString(filename);
#else
@@ -677,7 +674,7 @@ void queue_new_entry_py(void *py_mutator, const u8 *filename_new_queue,
py_args = PyTuple_New(2);
- // New queue
+// New queue
#if PY_MAJOR_VERSION >= 3
py_value = PyUnicode_FromString(filename_new_queue);
#else
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index f998c06b..cfeb6c5e 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -140,15 +140,22 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
afl->last_path_time = get_cur_time();
- if (afl->mutator && afl->mutator->afl_custom_queue_new_entry) {
+ if (afl->custom_mutators_count) {
- u8 *fname_orig = NULL;
+ LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
- /* At the initialization stage, queue_cur is NULL */
- if (afl->queue_cur) { fname_orig = afl->queue_cur->fname; }
+ if (el->afl_custom_queue_new_entry) {
- afl->mutator->afl_custom_queue_new_entry(afl->mutator->data, fname,
- fname_orig);
+ u8 *fname_orig = NULL;
+
+ /* At the initialization stage, queue_cur is NULL */
+ if (afl->queue_cur) fname_orig = afl->queue_cur->fname;
+
+ el->afl_custom_queue_new_entry(el->data, fname, fname_orig);
+
+ }
+
+ });
}
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 692026d4..4a22dad6 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -30,13 +30,37 @@
#include "cmplog.h"
+#ifdef PROFILING
+u64 time_spent_working = 0;
+#endif
+
/* Execute target application, monitoring for timeouts. Return status
information. The called program will update afl->fsrv->trace_bits. */
fsrv_run_result_t fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv,
u32 timeout) {
+#ifdef PROFILING
+ static u64 time_spent_start = 0;
+ struct timespec spec;
+ if (time_spent_start) {
+
+ u64 current;
+ clock_gettime(CLOCK_REALTIME, &spec);
+ current = (spec.tv_sec * 1000000000) + spec.tv_nsec;
+ time_spent_working += (current - time_spent_start);
+
+ }
+
+#endif
+
fsrv_run_result_t res = afl_fsrv_run_target(fsrv, timeout, &afl->stop_soon);
+
+#ifdef PROFILING
+ clock_gettime(CLOCK_REALTIME, &spec);
+ time_spent_start = (spec.tv_sec * 1000000000) + spec.tv_nsec;
+#endif
+
// TODO: Don't classify for faults?
classify_counts(fsrv);
return res;
@@ -65,21 +89,40 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
#endif
- if (unlikely(afl->mutator && afl->mutator->afl_custom_pre_save)) {
+ if (unlikely(afl->custom_mutators_count)) {
+
+ u8 * new_buf = NULL;
+ ssize_t new_size = len;
+ void * new_mem = mem;
+
+ LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
+
+ if (el->afl_custom_pre_save) {
+
+ new_size =
+ el->afl_custom_pre_save(el->data, new_mem, new_size, &new_buf);
- u8 *new_buf = NULL;
+ }
+
+ new_mem = new_buf;
- size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem,
- len, &new_buf);
+ });
- if (unlikely(!new_buf)) {
+ if (unlikely(!new_buf && (new_size <= 0))) {
FATAL("Custom_pre_save failed (ret: %lu)", (long unsigned)new_size);
- }
+ } else if (likely(new_buf)) {
+
+ /* everything as planned. use the new data. */
+ afl_fsrv_write_to_testcase(&afl->fsrv, new_buf, new_size);
- /* everything as planned. use the new data. */
- afl_fsrv_write_to_testcase(&afl->fsrv, new_buf, new_size);
+ } else {
+
+ /* custom mutators do not has a custom_pre_save function */
+ afl_fsrv_write_to_testcase(&afl->fsrv, mem, len);
+
+ }
} else {
@@ -489,9 +532,23 @@ void sync_fuzzers(afl_state_t *afl) {
u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
/* Custom mutator trimmer */
- if (afl->mutator && afl->mutator->afl_custom_trim) {
+ if (afl->custom_mutators_count) {
+
+ u8 trimmed_case = 0;
+ bool custom_trimmed = false;
+
+ LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
+
+ if (el->afl_custom_trim) {
+
+ trimmed_case = trim_case_custom(afl, q, in_buf, el);
+ custom_trimmed = true;
+
+ }
+
+ });
- return trim_case_custom(afl, q, in_buf);
+ if (custom_trimmed) return trimmed_case;
}
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 3cbb2d8c..014ed34d 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -72,7 +72,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
"start_time : %llu\n"
"last_update : %llu\n"
"run_time : %llu\n"
- "fuzzer_pid : %d\n"
+ "fuzzer_pid : %u\n"
"cycles_done : %llu\n"
"cycles_wo_finds : %llu\n"
"execs_done : %llu\n"
@@ -106,7 +106,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
"target_mode : %s%s%s%s%s%s%s%s\n"
"command_line : %s\n",
afl->start_time / 1000, cur_time / 1000,
- (cur_time - afl->start_time) / 1000, getpid(),
+ (cur_time - afl->start_time) / 1000, (u32)getpid(),
afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->cycles_wo_finds,
afl->fsrv.total_execs,
afl->fsrv.total_execs /
@@ -792,7 +792,7 @@ void show_stats(afl_state_t *afl) {
}
- if (afl->mutator) {
+ if (afl->custom_mutators_count) {
sprintf(tmp, "%s/%s",
u_stringify_int(IB(0), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 5920f5c0..aaf615e9 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -27,6 +27,10 @@
#include "cmplog.h"
#include <limits.h>
+#ifdef PROFILING
+extern u64 time_spent_working;
+#endif
+
static u8 *get_libradamsa_path(u8 *own_loc) {
u8 *tmp, *cp, *rsl, *own_copy;
@@ -644,10 +648,7 @@ int main(int argc, char **argv_orig, char **envp) {
}
afl->limit_time_puppet = limit_time_puppet2;
-
- SAYF("limit_time_puppet %d\n", afl->limit_time_puppet);
afl->swarm_now = 0;
-
if (afl->limit_time_puppet == 0) { afl->key_puppet = 1; }
int i;
@@ -1073,7 +1074,7 @@ int main(int argc, char **argv_orig, char **envp) {
setup_dirs_fds(afl);
- setup_custom_mutator(afl);
+ setup_custom_mutators(afl);
setup_cmdline_file(afl, argv + optind);
@@ -1351,10 +1352,17 @@ stop_fuzzing:
}
+#ifdef PROFILING
+ SAYF(cYEL "[!] " cRST
+ "Profiling information: %llu ms total work, %llu ns/run\n",
+ time_spent_working / 1000000,
+ time_spent_working / afl->fsrv.total_execs);
+#endif
+
fclose(afl->fsrv.plot_file);
destroy_queue(afl);
destroy_extras(afl);
- destroy_custom_mutator(afl);
+ destroy_custom_mutators(afl);
afl_shm_deinit(&afl->shm);
afl_fsrv_deinit(&afl->fsrv);
if (afl->orig_cmdline) { ck_free(afl->orig_cmdline); }
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index a51d520d..ed59f2f5 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -865,7 +865,8 @@ int main(int argc, char **argv_orig, char **envp) {
}
- stdin_file = alloc_printf("%s/.afl-showmap-temp-%u", use_dir, getpid());
+ stdin_file =
+ alloc_printf("%s/.afl-showmap-temp-%u", use_dir, (u32)getpid());
unlink(stdin_file);
atexit(at_exit_handler);
fsrv->out_fd = open(stdin_file, O_RDWR | O_CREAT | O_EXCL, 0600);
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 98568473..e15dc72d 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -619,7 +619,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
}
- out_file = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, getpid());
+ out_file = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, (u32)getpid());
}