forked from p98n2ja4z/AFLplusplus
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.
269 lines
5.7 KiB
269 lines
5.7 KiB
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include "afl-fuzz.h"
|
|
#include "gramfuzz.h"
|
|
#ifdef _GNU_SOURCE
|
|
#undef _GNU_SOURCE
|
|
#endif
|
|
#define _GNU_SOURCE
|
|
#include <sys/mman.h>
|
|
|
|
/* Dynamic Array for adding to the input repr
|
|
* */
|
|
void initArray(Array *a, size_t initialSize) {
|
|
|
|
a->start = (terminal *)calloc(1, sizeof(terminal) * initialSize);
|
|
a->used = 0;
|
|
a->size = initialSize;
|
|
a->inputlen = 0;
|
|
|
|
}
|
|
|
|
void insertArray(Array *a, int state, char *symbol, size_t symbol_len,
|
|
int trigger_idx) {
|
|
|
|
// a->used is the number of used entries, because a->array[a->used++] updates
|
|
// a->used only *after* the array has been accessed. Therefore a->used can go
|
|
// up to a->size
|
|
terminal *term_ptr;
|
|
if (a->used == a->size) {
|
|
|
|
a->size = a->size * sizeof(terminal);
|
|
a->start = (terminal *)realloc(a->start, a->size * sizeof(terminal));
|
|
|
|
}
|
|
|
|
// Add the element
|
|
term_ptr = &a->start[a->used];
|
|
term_ptr->state = state;
|
|
term_ptr->symbol = symbol;
|
|
term_ptr->symbol_len = symbol_len;
|
|
term_ptr->trigger_idx = trigger_idx;
|
|
|
|
// Increment the pointer
|
|
a->used += 1;
|
|
a->inputlen += symbol_len;
|
|
|
|
}
|
|
|
|
void freeArray(Array *a) {
|
|
|
|
terminal *ptr;
|
|
for (int x = 0; x < a->used; x++) {
|
|
|
|
ptr = &a->start[x];
|
|
free(ptr);
|
|
|
|
}
|
|
|
|
a->start = NULL;
|
|
a->used = a->size = 0;
|
|
|
|
}
|
|
|
|
/* Dynamic array for adding indices of states/recursive features
|
|
* Source:
|
|
* https://stackoverflow.com/questions/3536153/c-dynamically-growing-array
|
|
*/
|
|
void initArrayIdx(IdxMap *a, size_t initialSize) {
|
|
|
|
a->array = (int *)malloc(initialSize * sizeof(int));
|
|
a->used = 0;
|
|
a->size = initialSize;
|
|
|
|
}
|
|
|
|
void insertArrayIdx(IdxMap *a, int idx) {
|
|
|
|
// a->used is the number of used entries, because a->array[a->used++] updates
|
|
// a->used only *after* the array has been accessed. Therefore a->used can go
|
|
// up to a->size
|
|
if (a->used == a->size) {
|
|
|
|
a->size *= 2;
|
|
a->array = (int *)realloc(a->array, a->size * sizeof(int));
|
|
|
|
}
|
|
|
|
a->array[a->used++] = idx;
|
|
|
|
}
|
|
|
|
void freeArrayIdx(IdxMap *a) {
|
|
|
|
free(a->array);
|
|
a->array = NULL;
|
|
a->used = a->size = 0;
|
|
|
|
}
|
|
|
|
/* Dynamic array for adding potential splice points
|
|
*/
|
|
void initArraySplice(SpliceCandArray *a, size_t initialSize) {
|
|
|
|
a->start = (SpliceCand *)malloc(initialSize * sizeof(SpliceCand));
|
|
a->used = 0;
|
|
a->size = initialSize;
|
|
|
|
}
|
|
|
|
void insertArraySplice(SpliceCandArray *a, Candidate *candidate, int idx) {
|
|
|
|
// a->used is the number of used entries, because a->array[a->used++] updates
|
|
// a->used only *after* the array has been accessed. Therefore a->used can go
|
|
// up to a->size
|
|
SpliceCand *candptr;
|
|
if (a->used == a->size) {
|
|
|
|
a->size = a->size * sizeof(SpliceCand);
|
|
a->start = (SpliceCand *)realloc(a->start, a->size * sizeof(SpliceCand));
|
|
|
|
}
|
|
|
|
// Add the element
|
|
candptr = &a->start[a->used];
|
|
candptr->splice_cand = candidate;
|
|
candptr->idx = idx;
|
|
a->used += 1;
|
|
|
|
}
|
|
|
|
void freeArraySplice(IdxMap *a) {
|
|
|
|
free(a->array);
|
|
a->array = NULL;
|
|
a->used = a->size = 0;
|
|
|
|
}
|
|
|
|
int fact(int n) {
|
|
|
|
int i, f = 1;
|
|
for (i = 1; i <= n; i++) {
|
|
|
|
f *= i;
|
|
|
|
}
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
/* Uses the walk to create the input in-memory */
|
|
u8 *unparse_walk(Array *input) {
|
|
|
|
terminal *term_ptr;
|
|
int offset = 0;
|
|
u8 * unparsed = (u8 *)malloc(input->inputlen + 1);
|
|
term_ptr = &input->start[offset];
|
|
strcpy(unparsed, term_ptr->symbol);
|
|
offset += 1;
|
|
while (offset < input->used) {
|
|
|
|
term_ptr = &input->start[offset];
|
|
strcat(unparsed, term_ptr->symbol);
|
|
offset += 1;
|
|
|
|
}
|
|
|
|
return unparsed;
|
|
|
|
}
|
|
|
|
/*Dump the input representation into a file*/
|
|
void write_input(Array *input, u8 *fn) {
|
|
|
|
FILE *fp;
|
|
// If file already exists, then skip creating the file
|
|
if (access(fn, F_OK) != -1) { return; }
|
|
|
|
fp = fopen(fn, "wbx+");
|
|
// If the input has already been flushed, then skip silently
|
|
if (fp == NULL) {
|
|
|
|
fprintf(stderr, "\n File '%s' could not be open, exiting\n", fn);
|
|
exit(1);
|
|
|
|
}
|
|
|
|
// Write the length parameters
|
|
fwrite(&input->used, sizeof(size_t), 1, fp);
|
|
fwrite(&input->size, sizeof(size_t), 1, fp);
|
|
fwrite(&input->inputlen, sizeof(size_t), 1, fp);
|
|
|
|
// Write the dynamic array to file
|
|
fwrite(input->start, input->size * sizeof(terminal), 1, fp);
|
|
// printf("\nUsed:%zu Size:%zu Inputlen:%zu", input->used, input->size,
|
|
// input->inputlen);
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
Array *parse_input(state *pda, FILE *fp) {
|
|
|
|
terminal *term;
|
|
state * state_ptr;
|
|
trigger * trigger;
|
|
int trigger_idx;
|
|
Array * input = (Array *)calloc(1, sizeof(Array));
|
|
|
|
// Read the length parameters
|
|
fread(&input->used, sizeof(size_t), 1, fp);
|
|
fread(&input->size, sizeof(size_t), 1, fp);
|
|
fread(&input->inputlen, sizeof(size_t), 1, fp);
|
|
|
|
terminal *start_ptr = (terminal *)calloc(input->size, sizeof(terminal));
|
|
if (!start_ptr) {
|
|
|
|
fprintf(stderr, "alloc failed!\n");
|
|
return NULL;
|
|
|
|
}
|
|
|
|
// Read the dynamic array to memory
|
|
fread(start_ptr, input->size * sizeof(terminal), 1, fp);
|
|
// Update the pointers to the terminals since they would have
|
|
// changed
|
|
int idx = 0;
|
|
while (idx < input->used) {
|
|
|
|
terminal *term = &start_ptr[idx];
|
|
// Find the state
|
|
state_ptr = pda + term->state;
|
|
// Find the trigger and update the terminal address
|
|
trigger_idx = term->trigger_idx;
|
|
trigger = (state_ptr->ptr) + trigger_idx;
|
|
term->symbol = trigger->term;
|
|
idx += 1;
|
|
|
|
}
|
|
|
|
input->start = start_ptr;
|
|
// printf("\nUsed:%zu Size:%zu Inputlen:%zu", input->used, input->size,
|
|
// input->inputlen);
|
|
|
|
return input;
|
|
|
|
}
|
|
|
|
// Read the input representation into memory
|
|
Array *read_input(state *pda, u8 *fn) {
|
|
|
|
FILE *fp;
|
|
fp = fopen(fn, "rb");
|
|
if (fp == NULL) {
|
|
|
|
fprintf(stderr, "\n File '%s' does not exist, exiting\n", fn);
|
|
exit(1);
|
|
|
|
}
|
|
|
|
Array *res = parse_input(pda, fp);
|
|
fclose(fp);
|
|
return res;
|
|
|
|
}
|
|
|