You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
248 lines
5.8 KiB
248 lines
5.8 KiB
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include "afl-fuzz.h"
|
|
#include "gramfuzz.h"
|
|
|
|
Array *performRandomMutation(state *pda, Array *input) {
|
|
|
|
terminal *term_ptr;
|
|
// terminal *prev_ptr;
|
|
Array *mutated;
|
|
Array *sliced;
|
|
|
|
// Get offset at which to generate new input and slice it
|
|
int idx = rand_below(global_afl, input->used);
|
|
sliced = slice(input, idx);
|
|
// print_repr(sliced, "Slice");
|
|
|
|
// prev_ptr = & input->start[idx - 1];
|
|
// printf("\nState:%s Symbol:%s", prev_ptr->state, prev_ptr->symbol);
|
|
// Reset current state to that of the slice's last member
|
|
term_ptr = &input->start[idx];
|
|
curr_state = term_ptr->state;
|
|
// printf("\nState:%s Symbol:%s", curr_state, term_ptr->symbol);
|
|
|
|
// Set the next available cell to the one adjacent to this chosen point
|
|
mutated = gen_input(pda, sliced);
|
|
return mutated;
|
|
|
|
}
|
|
|
|
// Tries to perform splice operation between two automaton walks
|
|
UT_icd intpair_icd = {sizeof(intpair_t), NULL, NULL, NULL};
|
|
|
|
Array *performSpliceOne(Array *originput, IdxMap_new *statemap_orig,
|
|
Array *splicecand) {
|
|
|
|
UT_array * stateptr, *pairs;
|
|
intpair_t ip;
|
|
intpair_t *cand;
|
|
|
|
terminal *term_ptr;
|
|
Array * prefix;
|
|
int state;
|
|
|
|
// Initialize the dynamic holding the splice indice pairs
|
|
utarray_new(pairs, &intpair_icd);
|
|
// print_repr(originput, "Orig");
|
|
// print_repr(splicecand, "SpliceCand");
|
|
|
|
// Iterate through the splice candidate identifying potential splice points
|
|
// and pushing pair (orig_idx, splice_idx) to a dynamic array
|
|
for (int x = 0; x < splicecand->used; x++) {
|
|
|
|
term_ptr = &splicecand->start[x];
|
|
stateptr = statemap_orig[term_ptr->state].nums;
|
|
int length = utarray_len(stateptr);
|
|
if (length) {
|
|
|
|
int *splice_idx = (int *)utarray_eltptr(stateptr, rand_below(global_afl, length));
|
|
ip.orig_idx = *splice_idx;
|
|
ip.splice_idx = x;
|
|
utarray_push_back(pairs, &ip);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Pick a random pair
|
|
int length = utarray_len(pairs);
|
|
cand = (intpair_t *)utarray_eltptr(pairs, rand_below(global_afl, length));
|
|
// printf("\n Orig_idx:%d Splice_idx:%d", cand->orig_idx, cand->splice_idx);
|
|
|
|
// Perform the splicing
|
|
prefix = slice(originput, cand->orig_idx);
|
|
Array *spliced = spliceGF(prefix, splicecand, cand->splice_idx);
|
|
// print_repr(spliced, "Spliced");
|
|
//
|
|
utarray_free(pairs);
|
|
|
|
return spliced;
|
|
|
|
}
|
|
|
|
UT_array **get_dupes(Array *input, int *recur_len) {
|
|
|
|
// Variables related to finding duplicates
|
|
int offset = 0;
|
|
int state;
|
|
terminal * term_ptr;
|
|
IdxMap_new *idxMapPtr;
|
|
UT_array ** recurIdx;
|
|
|
|
// Declare the Recursive Map Table
|
|
IdxMap_new *idxmapStart =
|
|
(IdxMap_new *)malloc(sizeof(IdxMap_new) * numstates);
|
|
//
|
|
// UT_array *(recurIdx[numstates]);
|
|
recurIdx = malloc(sizeof(UT_array *) * numstates);
|
|
|
|
for (int x = 0; x < numstates; x++) {
|
|
|
|
idxMapPtr = &idxmapStart[x];
|
|
utarray_new(idxMapPtr->nums, &ut_int_icd);
|
|
|
|
}
|
|
|
|
// Obtain frequency distribution of states
|
|
while (offset < input->used) {
|
|
|
|
term_ptr = &input->start[offset];
|
|
state = term_ptr->state;
|
|
// int num = atoi(state + 1);
|
|
idxMapPtr = &idxmapStart[state];
|
|
utarray_push_back(idxMapPtr->nums, &offset);
|
|
offset += 1;
|
|
|
|
}
|
|
|
|
// Retrieve the duplicated states
|
|
offset = 0;
|
|
while (offset < numstates) {
|
|
|
|
idxMapPtr = &idxmapStart[offset];
|
|
int length = utarray_len(idxMapPtr->nums);
|
|
if (length >= 2) {
|
|
|
|
recurIdx[*recur_len] = idxMapPtr->nums;
|
|
*recur_len += 1;
|
|
|
|
}
|
|
|
|
// else {
|
|
|
|
// utarray_free(idxMapPtr->nums);
|
|
// }
|
|
offset += 1;
|
|
|
|
}
|
|
|
|
if (*recur_len) {
|
|
|
|
// Declare the return struct
|
|
// We use this struct so that we save the reference to IdxMap_new and free
|
|
// it after we have used it in doMult
|
|
// Get_Dupes_Ret* getdupesret =
|
|
// (Get_Dupes_Ret*)malloc(sizeof(Get_Dupes_Ret));
|
|
return recurIdx;
|
|
// getdupesret->idxmap = idxmapStart;
|
|
// getdupesret->recurIdx = recurIdx;
|
|
// return getdupesret;
|
|
|
|
} else {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Array *doMult(Array *input, UT_array **recur, int recurlen) {
|
|
|
|
int offset = 0;
|
|
int idx = rand_below(global_afl, recurlen);
|
|
UT_array *recurMap = recur[idx];
|
|
UT_array *recurPtr;
|
|
Array * prefix;
|
|
Array * postfix;
|
|
Array * feature;
|
|
|
|
// Choose two indices to get the recursive feature
|
|
int recurIndices = utarray_len(recurMap);
|
|
int firstIdx = 0;
|
|
int secondIdx = 0;
|
|
getTwoIndices(recurMap, recurIndices, &firstIdx, &secondIdx);
|
|
|
|
// Perform the recursive mut
|
|
// print_repr(input, "Orig");
|
|
prefix = slice(input, firstIdx);
|
|
// print_repr(prefix, "Prefix");
|
|
if (firstIdx < secondIdx) {
|
|
|
|
feature = carve(input, firstIdx, secondIdx);
|
|
|
|
} else {
|
|
|
|
feature = carve(input, secondIdx, firstIdx);
|
|
|
|
}
|
|
|
|
// print_repr(feature, "Feature");
|
|
concatPrefixFeature(prefix, feature);
|
|
|
|
// GC allocated structures
|
|
free(feature->start);
|
|
free(feature);
|
|
// for(int x = 0; x < recurlen; x++) {
|
|
|
|
// utarray_free(recur[x]);
|
|
// }
|
|
// free(recur);
|
|
// print_repr(prefix, "Concat");
|
|
return spliceGF(prefix, input, secondIdx);
|
|
|
|
}
|
|
|
|
void getTwoIndices(UT_array *recur, int recurlen, int *firstIdx,
|
|
int *secondIdx) {
|
|
|
|
int ArrayRecurIndices[recurlen];
|
|
int offset = 0, *p;
|
|
// Unroll into an array
|
|
for (p = (int *)utarray_front(recur); p != NULL;
|
|
p = (int *)utarray_next(recur, p)) {
|
|
|
|
ArrayRecurIndices[offset] = *p;
|
|
offset += 1;
|
|
|
|
}
|
|
|
|
/*Source:
|
|
* https://www.geeksforgeeks.org/shuffle-a-given-array-using-fisher-yates-shuffle-algorithm/
|
|
*/
|
|
for (int i = offset - 1; i > 0; i--) {
|
|
|
|
// Pick a random index from 0 to i
|
|
int j = rand_below(global_afl, i + 1);
|
|
|
|
// Swap arr[i] with the element at random index
|
|
swap(&ArrayRecurIndices[i], &ArrayRecurIndices[j]);
|
|
|
|
}
|
|
|
|
*firstIdx = ArrayRecurIndices[0];
|
|
*secondIdx = ArrayRecurIndices[1];
|
|
|
|
}
|
|
|
|
void swap(int *a, int *b) {
|
|
|
|
int temp = *a;
|
|
*a = *b;
|
|
*b = temp;
|
|
|
|
}
|
|
|