aboutsummaryrefslogtreecommitdiff
path: root/custom_mutators
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-07-23 15:58:13 +0200
committervan Hauser <vh@thc.org>2020-07-23 15:58:13 +0200
commit72b46a07d6a64a7871f029330bcf5eae649c8eb1 (patch)
tree1fe3e26d1f5ecf285de08acc798df2579e4de72e /custom_mutators
parent2ba88dcd8a9829612eb06eb130d688685a76a847 (diff)
downloadAFLplusplus-72b46a07d6a64a7871f029330bcf5eae649c8eb1.tar.gz
added honggfuzz custom mutator :)
Diffstat (limited to 'custom_mutators')
-rw-r--r--custom_mutators/honggfuzz/Makefile15
-rw-r--r--custom_mutators/honggfuzz/README.md12
-rw-r--r--custom_mutators/honggfuzz/common.h0
-rw-r--r--custom_mutators/honggfuzz/custom_mutator_helpers.h22
-rw-r--r--custom_mutators/honggfuzz/honggfuzz.c141
-rw-r--r--custom_mutators/honggfuzz/honggfuzz.h460
-rw-r--r--custom_mutators/honggfuzz/input.h106
l---------custom_mutators/honggfuzz/libhfcommon1
l---------custom_mutators/honggfuzz/log.h1
-rw-r--r--custom_mutators/honggfuzz/mangle.c1039
-rw-r--r--custom_mutators/honggfuzz/mangle.h32
l---------custom_mutators/honggfuzz/util.h1
12 files changed, 1830 insertions, 0 deletions
diff --git a/custom_mutators/honggfuzz/Makefile b/custom_mutators/honggfuzz/Makefile
new file mode 100644
index 00000000..2f46d0e7
--- /dev/null
+++ b/custom_mutators/honggfuzz/Makefile
@@ -0,0 +1,15 @@
+
+CFLAGS = -O3 -funroll-loops -fPIC -Wl,-Bsymbolic
+
+all: honggfuzz.so
+
+honggfuzz.so: honggfuzz.c input.h mangle.c ../../src/afl-performance.c
+ $(CC) $(CFLAGS) -I../../include -I. -shared -o honggfuzz.so honggfuzz.c mangle.c ../../src/afl-performance.c
+
+update:
+ wget --unlink https://github.com/google/honggfuzz/raw/master/mangle.c
+ wget --unlink https://github.com/google/honggfuzz/raw/master/mangle.h
+ wget --unlink https://github.com/google/honggfuzz/raw/master/honggfuzz.h
+
+clean:
+ rm -f *.o *~ *.so core
diff --git a/custom_mutators/honggfuzz/README.md b/custom_mutators/honggfuzz/README.md
new file mode 100644
index 00000000..8824976f
--- /dev/null
+++ b/custom_mutators/honggfuzz/README.md
@@ -0,0 +1,12 @@
+# custum mutator: honggfuzz mangle
+
+this is the very good honggfuzz mutator in mangle.c as a custom mutator
+module for afl++. It is the original mangle.c, mangle.h and honggfuzz.h
+with a lot of mocking around it :-)
+
+just type `make` to build
+
+```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/honggfuzz/honggfuzz.so afl-fuzz ...```
+
+> Original repository: https://github.com/google/honggfuzz
+> Source commit: d0fbcb0373c32436b8fb922e6937da93b17291f5
diff --git a/custom_mutators/honggfuzz/common.h b/custom_mutators/honggfuzz/common.h
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/custom_mutators/honggfuzz/common.h
diff --git a/custom_mutators/honggfuzz/custom_mutator_helpers.h b/custom_mutators/honggfuzz/custom_mutator_helpers.h
new file mode 100644
index 00000000..57754697
--- /dev/null
+++ b/custom_mutators/honggfuzz/custom_mutator_helpers.h
@@ -0,0 +1,22 @@
+#ifndef CUSTOM_MUTATOR_HELPERS
+#define CUSTOM_MUTATOR_HELPERS
+
+#include "config.h"
+#include "types.h"
+#include "afl-fuzz.h"
+#include <stdlib.h>
+
+#define INITIAL_GROWTH_SIZE (64)
+
+/* Use in a struct: creates a name_buf and a name_size variable. */
+#define BUF_VAR(type, name) \
+ type * name##_buf; \
+ size_t name##_size;
+/* this filles in `&structptr->something_buf, &structptr->something_size`. */
+#define BUF_PARAMS(struct, name) \
+ (void **)&struct->name##_buf, &struct->name##_size
+
+#undef INITIAL_GROWTH_SIZE
+
+#endif
+
diff --git a/custom_mutators/honggfuzz/honggfuzz.c b/custom_mutators/honggfuzz/honggfuzz.c
new file mode 100644
index 00000000..368741c1
--- /dev/null
+++ b/custom_mutators/honggfuzz/honggfuzz.c
@@ -0,0 +1,141 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "custom_mutator_helpers.h"
+#include "mangle.h"
+
+#define NUMBER_OF_MUTATIONS 5
+
+uint8_t * queue_input;
+size_t queue_input_size;
+afl_state_t * afl_struct;
+run_t run;
+honggfuzz_t global;
+struct _dynfile_t dynfile;
+
+typedef struct my_mutator {
+
+ afl_state_t *afl;
+ run_t * run;
+ u8 * mutator_buf;
+ unsigned int seed;
+ unsigned int extras_cnt, a_extras_cnt;
+
+} my_mutator_t;
+
+my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
+
+ my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
+ if (!data) {
+
+ perror("afl_custom_init alloc");
+ return NULL;
+
+ }
+
+ if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) {
+
+ perror("mutator_buf alloc");
+ return NULL;
+
+ }
+
+ run.dynfile = &dynfile;
+ run.global = &global;
+ data->afl = afl;
+ data->seed = seed;
+ data->run = &run;
+ afl_struct = afl;
+
+ run.global->mutate.maxInputSz = MAX_FILE;
+ run.global->mutate.mutationsPerRun = NUMBER_OF_MUTATIONS;
+ run.mutationsPerRun = NUMBER_OF_MUTATIONS;
+ run.global->timing.lastCovUpdate = 6;
+
+ // global->feedback.cmpFeedback
+ // global->feedback.cmpFeedbackMap
+
+ return data;
+
+}
+
+/* When a new queue entry is added we check if there are new dictionary
+ entries to add to honggfuzz structure */
+
+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 < data->afl->extras_cnt &&
+ run.global->mutate.dictionaryCnt < 1024) {
+
+ memcpy(run.global->mutate.dictionary[run.global->mutate.dictionaryCnt].val,
+ data->afl->extras[data->extras_cnt].data,
+ data->afl->extras[data->extras_cnt].len);
+ run.global->mutate.dictionary[run.global->mutate.dictionaryCnt].len =
+ data->afl->extras[data->extras_cnt].len;
+ run.global->mutate.dictionaryCnt++;
+ data->extras_cnt++;
+
+ }
+
+ while (data->extras_cnt < data->afl->a_extras_cnt &&
+ run.global->mutate.dictionaryCnt < 1024) {
+
+ memcpy(run.global->mutate.dictionary[run.global->mutate.dictionaryCnt].val,
+ data->afl->a_extras[data->a_extras_cnt].data,
+ data->afl->a_extras[data->a_extras_cnt].len);
+ run.global->mutate.dictionary[run.global->mutate.dictionaryCnt].len =
+ data->afl->a_extras[data->a_extras_cnt].len;
+ run.global->mutate.dictionaryCnt++;
+ data->a_extras_cnt++;
+
+ }
+
+}
+
+/* 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 */
+
+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) {
+
+ /* set everything up, costly ... :( */
+ memcpy(data->mutator_buf, buf, buf_size);
+ queue_input = data->mutator_buf;
+ run.dynfile->data = data->mutator_buf;
+ queue_input_size = buf_size;
+ run.dynfile->size = buf_size;
+ *out_buf = data->mutator_buf;
+
+ /* the mutation */
+ mangle_mangleContent(&run, NUMBER_OF_MUTATIONS);
+
+ /* return size of mutated data */
+ return run.dynfile->size;
+
+}
+
+/**
+ * Deinitialize everything
+ *
+ * @param data The data ptr from afl_custom_init
+ */
+void afl_custom_deinit(my_mutator_t *data) {
+
+ free(data->mutator_buf);
+ free(data);
+
+}
+
diff --git a/custom_mutators/honggfuzz/honggfuzz.h b/custom_mutators/honggfuzz/honggfuzz.h
new file mode 100644
index 00000000..4e045272
--- /dev/null
+++ b/custom_mutators/honggfuzz/honggfuzz.h
@@ -0,0 +1,460 @@
+/*
+ *
+ * honggfuzz - core structures and macros
+ * -----------------------------------------
+ *
+ * Author: Robert Swiecki <swiecki@google.com>
+ *
+ * Copyright 2010-2018 by Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ */
+
+#ifndef _HF_HONGGFUZZ_H_
+#define _HF_HONGGFUZZ_H_
+
+#include <dirent.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include "libhfcommon/util.h"
+
+#define PROG_NAME "honggfuzz"
+#define PROG_VERSION "2.2"
+
+/* Name of the template which will be replaced with the proper name of the file
+ */
+#define _HF_FILE_PLACEHOLDER "___FILE___"
+
+/* Default name of the report created with some architectures */
+#define _HF_REPORT_FILE "HONGGFUZZ.REPORT.TXT"
+
+/* Default stack-size of created threads. */
+#define _HF_PTHREAD_STACKSIZE (1024ULL * 1024ULL * 2ULL) /* 2MB */
+
+/* Name of envvar which indicates sequential number of fuzzer */
+#define _HF_THREAD_NO_ENV "HFUZZ_THREAD_NO"
+
+/* Name of envvar which indicates that the netDriver should be used */
+#define _HF_THREAD_NETDRIVER_ENV "HFUZZ_USE_NETDRIVER"
+
+/* Name of envvar which indicates honggfuzz's log level in use */
+#define _HF_LOG_LEVEL_ENV "HFUZZ_LOG_LEVEL"
+
+/* Number of crash verifier iterations before tag crash as stable */
+#define _HF_VERIFIER_ITER 5
+
+/* Size (in bytes) for report data to be stored in stack before written to file
+ */
+#define _HF_REPORT_SIZE 32768
+
+/* Perf bitmap size */
+#define _HF_PERF_BITMAP_SIZE_16M (1024U * 1024U * 16U)
+#define _HF_PERF_BITMAP_BITSZ_MASK 0x7FFFFFFULL
+/* Maximum number of PC guards (=trace-pc-guard) we support */
+#define _HF_PC_GUARD_MAX (1024ULL * 1024ULL * 64ULL)
+
+/* Maximum size of the input file in bytes (1 MiB) */
+#define _HF_INPUT_MAX_SIZE (1024ULL * 1024ULL)
+
+/* Default maximum size of produced inputs */
+#define _HF_INPUT_DEFAULT_SIZE (1024ULL * 8)
+
+/* Per-thread bitmap */
+#define _HF_PERTHREAD_BITMAP_FD 1018
+/* FD used to report back used int/str constants from the fuzzed process */
+#define _HF_CMP_BITMAP_FD 1019
+/* FD used to log inside the child process */
+#define _HF_LOG_FD 1020
+/* FD used to represent the input file */
+#define _HF_INPUT_FD 1021
+/* FD used to pass coverage feedback from the fuzzed process */
+#define _HF_COV_BITMAP_FD 1022
+#define _HF_BITMAP_FD _HF_COV_BITMAP_FD /* Old name for _HF_COV_BITMAP_FD */
+/* FD used to pass data to a persistent process */
+#define _HF_PERSISTENT_FD 1023
+
+/* Input file as a string */
+#define _HF_INPUT_FILE_PATH "/dev/fd/" HF_XSTR(_HF_INPUT_FD)
+
+/* Maximum number of supported execve() args */
+#define _HF_ARGS_MAX 2048
+
+/* Message indicating that the fuzzed process is ready for new data */
+static const uint8_t HFReadyTag = 'R';
+
+/* Maximum number of active fuzzing threads */
+#define _HF_THREAD_MAX 1024U
+
+/* Persistent-binary signature - if found within file, it means it's a
+ * persistent mode binary */
+#define _HF_PERSISTENT_SIG "\x01_LIBHFUZZ_PERSISTENT_BINARY_SIGNATURE_\x02\xFF"
+/* HF NetDriver signature - if found within file, it means it's a
+ * NetDriver-based binary */
+#define _HF_NETDRIVER_SIG "\x01_LIBHFUZZ_NETDRIVER_BINARY_SIGNATURE_\x02\xFF"
+
+/* printf() nonmonetary separator. According to MacOSX's man it's supported
+ * there as well */
+#define _HF_NONMON_SEP "'"
+
+typedef enum {
+
+ _HF_DYNFILE_NONE = 0x0,
+ _HF_DYNFILE_INSTR_COUNT = 0x1,
+ _HF_DYNFILE_BRANCH_COUNT = 0x2,
+ _HF_DYNFILE_BTS_EDGE = 0x10,
+ _HF_DYNFILE_IPT_BLOCK = 0x20,
+ _HF_DYNFILE_SOFT = 0x40,
+
+} dynFileMethod_t;
+
+typedef struct {
+
+ uint64_t cpuInstrCnt;
+ uint64_t cpuBranchCnt;
+ uint64_t bbCnt;
+ uint64_t newBBCnt;
+ uint64_t softCntPc;
+ uint64_t softCntEdge;
+ uint64_t softCntCmp;
+
+} hwcnt_t;
+
+typedef enum {
+
+ _HF_STATE_UNSET = 0,
+ _HF_STATE_STATIC,
+ _HF_STATE_DYNAMIC_DRY_RUN,
+ _HF_STATE_DYNAMIC_MAIN,
+ _HF_STATE_DYNAMIC_MINIMIZE,
+
+} fuzzState_t;
+
+typedef enum {
+
+ HF_MAYBE = -1,
+ HF_NO = 0,
+ HF_YES = 1,
+
+} tristate_t;
+
+struct _dynfile_t {
+
+ size_t size;
+ uint64_t cov[4];
+ size_t idx;
+ int fd;
+ uint64_t timeExecUSecs;
+ char path[PATH_MAX];
+ struct _dynfile_t *src;
+ uint32_t refs;
+ uint8_t * data;
+ TAILQ_ENTRY(_dynfile_t) pointers;
+
+};
+
+typedef struct _dynfile_t dynfile_t;
+
+struct strings_t {
+
+ size_t len;
+ TAILQ_ENTRY(strings_t) pointers;
+ char s[];
+
+};
+
+typedef struct {
+
+ uint8_t pcGuardMap[_HF_PC_GUARD_MAX];
+ uint8_t bbMapPc[_HF_PERF_BITMAP_SIZE_16M];
+ uint32_t bbMapCmp[_HF_PERF_BITMAP_SIZE_16M];
+ uint64_t pidNewPC[_HF_THREAD_MAX];
+ uint64_t pidNewEdge[_HF_THREAD_MAX];
+ uint64_t pidNewCmp[_HF_THREAD_MAX];
+ uint64_t guardNb;
+ uint64_t pidTotalPC[_HF_THREAD_MAX];
+ uint64_t pidTotalEdge[_HF_THREAD_MAX];
+ uint64_t pidTotalCmp[_HF_THREAD_MAX];
+
+} feedback_t;
+
+typedef struct {
+
+ uint32_t cnt;
+ struct {
+
+ uint8_t val[32];
+ uint32_t len;
+
+ } valArr[1024 * 16];
+
+} cmpfeedback_t;
+
+typedef struct {
+
+ struct {
+
+ size_t threadsMax;
+ size_t threadsFinished;
+ uint32_t threadsActiveCnt;
+ pthread_t mainThread;
+ pid_t mainPid;
+ pthread_t threads[_HF_THREAD_MAX];
+
+ } threads;
+
+ struct {
+
+ const char *inputDir;
+ const char *outputDir;
+ DIR * inputDirPtr;
+ size_t fileCnt;
+ size_t testedFileCnt;
+ const char *fileExtn;
+ size_t maxFileSz;
+ size_t newUnitsAdded;
+ char workDir[PATH_MAX];
+ const char *crashDir;
+ const char *covDirNew;
+ bool saveUnique;
+ size_t dynfileqMaxSz;
+ size_t dynfileqCnt;
+ dynfile_t * dynfileqCurrent;
+ dynfile_t * dynfileq2Current;
+ TAILQ_HEAD(dyns_t, _dynfile_t) dynfileq;
+ bool exportFeedback;
+
+ } io;
+
+ struct {
+
+ int argc;
+ const char *const *cmdline;
+ bool nullifyStdio;
+ bool fuzzStdin;
+ const char * externalCommand;
+ const char * postExternalCommand;
+ const char * feedbackMutateCommand;
+ bool netDriver;
+ bool persistent;
+ uint64_t asLimit;
+ uint64_t rssLimit;
+ uint64_t dataLimit;
+ uint64_t coreLimit;
+ uint64_t stackLimit;
+ bool clearEnv;
+ char * env_ptrs[128];
+ char env_vals[128][4096];
+ sigset_t waitSigSet;
+
+ } exe;
+
+ struct {
+
+ time_t timeStart;
+ time_t runEndTime;
+ time_t tmOut;
+ time_t lastCovUpdate;
+ int64_t timeOfLongestUnitUSecs;
+ bool tmoutVTALRM;
+
+ } timing;
+
+ struct {
+
+ struct {
+
+ uint8_t val[256];
+ size_t len;
+
+ } dictionary[1024];
+
+ size_t dictionaryCnt;
+ const char *dictionaryFile;
+ size_t mutationsMax;
+ unsigned mutationsPerRun;
+ size_t maxInputSz;
+
+ } mutate;
+
+ struct {
+
+ bool useScreen;
+ char cmdline_txt[65];
+ int64_t lastDisplayUSecs;
+
+ } display;
+
+ struct {
+
+ bool useVerifier;
+ bool exitUponCrash;
+ const char *reportFile;
+ size_t dynFileIterExpire;
+ bool only_printable;
+ bool minimize;
+ bool switchingToFDM;
+
+ } cfg;
+
+ struct {
+
+ bool enable;
+ bool del_report;
+
+ } sanitizer;
+
+ struct {
+
+ fuzzState_t state;
+ feedback_t * covFeedbackMap;
+ int covFeedbackFd;
+ cmpfeedback_t * cmpFeedbackMap;
+ int cmpFeedbackFd;
+ bool cmpFeedback;
+ const char * blacklistFile;
+ uint64_t * blacklist;
+ size_t blacklistCnt;
+ bool skipFeedbackOnTimeout;
+ uint64_t maxCov[4];
+ dynFileMethod_t dynFileMethod;
+ hwcnt_t hwCnts;
+
+ } feedback;
+
+ struct {
+
+ size_t mutationsCnt;
+ size_t crashesCnt;
+ size_t uniqueCrashesCnt;
+ size_t verifiedCrashesCnt;
+ size_t blCrashesCnt;
+ size_t timeoutedCnt;
+
+ } cnts;
+
+ struct {
+
+ bool enabled;
+ int serverSocket;
+ int clientSocket;
+
+ } socketFuzzer;
+
+ struct {
+
+ pthread_rwlock_t dynfileq;
+ pthread_mutex_t feedback;
+ pthread_mutex_t report;
+ pthread_mutex_t state;
+ pthread_mutex_t input;
+ pthread_mutex_t timing;
+
+ } mutex;
+
+ /* For the Linux code */
+ struct {
+
+ int exeFd;
+ uint64_t dynamicCutOffAddr;
+ bool disableRandomization;
+ void * ignoreAddr;
+ const char *symsBlFile;
+ char ** symsBl;
+ size_t symsBlCnt;
+ const char *symsWlFile;
+ char ** symsWl;
+ size_t symsWlCnt;
+ uintptr_t cloneFlags;
+ tristate_t useNetNs;
+ bool kernelOnly;
+ bool useClone;
+
+ } arch_linux;
+
+ /* For the NetBSD code */
+ struct {
+
+ void * ignoreAddr;
+ const char *symsBlFile;
+ char ** symsBl;
+ size_t symsBlCnt;
+ const char *symsWlFile;
+ char ** symsWl;
+ size_t symsWlCnt;
+
+ } arch_netbsd;
+
+} honggfuzz_t;
+
+typedef enum {
+
+ _HF_RS_UNKNOWN = 0,
+ _HF_RS_WAITING_FOR_INITIAL_READY = 1,
+ _HF_RS_WAITING_FOR_READY = 2,
+ _HF_RS_SEND_DATA = 3,
+
+} runState_t;
+
+typedef struct {
+
+ honggfuzz_t *global;
+ pid_t pid;
+ int64_t timeStartedUSecs;
+ char crashFileName[PATH_MAX];
+ uint64_t pc;
+ uint64_t backtrace;
+ uint64_t access;
+ int exception;
+ char report[_HF_REPORT_SIZE];
+ bool mainWorker;
+ unsigned mutationsPerRun;
+ dynfile_t * dynfile;
+ bool staticFileTryMore;
+ uint32_t fuzzNo;
+ int persistentSock;
+ runState_t runState;
+ bool tmOutSignaled;
+ char * args[_HF_ARGS_MAX + 1];
+ int perThreadCovFeedbackFd;
+ unsigned triesLeft;
+ dynfile_t * current;
+#if !defined(_HF_ARCH_DARWIN)
+ timer_t timerId;
+#endif // !defined(_HF_ARCH_DARWIN)
+ hwcnt_t hwCnts;
+
+ struct {
+
+ /* For Linux code */
+ uint8_t *perfMmapBuf;
+ uint8_t *perfMmapAux;
+ int cpuInstrFd;
+ int cpuBranchFd;
+ int cpuIptBtsFd;
+
+ } arch_linux;
+
+} run_t;
+
+#endif
+
diff --git a/custom_mutators/honggfuzz/input.h b/custom_mutators/honggfuzz/input.h
new file mode 100644
index 00000000..c67d88a6
--- /dev/null
+++ b/custom_mutators/honggfuzz/input.h
@@ -0,0 +1,106 @@
+#ifndef _HG_INPUT_
+#define _HG_INPUT_
+
+#include <stdarg.h>
+#ifdef __clang__
+#include <stdatomic.h>
+#endif
+#include <stdbool.h>
+#include <stdint.h>
+#include <time.h>
+
+#include "honggfuzz.h"
+#include "afl-fuzz.h"
+
+/*
+ * Go-style defer scoped implementation
+ *
+ * If compiled with clang, use: -fblocks -lBlocksRuntime
+ *
+ * Example of use:
+ *
+ * {
+ * int fd = open(fname, O_RDONLY);
+ * if (fd == -1) {
+ * error(....);
+ * return;
+ * }
+ * defer { close(fd); };
+ * ssize_t sz = read(fd, buf, sizeof(buf));
+ * ...
+ * ...
+ * }
+ *
+ */
+
+#define __STRMERGE(a, b) a##b
+#define _STRMERGE(a, b) __STRMERGE(a, b)
+#ifdef __clang__
+#if __has_extension(blocks)
+static void __attribute__((unused)) __clang_cleanup_func(void (^*dfunc)(void)) {
+ (*dfunc)();
+}
+
+#define defer \
+ void (^_STRMERGE(__defer_f_, __COUNTER__))(void) \
+ __attribute__((cleanup(__clang_cleanup_func))) __attribute__((unused)) = ^
+
+#else /* __has_extension(blocks) */
+#define defer UNIMPLEMENTED - NO - SUPPORT - FOR - BLOCKS - IN - YOUR - CLANG - ENABLED
+#endif /* __has_extension(blocks) */
+#else /* !__clang__, e.g.: gcc */
+
+#define __block
+#define _DEFER(a, count) \
+ auto void _STRMERGE(__defer_f_, count)(void* _defer_arg __attribute__((unused))); \
+ int _STRMERGE(__defer_var_, count) __attribute__((cleanup(_STRMERGE(__defer_f_, count)))) \
+ __attribute__((unused)); \
+ void _STRMERGE(__defer_f_, count)(void* _defer_arg __attribute__((unused)))
+#define defer _DEFER(a, __COUNTER__)
+#endif /* ifdef __clang__ */
+
+#define HF_MIN(x, y) (x <= y ? x : y)
+#define HF_MAX(x, y) (x >= y ? x : y)
+#define ATOMIC_GET
+#define ARRAYSIZE(x) (sizeof(x) / sizeof(*x))
+#define HF_ATTR_UNUSED __attribute__((unused))
+#define util_Malloc(x) malloc(x)
+
+extern uint8_t * queue_input;
+extern size_t queue_input_size;
+extern afl_state_t * afl_struct;
+
+inline void wmb() { }
+inline void LOG_F(const char *format, ...) { }
+static inline uint64_t util_rndGet(uint64_t min, uint64_t max) {
+ return min + rand_below(afl_struct, max - min + 1);
+}
+static inline uint64_t util_rnd64() { return rand_below(afl_struct, 1 << 30); }
+
+static inline size_t input_getRandomInputAsBuf(run_t *run, const uint8_t **buf) {
+ *buf = queue_input;
+ run->dynfile->data = queue_input;
+ run->dynfile->size = queue_input_size;
+ return queue_input_size;
+}
+static inline void input_setSize(run_t* run, size_t sz) {
+ run->dynfile->size = sz;
+}
+static inline uint8_t util_turnToPrintable(uint8_t* buf, size_t sz) {
+ for (size_t i = 0; i < sz; i++)
+ buf[i] = buf[i] % 95 + 32;
+}
+static inline void util_rndBuf(uint8_t* buf, size_t sz) {
+ if (sz == 0) return;
+ for (size_t i = 0; i < sz; i++)
+ buf[i] = (uint8_t)rand_below(afl_struct, 256);
+}
+static inline uint8_t util_rndPrintable() {
+ return 32 + rand_below(afl_struct, 127 - 32);
+}
+static inline void util_rndBufPrintable(uint8_t* buf, size_t sz) {
+ for (size_t i = 0; i < sz; i++)
+ buf[i] = util_rndPrintable();
+}
+
+#endif
diff --git a/custom_mutators/honggfuzz/libhfcommon b/custom_mutators/honggfuzz/libhfcommon
new file mode 120000
index 00000000..945c9b46
--- /dev/null
+++ b/custom_mutators/honggfuzz/libhfcommon
@@ -0,0 +1 @@
+. \ No newline at end of file
diff --git a/custom_mutators/honggfuzz/log.h b/custom_mutators/honggfuzz/log.h
new file mode 120000
index 00000000..51e19654
--- /dev/null
+++ b/custom_mutators/honggfuzz/log.h
@@ -0,0 +1 @@
+common.h \ No newline at end of file
diff --git a/custom_mutators/honggfuzz/mangle.c b/custom_mutators/honggfuzz/mangle.c
new file mode 100644
index 00000000..05e0dcfa
--- /dev/null
+++ b/custom_mutators/honggfuzz/mangle.c
@@ -0,0 +1,1039 @@
+/*
+ *
+ * honggfuzz - run->dynfile->datafer mangling routines
+ * -----------------------------------------
+ *
+ * Author:
+ * Robert Swiecki <swiecki@google.com>
+ *
+ * Copyright 2010-2018 by Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ */
+
+#include "mangle.h"
+
+#include <ctype.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include "input.h"
+#include "libhfcommon/common.h"
+#include "libhfcommon/log.h"
+#include "libhfcommon/util.h"
+
+static inline size_t mangle_LenLeft(run_t *run, size_t off) {
+
+ if (off >= run->dynfile->size) {
+
+ LOG_F("Offset is too large: off:%zu >= len:%zu", off, run->dynfile->size);
+
+ }
+
+ return (run->dynfile->size - off - 1);
+
+}
+
+/* Get a random value between <1:max> with x^2 distribution */
+static inline size_t mangle_getLen(size_t max) {
+
+ if (max > _HF_INPUT_MAX_SIZE) {
+
+ LOG_F("max (%zu) > _HF_INPUT_MAX_SIZE (%zu)", max,
+ (size_t)_HF_INPUT_MAX_SIZE);
+
+ }
+
+ if (max == 0) { LOG_F("max == 0"); }
+ if (max == 1) { return 1; }
+
+ const uint64_t max2 = (uint64_t)max * max;
+ const uint64_t max3 = (uint64_t)max * max * max;
+ const uint64_t rnd = util_rndGet(1, max2 - 1);
+
+ uint64_t ret = rnd * rnd;
+ ret /= max3;
+ ret += 1;
+
+ if (ret < 1) {
+
+ LOG_F("ret (%" PRIu64 ") < 1, max:%zu, rnd:%" PRIu64, ret, max, rnd);
+
+ }
+
+ if (ret > max) {
+
+ LOG_F("ret (%" PRIu64 ") > max (%zu), rnd:%" PRIu64, ret, max, rnd);
+
+ }
+
+ return (size_t)ret;
+
+}
+
+/* Prefer smaller values here, so use mangle_getLen() */
+static inline size_t mangle_getOffSet(run_t *run) {
+
+ return mangle_getLen(run->dynfile->size) - 1;
+
+}
+
+/* Offset which can be equal to the file size */
+static inline size_t mangle_getOffSetPlus1(run_t *run) {
+
+ size_t reqlen = HF_MIN(run->dynfile->size + 1, _HF_INPUT_MAX_SIZE);
+ return mangle_getLen(reqlen) - 1;
+
+}
+
+static inline void mangle_Move(run_t *run, size_t off_from, size_t off_to,
+ size_t len) {
+
+ if (off_from >= run->dynfile->size) { return; }
+ if (off_to >= run->dynfile->size) { return; }
+ if (off_from == off_to) { return; }
+
+ size_t len_from = run->dynfile->size - off_from;
+ len = HF_MIN(len, len_from);
+
+ size_t len_to = run->dynfile->size - off_to;
+ len = HF_MIN(len, len_to);
+
+ memmove(&run->dynfile->data[off_to], &run->dynfile->data[off_from], len);
+
+}
+
+static inline void mangle_Overwrite(run_t *run, size_t off, const uint8_t *src,
+ size_t len, bool printable) {
+
+ if (len == 0) { return; }
+ size_t maxToCopy = run->dynfile->size - off;
+ if (len > maxToCopy) { len = maxToCopy; }
+
+ memmove(&run->dynfile->data[off], src, len);
+ if (printable) { util_turnToPrintable(&run->dynfile->data[off], len); }
+
+}
+
+static inline size_t mangle_Inflate(run_t *run, size_t off, size_t len,
+ bool printable) {
+
+ if (run->dynfile->size >= run->global->mutate.maxInputSz) { return 0; }
+ if (len > (run->global->mutate.maxInputSz - run->dynfile->size)) {
+
+ len = run->global->mutate.maxInputSz - run->dynfile->size;
+
+ }
+
+ input_setSize(run, run->dynfile->size + len);
+ mangle_Move(run, off, off + len, run->dynfile->size);
+ if (printable) { memset(&run->dynfile->data[off], ' ', len); }
+
+ return len;
+
+}
+
+static inline void mangle_Insert(run_t *run, size_t off, const uint8_t *val,
+ size_t len, bool printable) {
+
+ len = mangle_Inflate(run, off, len, printable);
+ mangle_Overwrite(run, off, val, len, printable);
+
+}
+
+static inline void mangle_UseValue(run_t *run, const uint8_t *val, size_t len,
+ bool printable) {
+
+ if (util_rnd64() % 2) {
+
+ mangle_Insert(run, mangle_getOffSetPlus1(run), val, len, printable);
+
+ } else {
+
+ mangle_Overwrite(run, mangle_getOffSet(run), val, len, printable);
+
+ }
+
+}
+
+static void mangle_MemSwap(run_t *run, bool printable HF_ATTR_UNUSED) {
+
+ size_t off1 = mangle_getOffSet(run);
+ size_t maxlen1 = run->dynfile->size - off1;
+
+ size_t off2 = mangle_getOffSet(run);
+ size_t maxlen2 = run->dynfile->size - off2;
+
+ size_t len = mangle_getLen(HF_MIN(maxlen1, maxlen2));
+ uint8_t *tmpbuf = (uint8_t *)util_Malloc(len);
+ defer {
+
+ free(tmpbuf);
+
+ };
+
+ memcpy(tmpbuf, &run->dynfile->data[off1], len);
+ memmove(&run->dynfile->data[off1], &run->dynfile->data[off2], len);
+ memcpy(&run->dynfile->data[off2], tmpbuf, len);
+
+}
+
+static void mangle_MemCopy(run_t *run, bool printable HF_ATTR_UNUSED) {
+
+ size_t off = mangle_getOffSet(run);
+ size_t len = mangle_getLen(run->dynfile->size - off);
+
+ /* Use a temp buf, as Insert/Inflate can change source bytes */
+ uint8_t *tmpbuf = (uint8_t *)util_Malloc(len);
+ defer {
+
+ free(tmpbuf);
+
+ };
+
+ memcpy(tmpbuf, &run->dynfile->data[off], len);
+
+ mangle_UseValue(run, tmpbuf, len, printable);
+
+}
+
+static void mangle_Bytes(run_t *run, bool printable) {
+
+ uint16_t buf;
+ if (printable) {
+
+ util_rndBufPrintable((uint8_t *)&buf, sizeof(buf));
+
+ } else {
+
+ buf = util_rnd64();
+
+ }
+
+ /* Overwrite with random 1-2-byte values */
+ size_t toCopy = util_rndGet(1, 2);
+ mangle_UseValue(run, (const uint8_t *)&buf, toCopy, printable);
+
+}
+
+static void mangle_ByteRepeatOverwrite(run_t *run, bool printable) {
+
+ size_t off = mangle_getOffSet(run);
+ size_t destOff = off + 1;
+ size_t maxSz = run->dynfile->size - destOff;
+
+ /* No space to repeat */
+ if (!maxSz) {
+
+ mangle_Bytes(run, printable);
+ return;
+
+ }
+
+ size_t len = mangle_getLen(maxSz);
+ memset(&run->dynfile->data[destOff], run->dynfile->data[off], len);
+
+}
+
+static void mangle_ByteRepeatInsert(run_t *run, bool printable) {
+
+ size_t off = mangle_getOffSet(run);
+ size_t destOff = off + 1;
+ size_t maxSz = run->dynfile->size - destOff;
+
+ /* No space to repeat */
+ if (!maxSz) {
+
+ mangle_Bytes(run, printable);
+ return;
+
+ }
+
+ size_t len = mangle_getLen(maxSz);
+ len = mangle_Inflate(run, destOff, len, printable);
+ memset(&run->dynfile->data[destOff], run->dynfile->data[off], len);
+
+}
+
+static void mangle_Bit(run_t *run, bool printable) {
+
+ size_t off = mangle_getOffSet(run);
+ run->dynfile->data[off] ^= (uint8_t)(1U << util_rndGet(0, 7));
+ if (printable) { util_turnToPrintable(&(run->dynfile->data[off]), 1); }
+
+}
+
+static const struct {
+
+ const uint8_t val[8];
+ const size_t size;
+
+} mangleMagicVals[] = {
+
+ /* 1B - No endianness */
+ {"\x00\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x01\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x02\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x03\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x04\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x05\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x06\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x07\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x08\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x09\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x0A\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x0B\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x0C\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x0D\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x0E\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x0F\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x10\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x20\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x40\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x7E\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x7F\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x80\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\x81\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\xC0\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\xFE\x00\x00\x00\x00\x00\x00\x00", 1},
+ {"\xFF\x00\x00\x00\x00\x00\x00\x00", 1},
+ /* 2B - NE */
+ {"\x00\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x01\x01\x00\x00\x00\x00\x00\x00", 2},
+ {"\x80\x80\x00\x00\x00\x00\x00\x00", 2},
+ {"\xFF\xFF\x00\x00\x00\x00\x00\x00", 2},
+ /* 2B - BE */
+ {"\x00\x01\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x02\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x03\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x04\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x05\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x06\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x07\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x08\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x09\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x0A\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x0B\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x0C\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x0D\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x0E\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x0F\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x10\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x20\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x40\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x7E\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x7F\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x80\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x81\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\xC0\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\xFE\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\xFF\x00\x00\x00\x00\x00\x00", 2},
+ {"\x7E\xFF\x00\x00\x00\x00\x00\x00", 2},
+ {"\x7F\xFF\x00\x00\x00\x00\x00\x00", 2},
+ {"\x80\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x80\x01\x00\x00\x00\x00\x00\x00", 2},
+ {"\xFF\xFE\x00\x00\x00\x00\x00\x00", 2},
+ /* 2B - LE */
+ {"\x00\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x01\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x02\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x03\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x04\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x05\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x06\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x07\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x08\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x09\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x0A\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x0B\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x0C\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x0D\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x0E\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x0F\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x10\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x20\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x40\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x7E\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x7F\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x80\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\x81\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\xC0\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\xFE\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\xFF\x00\x00\x00\x00\x00\x00\x00", 2},
+ {"\xFF\x7E\x00\x00\x00\x00\x00\x00", 2},
+ {"\xFF\x7F\x00\x00\x00\x00\x00\x00", 2},
+ {"\x00\x80\x00\x00\x00\x00\x00\x00", 2},
+ {"\x01\x80\x00\x00\x00\x00\x00\x00", 2},
+ {"\xFE\xFF\x00\x00\x00\x00\x00\x00", 2},
+ /* 4B - NE */
+ {"\x00\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x01\x01\x01\x01\x00\x00\x00\x00", 4},
+ {"\x80\x80\x80\x80\x00\x00\x00\x00", 4},
+ {"\xFF\xFF\xFF\xFF\x00\x00\x00\x00", 4},
+ /* 4B - BE */
+ {"\x00\x00\x00\x01\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x02\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x03\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x04\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x05\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x06\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x07\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x08\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x09\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x0A\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x0B\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x0C\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x0D\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x0E\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x0F\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x10\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x20\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x40\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x7E\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x7F\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x80\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x81\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\xC0\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\xFE\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\xFF\x00\x00\x00\x00", 4},
+ {"\x7E\xFF\xFF\xFF\x00\x00\x00\x00", 4},
+ {"\x7F\xFF\xFF\xFF\x00\x00\x00\x00", 4},
+ {"\x80\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x80\x00\x00\x01\x00\x00\x00\x00", 4},
+ {"\xFF\xFF\xFF\xFE\x00\x00\x00\x00", 4},
+ /* 4B - LE */
+ {"\x00\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x01\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x02\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x03\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x04\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x05\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x06\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x07\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x08\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x09\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x0A\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x0B\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x0C\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x0D\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x0E\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x0F\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x10\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x20\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x40\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x7E\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x7F\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x80\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\x81\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\xC0\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\xFE\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\xFF\x00\x00\x00\x00\x00\x00\x00", 4},
+ {"\xFF\xFF\xFF\x7E\x00\x00\x00\x00", 4},
+ {"\xFF\xFF\xFF\x7F\x00\x00\x00\x00", 4},
+ {"\x00\x00\x00\x80\x00\x00\x00\x00", 4},
+ {"\x01\x00\x00\x80\x00\x00\x00\x00", 4},
+ {"\xFE\xFF\xFF\xFF\x00\x00\x00\x00", 4},
+ /* 8B - NE */
+ {"\x00\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x01\x01\x01\x01\x01\x01\x01\x01", 8},
+ {"\x80\x80\x80\x80\x80\x80\x80\x80", 8},
+ {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
+ /* 8B - BE */
+ {"\x00\x00\x00\x00\x00\x00\x00\x01", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x02", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x03", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x04", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x05", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x06", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x07", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x08", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x09", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x0A", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x0B", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x0C", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x0D", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x0E", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x0F", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x10", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x20", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x40", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x7E", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x7F", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x80", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x81", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\xC0", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\xFE", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\xFF", 8},
+ {"\x7E\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
+ {"\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
+ {"\x80\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x80\x00\x00\x00\x00\x00\x00\x01", 8},
+ {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE", 8},
+ /* 8B - LE */
+ {"\x00\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x01\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x02\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x03\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x04\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x05\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x06\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x07\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x08\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x09\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x0A\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x0B\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x0C\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x0D\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x0E\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x0F\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x10\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x20\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x40\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x7E\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x7F\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x80\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\x81\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\xC0\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\xFE\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\xFF\x00\x00\x00\x00\x00\x00\x00", 8},
+ {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7E", 8},
+ {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F", 8},
+ {"\x00\x00\x00\x00\x00\x00\x00\x80", 8},
+ {"\x01\x00\x00\x00\x00\x00\x00\x80", 8},
+ {"\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
+
+};
+
+static void mangle_Magic(run_t *run, bool printable) {
+
+ uint64_t choice = util_rndGet(0, ARRAYSIZE(mangleMagicVals) - 1);
+ mangle_UseValue(run, mangleMagicVals[choice].val,
+ mangleMagicVals[choice].size, printable);
+
+}
+
+static void mangle_StaticDict(run_t *run, bool printable) {
+
+ if (run->global->mutate.dictionaryCnt == 0) {
+
+ mangle_Bytes(run, printable);
+ return;
+
+ }
+
+ uint64_t choice = util_rndGet(0, run->global->mutate.dictionaryCnt - 1);
+ mangle_UseValue(run, run->global->mutate.dictionary[choice].val,
+ run->global->mutate.dictionary[choice].len, printable);
+
+}
+
+static inline const uint8_t *mangle_FeedbackDict(run_t *run, size_t *len) {
+
+ if (!run->global->feedback.cmpFeedback) { return NULL; }
+ cmpfeedback_t *cmpf = run->global->feedback.cmpFeedbackMap;
+ uint32_t cnt = ATOMIC_GET(cmpf->cnt);
+ if (cnt == 0) { return NULL; }
+ if (cnt > ARRAYSIZE(cmpf->valArr)) { cnt = ARRAYSIZE(cmpf->valArr); }
+ uint32_t choice = util_rndGet(0, cnt - 1);
+ *len = (size_t)ATOMIC_GET(cmpf->valArr[choice].len);
+ if (*len == 0) { return NULL; }
+ return cmpf->valArr[choice].val;
+
+}
+
+static void mangle_ConstFeedbackDict(run_t *run, bool printable) {
+
+ size_t len;
+ const uint8_t *val = mangle_FeedbackDict(run, &len);
+ if (val == NULL) {
+
+ mangle_Bytes(run, printable);
+ return;
+
+ }
+
+ mangle_UseValue(run, val, len, printable);
+
+}
+
+static void mangle_MemSet(run_t *run, bool printable) {
+
+ size_t off = mangle_getOffSet(run);
+ size_t len = mangle_getLen(run->dynfile->size - off);
+ int val =
+ printable ? (int)util_rndPrintable() : (int)util_rndGet(0, UINT8_MAX);
+
+ memset(&run->dynfile->data[off], val, len);
+
+}
+
+static void mangle_RandomOverwrite(run_t *run, bool printable) {
+
+ size_t off = mangle_getOffSet(run);
+ size_t len = mangle_getLen(run->dynfile->size - off);
+ if (printable) {
+
+ util_rndBufPrintable(&run->dynfile->data[off], len);
+
+ } else {
+
+ util_rndBuf(&run->dynfile->data[off], len);
+
+ }
+
+}
+
+static void mangle_RandomInsert(run_t *run, bool printable) {
+
+ size_t off = mangle_getOffSet(run);
+ size_t len = mangle_getLen(run->dynfile->size - off);
+
+ len = mangle_Inflate(run, off, len, printable);
+
+ if (printable) {
+
+ util_rndBufPrintable(&run->dynfile->data[off], len);
+
+ } else {
+
+ util_rndBuf(&run->dynfile->data[off], len);
+
+ }
+
+}
+
+static inline void mangle_AddSubWithRange(run_t *run, size_t off, size_t varLen,
+ uint64_t range, bool printable) {
+
+ int64_t delta = (int64_t)util_rndGet(0, range * 2) - (int64_t)range;
+
+ switch (varLen) {
+
+ case 1: {
+
+ run->dynfile->data[off] += delta;
+ break;
+
+ }
+
+ case 2: {
+
+ int16_t val;
+ memcpy(&val, &run->dynfile->data[off], sizeof(val));
+ if (util_rnd64() & 0x1) {
+
+ val += delta;
+
+ } else {
+
+ /* Foreign endianess */
+ val = __builtin_bswap16(val);
+ val += delta;
+ val = __builtin_bswap16(val);
+
+ }
+
+ mangle_Overwrite(run, off, (uint8_t *)&val, varLen, printable);
+ break;
+
+ }
+
+ case 4: {
+
+ int32_t val;
+ memcpy(&val, &run->dynfile->data[off], sizeof(val));
+ if (util_rnd64() & 0x1) {
+
+ val += delta;
+
+ } else {
+
+ /* Foreign endianess */
+ val = __builtin_bswap32(val);
+ val += delta;
+ val = __builtin_bswap32(val);
+
+ }
+
+ mangle_Overwrite(run, off, (uint8_t *)&val, varLen, printable);
+ break;
+
+ }
+
+ case 8: {
+
+ int64_t val;
+ memcpy(&val, &run->dynfile->data[off], sizeof(val));
+ if (util_rnd64() & 0x1) {
+
+ val += delta;
+
+ } else {
+
+ /* Foreign endianess */
+ val = __builtin_bswap64(val);
+ val += delta;
+ val = __builtin_bswap64(val);
+
+ }
+
+ mangle_Overwrite(run, off, (uint8_t *)&val, varLen, printable);
+ break;
+
+ }
+
+ default: {
+
+ LOG_F("Unknown variable length size: %zu", varLen);
+
+ }
+
+ }
+
+}
+
+static void mangle_AddSub(run_t *run, bool printable) {
+
+ size_t off = mangle_getOffSet(run);
+
+ /* 1,2,4,8 */
+ size_t varLen = 1U << util_rndGet(0, 3);
+ if ((run->dynfile->size - off) < varLen) { varLen = 1; }
+
+ uint64_t range;
+ switch (varLen) {
+
+ case 1:
+ range = 16;
+ break;
+ case 2:
+ range = 4096;
+ break;
+ case 4:
+ range = 1048576;
+ break;
+ case 8:
+ range = 268435456;
+ break;
+ default:
+ LOG_F("Invalid operand size: %zu", varLen);
+
+ }
+
+ mangle_AddSubWithRange(run, off, varLen, range, printable);
+
+}
+
+static void mangle_IncByte(run_t *run, bool printable) {
+
+ size_t off = mangle_getOffSet(run);
+ if (printable) {
+
+ run->dynfile->data[off] = (run->dynfile->data[off] - 32 + 1) % 95 + 32;
+
+ } else {
+
+ run->dynfile->data[off] += (uint8_t)1UL;
+
+ }
+
+}
+
+static void mangle_DecByte(run_t *run, bool printable) {
+
+ size_t off = mangle_getOffSet(run);
+ if (printable) {
+
+ run->dynfile->data[off] = (run->dynfile->data[off] - 32 + 94) % 95 + 32;
+
+ } else {
+
+ run->dynfile->data[off] -= (uint8_t)1UL;
+
+ }
+
+}
+
+static void mangle_NegByte(run_t *run, bool printable) {
+
+ size_t off = mangle_getOffSet(run);
+ if (printable) {
+
+ run->dynfile->data[off] = 94 - (run->dynfile->data[off] - 32) + 32;
+
+ } else {
+
+ run->dynfile->data[off] = ~(run->dynfile->data[off]);
+
+ }
+
+}
+
+static void mangle_Expand(run_t *run, bool printable) {
+
+ size_t off = mangle_getOffSet(run);
+ size_t len;
+ if (util_rnd64() % 16) {
+
+ len = mangle_getLen(HF_MIN(16, run->global->mutate.maxInputSz - off));
+
+ } else {
+
+ len = mangle_getLen(run->global->mutate.maxInputSz - off);
+
+ }
+
+ mangle_Inflate(run, off, len, printable);
+
+}
+
+static void mangle_Shrink(run_t *run, bool printable HF_ATTR_UNUSED) {
+
+ if (run->dynfile->size <= 2U) { return; }
+
+ size_t off_start = mangle_getOffSet(run);
+ size_t len = mangle_LenLeft(run, off_start);
+ if (len == 0) { return; }
+ if (util_rnd64() % 16) {
+
+ len = mangle_getLen(HF_MIN(16, len));
+
+ } else {
+
+ len = mangle_getLen(len);
+
+ }
+
+ size_t off_end = off_start + len;
+ size_t len_to_move = run->dynfile->size - off_end;
+
+ mangle_Move(run, off_end, off_start, len_to_move);
+ input_setSize(run, run->dynfile->size - len);
+
+}
+
+static void mangle_ASCIINum(run_t *run, bool printable) {
+
+ size_t len = util_rndGet(2, 8);
+
+ char buf[20];
+ snprintf(buf, sizeof(buf), "%-19" PRId64, (int64_t)util_rnd64());
+
+ mangle_UseValue(run, (const uint8_t *)buf, len, printable);
+
+}
+
+static void mangle_ASCIINumChange(run_t *run, bool printable) {
+
+ size_t off = mangle_getOffSet(run);
+
+ /* Find a digit */
+ for (; off < run->dynfile->size; off++) {
+
+ if (isdigit(run->dynfile->data[off])) { break; }
+
+ }
+
+ if (off == run->dynfile->size) {
+
+ mangle_Bytes(run, printable);
+ return;
+
+ }
+
+ size_t len = HF_MIN(20, run->dynfile->size - off);
+ char numbuf[21] = {};
+ strncpy(numbuf, (const char *)&run->dynfile->data[off], len);
+ uint64_t val = (uint64_t)strtoull(numbuf, NULL, 10);
+
+ switch (util_rndGet(0, 5)) {
+
+ case 0:
+ val += util_rndGet(1, 256);
+ break;
+ case 1:
+ val -= util_rndGet(1, 256);
+ break;
+ case 2:
+ val *= util_rndGet(1, 256);
+ break;
+ case 3:
+ val /= util_rndGet(1, 256);
+ break;
+ case 4:
+ val = ~(val);
+ break;
+ case 5:
+ val = util_rnd64();
+ break;
+ default:
+ LOG_F("Invalid choice");
+
+ };
+
+ len = HF_MIN((size_t)snprintf(numbuf, sizeof(numbuf), "%" PRIu64, val), len);
+ mangle_Overwrite(run, off, (const uint8_t *)numbuf, len, printable);
+
+}
+
+static void mangle_Splice(run_t *run, bool printable) {
+
+ const uint8_t *buf;
+ size_t sz = input_getRandomInputAsBuf(run, &buf);
+ if (!sz) {
+
+ mangle_Bytes(run, printable);
+ return;
+
+ }
+
+ size_t remoteOff = mangle_getLen(sz) - 1;
+ size_t len = mangle_getLen(sz - remoteOff);
+ mangle_UseValue(run, &buf[remoteOff], len, printable);
+
+}
+
+static void mangle_Resize(run_t *run, bool printable) {
+
+ ssize_t oldsz = run->dynfile->size;
+ ssize_t newsz = 0;
+
+ uint64_t choice = util_rndGet(0, 32);
+ switch (choice) {
+
+ case 0: /* Set new size arbitrarily */
+ newsz = (ssize_t)util_rndGet(1, run->global->mutate.maxInputSz);
+ break;
+ case 1 ... 4: /* Increase size by a small value */
+ newsz = oldsz + (ssize_t)util_rndGet(0, 8);
+ break;
+ case 5: /* Increase size by a larger value */
+ newsz = oldsz + (ssize_t)util_rndGet(9, 128);
+ break;
+ case 6 ... 9: /* Decrease size by a small value */
+ newsz = oldsz - (ssize_t)util_rndGet(0, 8);
+ break;
+ case 10: /* Decrease size by a larger value */
+ newsz = oldsz - (ssize_t)util_rndGet(9, 128);
+ break;
+ case 11 ... 32: /* Do nothing */
+ newsz = oldsz;
+ break;
+ default:
+ LOG_F("Illegal value from util_rndGet: %" PRIu64, choice);
+ break;
+
+ }
+
+ if (newsz < 1) { newsz = 1; }
+ if (newsz > (ssize_t)run->global->mutate.maxInputSz) {
+
+ newsz = run->global->mutate.maxInputSz;
+
+ }
+
+ input_setSize(run, (size_t)newsz);
+ if (newsz > oldsz) {
+
+ if (printable) { memset(&run->dynfile->data[oldsz], ' ', newsz - oldsz); }
+
+ }
+
+}
+
+void mangle_mangleContent(run_t *run, int speed_factor) {
+
+ static void (*const mangleFuncs[])(run_t * run, bool printable) = {
+
+ /* Every *Insert or Expand expands file, so add more Shrink's */
+ mangle_Shrink,
+ mangle_Shrink,
+ mangle_Shrink,
+ mangle_Shrink,
+ mangle_Expand,
+ mangle_Bit,
+ mangle_IncByte,
+ mangle_DecByte,
+ mangle_NegByte,
+ mangle_AddSub,
+ mangle_MemSet,
+ mangle_MemSwap,
+ mangle_MemCopy,
+ mangle_Bytes,
+ mangle_ASCIINum,
+ mangle_ASCIINumChange,
+ mangle_ByteRepeatOverwrite,
+ mangle_ByteRepeatInsert,
+ mangle_Magic,
+ mangle_StaticDict,
+ mangle_ConstFeedbackDict,
+ mangle_RandomOverwrite,
+ mangle_RandomInsert,
+ mangle_Splice,
+
+ };
+
+ if (run->mutationsPerRun == 0U) { return; }
+ if (run->dynfile->size == 0U) {
+
+ mangle_Resize(run, /* printable= */ run->global->cfg.only_printable);
+
+ }
+
+ uint64_t changesCnt = run->global->mutate.mutationsPerRun;
+
+ if (speed_factor < 5) {
+
+ changesCnt = util_rndGet(1, run->global->mutate.mutationsPerRun);
+
+ } else if (speed_factor < 10) {
+
+ changesCnt = run->global->mutate.mutationsPerRun;
+
+ } else {
+
+ changesCnt = HF_MIN(speed_factor, 12);
+ changesCnt = HF_MAX(changesCnt, run->global->mutate.mutationsPerRun);
+
+ }
+
+ /* If last coverage acquisition was more than 5 secs ago, use splicing more
+ * frequently */
+ if ((time(NULL) - ATOMIC_GET(run->global->timing.lastCovUpdate)) > 5) {
+
+ if (util_rnd64() % 2) {
+
+ mangle_Splice(run, run->global->cfg.only_printable);
+
+ }
+
+ }
+
+ for (uint64_t x = 0; x < changesCnt; x++) {
+
+ uint64_t choice = util_rndGet(0, ARRAYSIZE(mangleFuncs) - 1);
+ mangleFuncs[choice](run, /* printable= */ run->global->cfg.only_printable);
+
+ }
+
+ wmb();
+
+}
+
diff --git a/custom_mutators/honggfuzz/mangle.h b/custom_mutators/honggfuzz/mangle.h
new file mode 100644
index 00000000..1b6a4943
--- /dev/null
+++ b/custom_mutators/honggfuzz/mangle.h
@@ -0,0 +1,32 @@
+/*
+ *
+ * honggfuzz - buffer mangling routines
+ * -----------------------------------------
+ *
+ * Author: Robert Swiecki <swiecki@google.com>
+ *
+ * Copyright 2010-2018 by Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ */
+
+#ifndef _HF_MANGLE_H_
+#define _HF_MANGLE_H_
+
+#include "honggfuzz.h"
+
+extern void mangle_mangleContent(run_t *run, int speed_factor);
+
+#endif
+
diff --git a/custom_mutators/honggfuzz/util.h b/custom_mutators/honggfuzz/util.h
new file mode 120000
index 00000000..51e19654
--- /dev/null
+++ b/custom_mutators/honggfuzz/util.h
@@ -0,0 +1 @@
+common.h \ No newline at end of file