custom mutator code enhancements and code-format

This commit is contained in:
van Hauser
2020-05-09 11:35:54 +02:00
parent cf9238e09d
commit fa84e52af0
7 changed files with 98 additions and 89 deletions

View File

@ -605,9 +605,9 @@ typedef struct afl_state {
u8 * in_scratch_buf; u8 * in_scratch_buf;
size_t in_scratch_size; size_t in_scratch_size;
u8 * ex_buf; u8 * ex_buf;
size_t ex_size; size_t ex_size;
u32 custom_mutators_count; u32 custom_mutators_count;
list_t custom_mutator_list; list_t custom_mutator_list;
@ -623,8 +623,7 @@ 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, u8 stacked_custom_prob, stacked_custom;
stacked_custom;
void *data; /* custom mutator data ptr */ void *data; /* custom mutator data ptr */
@ -815,13 +814,14 @@ void read_afl_environment(afl_state_t *, char **);
/* Custom mutators */ /* Custom mutators */
void setup_custom_mutators(afl_state_t *); void setup_custom_mutators(afl_state_t *);
void destroy_custom_mutators(afl_state_t *); void destroy_custom_mutators(afl_state_t *);
u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf, struct custom_mutator * mutator); 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
struct custom_mutator * 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 **);
s32 init_trim_py(void *, u8 *, size_t); s32 init_trim_py(void *, u8 *, size_t);

View File

@ -28,15 +28,15 @@
struct custom_mutator *load_custom_mutator(afl_state_t *, const char *); struct custom_mutator *load_custom_mutator(afl_state_t *, const char *);
#ifdef USE_PYTHON #ifdef USE_PYTHON
struct custom_mutator * load_custom_mutator_py(afl_state_t *, char *); struct custom_mutator *load_custom_mutator_py(afl_state_t *, char *);
#endif #endif
void setup_custom_mutators(afl_state_t *afl) { void setup_custom_mutators(afl_state_t *afl) {
/* Try mutator library first */ /* Try mutator library first */
struct custom_mutator * mutator; struct custom_mutator *mutator;
u8 * fn = getenv("AFL_CUSTOM_MUTATOR_LIBRARY"); u8 * fn = afl->afl_env.afl_custom_mutator_library;
u32 prev_mutator_count = 0; u32 prev_mutator_count = 0;
if (fn) { if (fn) {
@ -44,9 +44,9 @@ void setup_custom_mutators(afl_state_t *afl) {
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/redqueen/...).");
u8 *fn_token = (u8 *)strsep((char **)&fn, ";"); u8 *fn_token = (u8 *)strsep((char **)&fn, ";:,");
if (likely(!fn_token)) { if (likely(!fn_token)) {
@ -58,14 +58,22 @@ void setup_custom_mutators(afl_state_t *afl) {
while (fn_token) { while (fn_token) {
prev_mutator_count = afl->custom_mutators_count; if (*fn_token) { // strsep can be empty if ";;"
mutator = load_custom_mutator(afl, fn_token);
list_append(&afl->custom_mutator_list, mutator); if (afl->not_on_tty && afl->debug)
afl->custom_mutators_count++; SAYF("[Custom] Processing: %s\n", fn_token);
if (prev_mutator_count > afl->custom_mutators_count) FATAL("Maximum Custom Mutator count reached."); prev_mutator_count = afl->custom_mutators_count;
fn_token = (u8 *)strsep((char **)&fn, ";"); 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, ";:,");
}
} }
} }
} }
@ -85,7 +93,7 @@ void setup_custom_mutators(afl_state_t *afl) {
} }
struct custom_mutator * mutator = load_custom_mutator_py(afl, module_name); struct custom_mutator *mutator = load_custom_mutator_py(afl, module_name);
afl->custom_mutators_count++; afl->custom_mutators_count++;
list_append(&afl->custom_mutator_list, mutator); list_append(&afl->custom_mutator_list, mutator);
@ -113,14 +121,16 @@ void destroy_custom_mutators(afl_state_t *afl) {
if (el->dh) dlclose(el->dh); if (el->dh) dlclose(el->dh);
if (el->pre_save_buf) { if (el->pre_save_buf) {
ck_free(el->pre_save_buf); ck_free(el->pre_save_buf);
el->pre_save_buf = NULL; el->pre_save_buf = NULL;
el->pre_save_size = 0; el->pre_save_size = 0;
} }
ck_free(el); ck_free(el);
} ); });
} }
@ -212,17 +222,18 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
/* Initialize the custom mutator */ /* Initialize the custom mutator */
if (mutator->afl_custom_init) if (mutator->afl_custom_init)
mutator->data = mutator->data = mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF));
mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF));
mutator->stacked_custom = (mutator && mutator->afl_custom_havoc_mutation); mutator->stacked_custom = (mutator && mutator->afl_custom_havoc_mutation);
mutator->stacked_custom_prob = 6; // like one of the default mutations in havoc mutator->stacked_custom_prob =
6; // like one of the default mutations in havoc
return mutator; return mutator;
} }
u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, struct custom_mutator *mutator) { 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;
@ -235,8 +246,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, struct
/* 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 = mutator->afl_custom_init_trim(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);
@ -299,8 +309,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, struct
} }
/* Tell the custom mutator that the trimming was successful */ /* Tell the custom mutator that the trimming was successful */
afl->stage_cur = afl->stage_cur = mutator->afl_custom_post_trim(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) {
@ -312,8 +321,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, struct
} else { } else {
/* Tell the custom mutator that the trimming was unsuccessful */ /* Tell the custom mutator that the trimming was unsuccessful */
afl->stage_cur = afl->stage_cur = mutator->afl_custom_post_trim(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);

View File

@ -384,17 +384,21 @@ u8 fuzz_one_original(afl_state_t *afl) {
#else #else
if (unlikely(afl->custom_mutators_count )) { 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. */
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
if (el->afl_custom_queue_get && !el->afl_custom_queue_get(el->data, 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)) {
@ -1660,13 +1664,14 @@ 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, { LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
if ( el->afl_custom_fuzz ) { if (el->afl_custom_fuzz) {
has_custom_fuzz = true; 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;
u32 tid; u32 tid;
@ -1698,7 +1703,7 @@ custom_mutator_stage:
/* Make sure that the target has a reasonable length. */ /* Make sure that the target has a reasonable length. */
while (target && (target->len < 2 || target == afl->queue_cur) && while (target && (target->len < 2 || target == afl->queue_cur) &&
afl->queued_paths > 1) { afl->queued_paths > 1) {
target = target->next; target = target->next;
++afl->splicing_with; ++afl->splicing_with;
@ -1717,9 +1722,9 @@ custom_mutator_stage:
u8 *mutated_buf = NULL; u8 *mutated_buf = NULL;
size_t mutated_size = el->afl_custom_fuzz( size_t mutated_size =
el->data, out_buf, len, &mutated_buf, new_buf, target->len, el->afl_custom_fuzz(el->data, out_buf, len, &mutated_buf, new_buf,
max_seed_size); target->len, max_seed_size);
if (unlikely(!mutated_buf)) { if (unlikely(!mutated_buf)) {
@ -1754,15 +1759,15 @@ custom_mutator_stage:
} }
/* `(afl->)out_buf` may have been changed by the call to custom_fuzz */ /* `(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. */ /* TODO: Only do this when `mutated_buf` == `out_buf`? Branch vs Memcpy.
*/
memcpy(out_buf, in_buf, len); memcpy(out_buf, in_buf, len);
} }
} }
});
} );
if (!has_custom_fuzz) goto havoc_stage; if (!has_custom_fuzz) goto havoc_stage;
@ -1827,14 +1832,15 @@ havoc_stage:
if (el->stacked_custom_prob > 100) { 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 "
"has to be in the range 0-100."); "has to be in the range 0-100.");
} }
} }
} ); });
} }
@ -1850,10 +1856,11 @@ havoc_stage:
for (i = 0; i < use_stacking; ++i) { for (i = 0; i < use_stacking; ++i) {
if (afl->custom_mutators_count) { if (afl->custom_mutators_count) {
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
if (el->stacked_custom && rand_below(afl, 100) < el->stacked_custom_prob) { 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 = el->afl_custom_havoc_mutation( size_t new_len = el->afl_custom_havoc_mutation(
@ -1877,8 +1884,9 @@ havoc_stage:
} }
} }
} ); });
} }
switch (rand_below( switch (rand_below(

View File

@ -295,9 +295,10 @@ void deinit_py(void *py_mutator) {
} }
struct custom_mutator * 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) {
struct custom_mutator * mutator; struct custom_mutator *mutator;
mutator = ck_alloc(sizeof(struct custom_mutator)); mutator = ck_alloc(sizeof(struct custom_mutator));
mutator->pre_save_buf = NULL; mutator->pre_save_buf = NULL;
@ -313,17 +314,9 @@ struct custom_mutator * load_custom_mutator_py(afl_state_t *afl, char *module_na
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]) { mutator->afl_custom_init = unsupported; }
mutator->afl_custom_init = unsupported; if (py_functions[PY_FUNC_DEINIT]) { mutator->afl_custom_deinit = deinit_py; }
}
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 /* "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. */
@ -374,8 +367,6 @@ struct custom_mutator * load_custom_mutator_py(afl_state_t *afl, char *module_na
} }
OKF("Python mutator '%s' installed successfully.", module_name); OKF("Python mutator '%s' installed successfully.", module_name);
/* Initialize the custom mutator */ /* Initialize the custom mutator */

View File

@ -144,16 +144,18 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
if ( el->afl_custom_queue_new_entry) { 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;
el->afl_custom_queue_new_entry(el->data, fname, fname_orig); el->afl_custom_queue_new_entry(el->data, fname, fname_orig);
} }
} ); });
} }

View File

@ -91,22 +91,22 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
if (unlikely(afl->custom_mutators_count)) { if (unlikely(afl->custom_mutators_count)) {
u8 *new_buf = NULL; u8 * new_buf = NULL;
ssize_t new_size = len; ssize_t new_size = len;
void * new_mem = mem; void * new_mem = mem;
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
if (el->afl_custom_pre_save) { if (el->afl_custom_pre_save) {
new_size = el->afl_custom_pre_save(
el->data, new_mem, new_size, &new_buf new_size =
); el->afl_custom_pre_save(el->data, new_mem, new_size, &new_buf);
} }
new_mem = new_buf; new_mem = new_buf;
} ); });
if (unlikely(!new_buf && (new_size <= 0))) { if (unlikely(!new_buf && (new_size <= 0))) {
@ -124,7 +124,6 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
} }
} else { } else {
/* boring uncustom. */ /* boring uncustom. */
@ -535,21 +534,22 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
/* Custom mutator trimmer */ /* Custom mutator trimmer */
if (afl->custom_mutators_count) { if (afl->custom_mutators_count) {
u8 trimmed_case = 0; u8 trimmed_case = 0;
bool custom_trimmed = false; bool custom_trimmed = false;
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
if (el->afl_custom_trim) { if (el->afl_custom_trim) {
trimmed_case = trim_case_custom(afl, q, in_buf, el); trimmed_case = trim_case_custom(afl, q, in_buf, el);
custom_trimmed = true; custom_trimmed = true;
} }
} ); });
if (custom_trimmed) return trimmed_case; if (custom_trimmed) return trimmed_case;
} }
u8 needs_write = 0, fault = 0; u8 needs_write = 0, fault = 0;

View File

@ -9,16 +9,16 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
int main(int argc, char ** argv) int main(int argc, char **argv) {
{
int a=0;
char s[16];
memset(s, 0, 16);
read(0, s, 0xa0);
if ( s[17] != '\x00') { int a = 0;
abort(); char s[16];
} memset(s, 0, 16);
read(0, s, 0xa0);
if (s[17] != '\x00') { abort(); }
return 0;
return 0;
} }