mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 19:08:08 +00:00
Support multiple custom mutators (#282)
* Make a list of custom mutators using env variable * Set up multiple custom mutators * Add destroy custom mutator and changes to load_custom_mutator * Use array instead of list, make changes to afl-fuzz-one for multiple mutators * Make change to fuzz-one custom_queue_get to support multiple mutators * Modify custom python mutator support * Fix bug * Fix missing afl->mutator->data * Revert to list with max count * Change custom_pre_save hook and code format * Free custom_mutator struct in the list * Add testcase for multiple custom mutators * Resolve merge conflict
This commit is contained in:
@ -607,6 +607,9 @@ typedef struct afl_state {
|
|||||||
|
|
||||||
u8 * ex_buf;
|
u8 * ex_buf;
|
||||||
size_t ex_size;
|
size_t ex_size;
|
||||||
|
u32 custom_mutators_count;
|
||||||
|
|
||||||
|
list_t custom_mutator_list;
|
||||||
|
|
||||||
/* this is a fixed buffer of size map_size that can be used by any function if
|
/* this is a fixed buffer of size map_size that can be used by any function if
|
||||||
* they do not call another function */
|
* they do not call another function */
|
||||||
@ -620,6 +623,8 @@ struct custom_mutator {
|
|||||||
void * dh;
|
void * dh;
|
||||||
u8 * pre_save_buf;
|
u8 * pre_save_buf;
|
||||||
size_t pre_save_size;
|
size_t pre_save_size;
|
||||||
|
u8 stacked_custom_prob,
|
||||||
|
stacked_custom;
|
||||||
|
|
||||||
void *data; /* custom mutator data ptr */
|
void *data; /* custom mutator data ptr */
|
||||||
|
|
||||||
@ -808,14 +813,14 @@ void read_afl_environment(afl_state_t *, char **);
|
|||||||
/**** Prototypes ****/
|
/**** Prototypes ****/
|
||||||
|
|
||||||
/* Custom mutators */
|
/* Custom mutators */
|
||||||
void setup_custom_mutator(afl_state_t *);
|
void setup_custom_mutators(afl_state_t *);
|
||||||
void destroy_custom_mutator(afl_state_t *);
|
void destroy_custom_mutators(afl_state_t *);
|
||||||
u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf);
|
u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf, struct custom_mutator * mutator);
|
||||||
|
|
||||||
/* Python */
|
/* Python */
|
||||||
#ifdef USE_PYTHON
|
#ifdef USE_PYTHON
|
||||||
|
|
||||||
void load_custom_mutator_py(afl_state_t *, char *);
|
struct custom_mutator * load_custom_mutator_py(afl_state_t *, char *);
|
||||||
void finalize_py_module(void *);
|
void finalize_py_module(void *);
|
||||||
|
|
||||||
size_t pre_save_py(void *, u8 *, size_t, u8 **);
|
size_t pre_save_py(void *, u8 *, size_t, u8 **);
|
||||||
|
@ -26,27 +26,47 @@
|
|||||||
|
|
||||||
#include "afl-fuzz.h"
|
#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 */
|
/* Try mutator library first */
|
||||||
u8 *fn = afl->afl_env.afl_custom_mutator_library;
|
struct custom_mutator * mutator;
|
||||||
|
u8 * fn = getenv("AFL_CUSTOM_MUTATOR_LIBRARY");
|
||||||
|
u32 prev_mutator_count = 0;
|
||||||
|
|
||||||
if (fn) {
|
if (fn) {
|
||||||
|
|
||||||
if (afl->limit_time_sig) {
|
if (afl->limit_time_sig)
|
||||||
|
|
||||||
FATAL(
|
FATAL(
|
||||||
"MOpt and custom mutator are mutually exclusive. We accept pull "
|
"MOpt and custom mutator are mutually exclusive. We accept pull "
|
||||||
"requests that integrates MOpt with the optional mutators "
|
"requests that integrates MOpt with the optional mutators "
|
||||||
"(custom/radamsa/redquenn/...).");
|
"(custom/radamsa/redquenn/...).");
|
||||||
|
|
||||||
|
u8 *fn_token = (u8 *)strsep((char **)&fn, ";");
|
||||||
|
|
||||||
|
if (likely(!fn_token)) {
|
||||||
|
|
||||||
|
mutator = load_custom_mutator(afl, fn);
|
||||||
|
list_append(&afl->custom_mutator_list, mutator);
|
||||||
|
afl->custom_mutators_count++;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
while (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, ";");
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
load_custom_mutator(afl, fn);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +85,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 +102,85 @@ 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 (afl->mutator->pre_save_buf) {
|
if (el->dh) dlclose(el->dh);
|
||||||
|
|
||||||
ck_free(afl->mutator->pre_save_buf);
|
|
||||||
afl->mutator->pre_save_buf = NULL;
|
|
||||||
afl->mutator->pre_save_size = 0;
|
|
||||||
|
|
||||||
|
if (el->pre_save_buf) {
|
||||||
|
ck_free(el->pre_save_buf);
|
||||||
|
el->pre_save_buf = NULL;
|
||||||
|
el->pre_save_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ck_free(afl->mutator);
|
ck_free(el);
|
||||||
afl->mutator = NULL;
|
|
||||||
|
} );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
void * dh;
|
||||||
afl->mutator = ck_alloc(sizeof(struct custom_mutator));
|
struct custom_mutator *mutator = ck_alloc(sizeof(struct custom_mutator));
|
||||||
afl->mutator->pre_save_buf = NULL;
|
|
||||||
afl->mutator->pre_save_size = 0;
|
|
||||||
|
|
||||||
afl->mutator->name = fn;
|
mutator->name = fn;
|
||||||
ACTF("Loading custom mutator library from '%s'...", fn);
|
ACTF("Loading custom mutator library from '%s'...", fn);
|
||||||
|
|
||||||
dh = dlopen(fn, RTLD_NOW);
|
dh = dlopen(fn, RTLD_NOW);
|
||||||
if (!dh) { FATAL("%s", dlerror()); }
|
if (!dh) FATAL("%s", dlerror());
|
||||||
afl->mutator->dh = dh;
|
mutator->dh = dh;
|
||||||
|
|
||||||
/* Mutator */
|
/* Mutator */
|
||||||
/* "afl_custom_init", required */
|
/* "afl_custom_init", optional for backward compatibility */
|
||||||
afl->mutator->afl_custom_init = dlsym(dh, "afl_custom_init");
|
mutator->afl_custom_init = dlsym(dh, "afl_custom_init");
|
||||||
if (!afl->mutator->afl_custom_init) {
|
if (!mutator->afl_custom_init) WARNF("Symbol 'afl_custom_init' not found.");
|
||||||
|
|
||||||
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_fuzz" or "afl_custom_mutator", required */
|
/* "afl_custom_fuzz" or "afl_custom_mutator", required */
|
||||||
afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz");
|
mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz");
|
||||||
if (!afl->mutator->afl_custom_fuzz) {
|
if (!mutator->afl_custom_fuzz) {
|
||||||
|
|
||||||
/* Try "afl_custom_mutator" for backward compatibility */
|
/* Try "afl_custom_mutator" for backward compatibility */
|
||||||
WARNF("Symbol 'afl_custom_fuzz' not found. Try 'afl_custom_mutator'.");
|
WARNF("Symbol 'afl_custom_fuzz' not found. Try 'afl_custom_mutator'.");
|
||||||
|
|
||||||
afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_mutator");
|
mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_mutator");
|
||||||
if (!afl->mutator->afl_custom_fuzz) {
|
if (!mutator->afl_custom_fuzz)
|
||||||
|
|
||||||
FATAL("Symbol 'afl_custom_mutator' not found.");
|
FATAL("Symbol 'afl_custom_mutator' not found.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* "afl_custom_pre_save", optional */
|
/* "afl_custom_pre_save", optional */
|
||||||
afl->mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save");
|
mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save");
|
||||||
if (!afl->mutator->afl_custom_pre_save) {
|
if (!mutator->afl_custom_pre_save)
|
||||||
|
|
||||||
WARNF("Symbol 'afl_custom_pre_save' not found.");
|
WARNF("Symbol 'afl_custom_pre_save' not found.");
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 notrim = 0;
|
u8 notrim = 0;
|
||||||
/* "afl_custom_init_trim", optional */
|
/* "afl_custom_init_trim", optional */
|
||||||
afl->mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim");
|
mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim");
|
||||||
if (!afl->mutator->afl_custom_init_trim) {
|
if (!mutator->afl_custom_init_trim)
|
||||||
|
|
||||||
WARNF("Symbol 'afl_custom_init_trim' not found.");
|
WARNF("Symbol 'afl_custom_init_trim' not found.");
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* "afl_custom_trim", optional */
|
/* "afl_custom_trim", optional */
|
||||||
afl->mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim");
|
mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim");
|
||||||
if (!afl->mutator->afl_custom_trim) {
|
if (!mutator->afl_custom_trim) WARNF("Symbol 'afl_custom_trim' not found.");
|
||||||
|
|
||||||
WARNF("Symbol 'afl_custom_trim' not found.");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* "afl_custom_post_trim", optional */
|
/* "afl_custom_post_trim", optional */
|
||||||
afl->mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim");
|
mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim");
|
||||||
if (!afl->mutator->afl_custom_post_trim) {
|
if (!mutator->afl_custom_post_trim)
|
||||||
|
|
||||||
WARNF("Symbol 'afl_custom_post_trim' not found.");
|
WARNF("Symbol 'afl_custom_post_trim' not found.");
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notrim) {
|
if (notrim) {
|
||||||
|
|
||||||
afl->mutator->afl_custom_init_trim = NULL;
|
mutator->afl_custom_init_trim = NULL;
|
||||||
afl->mutator->afl_custom_trim = NULL;
|
mutator->afl_custom_trim = NULL;
|
||||||
afl->mutator->afl_custom_post_trim = NULL;
|
mutator->afl_custom_post_trim = NULL;
|
||||||
WARNF(
|
WARNF(
|
||||||
"Custom mutator does not implement all three trim APIs, standard "
|
"Custom mutator does not implement all three trim APIs, standard "
|
||||||
"trimming will be used.");
|
"trimming will be used.");
|
||||||
@ -195,53 +188,41 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* "afl_custom_havoc_mutation", optional */
|
/* "afl_custom_havoc_mutation", optional */
|
||||||
afl->mutator->afl_custom_havoc_mutation =
|
mutator->afl_custom_havoc_mutation = dlsym(dh, "afl_custom_havoc_mutation");
|
||||||
dlsym(dh, "afl_custom_havoc_mutation");
|
if (!mutator->afl_custom_havoc_mutation)
|
||||||
if (!afl->mutator->afl_custom_havoc_mutation) {
|
|
||||||
|
|
||||||
WARNF("Symbol 'afl_custom_havoc_mutation' not found.");
|
WARNF("Symbol 'afl_custom_havoc_mutation' not found.");
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* "afl_custom_havoc_mutation", optional */
|
/* "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");
|
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.");
|
WARNF("Symbol 'afl_custom_havoc_mutation_probability' not found.");
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* "afl_custom_queue_get", optional */
|
/* "afl_custom_queue_get", optional */
|
||||||
afl->mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get");
|
mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get");
|
||||||
if (!afl->mutator->afl_custom_queue_get) {
|
if (!mutator->afl_custom_queue_get)
|
||||||
|
|
||||||
WARNF("Symbol 'afl_custom_queue_get' not found.");
|
WARNF("Symbol 'afl_custom_queue_get' not found.");
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* "afl_custom_queue_new_entry", optional */
|
/* "afl_custom_queue_new_entry", optional */
|
||||||
afl->mutator->afl_custom_queue_new_entry =
|
mutator->afl_custom_queue_new_entry = dlsym(dh, "afl_custom_queue_new_entry");
|
||||||
dlsym(dh, "afl_custom_queue_new_entry");
|
if (!mutator->afl_custom_queue_new_entry)
|
||||||
if (!afl->mutator->afl_custom_queue_new_entry) {
|
|
||||||
|
|
||||||
WARNF("Symbol 'afl_custom_queue_new_entry' not found");
|
WARNF("Symbol 'afl_custom_queue_new_entry' not found");
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
OKF("Custom mutator '%s' installed successfully.", fn);
|
OKF("Custom mutator '%s' installed successfully.", fn);
|
||||||
|
|
||||||
/* Initialize the custom mutator */
|
/* 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 =
|
mutator->stacked_custom = (mutator && mutator->afl_custom_havoc_mutation);
|
||||||
afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF));
|
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;
|
u8 needs_write = 0, fault = 0;
|
||||||
u32 trim_exec = 0;
|
u32 trim_exec = 0;
|
||||||
@ -255,7 +236,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
/* Initialize trimming in the custom mutator */
|
/* Initialize trimming in the custom mutator */
|
||||||
afl->stage_cur = 0;
|
afl->stage_cur = 0;
|
||||||
afl->stage_max =
|
afl->stage_max =
|
||||||
afl->mutator->afl_custom_init_trim(afl->mutator->data, in_buf, q->len);
|
mutator->afl_custom_init_trim(mutator->data, in_buf, q->len);
|
||||||
if (unlikely(afl->stage_max) < 0) {
|
if (unlikely(afl->stage_max) < 0) {
|
||||||
|
|
||||||
FATAL("custom_init_trim error ret: %d", afl->stage_max);
|
FATAL("custom_init_trim error ret: %d", afl->stage_max);
|
||||||
@ -278,7 +259,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
|
|
||||||
u32 cksum;
|
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)) {
|
if (unlikely(!retbuf)) {
|
||||||
|
|
||||||
@ -319,7 +300,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 */
|
/* Tell the custom mutator that the trimming was successful */
|
||||||
afl->stage_cur =
|
afl->stage_cur =
|
||||||
afl->mutator->afl_custom_post_trim(afl->mutator->data, 1);
|
mutator->afl_custom_post_trim(mutator->data, 1);
|
||||||
|
|
||||||
if (afl->not_on_tty && afl->debug) {
|
if (afl->not_on_tty && afl->debug) {
|
||||||
|
|
||||||
@ -332,7 +313,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
|
|
||||||
/* Tell the custom mutator that the trimming was unsuccessful */
|
/* Tell the custom mutator that the trimming was unsuccessful */
|
||||||
afl->stage_cur =
|
afl->stage_cur =
|
||||||
afl->mutator->afl_custom_post_trim(afl->mutator->data, 0);
|
mutator->afl_custom_post_trim(mutator->data, 0);
|
||||||
if (unlikely(afl->stage_cur < 0)) {
|
if (unlikely(afl->stage_cur < 0)) {
|
||||||
|
|
||||||
FATAL("Error ret in custom_post_trim: %d", afl->stage_cur);
|
FATAL("Error ret in custom_post_trim: %d", afl->stage_cur);
|
||||||
|
@ -384,17 +384,17 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
|||||||
|
|
||||||
#else
|
#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. */
|
/* The custom mutator will decide to skip this test case or not. */
|
||||||
|
|
||||||
if (!afl->mutator->afl_custom_queue_get(afl->mutator->data,
|
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
|
||||||
afl->queue_cur->fname)) {
|
|
||||||
|
|
||||||
|
if (el->afl_custom_queue_get && !el->afl_custom_queue_get(el->data, afl->queue_cur->fname)) {
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (likely(afl->pending_favored)) {
|
if (likely(afl->pending_favored)) {
|
||||||
@ -1646,13 +1646,13 @@ custom_mutator_stage:
|
|||||||
* CUSTOM MUTATORS *
|
* CUSTOM MUTATORS *
|
||||||
*******************/
|
*******************/
|
||||||
|
|
||||||
if (likely(!afl->mutator)) { goto havoc_stage; }
|
if (likely(!afl->custom_mutators_count)) { goto havoc_stage; }
|
||||||
if (likely(!afl->mutator->afl_custom_fuzz)) { goto havoc_stage; }
|
|
||||||
|
|
||||||
afl->stage_name = "custom mutator";
|
afl->stage_name = "custom mutator";
|
||||||
afl->stage_short = "custom";
|
afl->stage_short = "custom";
|
||||||
afl->stage_max = HAVOC_CYCLES * perf_score / afl->havoc_div / 100;
|
afl->stage_max = HAVOC_CYCLES * perf_score / afl->havoc_div / 100;
|
||||||
afl->stage_val_type = STAGE_VAL_NONE;
|
afl->stage_val_type = STAGE_VAL_NONE;
|
||||||
|
bool has_custom_fuzz = false;
|
||||||
|
|
||||||
if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; }
|
if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; }
|
||||||
|
|
||||||
@ -1660,6 +1660,12 @@ custom_mutator_stage:
|
|||||||
|
|
||||||
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
|
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
|
||||||
|
|
||||||
|
LIST_FOREACH (&afl->custom_mutator_list, struct custom_mutator, {
|
||||||
|
|
||||||
|
if ( el->afl_custom_fuzz ) {
|
||||||
|
|
||||||
|
has_custom_fuzz = true;
|
||||||
|
|
||||||
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
|
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
|
||||||
|
|
||||||
struct queue_entry *target;
|
struct queue_entry *target;
|
||||||
@ -1711,8 +1717,8 @@ custom_mutator_stage:
|
|||||||
|
|
||||||
u8 *mutated_buf = NULL;
|
u8 *mutated_buf = NULL;
|
||||||
|
|
||||||
size_t mutated_size = afl->mutator->afl_custom_fuzz(
|
size_t mutated_size = el->afl_custom_fuzz(
|
||||||
afl->mutator->data, out_buf, len, &mutated_buf, new_buf, target->len,
|
el->data, out_buf, len, &mutated_buf, new_buf, target->len,
|
||||||
max_seed_size);
|
max_seed_size);
|
||||||
|
|
||||||
if (unlikely(!mutated_buf)) {
|
if (unlikely(!mutated_buf)) {
|
||||||
@ -1753,6 +1759,13 @@ custom_mutator_stage:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
if (!has_custom_fuzz) goto havoc_stage;
|
||||||
|
|
||||||
new_hit_cnt = afl->queued_paths + afl->unique_crashes;
|
new_hit_cnt = afl->queued_paths + afl->unique_crashes;
|
||||||
|
|
||||||
afl->stage_finds[STAGE_CUSTOM_MUTATOR] += new_hit_cnt - orig_hit_cnt;
|
afl->stage_finds[STAGE_CUSTOM_MUTATOR] += new_hit_cnt - orig_hit_cnt;
|
||||||
@ -1803,14 +1816,15 @@ havoc_stage:
|
|||||||
|
|
||||||
havoc_queued = afl->queued_paths;
|
havoc_queued = afl->queued_paths;
|
||||||
|
|
||||||
u8 stacked_custom = (afl->mutator && afl->mutator->afl_custom_havoc_mutation);
|
if (afl->custom_mutators_count) {
|
||||||
u8 stacked_custom_prob = 6; // like one of the default mutations in havoc
|
|
||||||
|
|
||||||
if (stacked_custom && afl->mutator->afl_custom_havoc_mutation_probability) {
|
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
|
||||||
|
|
||||||
stacked_custom_prob =
|
if (el->stacked_custom && el->afl_custom_havoc_mutation_probability) {
|
||||||
afl->mutator->afl_custom_havoc_mutation_probability(afl->mutator->data);
|
|
||||||
if (stacked_custom_prob > 100) {
|
el->stacked_custom_prob =
|
||||||
|
el->afl_custom_havoc_mutation_probability(el->data);
|
||||||
|
if (el->stacked_custom_prob > 100) {
|
||||||
|
|
||||||
FATAL(
|
FATAL(
|
||||||
"The probability returned by afl_custom_havoc_mutation_propability "
|
"The probability returned by afl_custom_havoc_mutation_propability "
|
||||||
@ -1820,6 +1834,10 @@ havoc_stage:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* We essentially just do several thousand runs (depending on perf_score)
|
/* We essentially just do several thousand runs (depending on perf_score)
|
||||||
where we take the input file and make random stacked tweaks. */
|
where we take the input file and make random stacked tweaks. */
|
||||||
|
|
||||||
@ -1831,11 +1849,15 @@ havoc_stage:
|
|||||||
|
|
||||||
for (i = 0; i < use_stacking; ++i) {
|
for (i = 0; i < use_stacking; ++i) {
|
||||||
|
|
||||||
if (stacked_custom && rand_below(afl, 100) < stacked_custom_prob) {
|
if (afl->custom_mutators_count) {
|
||||||
|
|
||||||
|
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
|
||||||
|
|
||||||
|
if (el->stacked_custom && rand_below(afl, 100) < el->stacked_custom_prob) {
|
||||||
|
|
||||||
u8 * custom_havoc_buf = NULL;
|
u8 * custom_havoc_buf = NULL;
|
||||||
size_t new_len = afl->mutator->afl_custom_havoc_mutation(
|
size_t new_len = el->afl_custom_havoc_mutation(
|
||||||
afl->mutator->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE);
|
el->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE);
|
||||||
if (unlikely(!custom_havoc_buf)) {
|
if (unlikely(!custom_havoc_buf)) {
|
||||||
|
|
||||||
FATAL("Error in custom_havoc (return %zd)", new_len);
|
FATAL("Error in custom_havoc (return %zd)", new_len);
|
||||||
@ -1856,6 +1878,9 @@ havoc_stage:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
switch (rand_below(
|
switch (rand_below(
|
||||||
afl, 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0))) {
|
afl, 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0))) {
|
||||||
|
|
||||||
|
@ -295,88 +295,94 @@ 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));
|
struct custom_mutator * mutator;
|
||||||
afl->mutator->pre_save_buf = NULL;
|
|
||||||
afl->mutator->pre_save_size = 0;
|
|
||||||
|
|
||||||
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);
|
ACTF("Loading Python mutator library from '%s'...", module_name);
|
||||||
|
|
||||||
py_mutator_t *py_mutator;
|
py_mutator_t *py_mutator;
|
||||||
py_mutator = init_py_module(afl, module_name);
|
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."); }
|
if (!py_mutator) { FATAL("Failed to load python mutator."); }
|
||||||
|
|
||||||
PyObject **py_functions = py_mutator->py_functions;
|
PyObject **py_functions = py_mutator->py_functions;
|
||||||
|
|
||||||
if (py_functions[PY_FUNC_INIT]) {
|
if (py_functions[PY_FUNC_INIT]) {
|
||||||
|
|
||||||
afl->mutator->afl_custom_init = unsupported;
|
mutator->afl_custom_init = unsupported;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (py_functions[PY_FUNC_DEINIT]) {
|
if (py_functions[PY_FUNC_DEINIT]) {
|
||||||
|
|
||||||
afl->mutator->afl_custom_deinit = deinit_py;
|
mutator->afl_custom_deinit = deinit_py;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator
|
/* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator
|
||||||
is quite different from the custom 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]) {
|
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]) {
|
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]) {
|
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]) {
|
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]) {
|
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;
|
havoc_mutation_probability_py;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (py_functions[PY_FUNC_QUEUE_GET]) {
|
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]) {
|
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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
OKF("Python mutator '%s' installed successfully.", module_name);
|
OKF("Python mutator '%s' installed successfully.", module_name);
|
||||||
|
|
||||||
/* Initialize the custom mutator */
|
/* Initialize the custom mutator */
|
||||||
init_py(afl, py_mutator, rand_below(afl, 0xFFFFFFFF));
|
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) {
|
size_t pre_save_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf) {
|
||||||
|
@ -140,15 +140,20 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
|
|||||||
|
|
||||||
afl->last_path_time = get_cur_time();
|
afl->last_path_time = get_cur_time();
|
||||||
|
|
||||||
if (afl->mutator && afl->mutator->afl_custom_queue_new_entry) {
|
if (afl->custom_mutators_count) {
|
||||||
|
|
||||||
|
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
|
||||||
|
|
||||||
|
if ( el->afl_custom_queue_new_entry) {
|
||||||
u8 *fname_orig = NULL;
|
u8 *fname_orig = NULL;
|
||||||
|
|
||||||
/* At the initialization stage, queue_cur is NULL */
|
/* At the initialization stage, queue_cur is NULL */
|
||||||
if (afl->queue_cur) { fname_orig = afl->queue_cur->fname; }
|
if (afl->queue_cur) fname_orig = afl->queue_cur->fname;
|
||||||
|
|
||||||
afl->mutator->afl_custom_queue_new_entry(afl->mutator->data, fname,
|
el->afl_custom_queue_new_entry(el->data, fname, fname_orig);
|
||||||
fname_orig);
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,22 +89,42 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (unlikely(afl->mutator && afl->mutator->afl_custom_pre_save)) {
|
if (unlikely(afl->custom_mutators_count)) {
|
||||||
|
|
||||||
u8 *new_buf = NULL;
|
u8 *new_buf = NULL;
|
||||||
|
ssize_t new_size = len;
|
||||||
|
void * new_mem = mem;
|
||||||
|
|
||||||
size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem,
|
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
|
||||||
len, &new_buf);
|
|
||||||
|
|
||||||
if (unlikely(!new_buf)) {
|
if (el->afl_custom_pre_save) {
|
||||||
|
new_size = el->afl_custom_pre_save(
|
||||||
FATAL("Custom_pre_save failed (ret: %lu)", (long unsigned)new_size);
|
el->data, new_mem, new_size, &new_buf
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new_mem = 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. */
|
/* everything as planned. use the new data. */
|
||||||
afl_fsrv_write_to_testcase(&afl->fsrv, new_buf, new_size);
|
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 {
|
} else {
|
||||||
|
|
||||||
/* boring uncustom. */
|
/* boring uncustom. */
|
||||||
@ -513,9 +533,22 @@ void sync_fuzzers(afl_state_t *afl) {
|
|||||||
u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
||||||
|
|
||||||
/* Custom mutator trimmer */
|
/* Custom mutator trimmer */
|
||||||
if (afl->mutator && afl->mutator->afl_custom_trim) {
|
if (afl->custom_mutators_count) {
|
||||||
|
|
||||||
return trim_case_custom(afl, q, in_buf);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
if (custom_trimmed) return trimmed_case;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,7 +792,7 @@ void show_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afl->mutator) {
|
if (afl->custom_mutators_count) {
|
||||||
|
|
||||||
sprintf(tmp, "%s/%s",
|
sprintf(tmp, "%s/%s",
|
||||||
u_stringify_int(IB(0), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
|
u_stringify_int(IB(0), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
|
||||||
|
@ -1077,7 +1077,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
setup_dirs_fds(afl);
|
setup_dirs_fds(afl);
|
||||||
|
|
||||||
setup_custom_mutator(afl);
|
setup_custom_mutators(afl);
|
||||||
|
|
||||||
setup_cmdline_file(afl, argv + optind);
|
setup_cmdline_file(afl, argv + optind);
|
||||||
|
|
||||||
@ -1365,7 +1365,7 @@ stop_fuzzing:
|
|||||||
fclose(afl->fsrv.plot_file);
|
fclose(afl->fsrv.plot_file);
|
||||||
destroy_queue(afl);
|
destroy_queue(afl);
|
||||||
destroy_extras(afl);
|
destroy_extras(afl);
|
||||||
destroy_custom_mutator(afl);
|
destroy_custom_mutators(afl);
|
||||||
afl_shm_deinit(&afl->shm);
|
afl_shm_deinit(&afl->shm);
|
||||||
afl_fsrv_deinit(&afl->fsrv);
|
afl_fsrv_deinit(&afl->fsrv);
|
||||||
if (afl->orig_cmdline) { ck_free(afl->orig_cmdline); }
|
if (afl->orig_cmdline) { ck_free(afl->orig_cmdline); }
|
||||||
|
24
test/test-multiple-mutators.c
Normal file
24
test/test-multiple-mutators.c
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* Test-Case for multiple custom mutators in C
|
||||||
|
* Reference:
|
||||||
|
* https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/blob/master/4_libprotobuf_aflpp_custom_mutator/vuln.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int main(int argc, char ** argv)
|
||||||
|
{
|
||||||
|
int a=0;
|
||||||
|
char s[16];
|
||||||
|
memset(s, 0, 16);
|
||||||
|
read(0, s, 0xa0);
|
||||||
|
|
||||||
|
if ( s[17] != '\x00') {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
32
test/test.sh
32
test/test.sh
@ -949,7 +949,7 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
|
|||||||
}
|
}
|
||||||
test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUSTOM_MUTATOR_PATH}/example.py && {
|
test -e test-custom-mutator.c -a -e ${CUSTOM_MUTATOR_PATH}/example.c -a -e ${CUSTOM_MUTATOR_PATH}/example.py && {
|
||||||
unset AFL_CC
|
unset AFL_CC
|
||||||
# Compile the vulnerable program
|
# Compile the vulnerable program for single mutator
|
||||||
test -e ../afl-clang-fast && {
|
test -e ../afl-clang-fast && {
|
||||||
../afl-clang-fast -o test-custom-mutator test-custom-mutator.c > /dev/null 2>&1
|
../afl-clang-fast -o test-custom-mutator test-custom-mutator.c > /dev/null 2>&1
|
||||||
} || {
|
} || {
|
||||||
@ -959,6 +959,16 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
|
|||||||
../afl-gcc -o test-custom-mutator test-custom-mutator.c > /dev/null 2>&1
|
../afl-gcc -o test-custom-mutator test-custom-mutator.c > /dev/null 2>&1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# Compile the vulnerable program for multiple mutators
|
||||||
|
test -e ../afl-clang-fast && {
|
||||||
|
../afl-clang-fast -o test-multiple-mutators test-multiple-mutators.c > /dev/null 2>&1
|
||||||
|
} || {
|
||||||
|
test -e ../afl-gcc-fast && {
|
||||||
|
../afl-gcc-fast -o test-multiple-mutators test-multiple-mutators.c > /dev/null 2>&1
|
||||||
|
} || {
|
||||||
|
../afl-gcc -o test-multiple-mutators test-multiple-mutators.c > /dev/null 2>&1
|
||||||
|
}
|
||||||
|
}
|
||||||
# Compile the custom mutator
|
# Compile the custom mutator
|
||||||
make -C ../examples/custom_mutators libexamplemutator.so > /dev/null 2>&1
|
make -C ../examples/custom_mutators libexamplemutator.so > /dev/null 2>&1
|
||||||
test -e test-custom-mutator -a -e ${CUSTOM_MUTATOR_PATH}/libexamplemutator.so && {
|
test -e test-custom-mutator -a -e ${CUSTOM_MUTATOR_PATH}/libexamplemutator.so && {
|
||||||
@ -986,6 +996,25 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
|
|||||||
# Clean
|
# Clean
|
||||||
rm -rf out errors
|
rm -rf out errors
|
||||||
|
|
||||||
|
#Run afl-fuzz w/ multiple C mutators
|
||||||
|
$ECHO "$GREY[*] running afl-fuzz with multiple custom C mutators, this will take approx 20 seconds"
|
||||||
|
{
|
||||||
|
AFL_CUSTOM_MUTATOR_LIBRARY="${CUSTOM_MUTATOR_PATH}/libexamplemutator.so;${CUSTOM_MUTATOR_PATH}/libexamplemutator.so" ../afl-fuzz -V20 -m ${MEM_LIMIT} -i in -o out -- ./test-multiple-mutators >>errors 2>&1
|
||||||
|
} >>errors 2>&1
|
||||||
|
|
||||||
|
test -n "$( ls out/crashes/id:000000* 2>/dev/null )" && { # TODO: update here
|
||||||
|
$ECHO "$GREEN[+] afl-fuzz is working correctly with multiple C mutators"
|
||||||
|
} || {
|
||||||
|
echo CUT------------------------------------------------------------------CUT
|
||||||
|
cat errors
|
||||||
|
echo CUT------------------------------------------------------------------CUT
|
||||||
|
$ECHO "$RED[!] afl-fuzz is not working correctly with multiple C mutators"
|
||||||
|
CODE=1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clean
|
||||||
|
rm -rf out errors
|
||||||
|
|
||||||
# Run afl-fuzz w/ the Python mutator
|
# Run afl-fuzz w/ the Python mutator
|
||||||
$ECHO "$GREY[*] running afl-fuzz for the Python mutator, this will take approx 10 seconds"
|
$ECHO "$GREY[*] running afl-fuzz for the Python mutator, this will take approx 10 seconds"
|
||||||
{
|
{
|
||||||
@ -1021,6 +1050,7 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
|
|||||||
|
|
||||||
make -C ../examples/custom_mutators clean > /dev/null 2>&1
|
make -C ../examples/custom_mutators clean > /dev/null 2>&1
|
||||||
rm -f test-custom-mutator
|
rm -f test-custom-mutator
|
||||||
|
rm -f test-custom-mutators
|
||||||
} || {
|
} || {
|
||||||
$ECHO "$YELLOW[-] no custom mutators in $CUSTOM_MUTATOR_PATH, cannot test"
|
$ECHO "$YELLOW[-] no custom mutators in $CUSTOM_MUTATOR_PATH, cannot test"
|
||||||
INCOMPLETE=1
|
INCOMPLETE=1
|
||||||
|
Reference in New Issue
Block a user