1 #include <stdio.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <string.h>
5 
6 #include "custom_mutator_helpers.h"
7 #include "mangle.h"
8 
9 #define NUMBER_OF_MUTATIONS 5
10 
11 uint8_t *         queue_input;
12 size_t            queue_input_size;
13 afl_state_t *     afl_struct;
14 run_t             run;
15 honggfuzz_t       global;
16 struct _dynfile_t dynfile;
17 
18 typedef struct my_mutator {
19 
20   afl_state_t *afl;
21   run_t *      run;
22   u8 *         mutator_buf;
23   unsigned int seed;
24   unsigned int extras_cnt, a_extras_cnt;
25 
26 } my_mutator_t;
27 
afl_custom_init(afl_state_t * afl,unsigned int seed)28 my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
29 
30   my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
31   if (!data) {
32 
33     perror("afl_custom_init alloc");
34     return NULL;
35 
36   }
37 
38   if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) {
39 
40     free(data);
41     perror("mutator_buf alloc");
42     return NULL;
43 
44   }
45 
46   run.dynfile = &dynfile;
47   run.global = &global;
48   data->afl = afl;
49   data->seed = seed;
50   data->run = &run;
51   afl_struct = afl;
52 
53   run.global->mutate.maxInputSz = MAX_FILE;
54   run.global->mutate.mutationsPerRun = NUMBER_OF_MUTATIONS;
55   run.mutationsPerRun = NUMBER_OF_MUTATIONS;
56   run.global->timing.lastCovUpdate = 6;
57 
58   // global->feedback.cmpFeedback
59   // global->feedback.cmpFeedbackMap
60 
61   return data;
62 
63 }
64 
65 /* When a new queue entry is added we check if there are new dictionary
66    entries to add to honggfuzz structure */
67 
afl_custom_queue_new_entry(my_mutator_t * data,const uint8_t * filename_new_queue,const uint8_t * filename_orig_queue)68 void afl_custom_queue_new_entry(my_mutator_t * data,
69                                 const uint8_t *filename_new_queue,
70                                 const uint8_t *filename_orig_queue) {
71 
72   if (run.global->mutate.dictionaryCnt >= 1024) return;
73 
74   while (data->extras_cnt < data->afl->extras_cnt &&
75          run.global->mutate.dictionaryCnt < 1024) {
76 
77     memcpy(run.global->mutate.dictionary[run.global->mutate.dictionaryCnt].val,
78            data->afl->extras[data->extras_cnt].data,
79            data->afl->extras[data->extras_cnt].len);
80     run.global->mutate.dictionary[run.global->mutate.dictionaryCnt].len =
81         data->afl->extras[data->extras_cnt].len;
82     run.global->mutate.dictionaryCnt++;
83     data->extras_cnt++;
84 
85   }
86 
87   while (data->a_extras_cnt < data->afl->a_extras_cnt &&
88          run.global->mutate.dictionaryCnt < 1024) {
89 
90     memcpy(run.global->mutate.dictionary[run.global->mutate.dictionaryCnt].val,
91            data->afl->a_extras[data->a_extras_cnt].data,
92            data->afl->a_extras[data->a_extras_cnt].len);
93     run.global->mutate.dictionary[run.global->mutate.dictionaryCnt].len =
94         data->afl->a_extras[data->a_extras_cnt].len;
95     run.global->mutate.dictionaryCnt++;
96     data->a_extras_cnt++;
97 
98   }
99 
100 }
101 
102 /* we could set only_printable if is_ascii is set ... let's see
103 uint8_t afl_custom_queue_get(void *data, const uint8_t *filename) {
104 
105   //run.global->cfg.only_printable = ...
106 
107 }
108 
109 */
110 
111 /* here we run the honggfuzz mutator, which is really good */
112 
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)113 size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
114                        u8 **out_buf, uint8_t *add_buf, size_t add_buf_size,
115                        size_t max_size) {
116 
117   /* set everything up, costly ... :( */
118   memcpy(data->mutator_buf, buf, buf_size);
119   queue_input = data->mutator_buf;
120   run.dynfile->data = data->mutator_buf;
121   queue_input_size = buf_size;
122   run.dynfile->size = buf_size;
123   *out_buf = data->mutator_buf;
124 
125   /* the mutation */
126   mangle_mangleContent(&run, NUMBER_OF_MUTATIONS);
127 
128   /* return size of mutated data */
129   return run.dynfile->size;
130 
131 }
132 
133 /**
134  * Deinitialize everything
135  *
136  * @param data The data ptr from afl_custom_init
137  */
afl_custom_deinit(my_mutator_t * data)138 void afl_custom_deinit(my_mutator_t *data) {
139 
140   free(data->mutator_buf);
141   free(data);
142 
143 }
144 
145