about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Android.bp176
l---------Android.mk1
-rw-r--r--README.md6
-rwxr-xr-xafl-wine-trace4
-rw-r--r--custom_mutators/Android.bp115
-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
-rw-r--r--docs/Changelog.md1
-rw-r--r--include/afl-fuzz.h4
-rw-r--r--include/android-ashmem.h113
-rw-r--r--include/config.h2
-rw-r--r--instrumentation/README.instrument_list.md2
-rw-r--r--instrumentation/SanitizerCoverageLTO.so.cc2
-rw-r--r--instrumentation/afl-compiler-rt.o.c2
-rw-r--r--instrumentation/afl-llvm-lto-instrumentation.so.cc2
m---------qemu_mode/qemuafl0
-rw-r--r--src/afl-analyze.c3
-rw-r--r--src/afl-cc.c18
-rw-r--r--src/afl-fuzz-bitmap.c1
-rw-r--r--src/afl-fuzz-mutators.c5
-rw-r--r--src/afl-fuzz-run.c2
-rw-r--r--src/afl-fuzz-stats.c4
-rw-r--r--src/afl-fuzz.c6
-rw-r--r--src/afl-gotcpu.c3
-rw-r--r--src/afl-ld-lto.c1
-rw-r--r--src/afl-showmap.c3
-rw-r--r--src/afl-tmin.c4
-rw-r--r--utils/afl_frida/afl-frida.c201
-rw-r--r--utils/afl_frida/android/README.md1
-rw-r--r--utils/afl_frida/android/frida-gum-example.c130
-rw-r--r--utils/afl_network_proxy/afl-network-server.c4
35 files changed, 773 insertions, 223 deletions
diff --git a/Android.bp b/Android.bp
index 2c2114b2..5d6f0433 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,7 +1,16 @@
 cc_defaults {
   name: "afl-defaults",
+  sanitize: {
+    never: true,
+  },
+
+  local_include_dirs: [
+    "include",
+    "instrumentation",
+  ],
 
   cflags: [
+    "-flto=full",
     "-funroll-loops",
     "-Wno-pointer-sign",
     "-Wno-pointer-arith",
@@ -10,16 +19,22 @@ cc_defaults {
     "-Wno-unused-function",
     "-Wno-format",
     "-Wno-user-defined-warnings",
-    "-DUSE_TRACE_PC=1",
+    "-DAFL_LLVM_USE_TRACE_PC=1",
     "-DBIN_PATH=\"out/host/linux-x86/bin\"",
     "-DDOC_PATH=\"out/host/linux-x86/shared/doc/afl\"",
     "-D__USE_GNU",
+    "-D__aarch64__",
+    "-DDEBUG_BUILD",
+    "-U_FORTIFY_SOURCE",
+    "-ggdb3",
+    "-g",
+    "-O0",
+    "-fno-omit-frame-pointer",
   ],
 }
 
 cc_binary {
   name: "afl-fuzz",
-  static_executable: true,
   host_supported: true,
 
   defaults: [
@@ -27,7 +42,11 @@ cc_binary {
   ],
 
   srcs: [
-    "afl-fuzz.c",
+    "src/afl-fuzz*.c",
+    "src/afl-common.c",
+    "src/afl-sharedmem.c",
+    "src/afl-forkserver.c",
+    "src/afl-performance.c",
   ],
 }
 
@@ -41,7 +60,10 @@ cc_binary {
   ],
 
   srcs: [
-    "afl-showmap.c",
+    "src/afl-showmap.c",
+    "src/afl-common.c",
+    "src/afl-sharedmem.c",
+    "src/afl-forkserver.c",
   ],
 }
 
@@ -55,7 +77,11 @@ cc_binary {
   ],
 
   srcs: [
-    "afl-tmin.c",
+    "src/afl-tmin.c",
+    "src/afl-common.c",
+    "src/afl-sharedmem.c",
+    "src/afl-forkserver.c",
+    "src/afl-performance.c",
   ],
 }
 
@@ -69,7 +95,10 @@ cc_binary {
   ],
 
   srcs: [
-    "afl-analyze.c",
+    "src/afl-analyze.c",
+    "src/afl-common.c",
+    "src/afl-sharedmem.c",
+    "src/afl-performance.c",
   ],
 }
 
@@ -83,12 +112,13 @@ cc_binary {
   ],
 
   srcs: [
-    "afl-gotcpu.c",
+    "src/afl-gotcpu.c",
+    "src/afl-common.c",
   ],
 }
 
 cc_binary_host {
-  name: "afl-clang-fast",
+  name: "afl-cc",
   static_executable: true,
 
   defaults: [
@@ -98,44 +128,144 @@ cc_binary_host {
   cflags: [
     "-D__ANDROID__",
     "-DAFL_PATH=\"out/host/linux-x86/lib64\"",
+    "-DAFL_CLANG_FLTO=\"-flto=full\"",
+    "-DUSE_BINDIR=1",
+    "-DLLVM_BINDIR=\"prebuilts/clang/host/linux-x86/clang-r383902b/bin\"",
+    "-DLLVM_LIBDIR=\"prebuilts/clang/host/linux-x86/clang-r383902b/lib64\"",
+    "-DCLANGPP_BIN=\"prebuilts/clang/host/linux-x86/clang-r383902b/bin/clang++\"",
+    "-DAFL_REAL_LD=\"prebuilts/clang/host/linux-x86/clang-r383902b/bin/ld.lld\"",
+    "-DLLVM_LTO=1",
+    "-DLLVM_MAJOR=11",
+    "-DLLVM_MINOR=2",
   ],
 
   srcs: [
     "src/afl-cc.c",
+    "src/afl-common.c",
+  ],
+
+  symlinks: [
+    "afl-clang-fast",
+    "afl-clang-fast++",
   ],
 }
 
-cc_binary_host {
-  name: "afl-clang-fast++",
-  static_executable: true,
+cc_library_static {
+  name: "afl-llvm-rt",
+  compile_multilib: "both",
+  vendor_available: true,
+  host_supported: true,
+  recovery_available: true,
+  sdk_version: "9",
 
-  defaults: [
-    "afl-defaults",
+  apex_available: [
+    "com.android.adbd",
+    "com.android.appsearch",
+    "com.android.art",
+    "com.android.bluetooth.updatable",
+    "com.android.cellbroadcast",
+    "com.android.conscrypt",
+    "com.android.extservices",
+    "com.android.cronet",
+    "com.android.neuralnetworks",
+    "com.android.media",
+    "com.android.media.swcodec",
+    "com.android.mediaprovider",
+    "com.android.permission",
+    "com.android.runtime",
+    "com.android.resolv",
+    "com.android.tethering",
+    "com.android.wifi",
+    "com.android.sdkext",
+    "com.android.os.statsd",
+    "//any",
   ],
 
-  cflags: [
-    "-D__ANDROID__",
-    "-DAFL_PATH=\"out/host/linux-x86/lib64\"",
+  defaults: [
+    "afl-defaults",
   ],
 
   srcs: [
-    "src/afl-cc.c",
+    "instrumentation/afl-compiler-rt.o.c",
   ],
 }
 
-cc_library_static {
-  name: "afl-llvm-rt",
-  compile_multilib: "both",
+cc_library_headers {
+  name: "libafl_headers",
   vendor_available: true,
   host_supported: true,
-  recovery_available: true,
-  sdk_version: "9",
+
+  export_include_dirs: [
+    "include",
+  ],
+}
+
+cc_prebuilt_library_static {
+  name: "libfrida-gum",
+  compile_multilib: "64",
+  strip: {
+    none: true,
+  },
+
+  srcs: [
+    "utils/afl_frida/android/libfrida-gum.a",
+  ],
+
+  export_include_dirs: [
+    "utils/afl_frida/android",
+  ],
+}
+
+cc_library_shared {
+  name: "libtestinstr",
+
+  srcs: [
+    "utils/afl_frida/libtestinstr.c",
+  ],
+
+  cflags: [
+    "-O0",
+    "-fPIC",
+  ],
+}
+
+cc_binary {
+  name: "afl-frida",
+  compile_multilib: "64",
 
   defaults: [
     "afl-defaults",
   ],
 
+  cflags: [
+    "-g",
+    "-O0",
+    "-Wno-format",
+    "-Wno-pointer-sign",
+    "-fpermissive",
+    "-fPIC",
+  ],
+
+  static_libs: [
+    "afl-llvm-rt",
+    "libfrida-gum",
+  ],
+
+  shared_libs: [
+    "libdl",
+    "liblog",
+  ],
+
   srcs: [
-    "instrumentation/afl-llvm-rt.o.c",
+    "utils/afl_frida/afl-frida.c",
+  ],
+
+  local_include_dirs: [
+    "utils/afl_frida",
+    "utils/afl_frida/android",
   ],
 }
+
+subdirs = [
+  "custom_mutators",
+]
diff --git a/Android.mk b/Android.mk
deleted file mode 120000
index 33ceb8f0..00000000
--- a/Android.mk
+++ /dev/null
@@ -1 +0,0 @@
-Makefile
\ No newline at end of file
diff --git a/README.md b/README.md
index 9c0e3339..ce48f336 100644
--- a/README.md
+++ b/README.md
@@ -27,14 +27,14 @@
 
 ## Major changes in afl++ 3.0
 
-With afl++ 3.0 we introduced changes that break some previous afl and afl++
+With afl++ 3.0 we introduced changes that breaks some previous afl and afl++
 behaviours and defaults:
 
   * There are no llvm_mode and gcc_plugin subdirectories anymore and there is
     only one compiler: afl-cc. All previous compilers now symlink to this.
     All instrumentation source code is now in the `instrumentation/` folder.
   * The gcc_plugin was replaced with a new version submitted by AdaCore that
-    supports more features. thank you!
+    supports more features. Thank you!
   * qemu_mode got upgraded to QEMU 5.1, but to be able to build this a current
     ninja build tool version and python3 setuptools are required.
     qemu_mode also got new options like snapshotting, instrumenting specific
@@ -1107,7 +1107,7 @@ without feedback, bug reports, or patches from:
   Khaled Yakdan                         Kuang-che Wu
   Josephine Calliotte                   Konrad Welc
   Thomas Rooijakkers                    David Carlier
-  Ruben ten Hove
+  Ruben ten Hove                        Joey Jiao
 ```
 
 Thank you!
diff --git a/afl-wine-trace b/afl-wine-trace
index 8853a757..63ff896b 100755
--- a/afl-wine-trace
+++ b/afl-wine-trace
@@ -28,9 +28,9 @@ if not os.getenv("AFL_INST_LIBS"):
         os.environ["AFL_CODE_END"] = "0x%x" % (pe.OPTIONAL_HEADER.ImageBase + pe.OPTIONAL_HEADER.BaseOfCode + pe.OPTIONAL_HEADER.SizeOfCode)
 
 if pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_AMD64"] or pe.FILE_HEADER.Machine == pefile.MACHINE_TYPE["IMAGE_FILE_MACHINE_IA64"]:
-    os.environ["LD_PRELOAD"] = os.path.join(my_dir, "qemu_mode/unsigaction/unsigaction64.so")
+    os.environ["QEMU_SET_ENV"] = "LD_PRELOAD=" + os.path.join(my_dir, "qemu_mode/unsigaction/unsigaction64.so") + ",WINEARCH=win64"
 else:
-    os.environ["LD_PRELOAD"] = os.path.join(my_dir, "qemu_mode/unsigaction/unsigaction32.so")
+    os.environ["QEMU_SET_ENV"] = "LD_PRELOAD=" + os.path.join(my_dir, "qemu_mode/unsigaction/unsigaction32.so") + ",WINEARCH=win32"
 
 if os.getenv("WINECOV_QEMU_PATH"):
     qemu_path = os.getenv("WINECOV_QEMU_PATH")
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/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;
+}
+
diff --git a/docs/Changelog.md b/docs/Changelog.md
index e0f8e9bf..60f09ca5 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -19,6 +19,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
       for reporting)
     - if determinstic mode is active (-D, or -M without -d) then we sync
       after every queue entry as this can take very long time otherwise
+    - better detection if a target needs a large shared map
     - switched to a faster RNG
     - added hghwng's patch for faster trace map analysis
   - afl-cc
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 621e8745..f46d7707 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -37,10 +37,6 @@
   #define _FILE_OFFSET_BITS 64
 #endif
 
-#ifdef __ANDROID__
-  #include "android-ashmem.h"
-#endif
-
 #include "config.h"
 #include "types.h"
 #include "debug.h"
diff --git a/include/android-ashmem.h b/include/android-ashmem.h
index 41d4d2da..6939e06d 100644
--- a/include/android-ashmem.h
+++ b/include/android-ashmem.h
@@ -1,112 +1,81 @@
-/*
-   american fuzzy lop++ - android shared memory compatibility layer
-   ----------------------------------------------------------------
-
-   Originally written by Michal Zalewski
-
-   Now maintained by Marc Heuse <mh@mh-sec.de>,
-                     Heiko Eißfeldt <heiko.eissfeldt@hexco.de>,
-                     Andrea Fioraldi <andreafioraldi@gmail.com>,
-                     Dominik Maier <mail@dmnk.co>
-
-   Copyright 2016, 2017 Google Inc. All rights reserved.
-   Copyright 2019-2020 AFLplusplus Project. 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
-
-   This header re-defines the shared memory routines used by AFL++
-   using the Andoid API.
-
- */
-
+#ifdef __ANDROID__
 #ifndef _ANDROID_ASHMEM_H
 #define _ANDROID_ASHMEM_H
 
-#ifdef __ANDROID__
-
-  #include <fcntl.h>
-  #include <linux/shm.h>
-  #include <linux/ashmem.h>
-  #include <sys/ioctl.h>
-  #include <sys/mman.h>
-
-  #if __ANDROID_API__ >= 26
-    #define shmat bionic_shmat
-    #define shmctl bionic_shmctl
-    #define shmdt bionic_shmdt
-    #define shmget bionic_shmget
-  #endif
-
-  #include <sys/shm.h>
-  #undef shmat
-  #undef shmctl
-  #undef shmdt
-  #undef shmget
-  #include <stdio.h>
+#include <fcntl.h>
+#include <linux/ashmem.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
 
-  #define ASHMEM_DEVICE "/dev/ashmem"
+#if __ANDROID_API__ >= 26
+#define shmat bionic_shmat
+#define shmctl bionic_shmctl
+#define shmdt bionic_shmdt
+#define shmget bionic_shmget
+#endif
+#include <sys/shm.h>
+#undef shmat
+#undef shmctl
+#undef shmdt
+#undef shmget
+#include <stdio.h>
 
-static inline int shmctl(int __shmid, int __cmd, struct shmid_ds *__buf) {
+#define ASHMEM_DEVICE "/dev/ashmem"
 
+int shmctl(int __shmid, int __cmd, struct shmid_ds *__buf) {
   int ret = 0;
   if (__cmd == IPC_RMID) {
-
-    int               length = ioctl(__shmid, ASHMEM_GET_SIZE, NULL);
-    struct ashmem_pin pin = {0, (unsigned int)length};
+    int length = ioctl(__shmid, ASHMEM_GET_SIZE, NULL);
+    struct ashmem_pin pin = {0, length};
     ret = ioctl(__shmid, ASHMEM_UNPIN, &pin);
     close(__shmid);
-
   }
 
   return ret;
-
 }
 
-static inline int shmget(key_t __key, size_t __size, int __shmflg) {
-
-  (void)__shmflg;
-  int  fd, ret;
+int shmget(key_t __key, size_t __size, int __shmflg) {
+  (void) __shmflg;
+  int fd, ret;
   char ourkey[11];
 
   fd = open(ASHMEM_DEVICE, O_RDWR);
-  if (fd < 0) return fd;
+  if (fd < 0)
+    return fd;
 
   sprintf(ourkey, "%d", __key);
   ret = ioctl(fd, ASHMEM_SET_NAME, ourkey);
-  if (ret < 0) goto error;
+  if (ret < 0)
+    goto error;
 
   ret = ioctl(fd, ASHMEM_SET_SIZE, __size);
-  if (ret < 0) goto error;
+  if (ret < 0)
+    goto error;
 
   return fd;
 
 error:
   close(fd);
   return ret;
-
 }
 
-static inline void *shmat(int __shmid, const void *__shmaddr, int __shmflg) {
-
-  (void)__shmflg;
-  int   size;
+void *shmat(int __shmid, const void *__shmaddr, int __shmflg) {
+  (void) __shmflg;
+  int size;
   void *ptr;
 
   size = ioctl(__shmid, ASHMEM_GET_SIZE, NULL);
-  if (size < 0) { return NULL; }
+  if (size < 0) {
+    return NULL;
+  }
 
   ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, __shmid, 0);
-  if (ptr == MAP_FAILED) { return NULL; }
+  if (ptr == MAP_FAILED) {
+    return NULL;
+  }
 
   return ptr;
-
 }
 
-#endif                                                       /* __ANDROID__ */
-
-#endif
-
+#endif /* !_ANDROID_ASHMEM_H */
+#endif /* !__ANDROID__ */
diff --git a/include/config.h b/include/config.h
index c9c4a677..b5137553 100644
--- a/include/config.h
+++ b/include/config.h
@@ -192,7 +192,7 @@
 
 /* The same, for the test case minimizer: */
 
-#define TMIN_MAX_FILE (10 * 1024 * 1024U)
+#define TMIN_MAX_FILE (10 * 1024 * 1024)
 
 /* Block normalization steps for afl-tmin: */
 
diff --git a/instrumentation/README.instrument_list.md b/instrumentation/README.instrument_list.md
index 83197954..b47b50f6 100644
--- a/instrumentation/README.instrument_list.md
+++ b/instrumentation/README.instrument_list.md
@@ -41,7 +41,7 @@ in any function where you want:
   * `__AFL_COVERAGE_ON();` - enable coverage from this point onwards
   * `__AFL_COVERAGE_OFF();` - disable coverage from this point onwards
   * `__AFL_COVERAGE_DISCARD();` - reset all coverage gathered until this point
-  * `__AFL_COVERAGE_ABORT();` - mark this test case as unimportant. Whatever happens, afl-fuzz will ignore it.
+  * `__AFL_COVERAGE_SKIP();` - mark this test case as unimportant. Whatever happens, afl-fuzz will ignore it.
 
 ## 3) Selective instrumenation with AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST
 
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index 1d7ac934..016ac71f 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -1111,7 +1111,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
                getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
                getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
       OKF("Instrumented %u locations with no collisions (on average %llu "
-          "collisions would be in afl-gcc/afl-clang-fast) (%s mode).",
+          "collisions would be in afl-gcc/vanilla AFL) (%s mode).",
           inst, calculateCollisions(inst), modeline);
 
     }
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index de01cb69..14da4caa 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -1636,7 +1636,7 @@ void __afl_coverage_discard() {
 }
 
 // discard the testcase
-void __afl_coverage_abort() {
+void __afl_coverage_skip() {
 
   __afl_coverage_discard();
 
diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc
index 9cacacf9..13dca8c4 100644
--- a/instrumentation/afl-llvm-lto-instrumentation.so.cc
+++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc
@@ -1033,7 +1033,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
                getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
                getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
       OKF("Instrumented %d locations with no collisions (on average %llu "
-          "collisions would be in afl-gcc/afl-clang-fast) (%s mode).",
+          "collisions would be in afl-gcc/vanilla AFL) (%s mode).",
           inst_blocks, calculateCollisions(inst_blocks), modeline);
 
     }
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
-Subproject 5400ce883a751582473665d8fd18f8e8f9d14cd
+Subproject 21ff34383764a8c6f66509b3b8d5282468c721e
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index 8fc4434a..0af489fe 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -26,9 +26,6 @@
 
 #define AFL_MAIN
 
-#ifdef __ANDROID__
-  #include "android-ashmem.h"
-#endif
 #include "config.h"
 #include "types.h"
 #include "debug.h"
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 2ce986c7..b0b11f48 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -586,6 +586,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
       if (instrument_mode == INSTRUMENT_PCGUARD) {
 
 #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
+#ifdef __ANDROID__
+        cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
+#else
         if (have_instr_list) {
 
           if (!be_quiet)
@@ -605,6 +608,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
         }
 
+#endif
 #else
   #if LLVM_MAJOR >= 4
         if (!be_quiet)
@@ -834,7 +838,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     cc_params[cc_par_cnt++] =
         "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;"
         "extern \"C\" void __afl_coverage_discard();"
-        "extern \"C\" void __afl_coverage_abort();"
+        "extern \"C\" void __afl_coverage_skip();"
         "extern \"C\" void __afl_coverage_on();"
         "extern \"C\" void __afl_coverage_off();";
 
@@ -843,7 +847,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     cc_params[cc_par_cnt++] =
         "-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;"
         "void __afl_coverage_discard();"
-        "void __afl_coverage_abort();"
+        "void __afl_coverage_skip();"
         "void __afl_coverage_on();"
         "void __afl_coverage_off();";
 
@@ -1031,6 +1035,10 @@ int main(int argc, char **argv, char **envp) {
 
 #endif
 
+#ifdef __ANDROID__
+    have_llvm = 1;
+#endif
+
   if ((ptr = find_object("afl-gcc-pass.so", argv[0])) != NULL) {
 
     have_gcc_plugin = 1;
@@ -1802,11 +1810,8 @@ int main(int argc, char **argv, char **envp) {
   if (!be_quiet && cmplog_mode)
     printf("CmpLog mode by <andreafioraldi@gmail.com>\n");
 
-#ifdef __ANDROID__
-  ptr = find_object("afl-compiler-rt.so", argv[0]);
-#else
+#ifndef __ANDROID__
   ptr = find_object("afl-compiler-rt.o", argv[0]);
-#endif
 
   if (!ptr) {
 
@@ -1819,6 +1824,7 @@ int main(int argc, char **argv, char **envp) {
   if (debug) { DEBUGF("rt=%s obj_path=%s\n", ptr, obj_path); }
 
   ck_free(ptr);
+#endif
 
   edit_params(argc, argv, envp);
 
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index ed8c2510..586f3990 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -703,7 +703,6 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
         if (!classified) {
 
           classify_counts(&afl->fsrv);
-          //          classified = 1;
 
         }
 
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index 089707b9..80df6d08 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -141,7 +141,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
   struct custom_mutator *mutator = ck_alloc(sizeof(struct custom_mutator));
 
   mutator->name = fn;
-  mutator->name_short = strrchr(fn, '/') + 1;
+  if (memchr(fn, '/', strlen(fn)))
+    mutator->name_short = strrchr(fn, '/') + 1;
+  else
+    mutator->name_short = strdup(fn);
   ACTF("Loading custom mutator library from '%s'...", fn);
 
   dh = dlopen(fn, RTLD_NOW);
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index b597488b..17c305ed 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -424,7 +424,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
 
   if (unlikely(afl->fixed_seed)) {
 
-    diff_us = (afl->fsrv.exec_tmout - 1) * afl->stage_max;
+    diff_us = (u64)(afl->fsrv.exec_tmout - 1) * (u64)afl->stage_max;
 
   } else {
 
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index e86f2aeb..e67bace9 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -58,7 +58,11 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) {
   for (i = 0; i < argc; ++i) {
 
     if (i) fprintf(f, " ");
+#ifdef __ANDROID__
+    if (memchr(argv[i], '\'', sizeof(argv[i]))) {
+#else
     if (index(argv[i], '\'')) {
+#endif
 
       fprintf(f, "'");
       for (j = 0; j < strlen(argv[i]); j++)
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 88c40ee8..95bc0694 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -584,7 +584,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
         if (afl->timeout_given) { FATAL("Multiple -t options not supported"); }
 
-        if (sscanf(optarg, "%u%c", &afl->fsrv.exec_tmout, &suffix) < 1 ||
+        if (!optarg || sscanf(optarg, "%u%c", &afl->fsrv.exec_tmout, &suffix) < 1 ||
             optarg[0] == '-') {
 
           FATAL("Bad syntax used for -t");
@@ -766,7 +766,7 @@ int main(int argc, char **argv_orig, char **envp) {
       case 'V': {
 
         afl->most_time_key = 1;
-        if (sscanf(optarg, "%llu", &afl->most_time) < 1 || optarg[0] == '-') {
+        if (!optarg || sscanf(optarg, "%llu", &afl->most_time) < 1 || optarg[0] == '-') {
 
           FATAL("Bad syntax used for -V");
 
@@ -777,7 +777,7 @@ int main(int argc, char **argv_orig, char **envp) {
       case 'E': {
 
         afl->most_execs_key = 1;
-        if (sscanf(optarg, "%llu", &afl->most_execs) < 1 || optarg[0] == '-') {
+        if (!optarg || sscanf(optarg, "%llu", &afl->most_execs) < 1 || optarg[0] == '-') {
 
           FATAL("Bad syntax used for -E");
 
diff --git a/src/afl-gotcpu.c b/src/afl-gotcpu.c
index 1aea3e40..ac002a93 100644
--- a/src/afl-gotcpu.c
+++ b/src/afl-gotcpu.c
@@ -35,9 +35,6 @@
   #define _GNU_SOURCE
 #endif
 
-#ifdef __ANDROID__
-  #include "android-ashmem.h"
-#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c
index 7a4d9132..0671d1c4 100644
--- a/src/afl-ld-lto.c
+++ b/src/afl-ld-lto.c
@@ -253,7 +253,6 @@ static void edit_params(int argc, char **argv) {
 int main(int argc, char **argv) {
 
   s32 pid, i, status;
-  //  u8 * ptr;
   char thecwd[PATH_MAX];
 
   if (getenv("AFL_LD_CALLER") != NULL) {
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 5d98d646..ee6d6de9 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -31,9 +31,6 @@
 
 #define AFL_MAIN
 
-#ifdef __ANDROID__
-  #include "android-ashmem.h"
-#endif
 #include "config.h"
 #include "types.h"
 #include "debug.h"
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 6e2d7708..5fd60cd2 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -29,10 +29,6 @@
 
 #define AFL_MAIN
 
-#ifdef __ANDROID__
-  #include "android-ashmem.h"
-#endif
-
 #include "config.h"
 #include "types.h"
 #include "debug.h"
diff --git a/utils/afl_frida/afl-frida.c b/utils/afl_frida/afl-frida.c
index b5b8196d..087f18e8 100644
--- a/utils/afl_frida/afl-frida.c
+++ b/utils/afl_frida/afl-frida.c
@@ -153,7 +153,7 @@ static int enumerate_ranges(const GumRangeDetails *details,
 
 }
 
-int main() {
+int main(int argc, char** argv) {
 
 #ifndef __APPLE__
   (void)personality(ADDR_NO_RANDOMIZE);  // disable ASLR
@@ -164,105 +164,140 @@ int main() {
   //         If there is just one function, then there is nothing to change
   //         or add here.
 
-  void *dl = dlopen(TARGET_LIBRARY, RTLD_LAZY);
+  void *dl = NULL;
+  if (argc > 2) {
+    dl = dlopen(argv[1], RTLD_LAZY);
+  } else {
+    dl = dlopen(TARGET_LIBRARY, RTLD_LAZY);
+  }
   if (!dl) {
 
-    fprintf(stderr, "Could not load %s\n", TARGET_LIBRARY);
+    if (argc > 2)
+      fprintf(stderr, "Could not load %s\n", argv[1]);
+    else
+      fprintf(stderr, "Could not load %s\n", TARGET_LIBRARY);
     exit(-1);
 
   }
 
-  if (!(o_function = dlsym(dl, TARGET_FUNCTION))) {
+  if (argc > 2)
+    o_function = dlsym(dl, argv[2]);
+  else
+    o_function = dlsym(dl, TARGET_FUNCTION);
+  if (!o_function) {
 
-    fprintf(stderr, "Could not find function %s\n", TARGET_FUNCTION);
+    if (argc > 2)
+      fprintf(stderr, "Could not find function %s\n", argv[2]);
+    else
+      fprintf(stderr, "Could not find function %s\n", TARGET_FUNCTION);
     exit(-1);
 
   }
 
   // END STEP 2
 
-  gum_init_embedded();
-  if (!gum_stalker_is_supported()) {
-
-    gum_deinit_embedded();
-    return 1;
-
-  }
-
-  GumStalker *stalker = gum_stalker_new();
-
-  GumAddress     base_address = gum_module_find_base_address(TARGET_LIBRARY);
-  GumMemoryRange code_range;
-  gum_module_enumerate_ranges(TARGET_LIBRARY, GUM_PAGE_RX, enumerate_ranges,
-                              &code_range);
-
-  guint64 code_start = code_range.base_address;
-  guint64 code_end = code_range.base_address + code_range.size;
-  range_t instr_range = {0, code_start, code_end};
-
-  printf("Frida instrumentation: base=0x%lx instrumenting=0x%lx-%lx\n",
-         base_address, code_start, code_end);
-  if (!code_start || !code_end) {
-
-    fprintf(stderr, "Error: no valid memory address found for %s\n",
-            TARGET_LIBRARY);
-    exit(-1);
-
-  }
-
-  GumStalkerTransformer *transformer =
-      gum_stalker_transformer_make_from_callback(instr_basic_block,
-                                                 &instr_range, NULL);
-
-  // to ensure that the signatures are not optimized out
-  memcpy(__afl_area_ptr, (void *)AFL_PERSISTENT, sizeof(AFL_PERSISTENT) + 1);
-  memcpy(__afl_area_ptr + 32, (void *)AFL_DEFER_FORKSVR,
-         sizeof(AFL_DEFER_FORKSVR) + 1);
-  __afl_manual_init();
-
-  //
-  // any expensive target library initialization that has to be done just once
-  // - put that here
-  //
-
-  gum_stalker_follow_me(stalker, transformer, NULL);
-
-  while (__afl_persistent_loop(UINT32_MAX) != 0) {
-
-    previous_pc = 0;  // Required!
-
-#ifdef _DEBUG
-    fprintf(stderr, "CLIENT crc: %016llx len: %u\n",
-            hash64(__afl_fuzz_ptr, *__afl_fuzz_len), *__afl_fuzz_len);
-    fprintf(stderr, "RECV:");
-    for (int i = 0; i < *__afl_fuzz_len; i++)
-      fprintf(stderr, "%02x", __afl_fuzz_ptr[i]);
-    fprintf(stderr, "\n");
-#endif
-
-    // STEP 3: ensure the minimum length is present and setup the target
-    //         function to fuzz.
-
-    if (*__afl_fuzz_len > 0) {
-
-      __afl_fuzz_ptr[*__afl_fuzz_len] = 0;  // if you need to null terminate
-      (*o_function)(__afl_fuzz_ptr, *__afl_fuzz_len);
-
+  if (!getenv("AFL_FRIDA_TEST_INPUT")) {
+    gum_init_embedded();
+    if (!gum_stalker_is_supported()) {
+  
+      gum_deinit_embedded();
+      return 1;
+  
     }
+  
+    GumStalker *stalker = gum_stalker_new();
+  
+    GumAddress     base_address;
+    if (argc > 2)
+      base_address = gum_module_find_base_address(argv[1]);
+    else
+      base_address = gum_module_find_base_address(TARGET_LIBRARY);
+    GumMemoryRange code_range;
+    if (argc > 2)
+      gum_module_enumerate_ranges(argv[1], GUM_PAGE_RX, enumerate_ranges,
+                                &code_range);
+    else
+      gum_module_enumerate_ranges(TARGET_LIBRARY, GUM_PAGE_RX, enumerate_ranges,
+                                &code_range);
+  
+    guint64 code_start = code_range.base_address;
+    guint64 code_end = code_range.base_address + code_range.size;
+    range_t instr_range = {0, code_start, code_end};
+  
+    printf("Frida instrumentation: base=0x%lx instrumenting=0x%lx-%lx\n",
+           base_address, code_start, code_end);
+    if (!code_start || !code_end) {
+  
+      if (argc > 2)
+        fprintf(stderr, "Error: no valid memory address found for %s\n",
+              argv[1]);
+      else
+        fprintf(stderr, "Error: no valid memory address found for %s\n",
+              TARGET_LIBRARY);
+      exit(-1);
+  
+    }
+  
+    GumStalkerTransformer *transformer =
+        gum_stalker_transformer_make_from_callback(instr_basic_block,
+                                                   &instr_range, NULL);
+  
+    // to ensure that the signatures are not optimized out
+    memcpy(__afl_area_ptr, (void *)AFL_PERSISTENT, sizeof(AFL_PERSISTENT) + 1);
+    memcpy(__afl_area_ptr + 32, (void *)AFL_DEFER_FORKSVR,
+           sizeof(AFL_DEFER_FORKSVR) + 1);
+    __afl_manual_init();
+  
+    //
+    // any expensive target library initialization that has to be done just once
+    // - put that here
+    //
+  
+    gum_stalker_follow_me(stalker, transformer, NULL);
+  
+    while (__afl_persistent_loop(UINT32_MAX) != 0) {
+  
+      previous_pc = 0;  // Required!
+  
+  #ifdef _DEBUG
+      fprintf(stderr, "CLIENT crc: %016llx len: %u\n",
+              hash64(__afl_fuzz_ptr, *__afl_fuzz_len), *__afl_fuzz_len);
+      fprintf(stderr, "RECV:");
+      for (int i = 0; i < *__afl_fuzz_len; i++)
+        fprintf(stderr, "%02x", __afl_fuzz_ptr[i]);
+      fprintf(stderr, "\n");
+  #endif
+  
+      // STEP 3: ensure the minimum length is present and setup the target
+      //         function to fuzz.
+  
+      if (*__afl_fuzz_len > 0) {
+  
+        __afl_fuzz_ptr[*__afl_fuzz_len] = 0;  // if you need to null terminate
+        (*o_function)(__afl_fuzz_ptr, *__afl_fuzz_len);
+  
+      }
+  
+      // END STEP 3
+  
+    }
+  
+    gum_stalker_unfollow_me(stalker);
+  
+    while (gum_stalker_garbage_collect(stalker))
+      g_usleep(10000);
+  
+    g_object_unref(stalker);
+    g_object_unref(transformer);
+    gum_deinit_embedded();
 
-    // END STEP 3
-
+  } else {
+    char buf[8*1024] = {0};
+    int count = read(0, buf, sizeof(buf));
+    buf[8*1024-1] = '\0';
+    (*o_function)(buf, count);
   }
 
-  gum_stalker_unfollow_me(stalker);
-
-  while (gum_stalker_garbage_collect(stalker))
-    g_usleep(10000);
-
-  g_object_unref(stalker);
-  g_object_unref(transformer);
-  gum_deinit_embedded();
-
   return 0;
 
 }
diff --git a/utils/afl_frida/android/README.md b/utils/afl_frida/android/README.md
new file mode 100644
index 00000000..044b48a1
--- /dev/null
+++ b/utils/afl_frida/android/README.md
@@ -0,0 +1 @@
+For android, frida-gum package (ex. https://github.com/frida/frida/releases/download/14.2.6/frida-gum-devkit-14.2.6-android-arm64.tar.xz) is needed to be extracted in the directory.
diff --git a/utils/afl_frida/android/frida-gum-example.c b/utils/afl_frida/android/frida-gum-example.c
new file mode 100644
index 00000000..14d98248
--- /dev/null
+++ b/utils/afl_frida/android/frida-gum-example.c
@@ -0,0 +1,130 @@
+/*
+ * Compile with:
+ *
+ * clang -fPIC -DANDROID -ffunction-sections -fdata-sections -Os -pipe -g3 frida-gum-example.c -o frida-gum-example -L. -lfrida-gum -llog -ldl -lm -pthread -Wl,--gc-sections,-z,noexecstack,-z,relro,-z,now -fuse-ld=gold -fuse-ld=gold -Wl,--icf=all
+ *
+ * Visit https://frida.re to learn more about Frida.
+ */
+
+#include "frida-gum.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+
+typedef struct _ExampleListener ExampleListener;
+typedef enum _ExampleHookId ExampleHookId;
+
+struct _ExampleListener
+{
+  GObject parent;
+
+  guint num_calls;
+};
+
+enum _ExampleHookId
+{
+  EXAMPLE_HOOK_OPEN,
+  EXAMPLE_HOOK_CLOSE
+};
+
+static void example_listener_iface_init (gpointer g_iface, gpointer iface_data);
+
+#define EXAMPLE_TYPE_LISTENER (example_listener_get_type ())
+G_DECLARE_FINAL_TYPE (ExampleListener, example_listener, EXAMPLE, LISTENER, GObject)
+G_DEFINE_TYPE_EXTENDED (ExampleListener,
+                        example_listener,
+                        G_TYPE_OBJECT,
+                        0,
+                        G_IMPLEMENT_INTERFACE (GUM_TYPE_INVOCATION_LISTENER,
+                            example_listener_iface_init))
+
+int
+main (int argc,
+      char * argv[])
+{
+  GumInterceptor * interceptor;
+  GumInvocationListener * listener;
+
+  gum_init_embedded ();
+
+  interceptor = gum_interceptor_obtain ();
+  listener = g_object_new (EXAMPLE_TYPE_LISTENER, NULL);
+
+  gum_interceptor_begin_transaction (interceptor);
+  gum_interceptor_attach (interceptor,
+      GSIZE_TO_POINTER (gum_module_find_export_by_name (NULL, "open")),
+      listener,
+      GSIZE_TO_POINTER (EXAMPLE_HOOK_OPEN));
+  gum_interceptor_attach (interceptor,
+      GSIZE_TO_POINTER (gum_module_find_export_by_name (NULL, "close")),
+      listener,
+      GSIZE_TO_POINTER (EXAMPLE_HOOK_CLOSE));
+  gum_interceptor_end_transaction (interceptor);
+
+  close (open ("/etc/hosts", O_RDONLY));
+  close (open ("/etc/fstab", O_RDONLY));
+
+  g_print ("[*] listener got %u calls\n", EXAMPLE_LISTENER (listener)->num_calls);
+
+  gum_interceptor_detach (interceptor, listener);
+
+  close (open ("/etc/hosts", O_RDONLY));
+  close (open ("/etc/fstab", O_RDONLY));
+
+  g_print ("[*] listener still has %u calls\n", EXAMPLE_LISTENER (listener)->num_calls);
+
+  g_object_unref (listener);
+  g_object_unref (interceptor);
+
+  gum_deinit_embedded ();
+
+  return 0;
+}
+
+static void
+example_listener_on_enter (GumInvocationListener * listener,
+                           GumInvocationContext * ic)
+{
+  ExampleListener * self = EXAMPLE_LISTENER (listener);
+  ExampleHookId hook_id = GUM_IC_GET_FUNC_DATA (ic, ExampleHookId);
+
+  switch (hook_id)
+  {
+    case EXAMPLE_HOOK_OPEN:
+      g_print ("[*] open(\"%s\")\n", (const gchar *) gum_invocation_context_get_nth_argument (ic, 0));
+      break;
+    case EXAMPLE_HOOK_CLOSE:
+      g_print ("[*] close(%d)\n", GPOINTER_TO_INT (gum_invocation_context_get_nth_argument (ic, 0)));
+      break;
+  }
+
+  self->num_calls++;
+}
+
+static void
+example_listener_on_leave (GumInvocationListener * listener,
+                           GumInvocationContext * ic)
+{
+}
+
+static void
+example_listener_class_init (ExampleListenerClass * klass)
+{
+  (void) EXAMPLE_IS_LISTENER;
+  (void) glib_autoptr_cleanup_ExampleListener;
+}
+
+static void
+example_listener_iface_init (gpointer g_iface,
+                             gpointer iface_data)
+{
+  GumInvocationListenerInterface * iface = g_iface;
+
+  iface->on_enter = example_listener_on_enter;
+  iface->on_leave = example_listener_on_leave;
+}
+
+static void
+example_listener_init (ExampleListener * self)
+{
+}
diff --git a/utils/afl_network_proxy/afl-network-server.c b/utils/afl_network_proxy/afl-network-server.c
index 513dc8f2..fe225416 100644
--- a/utils/afl_network_proxy/afl-network-server.c
+++ b/utils/afl_network_proxy/afl-network-server.c
@@ -24,10 +24,6 @@
 
 #define AFL_MAIN
 
-#ifdef __ANDROID__
-  #include "android-ashmem.h"
-#endif
-
 #include "config.h"
 #include "types.h"
 #include "debug.h"