about summary refs log tree commit diff
path: root/custom_mutators
diff options
context:
space:
mode:
Diffstat (limited to 'custom_mutators')
-rw-r--r--custom_mutators/honggfuzz/honggfuzz.c1
-rw-r--r--custom_mutators/libfuzzer/FuzzerIO.cpp7
-rw-r--r--custom_mutators/libfuzzer/FuzzerLoop.cpp13
-rw-r--r--custom_mutators/libfuzzer/FuzzerMutate.cpp24
-rw-r--r--custom_mutators/libfuzzer/FuzzerMutate.h1
-rw-r--r--custom_mutators/libfuzzer/Makefile5
-rw-r--r--custom_mutators/libfuzzer/libfuzzer.cpp13
-rw-r--r--custom_mutators/radamsa/radamsa-mutator.c1
-rw-r--r--custom_mutators/symcc/symcc.c124
-rw-r--r--custom_mutators/symcc/test_examples/file_test.c36
-rw-r--r--custom_mutators/symcc/test_examples/stdin_test.c28
11 files changed, 237 insertions, 16 deletions
diff --git a/custom_mutators/honggfuzz/honggfuzz.c b/custom_mutators/honggfuzz/honggfuzz.c
index bde922c6..b4f07258 100644
--- a/custom_mutators/honggfuzz/honggfuzz.c
+++ b/custom_mutators/honggfuzz/honggfuzz.c
@@ -37,6 +37,7 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
 
   if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) {
 
+    free(data);
     perror("mutator_buf alloc");
     return NULL;
 
diff --git a/custom_mutators/libfuzzer/FuzzerIO.cpp b/custom_mutators/libfuzzer/FuzzerIO.cpp
index e0c15db4..d8d52b63 100644
--- a/custom_mutators/libfuzzer/FuzzerIO.cpp
+++ b/custom_mutators/libfuzzer/FuzzerIO.cpp
@@ -83,6 +83,8 @@ void WriteToFile(const std::string &Data, const std::string &Path) {
 
 void WriteToFile(const uint8_t *Data, size_t Size, const std::string &Path) {
 
+  return;
+ 
   // Use raw C interface because this function may be called from a sig handler.
   FILE *Out = fopen(Path.c_str(), "wb");
   if (!Out) return;
@@ -93,6 +95,8 @@ void WriteToFile(const uint8_t *Data, size_t Size, const std::string &Path) {
 
 void AppendToFile(const std::string &Data, const std::string &Path) {
 
+  return;
+
   AppendToFile(reinterpret_cast<const uint8_t *>(Data.data()), Data.size(),
                Path);
 
@@ -100,6 +104,8 @@ void AppendToFile(const std::string &Data, const std::string &Path) {
 
 void AppendToFile(const uint8_t *Data, size_t Size, const std::string &Path) {
 
+  return;
+
   FILE *Out = fopen(Path.c_str(), "a");
   if (!Out) return;
   fwrite(Data, sizeof(Data[0]), Size, Out);
@@ -182,6 +188,7 @@ void Printf(const char *Fmt, ...) {
 
 void VPrintf(bool Verbose, const char *Fmt, ...) {
 
+  return;
   if (!Verbose) return;
   va_list ap;
   va_start(ap, Fmt);
diff --git a/custom_mutators/libfuzzer/FuzzerLoop.cpp b/custom_mutators/libfuzzer/FuzzerLoop.cpp
index 201883f0..08fda520 100644
--- a/custom_mutators/libfuzzer/FuzzerLoop.cpp
+++ b/custom_mutators/libfuzzer/FuzzerLoop.cpp
@@ -206,6 +206,8 @@ void Fuzzer::StaticDeathCallback() {
 
 void Fuzzer::DumpCurrentUnit(const char *Prefix) {
 
+  return;
+
   if (!CurrentUnitData) return;  // Happens when running individual inputs.
   ScopedDisableMsanInterceptorChecks S;
   MD.PrintMutationSequence();
@@ -733,6 +735,7 @@ std::string Fuzzer::WriteToOutputCorpus(const Unit &U) {
 
 void Fuzzer::WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix) {
 
+  return;
   if (!Options.SaveArtifacts) return;
   std::string Path = Options.ArtifactPrefix + Prefix + Hash(U);
   if (!Options.ExactArtifactPath.empty())
@@ -1073,13 +1076,21 @@ void Fuzzer::MinimizeCrashLoop(const Unit &U) {
 
 }  // namespace fuzzer
 
+#ifdef  INTROSPECTION
+  extern const char *introspection_ptr;
+#endif
+
 extern "C" {
 
 ATTRIBUTE_INTERFACE size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size,
                                             size_t MaxSize) {
 
   assert(fuzzer::F);
-  return fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize);
+  size_t r = fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize);
+#ifdef  INTROSPECTION
+  introspection_ptr = fuzzer::F->GetMD().WriteMutationSequence();
+#endif
+  return r;
 
 }
 
diff --git a/custom_mutators/libfuzzer/FuzzerMutate.cpp b/custom_mutators/libfuzzer/FuzzerMutate.cpp
index eebae39b..edfe0455 100644
--- a/custom_mutators/libfuzzer/FuzzerMutate.cpp
+++ b/custom_mutators/libfuzzer/FuzzerMutate.cpp
@@ -14,6 +14,8 @@
 #include "FuzzerMutate.h"
 #include "FuzzerOptions.h"
 #include "FuzzerTracePC.h"
+#include <random>
+#include <chrono>
 
 namespace fuzzer {
 
@@ -100,15 +102,17 @@ size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size,
 
 }
 
+
 size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
                                                size_t MaxSize) {
-
   if (Size > MaxSize || Size == 0) return 0;
   size_t ShuffleAmount =
       Rand(std::min(Size, (size_t)8)) + 1;  // [1,8] and <= Size.
   size_t ShuffleStart = Rand(Size - ShuffleAmount);
   assert(ShuffleStart + ShuffleAmount <= Size);
-  std::shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, Rand);
+  unsigned num = std::chrono::system_clock::now().time_since_epoch().count();
+  std::shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, std::default_random_engine(num));
+  //std::shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, Rand);
   return Size;
 
 }
@@ -609,8 +613,24 @@ void MutationDispatcher::PrintRecommendedDictionary() {
 
 }
 
+const char *MutationDispatcher::WriteMutationSequence() {
+
+  static std::string buf;
+  buf = "";
+
+  for (size_t i = 0; i < CurrentMutatorSequence.size(); i++) {
+  
+    buf = buf + " " + CurrentMutatorSequence[i].Name;
+  
+  }
+  
+  return buf.c_str();
+
+}
+
 void MutationDispatcher::PrintMutationSequence(bool Verbose) {
 
+  return;
   Printf("MS: %zd ", CurrentMutatorSequence.size());
   size_t EntriesToPrint =
       Verbose ? CurrentMutatorSequence.size()
diff --git a/custom_mutators/libfuzzer/FuzzerMutate.h b/custom_mutators/libfuzzer/FuzzerMutate.h
index 37fd6100..6252f265 100644
--- a/custom_mutators/libfuzzer/FuzzerMutate.h
+++ b/custom_mutators/libfuzzer/FuzzerMutate.h
@@ -26,6 +26,7 @@ public:
   void StartMutationSequence();
   /// Print the current sequence of mutations. Only prints the full sequence
   /// when Verbose is true.
+  const char *WriteMutationSequence();
   void PrintMutationSequence(bool Verbose = true);
   /// Return the current sequence of mutations.
   std::string MutationSequence();
diff --git a/custom_mutators/libfuzzer/Makefile b/custom_mutators/libfuzzer/Makefile
index 95402f6c..51263b89 100644
--- a/custom_mutators/libfuzzer/Makefile
+++ b/custom_mutators/libfuzzer/Makefile
@@ -3,6 +3,11 @@ CFLAGS = -g -O3 -funroll-loops -fPIC -fpermissive -std=c++11
 #CFLAGS = -g -O0 -fPIC -fpermissive -std=c++11
 CXX ?= clang++
 
+ifdef INTROSPECTION
+  $(info Compiling with introspection documentation)
+  CFLAGS += -DINTROSPECTION=1
+endif
+
 all: libfuzzer-mutator.so
 
 FuzzerCrossOver.o:	FuzzerCrossOver.cpp
diff --git a/custom_mutators/libfuzzer/libfuzzer.cpp b/custom_mutators/libfuzzer/libfuzzer.cpp
index 5e37df66..dc1fbeb2 100644
--- a/custom_mutators/libfuzzer/libfuzzer.cpp
+++ b/custom_mutators/libfuzzer/libfuzzer.cpp
@@ -6,6 +6,10 @@
 //#include "debug.h"
 #include "afl-fuzz.h"
 
+#ifdef  INTROSPECTION
+  const char *introspection_ptr;
+#endif
+
 afl_state_t *afl_struct;
 
 extern "C" size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);
@@ -46,6 +50,7 @@ extern "C" my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
 
   if ((data->mutator_buf = (u8 *)malloc(MAX_FILE)) == NULL) {
 
+    free(data);
     perror("mutator_buf alloc");
     return NULL;
 
@@ -133,6 +138,14 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf,
 
 }
 
+#ifdef  INTROSPECTION
+extern "C" const char* afl_custom_introspection(my_mutator_t *data) {
+
+  return introspection_ptr;
+
+}
+#endif
+
 /**
  * Deinitialize everything
  *
diff --git a/custom_mutators/radamsa/radamsa-mutator.c b/custom_mutators/radamsa/radamsa-mutator.c
index 82d28001..624ace3d 100644
--- a/custom_mutators/radamsa/radamsa-mutator.c
+++ b/custom_mutators/radamsa/radamsa-mutator.c
@@ -33,6 +33,7 @@ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) {
 
   if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) {
 
+    free(data);
     perror("mutator_buf alloc");
     return NULL;
 
diff --git a/custom_mutators/symcc/symcc.c b/custom_mutators/symcc/symcc.c
index 18b475b8..a609dafb 100644
--- a/custom_mutators/symcc/symcc.c
+++ b/custom_mutators/symcc/symcc.c
@@ -1,7 +1,10 @@
+#define _GNU_SOURCE
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
 #include "config.h"
 #include "debug.h"
 #include "afl-fuzz.h"
@@ -21,6 +24,7 @@ typedef struct my_mutator {
   afl_state_t *afl;
   u8 *         mutator_buf;
   u8 *         out_dir;
+  u8 *         tmp_dir;
   u8 *         target;
   uint32_t     seed;
 
@@ -41,6 +45,7 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
 
   if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) {
 
+    free(data);
     perror("mutator_buf alloc");
     return NULL;
 
@@ -54,10 +59,11 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
   if (!(data->out_dir = getenv("SYMCC_OUTPUT_DIR"))) {
 
     data->out_dir = alloc_printf("%s/symcc", afl->out_dir);
-    setenv("SYMCC_OUTPUT_DIR", data->out_dir, 1);
 
   }
 
+  data->tmp_dir = alloc_printf("%s/tmp", data->out_dir);
+  setenv("SYMCC_OUTPUT_DIR", data->tmp_dir, 1);
   int pid = fork();
 
   if (pid == -1) return NULL;
@@ -83,6 +89,10 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
 
   if (mkdir(data->out_dir, 0755))
     PFATAL("Could not create directory %s", data->out_dir);
+
+  if (mkdir(data->tmp_dir, 0755))
+    PFATAL("Could not create directory %s", data->tmp_dir);
+
   DBG("out_dir=%s, target=%s\n", data->out_dir, data->target);
 
   return data;
@@ -95,33 +105,119 @@ void afl_custom_queue_new_entry(my_mutator_t * data,
                                 const uint8_t *filename_new_queue,
                                 const uint8_t *filename_orig_queue) {
 
-  int pid = fork();
+  int         pipefd[2];
+  struct stat st;
+  ACTF("Queueing to symcc: %s", filename_new_queue);
+  u8 *fn = alloc_printf("%s", filename_new_queue);
+  if (!(stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size)) {
 
-  if (pid == -1) return;
+    ck_free(fn);
+    PFATAL("Couldn't find enqueued file: %s", fn);
 
-  if (pid) pid = waitpid(pid, NULL, 0);
+  }
 
-  if (pid == 0) {
+  if (afl_struct->fsrv.use_stdin) {
+
+    if (pipe(pipefd) == -1) {
+
+      ck_free(fn);
+      PFATAL("Couldn't create a pipe for interacting with symcc child process");
+
+    }
+
+  }
+
+  int pid = fork();
 
-    setenv("SYMCC_INPUT_FILE", afl_struct->fsrv.out_file, 1);
+  if (pid == -1) return;
+
+  if (pid) {
 
     if (afl_struct->fsrv.use_stdin) {
 
-      u8 *fn = alloc_printf("%s/%s", afl_struct->out_dir, filename_new_queue);
+      close(pipefd[0]);
       int fd = open(fn, O_RDONLY);
 
       if (fd >= 0) {
 
         ssize_t r = read(fd, data->mutator_buf, MAX_FILE);
-        close(fd);
         DBG("fn=%s, fd=%d, size=%ld\n", fn, fd, r);
-        if (r <= 0) return;
-        close(0);
-        ck_write(0, data->mutator_buf, r, fn);
         ck_free(fn);
+        close(fd);
+        if (r <= 0) {
+
+          close(pipefd[1]);
+          return;
+
+        }
+
+        if (r > fcntl(pipefd[1], F_GETPIPE_SZ))
+          fcntl(pipefd[1], F_SETPIPE_SZ, MAX_FILE);
+        ck_write(pipefd[1], data->mutator_buf, r, filename_new_queue);
+
+      } else {
+
+        ck_free(fn);
+        close(pipefd[1]);
+        PFATAL(
+            "Something happened to the enqueued file before sending its "
+            "contents to symcc binary");
 
       }
 
+      close(pipefd[1]);
+
+    }
+
+    pid = waitpid(pid, NULL, 0);
+
+    // At this point we need to transfer files to output dir, since their names
+    // collide and symcc will just overwrite them
+
+    struct dirent **nl;
+    int32_t         items = scandir(data->tmp_dir, &nl, NULL, NULL);
+    u8 *            origin_name = basename(filename_new_queue);
+    int32_t         i;
+    if (items > 0) {
+
+      for (i = 0; i < (u32)items; ++i) {
+
+        struct stat st;
+        u8 *source_name = alloc_printf("%s/%s", data->tmp_dir, nl[i]->d_name);
+        DBG("test=%s\n", fn);
+        if (stat(source_name, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
+
+          u8 *destination_name =
+              alloc_printf("%s/%s.%s", data->out_dir, origin_name, nl[i]->d_name);
+          rename(source_name, destination_name);
+          ck_free(destination_name);
+          DBG("found=%s\n", source_name);
+
+        }
+
+        ck_free(source_name);
+        free(nl[i]);
+
+      }
+
+      free(nl);
+
+    }
+
+  }
+
+  if (pid == 0) {
+
+    if (afl_struct->fsrv.use_stdin) {
+
+      unsetenv("SYMCC_INPUT_FILE");
+      close(pipefd[1]);
+      dup2(pipefd[0], 0);
+
+    } else {
+
+      setenv("SYMCC_INPUT_FILE", afl_struct->fsrv.out_file, 1);
+
     }
 
     DBG("exec=%s\n", data->target);
@@ -129,6 +225,7 @@ void afl_custom_queue_new_entry(my_mutator_t * data,
     close(2);
     dup2(afl_struct->fsrv.dev_null_fd, 1);
     dup2(afl_struct->fsrv.dev_null_fd, 2);
+
     execvp(data->target, afl_struct->argv);
     DBG("exec=FAIL\n");
     exit(-1);
@@ -179,7 +276,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
 
   struct dirent **nl;
   int32_t         i, done = 0, items = scandir(data->out_dir, &nl, NULL, NULL);
-  size_t          size = 0;
+  ssize_t         size = 0;
 
   if (items <= 0) return 0;
 
@@ -198,6 +295,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
 
           size = read(fd, data->mutator_buf, max_size);
           *out_buf = data->mutator_buf;
+
           close(fd);
           done = 1;
 
@@ -216,7 +314,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
 
   free(nl);
   DBG("FUZZ size=%lu\n", size);
-  return size;
+  return (uint32_t)size;
 
 }
 
diff --git a/custom_mutators/symcc/test_examples/file_test.c b/custom_mutators/symcc/test_examples/file_test.c
new file mode 100644
index 00000000..f2b92986
--- /dev/null
+++ b/custom_mutators/symcc/test_examples/file_test.c
@@ -0,0 +1,36 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv) {
+
+  if (argc < 2) {
+
+    printf("Need a file argument\n");
+    return 1;
+
+  }
+
+  int fd = open(argv[1], O_RDONLY);
+  if (fd < 0) {
+
+    printf("Couldn't open file\n");
+    return 1;
+
+  }
+
+  uint32_t value = 0;
+
+  read(fd, &value, sizeof(value));
+  close(fd);
+
+  value = value ^ 0xffffffff;
+  if (value == 0x11223344) printf("Value one\n");
+  if (value == 0x44332211) printf("Value two\n");
+  if (value != 0x0) printf("Not zero\n");
+  return 0;
+
+}
+
diff --git a/custom_mutators/symcc/test_examples/stdin_test.c b/custom_mutators/symcc/test_examples/stdin_test.c
new file mode 100644
index 00000000..3acfc523
--- /dev/null
+++ b/custom_mutators/symcc/test_examples/stdin_test.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+
+  char     input_buffer[16];
+  uint32_t comparisonValue;
+  size_t   bytesRead;
+  bytesRead = read(STDIN_FILENO, input_buffer, sizeof(input_buffer));
+  if (bytesRead < 0) exit(-1);
+  comparisonValue = *(uint32_t *)input_buffer;
+  comparisonValue = comparisonValue ^ 0xff112233;
+  if (comparisonValue == 0x66554493) {
+
+    printf("First value\n");
+
+  } else {
+
+    if (comparisonValue == 0x84444415) printf("Second value\n");
+
+  }
+
+  return 0;
+
+}
+