#include #include #include #include //#include "config.h" //#include "debug.h" #include "afl-fuzz.h" #ifdef INTROSPECTION const char *introspection_ptr; #endif afl_state_t *afl_struct; extern "C" size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize); extern "C" int LLVMFuzzerRunDriver(int *argc, char ***argv, int (*UserCb)(const uint8_t *Data, size_t Size)); extern "C" void LLVMFuzzerMyInit(int (*UserCb)(const uint8_t *Data, size_t Size), unsigned int Seed); typedef struct my_mutator { afl_state_t *afl; u8 * mutator_buf; unsigned int seed; unsigned int extras_cnt, a_extras_cnt; } my_mutator_t; extern "C" int dummy(const uint8_t *Data, size_t Size) { (void)(Data); (void)(Size); fprintf(stderr, "dummy() called\n"); return 0; } extern "C" my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { my_mutator_t *data = (my_mutator_t *)calloc(1, sizeof(my_mutator_t)); if (!data) { perror("afl_custom_init alloc"); return NULL; } if ((data->mutator_buf = (u8 *)malloc(MAX_FILE)) == NULL) { free(data); perror("mutator_buf alloc"); return NULL; } data->afl = afl; data->seed = seed; afl_struct = afl; /* char **argv; argv = (char**)malloc(sizeof(size_t) * 2); argv[0] = (char*)"foo"; argv[1] = NULL; int eins = 1; LLVMFuzzerRunDriver(&eins, &argv, dummy); */ LLVMFuzzerMyInit(dummy, seed); return data; } /* When a new queue entry is added we check if there are new dictionary entries to add to honggfuzz structure */ #if 0 extern "C" void afl_custom_queue_new_entry(my_mutator_t * data, const uint8_t *filename_new_queue, const uint8_t *filename_orig_queue) { while (data->extras_cnt < afl_struct->extras_cnt) { /* memcpy(run.global->mutate.dictionary[run.global->mutate.dictionaryCnt].val, afl_struct->extras[data->extras_cnt].data, afl_struct->extras[data->extras_cnt].len); run.global->mutate.dictionary[run.global->mutate.dictionaryCnt].len = afl_struct->extras[data->extras_cnt].len; run.global->mutate.dictionaryCnt++; */ data->extras_cnt++; } while (data->a_extras_cnt < afl_struct->a_extras_cnt) { /* memcpy(run.global->mutate.dictionary[run.global->mutate.dictionaryCnt].val, afl_struct->a_extras[data->a_extras_cnt].data, afl_struct->a_extras[data->a_extras_cnt].len); run.global->mutate.dictionary[run.global->mutate.dictionaryCnt].len = afl_struct->a_extras[data->a_extras_cnt].len; run.global->mutate.dictionaryCnt++; data->a_extras_cnt++; */ } } #endif /* we could set only_printable if is_ascii is set ... let's see uint8_t afl_custom_queue_get(void *data, const uint8_t *filename) { //run.global->cfg.only_printable = ... } */ /* here we run the honggfuzz mutator, which is really good */ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, u8 **out_buf, uint8_t *add_buf, size_t add_buf_size, size_t max_size) { memcpy(data->mutator_buf, buf, buf_size); size_t ret = LLVMFuzzerMutate(data->mutator_buf, buf_size, max_size); /* return size of mutated data */ *out_buf = data->mutator_buf; return ret; } #ifdef INTROSPECTION extern "C" const char* afl_custom_introspection(my_mutator_t *data) { return introspection_ptr; } #endif /** * Deinitialize everything * * @param data The data ptr from afl_custom_init */ extern "C" void afl_custom_deinit(my_mutator_t *data) { free(data->mutator_buf); free(data); }