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/Android.bp115
-rw-r--r--custom_mutators/honggfuzz/mangle.c2
-rw-r--r--custom_mutators/libfuzzer/FuzzerDataFlowTrace.cpp10
-rw-r--r--custom_mutators/libfuzzer/FuzzerDefs.h2
-rw-r--r--custom_mutators/libfuzzer/FuzzerDictionary.h4
-rw-r--r--custom_mutators/libfuzzer/FuzzerRandom.h2
-rw-r--r--custom_mutators/libfuzzer/FuzzerTracePC.h8
-rw-r--r--custom_mutators/libprotobuf-mutator-example/Android.bp32
-rw-r--r--custom_mutators/libprotobuf-mutator-example/README.md1
-rw-r--r--custom_mutators/libprotobuf-mutator-example/lpm_aflpp_custom_mutator_input.cc118
-rw-r--r--custom_mutators/libprotobuf-mutator-example/lpm_aflpp_custom_mutator_input.h5
-rw-r--r--custom_mutators/libprotobuf-mutator-example/test.proto7
-rw-r--r--custom_mutators/libprotobuf-mutator-example/vuln.c17
13 files changed, 309 insertions, 14 deletions
diff --git a/custom_mutators/Android.bp b/custom_mutators/Android.bp
new file mode 100644
index 00000000..89abc3e9
--- /dev/null
+++ b/custom_mutators/Android.bp
@@ -0,0 +1,115 @@
+cc_library_shared {
+  name: "libfuzzer-mutator",
+  vendor_available: true,
+  host_supported: true,
+
+  cflags: [
+    "-g",
+    "-O0",
+    "-funroll-loops",
+    "-fPIC",
+    "-fpermissive",
+    "-std=c++11",
+  ],
+
+  srcs: [
+    "libfuzzer/FuzzerCrossOver.cpp",
+    "libfuzzer/FuzzerDataFlowTrace.cpp",
+    "libfuzzer/FuzzerDriver.cpp",
+    "libfuzzer/FuzzerExtFunctionsDlsym.cpp",
+    "libfuzzer/FuzzerExtFunctionsWeak.cpp",
+    "libfuzzer/FuzzerExtFunctionsWindows.cpp",
+    "libfuzzer/FuzzerExtraCounters.cpp",
+    "libfuzzer/FuzzerFork.cpp",
+    "libfuzzer/FuzzerIO.cpp",
+    "libfuzzer/FuzzerIOPosix.cpp",
+    "libfuzzer/FuzzerIOWindows.cpp",
+    "libfuzzer/FuzzerLoop.cpp",
+    "libfuzzer/FuzzerMerge.cpp",
+    "libfuzzer/FuzzerMutate.cpp",
+    "libfuzzer/FuzzerSHA1.cpp",
+    "libfuzzer/FuzzerTracePC.cpp",
+    "libfuzzer/FuzzerUtil.cpp",
+    "libfuzzer/FuzzerUtilDarwin.cpp",
+    "libfuzzer/FuzzerUtilFuchsia.cpp",
+    "libfuzzer/FuzzerUtilLinux.cpp",
+    "libfuzzer/FuzzerUtilPosix.cpp",
+    "libfuzzer/FuzzerUtilWindows.cpp",
+    "libfuzzer/libfuzzer.cpp",
+  ],
+
+  header_libs: [
+    "libafl_headers",
+  ],
+}
+
+/*cc_library_shared {
+  name: "honggfuzz-mutator",
+  vendor_available: true,
+  host_supported: true,
+
+  cflags: [
+    "-g",
+    "-O0",
+    "-funroll-loops",
+    "-fPIC",
+    "-Wl,-Bsymbolic",
+  ],
+
+  srcs: [
+    "honggfuzz/honggfuzz.c",
+    "honggfuzz/mangle.c",
+//    "../src/afl-perfomance.c",
+  ],
+
+  header_libs: [
+    "libafl_headers",
+  ],
+}*/
+
+cc_library_shared {
+  name: "radamsa-mutator",
+  vendor_available: true,
+  host_supported: true,
+
+  cflags: [
+    "-g",
+    "-O0",
+    "-funroll-loops",
+    "-fPIC",
+  ],
+
+  srcs: [
+    "radamsa/libradamsa.c",
+    "radamsa/radamsa-mutator.c",
+  ],
+
+  header_libs: [
+    "libafl_headers",
+  ],
+}
+
+cc_library_shared {
+  name: "symcc-mutator",
+  vendor_available: true,
+  host_supported: true,
+
+  cflags: [
+    "-g",
+    "-O0",
+    "-funroll-loops",
+    "-fPIC",
+  ],
+
+  srcs: [
+    "symcc/symcc.c",
+  ],
+
+  header_libs: [
+    "libafl_headers",
+  ],
+}
+
+subdirs = [
+  "libprotobuf-mutator-example",
+]
diff --git a/custom_mutators/honggfuzz/mangle.c b/custom_mutators/honggfuzz/mangle.c
index c2988319..9c3d1ed4 100644
--- a/custom_mutators/honggfuzz/mangle.c
+++ b/custom_mutators/honggfuzz/mangle.c
@@ -995,7 +995,7 @@ void mangle_mangleContent(run_t *run, int speed_factor) {
 
   }
 
-  uint64_t changesCnt = run->global->mutate.mutationsPerRun;
+  uint64_t changesCnt;
 
   if (speed_factor < 5) {
 
diff --git a/custom_mutators/libfuzzer/FuzzerDataFlowTrace.cpp b/custom_mutators/libfuzzer/FuzzerDataFlowTrace.cpp
index 797a52a7..489665f7 100644
--- a/custom_mutators/libfuzzer/FuzzerDataFlowTrace.cpp
+++ b/custom_mutators/libfuzzer/FuzzerDataFlowTrace.cpp
@@ -246,7 +246,7 @@ bool DataFlowTrace::Init(const std::string &DirPath, std::string *FocusFunction,
 
   }
 
-  if (!NumFunctions || FocusFuncIdx == SIZE_MAX || Files.size() <= 1)
+  if (FocusFuncIdx == SIZE_MAX || Files.size() <= 1)
     return false;
 
   // Read traces.
@@ -259,8 +259,8 @@ bool DataFlowTrace::Init(const std::string &DirPath, std::string *FocusFunction,
     if (!CorporaHashes.count(Name)) continue;  // not in the corpus.
     NumTraceFiles++;
     // Printf("=== %s\n", Name.c_str());
-    std::ifstream IF(SF.File);
-    while (std::getline(IF, L, '\n')) {
+    std::ifstream IF2(SF.File);
+    while (std::getline(IF2, L, '\n')) {
 
       size_t      FunctionNum = 0;
       std::string DFTString;
@@ -314,8 +314,8 @@ int CollectDataFlow(const std::string &DFTBinary, const std::string &DirPath,
     // we then request tags in [0,Size/2) and [Size/2, Size), and so on.
     // Function number => DFT.
     auto OutPath = DirPlusFile(DirPath, Hash(FileToVector(F.File)));
-    std::unordered_map<size_t, Vector<uint8_t>> DFTMap;
-    std::unordered_set<std::string>             Cov;
+//    std::unordered_map<size_t, Vector<uint8_t>> DFTMap;
+//    std::unordered_set<std::string>             Cov;
     Command                                     Cmd;
     Cmd.addArgument(DFTBinary);
     Cmd.addArgument(F.File);
diff --git a/custom_mutators/libfuzzer/FuzzerDefs.h b/custom_mutators/libfuzzer/FuzzerDefs.h
index 1a2752af..3952ac51 100644
--- a/custom_mutators/libfuzzer/FuzzerDefs.h
+++ b/custom_mutators/libfuzzer/FuzzerDefs.h
@@ -46,7 +46,7 @@ template<typename T>
       fuzzer_allocator() = default;
 
       template<class U>
-      fuzzer_allocator(const fuzzer_allocator<U>&) {}
+      explicit fuzzer_allocator(const fuzzer_allocator<U>&) {}
 
       template<class Other>
       struct rebind { typedef fuzzer_allocator<Other> other;  };
diff --git a/custom_mutators/libfuzzer/FuzzerDictionary.h b/custom_mutators/libfuzzer/FuzzerDictionary.h
index 301c5d9a..ddd2d2f1 100644
--- a/custom_mutators/libfuzzer/FuzzerDictionary.h
+++ b/custom_mutators/libfuzzer/FuzzerDictionary.h
@@ -49,7 +49,7 @@ typedef FixedWord<64> Word;
 class DictionaryEntry {
  public:
   DictionaryEntry() {}
-  DictionaryEntry(Word W) : W(W) {}
+  explicit DictionaryEntry(Word W) : W(W) {}
   DictionaryEntry(Word W, size_t PositionHint) : W(W), PositionHint(PositionHint) {}
   const Word &GetW() const { return W; }
 
@@ -92,7 +92,7 @@ class Dictionary {
     assert(Idx < Size);
     return DE[Idx];
   }
-  void push_back(DictionaryEntry DE) {
+  void push_back(const DictionaryEntry &DE) {
     if (Size < kMaxDictSize)
       this->DE[Size++] = DE;
   }
diff --git a/custom_mutators/libfuzzer/FuzzerRandom.h b/custom_mutators/libfuzzer/FuzzerRandom.h
index 659283ee..7b1e1b1d 100644
--- a/custom_mutators/libfuzzer/FuzzerRandom.h
+++ b/custom_mutators/libfuzzer/FuzzerRandom.h
@@ -16,7 +16,7 @@
 namespace fuzzer {
 class Random : public std::minstd_rand {
  public:
-  Random(unsigned int seed) : std::minstd_rand(seed) {}
+  explicit Random(unsigned int seed) : std::minstd_rand(seed) {}
   result_type operator()() { return this->std::minstd_rand::operator()(); }
   size_t Rand() { return this->operator()(); }
   size_t RandBool() { return Rand() % 2; }
diff --git a/custom_mutators/libfuzzer/FuzzerTracePC.h b/custom_mutators/libfuzzer/FuzzerTracePC.h
index 4601300c..a58fdf8d 100644
--- a/custom_mutators/libfuzzer/FuzzerTracePC.h
+++ b/custom_mutators/libfuzzer/FuzzerTracePC.h
@@ -145,10 +145,10 @@ private:
     };
     Region *Regions;
     size_t NumRegions;
-    uint8_t *Start() { return Regions[0].Start; }
-    uint8_t *Stop()  { return Regions[NumRegions - 1].Stop; }
-    size_t Size()   { return Stop() - Start(); }
-    size_t  Idx(uint8_t *P) {
+    uint8_t *Start() const { return Regions[0].Start; }
+    uint8_t *Stop()  const { return Regions[NumRegions - 1].Stop; }
+    size_t Size()    const { return Stop() - Start(); }
+    size_t  Idx(uint8_t *P) const {
       assert(P >= Start() && P < Stop());
       return P - Start();
     }
diff --git a/custom_mutators/libprotobuf-mutator-example/Android.bp b/custom_mutators/libprotobuf-mutator-example/Android.bp
new file mode 100644
index 00000000..01f1c23e
--- /dev/null
+++ b/custom_mutators/libprotobuf-mutator-example/Android.bp
@@ -0,0 +1,32 @@
+cc_library_shared {
+  name: "libprotobuf-mutator-example-afl",
+  vendor_available: true,
+  host_supported: true,
+
+  cflags: [
+    "-g",
+    "-O0",
+    "-fPIC",
+    "-Wall",
+  ],
+
+  srcs: [
+    "lpm_aflpp_custom_mutator_input.cc",
+    "test.proto",
+  ],
+
+  shared_libs: [
+    "libprotobuf-cpp-full",
+    "libprotobuf-mutator",
+  ],
+}
+
+cc_binary {
+  name: "libprotobuf-mutator-vuln",
+  vendor_available: true,
+  host_supported: true,
+
+  srcs: [
+    "vuln.c",
+  ],
+}
diff --git a/custom_mutators/libprotobuf-mutator-example/README.md b/custom_mutators/libprotobuf-mutator-example/README.md
new file mode 100644
index 00000000..5a844c00
--- /dev/null
+++ b/custom_mutators/libprotobuf-mutator-example/README.md
@@ -0,0 +1 @@
+Ported from [https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/5_libprotobuf_aflpp_custom_mutator_input](https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/5_libprotobuf_aflpp_custom_mutator_input)
diff --git a/custom_mutators/libprotobuf-mutator-example/lpm_aflpp_custom_mutator_input.cc b/custom_mutators/libprotobuf-mutator-example/lpm_aflpp_custom_mutator_input.cc
new file mode 100644
index 00000000..e0273849
--- /dev/null
+++ b/custom_mutators/libprotobuf-mutator-example/lpm_aflpp_custom_mutator_input.cc
@@ -0,0 +1,118 @@
+#include "lpm_aflpp_custom_mutator_input.h"
+#include <iostream>
+#include <sstream>
+#include <fstream>
+
+using std::cin;
+using std::cout;
+using std::endl;
+
+std::string ProtoToData(const TEST &test_proto) {
+    std::stringstream all;
+    const auto &aa = test_proto.a();
+    const auto &bb = test_proto.b();
+    all.write((const char*)&aa, sizeof(aa));
+    if(bb.size() != 0) {
+        all.write(bb.c_str(), bb.size());
+    }
+
+    std::string res = all.str();
+    if (bb.size() != 0 && res.size() != 0) {
+        // set PROTO_FUZZER_DUMP_PATH env to dump the serialized protobuf
+        if (const char *dump_path = getenv("PROTO_FUZZER_DUMP_PATH")) {
+            std::ofstream of(dump_path);
+            of.write(res.data(), res.size());
+        }
+    }
+    return res;
+}
+
+/**
+ * Initialize this custom mutator
+ *
+ * @param[in] afl a pointer to the internal state object. Can be ignored for
+ * now.
+ * @param[in] seed A seed for this mutator - the same seed should always mutate
+ * in the same way.
+ * @return Pointer to the data object this custom mutator instance should use.
+ *         There may be multiple instances of this mutator in one afl-fuzz run!
+ *         Return NULL on error.
+ */
+extern "C" MyMutator *afl_custom_init(void *afl, unsigned int seed) {
+    MyMutator *mutator = new MyMutator();
+    
+    mutator->RegisterPostProcessor(
+        TEST::descriptor(),
+        [](google::protobuf::Message* message, unsigned int seed) {
+            // libprotobuf-mutator's built-in mutator is kind of....crappy :P
+            // Even a dumb fuzz like `TEST.a = rand();` is better in this case... Q_Q
+            // We register a post processor to apply our dumb fuzz
+            
+            TEST *t = static_cast<TEST *>(message);
+            t->set_a(rand());
+        });
+
+    srand(seed);
+    return mutator;
+}
+
+/**
+ * Perform custom mutations on a given input
+ *
+ * @param[in] data pointer returned in afl_custom_init for this fuzz case
+ * @param[in] buf Pointer to input data to be mutated
+ * @param[in] buf_size Size of input data
+ * @param[out] out_buf the buffer we will work on. we can reuse *buf. NULL on
+ * error.
+ * @param[in] add_buf Buffer containing the additional test case
+ * @param[in] add_buf_size Size of the additional test case
+ * @param[in] max_size Maximum size of the mutated output. The mutation must not
+ *     produce data larger than max_size.
+ * @return Size of the mutated output.
+ */
+extern "C" size_t afl_custom_fuzz(MyMutator *mutator, // return value from afl_custom_init
+                       uint8_t *buf, size_t buf_size, // input data to be mutated
+                       uint8_t **out_buf, // output buffer
+                       uint8_t *add_buf, size_t add_buf_size,  // add_buf can be NULL
+                       size_t max_size) {
+    // This function can be named either "afl_custom_fuzz" or "afl_custom_mutator"
+    // A simple test shows that "buf" will be the content of the current test case
+    // "add_buf" will be the next test case ( from AFL++'s input queue )
+    
+    TEST input;
+    // parse input data to TEST
+    // Notice that input data should be a serialized protobuf data
+    // Check ./in/ii and test_protobuf_serializer for more detail
+    bool parse_ok = input.ParseFromArray(buf, buf_size);
+    if(!parse_ok) {
+        // Invalid serialize protobuf data. Don't mutate.
+        // Return a dummy buffer. Also mutated_size = 0
+        static uint8_t *dummy = new uint8_t[10]; // dummy buffer with no data
+        *out_buf = dummy;
+        return 0;
+    }
+    // mutate the protobuf
+    mutator->Mutate(&input, max_size);
+    
+    // Convert protobuf to raw data
+    const TEST *p = &input;
+    std::string s = ProtoToData(*p);
+    // Copy to a new buffer ( mutated_out )
+    size_t mutated_size = s.size() <= max_size ? s.size() : max_size; // check if raw data's size is larger than max_size
+    uint8_t *mutated_out = new uint8_t[mutated_size+1];
+    memcpy(mutated_out, s.c_str(), mutated_size); // copy the mutated data
+    // Assign the mutated data and return mutated_size
+    *out_buf = mutated_out;
+    return mutated_size;
+}
+
+/**
+ * Deinitialize everything
+ *
+ * @param data The data ptr from afl_custom_init
+ */
+extern "C" void afl_custom_deinit(void *data) {
+    // Honestly I don't know what to do with this...
+    return;
+}
+
diff --git a/custom_mutators/libprotobuf-mutator-example/lpm_aflpp_custom_mutator_input.h b/custom_mutators/libprotobuf-mutator-example/lpm_aflpp_custom_mutator_input.h
new file mode 100644
index 00000000..ebd3ca65
--- /dev/null
+++ b/custom_mutators/libprotobuf-mutator-example/lpm_aflpp_custom_mutator_input.h
@@ -0,0 +1,5 @@
+#include <src/mutator.h>
+#include "test.pb.h"
+
+class MyMutator : public protobuf_mutator::Mutator {
+};
diff --git a/custom_mutators/libprotobuf-mutator-example/test.proto b/custom_mutators/libprotobuf-mutator-example/test.proto
new file mode 100644
index 00000000..e2256c6e
--- /dev/null
+++ b/custom_mutators/libprotobuf-mutator-example/test.proto
@@ -0,0 +1,7 @@
+syntax = "proto2";
+
+message TEST {
+  required uint32 a = 1;
+  required string b = 2;
+}
+
diff --git a/custom_mutators/libprotobuf-mutator-example/vuln.c b/custom_mutators/libprotobuf-mutator-example/vuln.c
new file mode 100644
index 00000000..8ffb7080
--- /dev/null
+++ b/custom_mutators/libprotobuf-mutator-example/vuln.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+    char str[100]={};
+    read(0, str, 100);
+    int *ptr = NULL;
+    if( str[0] == '\x02' || str[0] == '\xe8') {
+        *ptr = 123; 
+    }
+    return 0;
+}
+