#include #include #include #include #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; }