about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--README.md112
m---------custom_mutators/grammar_mutator/grammar_mutator0
-rw-r--r--custom_mutators/libfuzzer/FuzzerLoop.cpp1
-rw-r--r--docs/Changelog.md8
-rw-r--r--docs/best_practices.md6
-rw-r--r--docs/branches.md3
-rw-r--r--docs/env_variables.md4
-rw-r--r--docs/fuzzing_binary-only_targets.md2
-rw-r--r--docs/fuzzing_expert.md4
-rw-r--r--docs/interpreting_output.md4
-rw-r--r--docs/known_limitations.md4
-rw-r--r--docs/life_pro_tips.md87
-rw-r--r--docs/parallel_fuzzing.md2
-rw-r--r--docs/rpc_statsd.md4
-rw-r--r--docs/triaging_crashes.md2
-rw-r--r--frida_mode/GNUmakefile23
-rw-r--r--frida_mode/README.md14
-rw-r--r--frida_mode/include/instrument.h1
-rw-r--r--frida_mode/include/ranges.h2
-rw-r--r--frida_mode/src/instrument/instrument.c1
-rw-r--r--frida_mode/src/instrument/instrument_arm32.c4
-rw-r--r--frida_mode/src/instrument/instrument_arm64.c3
-rw-r--r--frida_mode/src/instrument/instrument_x64.c369
-rw-r--r--frida_mode/src/instrument/instrument_x86.c3
-rw-r--r--frida_mode/src/ranges.c13
-rw-r--r--frida_mode/src/seccomp/seccomp_atomic.c2
-rw-r--r--frida_mode/src/seccomp/seccomp_callback.c2
-rw-r--r--frida_mode/src/seccomp/seccomp_child.c2
-rw-r--r--frida_mode/src/seccomp/seccomp_event.c2
-rw-r--r--frida_mode/src/seccomp/seccomp_filter.c2
-rw-r--r--frida_mode/src/seccomp/seccomp_print.c2
-rw-r--r--frida_mode/src/seccomp/seccomp_socket.c2
-rw-r--r--frida_mode/src/seccomp/seccomp_syscall.c2
-rw-r--r--include/afl-fuzz.h1
-rw-r--r--instrumentation/README.laf-intel.md5
-rw-r--r--instrumentation/README.llvm.md2
-rw-r--r--instrumentation/SanitizerCoverageLTO.so.cc36
-rw-r--r--instrumentation/SanitizerCoveragePCGUARD.so.cc2
-rw-r--r--instrumentation/afl-llvm-dict2file.so.cc24
-rw-r--r--instrumentation/afl-llvm-lto-instrumentation.so.cc24
-rw-r--r--instrumentation/afl-llvm-lto-instrumentlist.so.cc7
-rw-r--r--instrumentation/split-compares-pass.so.cc10
-rw-r--r--src/afl-forkserver.c6
-rw-r--r--src/afl-fuzz-init.c37
-rw-r--r--src/afl-fuzz-run.c30
-rw-r--r--src/afl-fuzz-stats.c49
-rw-r--r--src/afl-fuzz.c17
-rw-r--r--src/afl-showmap.c11
-rw-r--r--unicorn_mode/UNICORNAFL_VERSION2
-rw-r--r--unicorn_mode/samples/speedtest/rust/src/main.rs43
m---------unicorn_mode/unicornafl0
-rw-r--r--utils/socket_fuzzing/README.md2
52 files changed, 530 insertions, 470 deletions
diff --git a/README.md b/README.md
index 76ef8448..575a6a1a 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,8 @@ Release version: [3.14c](https://github.com/AFLplusplus/AFLplusplus/releases)
 
 GitHub version: 3.15a
 
-Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
+Repository: 
+[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
 
 AFL++ is maintained by:
 
@@ -17,57 +18,74 @@ AFL++ is maintained by:
 
 Originally developed by Michał "lcamtuf" Zalewski.
 
-AFL++ is a superior fork to Google's AFL - more speed, more and better mutations, more and better instrumentation, custom module support, etc.
+AFL++ is a superior fork to Google's AFL - more speed, more and better 
+mutations, more and better instrumentation, custom module support, etc.
 
-You are free to copy, modify, and distribute AFL++ with attribution under the terms of the Apache-2.0 License. See the [LICENSE](LICENSE) for details.
+You are free to copy, modify, and distribute AFL++ with attribution under the 
+terms of the Apache-2.0 License. See the [LICENSE](LICENSE) for details.
 
 ## Getting started
 
 Here is some information to get you started:
 
-* For releases, please see the [Releases](https://github.com/AFLplusplus/AFLplusplus/releases) tab and [branches](docs/branches.md). Also take a look at the list of [major behaviour changes in AFL++](docs/behaviour_changes.md).
-* If you want to use AFL++ for your academic work, check the [papers page](https://aflplus.plus/papers/) on the website.
+* For releases, please see the 
+  [Releases](https://github.com/AFLplusplus/AFLplusplus/releases) tab and 
+  [branches](docs/branches.md). Also take a look at the list of 
+  [important changes in AFL++](docs/important_changes.md).
+* If you want to use AFL++ for your academic work, check the 
+  [papers page](https://aflplus.plus/papers/) on the website.
 * To cite our work, look at the [Cite](#cite) section.
-* For comparisons, use the fuzzbench `aflplusplus` setup, or use `afl-clang-fast` with `AFL_LLVM_CMPLOG=1`. You can find the `aflplusplus` default configuration on Google's [fuzzbench](https://github.com/google/fuzzbench/tree/master/fuzzers/aflplusplus).
-* To get you started with tutorials, go to [docs/tutorials.md](docs/tutorials.md).
+* For comparisons, use the fuzzbench `aflplusplus` setup, or use 
+  `afl-clang-fast` with `AFL_LLVM_CMPLOG=1`. You can find the `aflplusplus` 
+  default configuration on Google's 
+  [fuzzbench](https://github.com/google/fuzzbench/tree/master/fuzzers/aflplusplus).
+* To get you started with tutorials, go to 
+  [docs/tutorials.md](docs/tutorials.md).
 
 ## Building and installing AFL++
 
-To have AFL++ easily available with everything compiled, pull the image directly from the Docker Hub:
+To have AFL++ easily available with everything compiled, pull the image 
+directly from the Docker Hub:
 
 ```shell
 docker pull aflplusplus/aflplusplus
 docker run -ti -v /location/of/your/target:/src aflplusplus/aflplusplus
 ```
 
-This image is automatically generated when a push to the stable repo happens (see [docs/branches.md](docs/branches.md)).
-You will find your target source code in `/src` in the container.
+This image is automatically generated when a push to the stable repo happens 
+(see [docs/branches.md](docs/branches.md)). You will find your target source 
+code in `/src` in the container.
 
 To build AFL++ yourself, continue at [docs/INSTALL.md](docs/INSTALL.md).
 
 ## Quick start: Fuzzing with AFL++
 
-*NOTE: Before you start, please read about the [common sense risks of fuzzing](docs/common_sense_risks.md).*
+*NOTE: Before you start, please read about the [common sense risks of 
+fuzzing](docs/common_sense_risks.md).*
 
-This is a quick start for fuzzing targets with the source code available.
-To read about the process in detail, see [docs/fuzzing_expert.md](docs/fuzzing_expert.md).
+This is a quick start for fuzzing targets with the source code available. To 
+read about the process in detail, see
+[docs/fuzzing_expert.md](docs/fuzzing_expert.md).
 
 To learn about fuzzing other targets, see:
-* Binary-only targets: [docs/fuzzing_binary-only_targets.md](docs/fuzzing_binary-only_targets.md)
-* Network services: [docs/best_practices.md#fuzzing-a-network-service](docs/best_practices.md#fuzzing-a-network-service)
-* GUI programs: [docs/best_practices.md#fuzzing-a-gui-program](docs/best_practices.md#fuzzing-a-gui-program)
+* Binary-only targets: 
+  [docs/fuzzing_binary-only_targets.md](docs/fuzzing_binary-only_targets.md)
+* Network services: 
+  [docs/best_practices.md#fuzzing-a-network-service](docs/best_practices.md#fuzzing-a-network-service)
+* GUI programs: 
+  [docs/best_practices.md#fuzzing-a-gui-program](docs/best_practices.md#fuzzing-a-gui-program)
 
 Step-by-step quick start:
 
-1. Compile the program or library to be fuzzed using `afl-cc`.
-A common way to do this would be:
+1. Compile the program or library to be fuzzed using `afl-cc`. A common way to 
+   do this would be:
 
         CC=/path/to/afl-cc CXX=/path/to/afl-c++ ./configure --disable-shared
         make clean all
 
-2. Get a small but valid input file that makes sense to the program.
-When fuzzing verbose syntax (SQL, HTTP, etc), create a dictionary as described
-in [dictionaries/README.md](../dictionaries/README.md), too.
+2. Get a small but valid input file that makes sense to the program. When 
+   fuzzing verbose syntax (SQL, HTTP, etc), create a dictionary as described in 
+   [dictionaries/README.md](dictionaries/README.md), too.
 
 3. If the program reads from stdin, run `afl-fuzz` like so:
 
@@ -78,42 +96,52 @@ in [dictionaries/README.md](../dictionaries/README.md), too.
 
    To add a dictionary, add `-x /path/to/dictionary.txt` to afl-fuzz.
 
-   If the program takes input from a file, you can put `@@` in the program's
+   If the program takes input from a file, you can put `@@` in the program's 
    command line; AFL will put an auto-generated file name in there for you.
 
-4. Investigate anything shown in red in the fuzzer UI by promptly consulting [docs/status_screen.md](docs/status_screen.md).
+4. Investigate anything shown in red in the fuzzer UI by promptly consulting 
+   [docs/status_screen.md](docs/status_screen.md).
 
-5. You will find found crashes and hangs in the subdirectories `crashes/` and
-   `hangs/` in the `-o output_dir` directory. You can replay the crashes by
-   feeding them to the target, e.g.:
-   `cat output_dir/crashes/id:000000,* | /path/to/tested/program [...program's cmdline...]`
-   You can generate cores or use gdb directly to follow up the crashes.
+5. You will find found crashes and hangs in the subdirectories `crashes/` and 
+   `hangs/` in the `-o output_dir` directory. You can replay the crashes by 
+   feeding them to the target, e.g.: `cat output_dir/crashes/id:000000,* | 
+   /path/to/tested/program [...program's cmdline...]` You can generate cores or 
+   use gdb directly to follow up the crashes.
 
 ## Contact
 
 Questions? Concerns? Bug reports?
 
-* The contributors can be reached via [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus).
-* Take a look at our [FAQ](docs/faq.md). If you find an interesting or important question missing, submit it via
-[https://github.com/AFLplusplus/AFLplusplus/discussions](https://github.com/AFLplusplus/AFLplusplus/discussions).
-* There is a mailing list for the AFL/AFL++ project ([browse archive](https://groups.google.com/group/afl-users)). To compare notes with other users or to get notified about major new features, send an email to <afl-users+subscribe@googlegroups.com>.
+* The contributors can be reached via 
+  [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus).
+* Take a look at our [FAQ](docs/FAQ.md). If you find an interesting or 
+  important question missing, submit it via 
+  [https://github.com/AFLplusplus/AFLplusplus/discussions](https://github.com/AFLplusplus/AFLplusplus/discussions).
+* There is a mailing list for the AFL/AFL++ project 
+  ([browse archive](https://groups.google.com/group/afl-users)). To compare 
+  notes with other users or to get notified about major new features, send an 
+  email to <afl-users+subscribe@googlegroups.com>.
 * Or join the [Awesome Fuzzing](https://discord.gg/gCraWct) Discord server.
 
 ## Help wanted
 
-We have several [ideas](docs/ideas.md) we would like to see in AFL++ to make it even better.
-However, we already work on so many things that we do not have the time for all the big ideas.
+We have several [ideas](docs/ideas.md) we would like to see in AFL++ to make it 
+even better. However, we already work on so many things that we do not have the 
+time for all the big ideas.
 
-This can be your way to support and contribute to AFL++ - extend it to do something cool.
+This can be your way to support and contribute to AFL++ - extend it to do 
+something cool.
 
-For everyone who wants to contribute (and send pull requests), please read our [contributing guidelines](CONTRIBUTING.md) before your submit.
+For everyone who wants to contribute (and send pull requests), please read our 
+[contributing guidelines](CONTRIBUTING.md) before your submit.
 
 ## Special thanks
 
-Many of the improvements to the original AFL and AFL++ wouldn't be possible without feedback, bug reports, or patches from our contributors.
+Many of the improvements to the original AFL and AFL++ wouldn't be possible 
+without feedback, bug reports, or patches from our contributors.
 
-Thank you!
-(For people sending pull requests - please add yourself to this list :-)
+Thank you! (For people sending pull requests - please add yourself to this list 
+:-)
 
 <details>
 
@@ -172,7 +200,9 @@ Thank you!
 
 ## Cite
 
-If you use AFL++ in scientific work, consider citing [our paper](https://www.usenix.org/conference/woot20/presentation/fioraldi) presented at WOOT'20:
+If you use AFL++ in scientific work, consider citing 
+[our paper](https://www.usenix.org/conference/woot20/presentation/fioraldi) 
+presented at WOOT'20:
 
     Andrea Fioraldi, Dominik Maier, Heiko Eißfeldt, and Marc Heuse. “AFL++: Combining incremental steps of fuzzing research”. In 14th USENIX Workshop on Offensive Technologies (WOOT 20). USENIX Association, Aug. 2020.
 
@@ -191,4 +221,4 @@ If you use AFL++ in scientific work, consider citing [our paper](https://www.use
   }
   ```
 
-</details>
\ No newline at end of file
+</details>
diff --git a/custom_mutators/grammar_mutator/grammar_mutator b/custom_mutators/grammar_mutator/grammar_mutator
-Subproject eedf07ddb0fb1f437f5e76b77cfd4064cf6a5d6
+Subproject b79d51a8daccbd7a693f9b6765c81ead14f28e2
diff --git a/custom_mutators/libfuzzer/FuzzerLoop.cpp b/custom_mutators/libfuzzer/FuzzerLoop.cpp
index 08fda520..6716dbf5 100644
--- a/custom_mutators/libfuzzer/FuzzerLoop.cpp
+++ b/custom_mutators/libfuzzer/FuzzerLoop.cpp
@@ -1086,6 +1086,7 @@ ATTRIBUTE_INTERFACE size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size,
                                             size_t MaxSize) {
 
   assert(fuzzer::F);
+  fuzzer::F->GetMD().StartMutationSequence();
   size_t r = fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize);
 #ifdef  INTROSPECTION
   introspection_ptr = fuzzer::F->GetMD().WriteMutationSequence();
diff --git a/docs/Changelog.md b/docs/Changelog.md
index dad5fee2..63896622 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -16,11 +16,16 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
     - fix a regression introduced in 3.10 that resulted in less
       coverage being detected. thanks to Collin May for reporting!
     - fix -n dumb mode (nobody should use this)
+    - fix stability issue with LTO and cmplog
+    - better banner
+  - frida_mode: David Carlier added Android support :)
   - afl-showmap, afl-tmin and afl-analyze now honor persistent mode
     for more speed. thanks to dloffre-snl for reporting!
+  - Prevent accidently killing non-afl/fuzz services when aborting
+    afl-showmap and other tools.
   - afl-cc:
     - fix for shared linking on MacOS
-    - llvm and LTO mode verified to work with new llvm 14-dev
+    - llvm and LTO mode modified to work with new llvm 14-dev (again)
   - added the very good grammar mutator "GramaTron" to the
     custom_mutators
   - added optimin, a faster and better corpus minimizer by
@@ -32,6 +37,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
   - fix AFL_PRELOAD issues on MacOS
   - removed utils/afl_frida because frida_mode/ is now so much better
   - added uninstall target to makefile (todo: update new readme!)
+  - removed indirections in rust callbacks for unicornafl
 
 
 ### Version ++3.14c (release)
diff --git a/docs/best_practices.md b/docs/best_practices.md
index 23fa237d..0708d49d 100644
--- a/docs/best_practices.md
+++ b/docs/best_practices.md
@@ -59,10 +59,10 @@ which allows you to define network state with different type of data packets.
 1. Use [llvm_mode](../instrumentation/README.llvm.md): afl-clang-lto (llvm >= 11) or afl-clang-fast (llvm >= 9 recommended).
 2. Use [persistent mode](../instrumentation/README.persistent_mode.md) (x2-x20 speed increase).
 3. Use the [AFL++ snapshot module](https://github.com/AFLplusplus/AFL-Snapshot-LKM) (x2 speed increase).
-4. If you do not use shmem persistent mode, use `AFL_TMPDIR` to put the input file directory on a tempfs location, see [docs/env_variables.md](docs/env_variables.md).
+4. If you do not use shmem persistent mode, use `AFL_TMPDIR` to put the input file directory on a tempfs location, see [env_variables.md](env_variables.md).
 5. Improve Linux kernel performance: modify `/etc/default/grub`, set `GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=off l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs nopcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off"`; then `update-grub` and `reboot` (warning: makes the system less secure).
 6. Running on an `ext2` filesystem with `noatime` mount option will be a bit faster than on any other journaling filesystem.
-7. Use your cores! [README.md:3.b) Using multiple cores/threads](../README.md#b-using-multiple-coresthreads).
+7. Use your cores! [fuzzing_expert.md:b) Using multiple cores](fuzzing_expert.md#b-using-multiple-cores).
 
 ### Improving stability
 
@@ -117,4 +117,4 @@ Four steps are required to do this and it also requires quite some knowledge of
 
      Recompile, fuzz it, be happy :)
 
-     This link explains this process for [Fuzzbench](https://github.com/google/fuzzbench/issues/677).
\ No newline at end of file
+     This link explains this process for [Fuzzbench](https://github.com/google/fuzzbench/issues/677).
diff --git a/docs/branches.md b/docs/branches.md
index 1e4ebbb2..ae147b08 100644
--- a/docs/branches.md
+++ b/docs/branches.md
@@ -7,4 +7,5 @@ The following branches exist:
 * [dev](https://github.com/AFLplusplus/AFLplusplus/tree/dev): development state of AFL++ - bleeding edge and you might catch a checkout which does not compile or has a bug. *We only accept PRs in dev!!*
 * (any other): experimental branches to work on specific features or testing new functionality or changes.
 
-For releases, please see the [Releases](https://github.com/AFLplusplus/AFLplusplus/releases) tab. Also take a look at the list of [major behaviour changes in AFL++](behaviour_changes.md).
\ No newline at end of file
+For releases, please see the [Releases](https://github.com/AFLplusplus/AFLplusplus/releases) tab.
+Also take a look at the list of [important changes in AFL++](important_changes.md).
\ No newline at end of file
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 0686f1a8..5f5c2510 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -2,7 +2,7 @@
 
   This document discusses the environment variables used by American Fuzzy Lop++
   to expose various exotic functions that may be (rarely) useful for power
-  users or for some types of custom fuzzing setups. See [README.md](README.md) for the general
+  users or for some types of custom fuzzing setups. See [../README.md](../README.md) for the general
   instruction manual.
 
   Note that most tools will warn on any unknown AFL environment variables.
@@ -422,7 +422,7 @@ checks or alter some of the more exotic semantics of the tool:
   - Setting `AFL_FORCE_UI` will force painting the UI on the screen even if
     no valid terminal was detected (for virtual consoles)
 
-  - If you are using persistent mode (you should, see [instrumentation/README.persistent_mode.md](instrumentation/README.persistent_mode.md))
+  - If you are using persistent mode (you should, see [instrumentation/README.persistent_mode.md](../instrumentation/README.persistent_mode.md))
     some targets keep inherent state due which a detected crash testcase does
     not crash the target again when the testcase is given. To be able to still
     re-trigger these crashes you can use the `AFL_PERSISTENT_RECORD` variable
diff --git a/docs/fuzzing_binary-only_targets.md b/docs/fuzzing_binary-only_targets.md
index 8b3bbeff..ea262f6e 100644
--- a/docs/fuzzing_binary-only_targets.md
+++ b/docs/fuzzing_binary-only_targets.md
@@ -72,7 +72,7 @@ cd unicorn_mode
 If the goal is to fuzz a dynamic library then there are two options available.
 For both you need to write a small harness that loads and calls the library.
 Then you fuzz this with either frida_mode or qemu_mode, and either use
-`AFL_INST_LIBS=1` or `AFL_QEMU/FRIDA_INST_RANGES`
+`AFL_INST_LIBS=1` or `AFL_QEMU/FRIDA_INST_RANGES`.
 
 Another, less precise and slower option is using ptrace with debugger interrupt
 instrumentation: [utils/afl_untracer/README.md](../utils/afl_untracer/README.md).
diff --git a/docs/fuzzing_expert.md b/docs/fuzzing_expert.md
index ca884159..96193f88 100644
--- a/docs/fuzzing_expert.md
+++ b/docs/fuzzing_expert.md
@@ -613,7 +613,7 @@ switch or honggfuzz.
  * If you do not use shmem persistent mode, use `AFL_TMPDIR` to point the input file on a tempfs location, see [env_variables.md](env_variables.md)
  * Linux: Improve kernel performance: modify `/etc/default/grub`, set `GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=off l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs nopcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off"`; then `update-grub` and `reboot` (warning: makes the system more insecure) - you can also just run `sudo afl-persistent-config`
  * Linux: Running on an `ext2` filesystem with `noatime` mount option will be a bit faster than on any other journaling filesystem
- * Use your cores! [3.b) Using multiple cores/threads](#b-using-multiple-coresthreads)
+ * Use your cores! [b) Using multiple cores](#b-using-multiple-cores)
  * Run `sudo afl-system-config` before starting the first afl-fuzz instance after a reboot
 
 ### The End
@@ -625,4 +625,4 @@ This is basically all you need to know to professionally run fuzzing campaigns.
 If you want to know more, the tons of texts in [docs/](./) will have you covered.
 
 Note that there are also a lot of tools out there that help fuzzing with AFL++
-(some might be deprecated or unsupported), see [links_tools.md](links_tools.md).
+(some might be deprecated or unsupported), see [tools.md](tools.md).
\ No newline at end of file
diff --git a/docs/interpreting_output.md b/docs/interpreting_output.md
index 54ad76df..327a0ac0 100644
--- a/docs/interpreting_output.md
+++ b/docs/interpreting_output.md
@@ -1,6 +1,6 @@
 # Interpreting output
 
-See the [docs/status_screen.md](docs/status_screen.md) file for information on
+See the [status_screen.md](status_screen.md) file for information on
 how to interpret the displayed stats and monitor the health of the process. Be
 sure to consult this file especially if any UI elements are highlighted in red.
 
@@ -68,4 +68,4 @@ cd utils/plot_ui
 make
 cd ../../
 sudo make install
-```
\ No newline at end of file
+```
diff --git a/docs/known_limitations.md b/docs/known_limitations.md
index deb539e2..2d8f84a5 100644
--- a/docs/known_limitations.md
+++ b/docs/known_limitations.md
@@ -15,7 +15,7 @@ Here are some of the most important caveats for AFL:
     To work around this, you can comment out the relevant checks (see
     utils/libpng_no_checksum/ for inspiration); if this is not possible,
     you can also write a postprocessor, one of the hooks of custom mutators.
-    See [docs/custom_mutators.md](docs/custom_mutators.md) on how to use
+    See [custom_mutators.md](custom_mutators.md) on how to use
     `AFL_CUSTOM_MUTATOR_LIBRARY`
 
   - There are some unfortunate trade-offs with ASAN and 64-bit binaries. This
@@ -33,4 +33,4 @@ Here are some of the most important caveats for AFL:
   - Occasionally, sentient machines rise against their creators. If this
     happens to you, please consult [http://lcamtuf.coredump.cx/prep/](http://lcamtuf.coredump.cx/prep/).
 
-Beyond this, see [INSTALL.md](INSTALL.md) for platform-specific tips.
\ No newline at end of file
+Beyond this, see [INSTALL.md](INSTALL.md) for platform-specific tips.
diff --git a/docs/life_pro_tips.md b/docs/life_pro_tips.md
deleted file mode 100644
index 13ffcea0..00000000
--- a/docs/life_pro_tips.md
+++ /dev/null
@@ -1,87 +0,0 @@
-# AFL "Life Pro Tips"
-
-Bite-sized advice for those who understand the basics, but can't be bothered
-to read or memorize every other piece of documentation for AFL.
-
-## Get more bang for your buck by using fuzzing dictionaries.
-
-See [dictionaries/README.md](../dictionaries/README.md) to learn how.
-
-## You can get the most out of your hardware by parallelizing AFL jobs.
-
-See [parallel_fuzzing.md](parallel_fuzzing.md) for step-by-step tips.
-
-## Improve the odds of spotting memory corruption bugs with libdislocator.so!
-
-It's easy. Consult [utils/libdislocator/README.md](../utils/libdislocator/README.md) for usage tips.
-
-## Want to understand how your target parses a particular input file?
-
-Try the bundled `afl-analyze` tool; it's got colors and all!
-
-## You can visually monitor the progress of your fuzzing jobs.
-
-Run the bundled `afl-plot` utility to generate browser-friendly graphs.
-
-## Need to monitor AFL jobs programmatically? 
-Check out the `fuzzer_stats` file in the AFL output dir or try `afl-whatsup`.
-
-## Puzzled by something showing up in red or purple in the AFL UI?
-It could be important - consult docs/status_screen.md right away!
-
-## Know your target? Convert it to persistent mode for a huge performance gain!
-Consult section #5 in README.llvm.md for tips.
-
-## Using clang? 
-Check out instrumentation/ for a faster alternative to afl-gcc!
-
-## Did you know that AFL can fuzz closed-source or cross-platform binaries?
-Check out qemu_mode/README.md and unicorn_mode/README.md for more.
-
-## Did you know that afl-fuzz can minimize any test case for you?
-Try the bundled `afl-tmin` tool - and get small repro files fast!
-
-## Not sure if a crash is exploitable? AFL can help you figure it out. Specify
-`-C` to enable the peruvian were-rabbit mode.
-
-## Trouble dealing with a machine uprising? Relax, we've all been there.
-
-Find essential survival tips at http://lcamtuf.coredump.cx/prep/.
-
-## Want to automatically spot non-crashing memory handling bugs?
-
-Try running an AFL-generated corpus through ASAN, MSAN, or Valgrind.
-
-## Good selection of input files is critical to a successful fuzzing job.
-
-See docs/perf_tips.md for pro tips.
-
-## You can improve the odds of automatically spotting stack corruption issues.
-
-Specify `AFL_HARDEN=1` in the environment to enable hardening flags.
-
-## Bumping into problems with non-reproducible crashes? 
-It happens, but usually
-isn't hard to diagnose. See section #7 in README.md for tips.
-
-## Fuzzing is not just about memory corruption issues in the codebase. 
-Add some
-sanity-checking `assert()` / `abort()` statements to effortlessly catch logic bugs.
-
-## Hey kid... pssst... want to figure out how AFL really works?
-
-Check out docs/technical_details.md for all the gory details in one place!
-
-## There's a ton of third-party helper tools designed to work with AFL!
-
-Be sure to check out docs/sister_projects.md before writing your own.
-
-## Need to fuzz the command-line arguments of a particular program?
-
-You can find a simple solution in utils/argv_fuzzing.
-
-## Attacking a format that uses checksums? 
-
-Remove the checksum-checking code or use a postprocessor!
-See `afl_custom_post_process` in custom_mutators/examples/example.c for more.
-
diff --git a/docs/parallel_fuzzing.md b/docs/parallel_fuzzing.md
index 90e12e89..e37276a5 100644
--- a/docs/parallel_fuzzing.md
+++ b/docs/parallel_fuzzing.md
@@ -4,7 +4,7 @@ This document talks about synchronizing afl-fuzz jobs on a single machine
 or across a fleet of systems. See README.md for the general instruction manual.
 
 Note that this document is rather outdated. please refer to the main document
-section on multiple core usage [../README.md#Using multiple cores](../README.md#b-using-multiple-coresthreads)
+section on multiple core usage [fuzzing_expert.md#Using multiple cores](fuzzing_expert.md#b-using-multiple-cores)
 for up to date strategies!
 
 ## 1) Introduction
diff --git a/docs/rpc_statsd.md b/docs/rpc_statsd.md
index 288d56cb..9b3d8d40 100644
--- a/docs/rpc_statsd.md
+++ b/docs/rpc_statsd.md
@@ -50,7 +50,7 @@ Depending on your StatsD server, you will be able to monitor, trigger alerts, or
     -  `librato`
     -  `signalfx`
     
-    For more information on environment variables, see [docs/env_variables.md](docs/env_variables.md).
+    For more information on environment variables, see [env_variables.md](env_variables.md).
 
     Note: When using multiple fuzzer instances with StatsD it is *strongly* recommended to set up `AFL_STATSD_TAGS_FLAVOR` to match your StatsD server. This will allow you to see individual fuzzer performance, detect bad ones, and see the progress of each strategy.
 
@@ -152,4 +152,4 @@ To run your fuzzing instances:
 AFL_STATSD_TAGS_FLAVOR=dogstatsd AFL_STATSD=1 afl-fuzz -M test-fuzzer-1 -i i -o o [./bin/my-application] @@
 AFL_STATSD_TAGS_FLAVOR=dogstatsd AFL_STATSD=1 afl-fuzz -S test-fuzzer-2 -i i -o o [./bin/my-application] @@
 ...
-```
\ No newline at end of file
+```
diff --git a/docs/triaging_crashes.md b/docs/triaging_crashes.md
index 1857c4b1..21ccecaa 100644
--- a/docs/triaging_crashes.md
+++ b/docs/triaging_crashes.md
@@ -43,4 +43,4 @@ file, attempts to sequentially flip bytes, and observes the behavior of the
 tested program. It then color-codes the input based on which sections appear to
 be critical, and which are not; while not bulletproof, it can often offer quick
 insights into complex file formats. More info about its operation can be found
-near the end of [docs/technical_details.md](docs/technical_details.md).
\ No newline at end of file
+near the end of [technical_details.md](technical_details.md).
\ No newline at end of file
diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile
index 3e35e2f6..ed35c9f6 100644
--- a/frida_mode/GNUmakefile
+++ b/frida_mode/GNUmakefile
@@ -30,8 +30,7 @@ AFL_CFLAGS:=-Wno-unused-parameter \
 
 LDFLAGS+=-shared \
 		 -lpthread \
-		 -lresolv \
-		 -ldl
+		 -lresolv
 
 ifdef DEBUG
 CFLAGS+=-Werror \
@@ -71,7 +70,9 @@ ifdef DEBUG
 endif
 LDFLAGS+=	-z noexecstack \
 			-Wl,--gc-sections \
-			-Wl,--exclude-libs,ALL
+			-Wl,--exclude-libs,ALL \
+		    -ldl \
+		    -lrt
 LDSCRIPT:=-Wl,--version-script=$(PWD)frida.map
 endif
 
@@ -79,6 +80,22 @@ ifeq "$(shell uname)" "Linux"
  OS:=linux
 endif
 
+ifneq "$(findstring android, $(shell $(CC) --version 2>/dev/null))" ""
+ OS:=android
+ ifneq "$(findstring aarch64, $(shell $(CC) --version 2>/dev/null))" ""
+   ARCH:=arm64
+ endif
+ ifneq "$(findstring arm, $(shell $(CC) --version 2>/dev/null))" ""
+   ARCH:=arm
+ endif
+ ifneq "$(findstring x86_64, $(shell $(CC) --version 2>/dev/null))" ""
+   ARCH:=x86_64
+ endif
+ ifneq "$(findstring i686, $(shell $(CC) --version 2>/dev/null))" ""
+   ARCH:=x86
+ endif
+endif
+
 ifndef OS
  $(error "Operating system unsupported")
 endif
diff --git a/frida_mode/README.md b/frida_mode/README.md
index 165f8089..df40c771 100644
--- a/frida_mode/README.md
+++ b/frida_mode/README.md
@@ -55,6 +55,20 @@ tests in 32-bit mode, run `make ARCH=x86 frida`. When switching between
 architectures it may be necessary to run `make clean` first for a given build
 target to remove previously generated binaries for a different architecture.
 
+### Android
+
+In order to build, you need to download the Android SDK.
+
+```
+https://developer.android.com/ndk/downloads
+```
+
+Then creating locally a standalone chain as follow.
+
+```
+https://developer.android.com/ndk/guides/standalone_toolchain
+```
+
 ## Usage
 
 FRIDA mode added some small modifications to `afl-fuzz` and similar tools
diff --git a/frida_mode/include/instrument.h b/frida_mode/include/instrument.h
index 909b2a2c..cac5ee93 100644
--- a/frida_mode/include/instrument.h
+++ b/frida_mode/include/instrument.h
@@ -29,6 +29,7 @@ GumStalkerTransformer *instrument_get_transformer(void);
 /* Functions to be implemented by the different architectures */
 gboolean instrument_is_coverage_optimize_supported(void);
 
+void instrument_coverage_optimize_init(void);
 void instrument_coverage_optimize(const cs_insn *   instr,
                                   GumStalkerOutput *output);
 
diff --git a/frida_mode/include/ranges.h b/frida_mode/include/ranges.h
index 0220a59d..3bd9eaa6 100644
--- a/frida_mode/include/ranges.h
+++ b/frida_mode/include/ranges.h
@@ -10,6 +10,8 @@ extern gboolean ranges_inst_jit;
 void ranges_config(void);
 void ranges_init(void);
 
+void ranges_print_debug_maps(void);
+
 gboolean range_is_excluded(GumAddress address);
 
 void ranges_exclude();
diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c
index 71d9bdf6..81d85aa1 100644
--- a/frida_mode/src/instrument/instrument.c
+++ b/frida_mode/src/instrument/instrument.c
@@ -356,6 +356,7 @@ void instrument_init(void) {
       instrument_hash_seed);
   instrument_hash_zero = instrument_get_offset_hash(0);
 
+  instrument_coverage_optimize_init();
   instrument_debug_init();
   instrument_coverage_init();
   asan_init();
diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c
index 0e15940a..4b0a648e 100644
--- a/frida_mode/src/instrument/instrument_arm32.c
+++ b/frida_mode/src/instrument/instrument_arm32.c
@@ -22,6 +22,10 @@ void instrument_coverage_optimize(const cs_insn *   instr,
 
 }
 
+void instrument_coverage_optimize_init(void) {
+  WARNF("Optimized coverage not supported on this architecture");
+}
+
 void instrument_flush(GumStalkerOutput *output) {
 
   gum_arm_writer_flush(output->writer.arm);
diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c
index cf37e048..80d1d845 100644
--- a/frida_mode/src/instrument/instrument_arm64.c
+++ b/frida_mode/src/instrument/instrument_arm64.c
@@ -95,6 +95,9 @@ void instrument_coverage_optimize(const cs_insn *   instr,
 
 }
 
+void instrument_coverage_optimize_init(void) {
+}
+
 void instrument_flush(GumStalkerOutput *output) {
 
   gum_arm64_writer_flush(output->writer.arm64);
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index 1c2cf113..a7eb650a 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -1,4 +1,16 @@
+#include <fcntl.h>
 #include <stddef.h>
+#include <sys/mman.h>
+#include <sys/shm.h>
+
+#if defined(__linux__)
+#if !defined(__ANDROID__)
+#include <asm/prctl.h>
+#include <sys/syscall.h>
+#else
+#include <linux/ashmem.h>
+#endif
+#endif
 
 #include "frida-gumjs.h"
 
@@ -6,245 +18,290 @@
 #include "debug.h"
 
 #include "instrument.h"
+#include "ranges.h"
 
 #if defined(__x86_64__)
 
-static GumAddress current_log_impl = GUM_ADDRESS(0);
+#ifndef MAP_FIXED_NOREPLACE
+  #ifdef MAP_EXCL
+    #define MAP_FIXED_NOREPLACE MAP_EXCL | MAP_FIXED
+  #else
+    #define MAP_FIXED_NOREPLACE MAP_FIXED
+  #endif
+#endif
 
-  #pragma pack(push, 1)
+gboolean instrument_is_coverage_optimize_supported(void) {
 
+  return true;
+
+}
+
+static gboolean instrument_coverage_in_range(gssize offset) {
+
+  return (offset >= G_MININT32 && offset <= G_MAXINT32);
+
+}
+
+  #pragma pack(push, 1)
 typedef struct {
 
-  /*
-   * pushfq
-   * push rdx
-   * mov rdx, [&previouspc] (rip relative addr)
-   * xor rdx, rdi (current_pc)
-   * shr rdi. 1
-   * mov [&previouspc], rdi
-   * lea rsi, [&_afl_area_ptr] (rip relative)
-   * add rdx, rsi
-   * add byte ptr [rdx], 1
-   * adc byte ptr [rdx], 0
-
-   * pop rdx
-   * popfq
-   */
+  // cur_location = (block_address >> 4) ^ (block_address << 8);
+  // shared_mem[cur_location ^ prev_location]++;
+  // prev_location = cur_location >> 1;
+
+  // => 0x7ffff6cfb086:      lea    rsp,[rsp-0x80]
+  //    0x7ffff6cfb08b:      pushf
+  //    0x7ffff6cfb08c:      push   rsi
+  //    0x7ffff6cfb08d:      mov    rsi,0x228
+  //    0x7ffff6cfb094:      xchg   QWORD PTR [rip+0x3136a5],rsi        # 0x7ffff700e740
+  //    0x7ffff6cfb09b:      xor    rsi,0x451
+  //    0x7ffff6cfb0a2:      add    BYTE PTR [rsi+0x10000],0x1
+  //    0x7ffff6cfb0a9:      adc    BYTE PTR [rsi+0x10000],0x0
+  //    0x7ffff6cfb0b0:      pop    rsi
+  //    0x7ffff6cfb0b1:      popf
+  //    0x7ffff6cfb0b2:      lea    rsp,[rsp+0x80]
+
+
+  uint8_t lea_rsp_rsp_sub_rz[5];
   uint8_t push_fq;
-  uint8_t push_rdx;
-  uint8_t mov_rdx_rip_off[7];
-  uint8_t xor_rdx_rdi[3];
-  uint8_t shr_rdi[3];
-  uint8_t mov_rip_off_rdi[7];
-
-  uint8_t lea_rdi_rip_off[7];
-  uint8_t add_rdx_rdi[3];
-  uint8_t add_byte_ptr_rdx[3];
-  uint8_t adc_byte_ptr_rdx[3];
-
-  uint8_t pop_rdx;
+  uint8_t push_rsi;
+
+  uint8_t mov_rsi_curr_loc_shr_1[7];
+  uint8_t xchg_rsi_prev_loc_curr_loc[7];
+  uint8_t xor_rsi_curr_loc[7];
+
+  uint8_t add_rsi_1[7];
+  uint8_t adc_rsi_0[7];
+
+  uint8_t pop_rsi;
   uint8_t pop_fq;
-  uint8_t ret;
+  uint8_t lsa_rsp_rsp_add_rz[8];
 
 } afl_log_code_asm_t;
 
   #pragma pack(pop)
 
-  #pragma pack(push, 8)
-typedef struct {
+typedef union {
 
-  afl_log_code_asm_t assembly;
-  uint64_t           current_pc;
+  afl_log_code_asm_t code;
+  uint8_t            bytes[0];
 
-} afl_log_code_t;
+} afl_log_code;
 
-  #pragma pack(pop)
+static const afl_log_code_asm_t template =
+    {
 
-typedef union {
+        .lea_rsp_rsp_sub_rz = {0x48, 0x8D, 0x64, 0x24, 0x80},
+        .push_fq = 0x9c,
+        .push_rsi = 0x56,
 
-  afl_log_code_t data;
-  uint8_t        bytes[0];
+        .mov_rsi_curr_loc_shr_1 = {0x48, 0xC7, 0xC6},
+        .xchg_rsi_prev_loc_curr_loc = {0x48, 0x87, 0x35},
+        .xor_rsi_curr_loc = {0x48, 0x81, 0xF6},
 
-} afl_log_code;
+        .add_rsi_1 = {0x80, 0x86, 0x00, 0x00, 0x00, 0x00, 0x01},
+        .adc_rsi_0 = {0x80, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00},
 
-static const afl_log_code_asm_t template = {
+        .pop_rsi = 0x5E,
+        .pop_fq = 0x9D,
+        .lsa_rsp_rsp_add_rz = {0x48, 0x8D, 0xA4, 0x24, 0x80, 0x00, 0x00, 0x00},
 
-    .push_fq = 0x9c,
-    .push_rdx = 0x52,
-    .mov_rdx_rip_off =
-        {
+}
 
-            0x48, 0x8b, 0x15,
-            /* TBC */
+;
 
-        },
+static gboolean instrument_coverage_find_low(const GumRangeDetails *details,
+                                             gpointer               user_data) {
 
-    .xor_rdx_rdi =
-        {
+  static GumAddress last_limit = (64ULL << 10);
+  gpointer *        address = (gpointer *)user_data;
 
-            0x48,
-            0x31,
-            0xfa,
+  if ((details->range->base_address - last_limit) > __afl_map_size) {
 
-        },
+    *address = GSIZE_TO_POINTER(last_limit);
+    return FALSE;
 
-    .shr_rdi = {0x48, 0xd1, 0xef},
-    .mov_rip_off_rdi = {0x48, 0x89, 0x3d},
+  }
 
-    .lea_rdi_rip_off =
-        {
+  if (details->range->base_address > ((2ULL << 20) - __afl_map_size)) {
 
-            0x48,
-            0x8d,
-            0x3d,
+    return FALSE;
 
-        },
+  }
 
-    .add_rdx_rdi = {0x48, 0x01, 0xfA},
+  last_limit = details->range->base_address + details->range->size;
+  return TRUE;
 
-    .add_byte_ptr_rdx =
-        {
+}
 
-            0x80,
-            0x02,
-            0x01,
+static void instrument_coverage_optimize_map_mmap_anon(gpointer address) {
 
-        },
+  __afl_area_ptr =
+      mmap(address, __afl_map_size, PROT_READ | PROT_WRITE,
+           MAP_FIXED_NOREPLACE | MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+  if (__afl_area_ptr != address) {
 
-    .adc_byte_ptr_rdx =
-        {
+    FATAL("Failed to map mmap __afl_area_ptr: %d", errno);
 
-            0x80,
-            0x12,
-            0x00,
+  }
 
-        },
+}
 
-    .pop_rdx = 0x5a,
-    .pop_fq = 0x9d,
-    .ret = 0xc3};
+static void instrument_coverage_optimize_map_mmap(char *   shm_file_path,
+                                                  gpointer address) {
 
-static guint8 align_pad[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
+  int shm_fd = -1;
 
-gboolean instrument_is_coverage_optimize_supported(void) {
+  if (munmap(__afl_area_ptr, __afl_map_size) != 0) {
 
-  return true;
+    FATAL("Failed to unmap previous __afl_area_ptr");
 
-}
+  }
 
-static gboolean instrument_coverage_in_range(gssize offset) {
+  __afl_area_ptr = NULL;
 
-  return (offset >= G_MININT32 && offset <= G_MAXINT32);
+#if !defined(__ANDROID__)
+  shm_fd = shm_open(shm_file_path, O_RDWR, DEFAULT_PERMISSION);
+  if (shm_fd == -1) { FATAL("shm_open() failed\n"); }
+#else
+  shm_fd = open("/dev/ashmem", O_RDWR);
+  if (shm_fd == -1) { FATAL("open() failed\n"); }
+  if (ioctl(shm_fd, ASHMEM_SET_NAME, shm_file_path) == -1) { FATAL("ioctl(ASHMEM_SET_NAME) failed"); }
+  if (ioctl(shm_fd, ASHMEM_SET_SIZE, __afl_map_size) == -1) { FATAL("ioctl(ASHMEM_SET_SIZE) failed"); }
+
+#endif
+
+  __afl_area_ptr = mmap(address, __afl_map_size, PROT_READ | PROT_WRITE,
+                        MAP_FIXED_NOREPLACE | MAP_SHARED, shm_fd, 0);
+  if (__afl_area_ptr != address) {
+
+    FATAL("Failed to map mmap __afl_area_ptr: %d", errno);
+
+  }
+
+  if (close(shm_fd) != 0) { FATAL("Failed to close shm_fd"); }
 
 }
 
-static void instrument_coverate_write_function(GumStalkerOutput *output) {
+static void instrument_coverage_optimize_map_shm(guint64  shm_env_val,
+                                                 gpointer address) {
 
-  guint64       misalign = 0;
-  GumX86Writer *cw = output->writer.x86;
-  GumAddress    code_addr = 0;
-  afl_log_code  code = {0};
-  /*guint64       instrument_hash_zero = 0;*/
+  if (shmdt(__afl_area_ptr) != 0) {
 
-  if (current_log_impl == 0 ||
-      !gum_x86_writer_can_branch_directly_between(cw->pc, current_log_impl) ||
-      !gum_x86_writer_can_branch_directly_between(cw->pc + 128,
-                                                  current_log_impl)) {
+    FATAL("Failed to detach previous __afl_area_ptr");
 
-    gconstpointer after_log_impl = cw->code + 1;
+  }
 
-    gum_x86_writer_put_jmp_near_label(cw, after_log_impl);
+  __afl_area_ptr = shmat(shm_env_val, address, 0);
+  if (__afl_area_ptr != address) {
 
-    misalign = (cw->pc & 0x7);
-    if (misalign != 0) {
+    FATAL("Failed to map shm __afl_area_ptr: %d", errno);
 
-      gum_x86_writer_put_bytes(cw, align_pad, 8 - misalign);
+  }
 
-    }
+}
 
-    current_log_impl = cw->pc;
-    // gum_x86_writer_put_breakpoint(cw);
-    code_addr = cw->pc;
+void instrument_coverage_optimize_init(void) {
 
-    code.data.assembly = template;
-    code.data.current_pc = instrument_get_offset_hash(0);
+  gpointer low_address = NULL;
 
-    gssize current_pc_value1 =
-        GPOINTER_TO_SIZE(&instrument_previous_pc) -
-        (code_addr + offsetof(afl_log_code, data.assembly.mov_rdx_rip_off) +
-         sizeof(code.data.assembly.mov_rdx_rip_off));
-    gssize patch_offset1 =
-        offsetof(afl_log_code, data.assembly.mov_rdx_rip_off) +
-        sizeof(code.data.assembly.mov_rdx_rip_off) - sizeof(gint);
-    if (!instrument_coverage_in_range(current_pc_value1)) {
+  gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, instrument_coverage_find_low,
+                               &low_address);
 
-      FATAL("Patch out of range (current_pc_value1): 0x%016lX",
-            current_pc_value1);
+  OKF("Low address: %p", low_address);
 
-    }
+  if (low_address == 0 ||
+      GPOINTER_TO_SIZE(low_address) > ((2UL << 20) - __afl_map_size)) {
 
-    gint *dst_pc_value = (gint *)&code.bytes[patch_offset1];
-    *dst_pc_value = (gint)current_pc_value1;
+    FATAL("Invalid low_address: %p", low_address);
 
-    gssize current_pc_value2 =
-        GPOINTER_TO_SIZE(&instrument_previous_pc) -
-        (code_addr + offsetof(afl_log_code, data.assembly.mov_rip_off_rdi) +
-         sizeof(code.data.assembly.mov_rip_off_rdi));
-    gssize patch_offset2 =
-        offsetof(afl_log_code, data.assembly.mov_rip_off_rdi) +
-        sizeof(code.data.assembly.mov_rip_off_rdi) - sizeof(gint);
+  }
 
-    if (!instrument_coverage_in_range(current_pc_value2)) {
+  ranges_print_debug_maps();
 
-      FATAL("Patch out of range (current_pc_value2): 0x%016lX",
-            current_pc_value2);
+  char *shm_env = getenv(SHM_ENV_VAR);
+  OKF("SHM_ENV_VAR: %s", shm_env);
 
-    }
+  if (shm_env == NULL) {
 
-    dst_pc_value = (gint *)&code.bytes[patch_offset2];
-    *dst_pc_value = (gint)current_pc_value2;
+    WARNF("SHM_ENV_VAR not set, using anonymous map for debugging purposes");
 
-    gsize afl_area_ptr_value =
-        GPOINTER_TO_SIZE(__afl_area_ptr) -
-        (code_addr + offsetof(afl_log_code, data.assembly.lea_rdi_rip_off) +
-         sizeof(code.data.assembly.lea_rdi_rip_off));
-    gssize afl_area_ptr_offset =
-        offsetof(afl_log_code, data.assembly.lea_rdi_rip_off) +
-        sizeof(code.data.assembly.lea_rdi_rip_off) - sizeof(gint);
+    instrument_coverage_optimize_map_mmap_anon(low_address);
 
-    if (!instrument_coverage_in_range(afl_area_ptr_value)) {
+  } else {
 
-      FATAL("Patch out of range (afl_area_ptr_value): 0x%016lX",
-            afl_area_ptr_value);
+    guint64 shm_env_val = g_ascii_strtoull(shm_env, NULL, 10);
 
-    }
+    if (shm_env_val == 0) {
 
-    gint *dst_afl_area_ptr_value = (gint *)&code.bytes[afl_area_ptr_offset];
-    *dst_afl_area_ptr_value = (gint)afl_area_ptr_value;
+      instrument_coverage_optimize_map_mmap(shm_env, low_address);
 
-    gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
+    } else {
 
-    gum_x86_writer_put_label(cw, after_log_impl);
+      instrument_coverage_optimize_map_shm(shm_env_val, low_address);
+
+    }
 
   }
 
+  OKF("__afl_area_ptr: %p", __afl_area_ptr);
+  OKF("instrument_previous_pc: %p", &instrument_previous_pc);
+
 }
 
 void instrument_coverage_optimize(const cs_insn *   instr,
                                   GumStalkerOutput *output) {
 
+  afl_log_code  code = {0};
   GumX86Writer *cw = output->writer.x86;
   guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address));
-  instrument_coverate_write_function(output);
-
-  gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP,
-                                        -GUM_RED_ZONE_SIZE);
-  gum_x86_writer_put_push_reg(cw, GUM_REG_RDI);
-  gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RDI, area_offset);
-  gum_x86_writer_put_call_address(cw, current_log_impl);
-  gum_x86_writer_put_pop_reg(cw, GUM_REG_RDI);
-  gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP,
-                                        GUM_RED_ZONE_SIZE);
+  GumAddress code_addr = 0;
+
+  // gum_x86_writer_put_breakpoint(cw);
+  code_addr = cw->pc;
+  code.code = template;
+
+  gssize curr_loc_shr_1_offset =
+      offsetof(afl_log_code, code.mov_rsi_curr_loc_shr_1) +
+      sizeof(code.code.mov_rsi_curr_loc_shr_1) - sizeof(guint32);
+
+  *((guint32 *)&code.bytes[curr_loc_shr_1_offset]) =
+      (guint32)(area_offset >> 1);
+
+  gssize prev_loc_value =
+      GPOINTER_TO_SIZE(&instrument_previous_pc) -
+      (code_addr + offsetof(afl_log_code, code.xchg_rsi_prev_loc_curr_loc) +
+       sizeof(code.code.xchg_rsi_prev_loc_curr_loc));
+  gssize prev_loc_value_offset =
+      offsetof(afl_log_code, code.xchg_rsi_prev_loc_curr_loc) +
+      sizeof(code.code.xchg_rsi_prev_loc_curr_loc) - sizeof(gint);
+  if (!instrument_coverage_in_range(prev_loc_value)) {
+
+    FATAL("Patch out of range (current_pc_value1): 0x%016lX", prev_loc_value);
+
+  }
+
+  *((gint *)&code.bytes[prev_loc_value_offset]) = (gint)prev_loc_value;
+
+  gssize xor_curr_loc_offset = offsetof(afl_log_code, code.xor_rsi_curr_loc) +
+                               sizeof(code.code.xor_rsi_curr_loc) -
+                               sizeof(guint32);
+
+  *((guint32 *)&code.bytes[xor_curr_loc_offset]) = (guint32)(area_offset);
+
+  gssize add_rsi_1_offset = offsetof(afl_log_code, code.add_rsi_1) +
+                            sizeof(code.code.add_rsi_1) - sizeof(guint32) - 1;
+
+  *((guint32 *)&code.bytes[add_rsi_1_offset]) =
+      (guint32)GPOINTER_TO_SIZE(__afl_area_ptr);
+
+  gssize adc_rsi_0_ffset = offsetof(afl_log_code, code.adc_rsi_0) +
+                           sizeof(code.code.adc_rsi_0) - sizeof(guint32) - 1;
+
+  *((guint32 *)&code.bytes[adc_rsi_0_ffset]) =
+      (guint32)GPOINTER_TO_SIZE(__afl_area_ptr);
+
+  gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
 
 }
 
diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c
index 7bf48f96..1ff5c920 100644
--- a/frida_mode/src/instrument/instrument_x86.c
+++ b/frida_mode/src/instrument/instrument_x86.c
@@ -83,6 +83,9 @@ void instrument_coverage_optimize(const cs_insn *   instr,
 
 }
 
+void instrument_coverage_optimize_init(void) {
+}
+
 void instrument_flush(GumStalkerOutput *output) {
 
   gum_x86_writer_flush(output->writer.x86);
diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c
index 5b6eb462..1b666fce 100644
--- a/frida_mode/src/ranges.c
+++ b/frida_mode/src/ranges.c
@@ -549,18 +549,19 @@ static GArray *merge_ranges(GArray *a) {
 
 }
 
+void ranges_print_debug_maps(void) {
+
+  gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges_callback, NULL);
+
+}
+
 void ranges_config(void) {
 
   if (getenv("AFL_FRIDA_DEBUG_MAPS") != NULL) { ranges_debug_maps = TRUE; }
   if (getenv("AFL_INST_LIBS") != NULL) { ranges_inst_libs = TRUE; }
   if (getenv("AFL_FRIDA_INST_JIT") != NULL) { ranges_inst_jit = TRUE; }
 
-  if (ranges_debug_maps) {
-
-    gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges_callback,
-                                 NULL);
-
-  }
+  if (ranges_debug_maps) { ranges_print_debug_maps(); }
 
   include_ranges = collect_ranges("AFL_FRIDA_INST_RANGES");
   exclude_ranges = collect_ranges("AFL_FRIDA_EXCLUDE_RANGES");
diff --git a/frida_mode/src/seccomp/seccomp_atomic.c b/frida_mode/src/seccomp/seccomp_atomic.c
index 5097511a..c2042f97 100644
--- a/frida_mode/src/seccomp/seccomp_atomic.c
+++ b/frida_mode/src/seccomp/seccomp_atomic.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <stdbool.h>
   #include <stdio.h>
diff --git a/frida_mode/src/seccomp/seccomp_callback.c b/frida_mode/src/seccomp/seccomp_callback.c
index 7e1e2070..a88196ac 100644
--- a/frida_mode/src/seccomp/seccomp_callback.c
+++ b/frida_mode/src/seccomp/seccomp_callback.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <execinfo.h>
   #include <fcntl.h>
diff --git a/frida_mode/src/seccomp/seccomp_child.c b/frida_mode/src/seccomp/seccomp_child.c
index f665f472..43a79894 100644
--- a/frida_mode/src/seccomp/seccomp_child.c
+++ b/frida_mode/src/seccomp/seccomp_child.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <fcntl.h>
   #include <sched.h>
diff --git a/frida_mode/src/seccomp/seccomp_event.c b/frida_mode/src/seccomp/seccomp_event.c
index dd4abde7..e2f592ca 100644
--- a/frida_mode/src/seccomp/seccomp_event.c
+++ b/frida_mode/src/seccomp/seccomp_event.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <stdint.h>
   #include <stdio.h>
diff --git a/frida_mode/src/seccomp/seccomp_filter.c b/frida_mode/src/seccomp/seccomp_filter.c
index 13ff7522..8d56c367 100644
--- a/frida_mode/src/seccomp/seccomp_filter.c
+++ b/frida_mode/src/seccomp/seccomp_filter.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <alloca.h>
   #include <errno.h>
diff --git a/frida_mode/src/seccomp/seccomp_print.c b/frida_mode/src/seccomp/seccomp_print.c
index be4d80ce..3cea1239 100644
--- a/frida_mode/src/seccomp/seccomp_print.c
+++ b/frida_mode/src/seccomp/seccomp_print.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <stdarg.h>
 
diff --git a/frida_mode/src/seccomp/seccomp_socket.c b/frida_mode/src/seccomp/seccomp_socket.c
index fae95805..ef937420 100644
--- a/frida_mode/src/seccomp/seccomp_socket.c
+++ b/frida_mode/src/seccomp/seccomp_socket.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <stdio.h>
   #include <string.h>
diff --git a/frida_mode/src/seccomp/seccomp_syscall.c b/frida_mode/src/seccomp/seccomp_syscall.c
index e023c131..8335b93c 100644
--- a/frida_mode/src/seccomp/seccomp_syscall.c
+++ b/frida_mode/src/seccomp/seccomp_syscall.c
@@ -1,4 +1,4 @@
-#ifndef __APPLE__
+#if defined(__linux__) && !defined(__ANDROID__)
 
   #include <limits.h>
   #include <stdio.h>
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 4b19e698..eaf55fb8 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -1130,7 +1130,6 @@ void   get_core_count(afl_state_t *);
 void   fix_up_sync(afl_state_t *);
 void   check_asan_opts(afl_state_t *);
 void   check_binary(afl_state_t *, u8 *);
-void   fix_up_banner(afl_state_t *, u8 *);
 void   check_if_tty(afl_state_t *);
 void   setup_signal_handlers(void);
 void   save_cmdline(afl_state_t *, u32, char **);
diff --git a/instrumentation/README.laf-intel.md b/instrumentation/README.laf-intel.md
index 229807e8..789055ed 100644
--- a/instrumentation/README.laf-intel.md
+++ b/instrumentation/README.laf-intel.md
@@ -3,9 +3,8 @@
 ## Introduction
 
 This originally is the work of an individual nicknamed laf-intel.
-His blog [Circumventing Fuzzing Roadblocks with Compiler Transformations]
-(https://lafintel.wordpress.com/) and gitlab repo [laf-llvm-pass]
-(https://gitlab.com/laf-intel/laf-llvm-pass/)
+His blog [Circumventing Fuzzing Roadblocks with Compiler Transformations](https://lafintel.wordpress.com/)
+and gitlab repo [laf-llvm-pass](https://gitlab.com/laf-intel/laf-llvm-pass/)
 describe some code transformations that
 help AFL++ to enter conditional blocks, where conditions consist of
 comparisons of large values.
diff --git a/instrumentation/README.llvm.md b/instrumentation/README.llvm.md
index 6e210a7c..5b1e60cc 100644
--- a/instrumentation/README.llvm.md
+++ b/instrumentation/README.llvm.md
@@ -2,7 +2,7 @@
 
   (See [../README.md](../README.md) for the general instruction manual.)
 
-  (See [README.gcc_plugin.md](../README.gcc_plugin.md) for the GCC-based instrumentation.)
+  (See [README.gcc_plugin.md](README.gcc_plugin.md) for the GCC-based instrumentation.)
 
 ## 1) Introduction
 
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index e06f8b93..d90fa867 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -250,7 +250,7 @@ class ModuleSanitizerCoverage {
   Module *                         Mo = NULL;
   GlobalVariable *                 AFLMapPtr = NULL;
   Value *                          MapPtrFixed = NULL;
-  FILE *                           documentFile = NULL;
+  std::ofstream                    dFile;
   size_t                           found = 0;
   // afl++ END
 
@@ -446,8 +446,8 @@ bool ModuleSanitizerCoverage::instrumentModule(
 
   if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) {
 
-    if ((documentFile = fopen(ptr, "a")) == NULL)
-      WARNF("Cannot access document file %s", ptr);
+    dFile.open(ptr, std::ofstream::out | std::ofstream::app);
+    if (dFile.is_open()) WARNF("Cannot access document file %s", ptr);
 
   }
 
@@ -1003,12 +1003,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
     instrumentFunction(F, DTCallback, PDTCallback);
 
   // afl++ START
-  if (documentFile) {
-
-    fclose(documentFile);
-    documentFile = NULL;
-
-  }
+  if (dFile.is_open()) dFile.close();
 
   if (!getenv("AFL_LLVM_LTO_DONTWRITEID") || dictionary.size() || map_addr) {
 
@@ -1069,7 +1064,6 @@ bool ModuleSanitizerCoverage::instrumentModule(
     if (dictionary.size()) {
 
       size_t memlen = 0, count = 0, offset = 0;
-      char * ptr;
 
       // sort and unique the dictionary
       std::sort(dictionary.begin(), dictionary.end());
@@ -1089,13 +1083,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
 
       if (count) {
 
-        if ((ptr = (char *)malloc(memlen + count)) == NULL) {
-
-          fprintf(stderr, "Error: malloc for %lu bytes failed!\n",
-                  memlen + count);
-          exit(-1);
-
-        }
+        auto ptrhld = std::unique_ptr<char[]>(new char[memlen + count]);
 
         count = 0;
 
@@ -1103,8 +1091,8 @@ bool ModuleSanitizerCoverage::instrumentModule(
 
           if (offset + token.length() < 0xfffff0 && count < MAX_AUTO_EXTRAS) {
 
-            ptr[offset++] = (uint8_t)token.length();
-            memcpy(ptr + offset, token.c_str(), token.length());
+            ptrhld.get()[offset++] = (uint8_t)token.length();
+            memcpy(ptrhld.get() + offset, token.c_str(), token.length());
             offset += token.length();
             count++;
 
@@ -1124,10 +1112,10 @@ bool ModuleSanitizerCoverage::instrumentModule(
         GlobalVariable *AFLInternalDictionary = new GlobalVariable(
             M, ArrayTy, true, GlobalValue::ExternalLinkage,
             ConstantDataArray::get(Ctx,
-                                   *(new ArrayRef<char>((char *)ptr, offset))),
+                                   *(new ArrayRef<char>(ptrhld.get(), offset))),
             "__afl_internal_dictionary");
         AFLInternalDictionary->setInitializer(ConstantDataArray::get(
-            Ctx, *(new ArrayRef<char>((char *)ptr, offset))));
+            Ctx, *(new ArrayRef<char>(ptrhld.get(), offset))));
         AFLInternalDictionary->setConstant(true);
 
         GlobalVariable *AFLDictionary = new GlobalVariable(
@@ -1509,12 +1497,12 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
     // afl++ START
     ++afl_global_id;
 
-    if (documentFile) {
+    if (dFile.is_open()) {
 
       unsigned long long int moduleID =
           (((unsigned long long int)(rand() & 0xffffffff)) << 32) | getpid();
-      fprintf(documentFile, "ModuleID=%llu Function=%s edgeID=%u\n", moduleID,
-              F.getName().str().c_str(), afl_global_id);
+      dFile << "ModuleID=" << moduleID << " Function=" << F.getName().str()
+            << " edgeID=" << afl_global_id << "\n";
 
     }
 
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 48ad2d02..013492f9 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -881,8 +881,6 @@ void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls(
     Function &F, ArrayRef<Instruction *> IndirCalls) {
 
   if (IndirCalls.empty()) return;
-  assert(Options.TracePC || Options.TracePCGuard ||
-         Options.Inline8bitCounters /*|| Options.InlineBoolFlag*/);
   for (auto I : IndirCalls) {
 
     IRBuilder<> IRB(I);
diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc
index 4622e488..0a3e74b9 100644
--- a/instrumentation/afl-llvm-dict2file.so.cc
+++ b/instrumentation/afl-llvm-dict2file.so.cc
@@ -66,6 +66,9 @@ namespace {
 
 class AFLdict2filePass : public ModulePass {
 
+  std::ofstream of;
+  void          dict2file(u8 *, u32);
+
  public:
   static char ID;
 
@@ -81,7 +84,7 @@ class AFLdict2filePass : public ModulePass {
 
 }  // namespace
 
-void dict2file(int fd, u8 *mem, u32 len) {
+void AFLdict2filePass::dict2file(u8 *mem, u32 len) {
 
   u32  i, j, binary = 0;
   char line[MAX_AUTO_EXTRA * 8], tmp[8];
@@ -113,9 +116,8 @@ void dict2file(int fd, u8 *mem, u32 len) {
 
   line[j] = 0;
   strcat(line, "\"\n");
-  if (write(fd, line, strlen(line)) <= 0)
-    PFATAL("Could not write to dictionary file");
-  fsync(fd);
+  of << line;
+  of.flush();
 
   if (!be_quiet) fprintf(stderr, "Found dictionary token: %s", line);
 
@@ -125,7 +127,7 @@ bool AFLdict2filePass::runOnModule(Module &M) {
 
   DenseMap<Value *, std::string *> valueMap;
   char *                           ptr;
-  int                              fd, found = 0;
+  int                              found = 0;
 
   /* Show a banner */
   setvbuf(stdout, NULL, _IONBF, 0);
@@ -146,8 +148,8 @@ bool AFLdict2filePass::runOnModule(Module &M) {
   if (!ptr || *ptr != '/')
     FATAL("AFL_LLVM_DICT2FILE is not set to an absolute path: %s", ptr);
 
-  if ((fd = open(ptr, O_WRONLY | O_APPEND | O_CREAT | O_DSYNC, 0644)) < 0)
-    PFATAL("Could not open/create %s.", ptr);
+  of.open(ptr, std::ofstream::out | std::ofstream::app);
+  if (!of.is_open()) PFATAL("Could not open/create %s.", ptr);
 
   /* Instrument all the things! */
 
@@ -264,11 +266,11 @@ bool AFLdict2filePass::runOnModule(Module &M) {
 
               }
 
-              dict2file(fd, (u8 *)&val, len);
+              dict2file((u8 *)&val, len);
               found++;
               if (val2) {
 
-                dict2file(fd, (u8 *)&val2, len);
+                dict2file((u8 *)&val2, len);
                 found++;
 
               }
@@ -630,7 +632,7 @@ bool AFLdict2filePass::runOnModule(Module &M) {
 
           ptr = (char *)thestring.c_str();
 
-          dict2file(fd, (u8 *)ptr, optLen);
+          dict2file((u8 *)ptr, optLen);
           found++;
 
         }
@@ -641,7 +643,7 @@ bool AFLdict2filePass::runOnModule(Module &M) {
 
   }
 
-  close(fd);
+  of.close();
 
   /* Say something nice. */
 
diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc
index 4a5738de..c2f61d34 100644
--- a/instrumentation/afl-llvm-lto-instrumentation.so.cc
+++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc
@@ -108,8 +108,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
   //  std::vector<CallInst *>          calls;
   DenseMap<Value *, std::string *> valueMap;
   std::vector<BasicBlock *>        BlockList;
+  std::ofstream                    dFile;
   char *                           ptr;
-  FILE *                           documentFile = NULL;
   size_t                           found = 0;
 
   srand((unsigned int)time(NULL));
@@ -137,8 +137,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
   if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) {
 
-    if ((documentFile = fopen(ptr, "a")) == NULL)
-      WARNF("Cannot access document file %s", ptr);
+    dFile.open(ptr, std::ofstream::out | std::ofstream::app);
+    if (!dFile.is_open()) WARNF("Cannot access document file %s", ptr);
 
   }
 
@@ -243,8 +243,14 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
     // the instrument file list check
     AttributeList Attrs = F.getAttributes();
+#if LLVM_VERSION_MAJOR < 14
     if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) {
 
+#else
+    if (Attrs.hasFnAttr(StringRef("skipinstrument"))) {
+
+#endif
+
       if (debug)
         fprintf(stderr,
                 "DEBUG: Function %s is not in a source file that was specified "
@@ -845,10 +851,11 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
           }
 
-          if (documentFile) {
+          if (dFile.is_open()) {
 
-            fprintf(documentFile, "ModuleID=%llu Function=%s edgeID=%u\n",
-                    moduleID, F.getName().str().c_str(), afl_global_id);
+            dFile << "ModuleID=" << moduleID
+                  << " Function=" << F.getName().str()
+                  << " edgeID=" << afl_global_id << "\n";
 
           }
 
@@ -920,8 +927,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
   }
 
-  if (documentFile) fclose(documentFile);
-  documentFile = NULL;
+  if (dFile.is_open()) dFile.close();
 
   // save highest location ID to global variable
   // do this after each function to fail faster
@@ -1016,7 +1022,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
       if (count) {
 
-        auto ptrhld = std::unique_ptr<char []>(new char[memlen + count]);
+        auto ptrhld = std::unique_ptr<char[]>(new char[memlen + count]);
 
         count = 0;
 
diff --git a/instrumentation/afl-llvm-lto-instrumentlist.so.cc b/instrumentation/afl-llvm-lto-instrumentlist.so.cc
index 416dbb88..ee2e5dd3 100644
--- a/instrumentation/afl-llvm-lto-instrumentlist.so.cc
+++ b/instrumentation/afl-llvm-lto-instrumentlist.so.cc
@@ -116,10 +116,15 @@ bool AFLcheckIfInstrument::runOnModule(Module &M) {
 
       auto &        Ctx = F.getContext();
       AttributeList Attrs = F.getAttributes();
-      AttrBuilder   NewAttrs;
+#if LLVM_VERSION_MAJOR < 14
+      AttrBuilder NewAttrs;
       NewAttrs.addAttribute("skipinstrument");
       F.setAttributes(
           Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
+#else
+      AttributeList NewAttrs = Attrs.addFnAttribute(Ctx, "skipinstrument");
+      F.setAttributes(NewAttrs);
+#endif
 
     }
 
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index 13f45b69..e63be98c 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -578,16 +578,16 @@ bool SplitComparesTransform::splitCompare(CmpInst *cmp_inst, Module &M,
 
       /* dependent on the cmp of the high parts go to the end or go on with
        * the comparison */
-      auto        term = bb->getTerminator();
-      BranchInst *br = nullptr;
+      auto term = bb->getTerminator();
+
       if (pred == CmpInst::ICMP_EQ) {
 
-        br = BranchInst::Create(cmp_low_bb, end_bb, icmp_high, bb);
+        BranchInst::Create(cmp_low_bb, end_bb, icmp_high, bb);
 
       } else {
 
-        /* CmpInst::ICMP_NE */
-        br = BranchInst::Create(end_bb, cmp_low_bb, icmp_high, bb);
+        // CmpInst::ICMP_NE
+        BranchInst::Create(end_bb, cmp_low_bb, icmp_high, bb);
 
       }
 
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index c8c94c08..54f510c4 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -610,12 +610,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
     if (!time_ms) {
 
-      kill(fsrv->fsrv_pid, fsrv->kill_signal);
+      if (fsrv->fsrv_pid > 0) { kill(fsrv->fsrv_pid, fsrv->kill_signal); }
 
     } else if (time_ms > fsrv->init_tmout) {
 
       fsrv->last_run_timed_out = 1;
-      kill(fsrv->fsrv_pid, fsrv->kill_signal);
+      if (fsrv->fsrv_pid > 0) { kill(fsrv->fsrv_pid, fsrv->kill_signal); }
 
     } else {
 
@@ -1248,7 +1248,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
     /* If there was no response from forkserver after timeout seconds,
     we kill the child. The forkserver should inform us afterwards */
 
-    kill(fsrv->child_pid, fsrv->kill_signal);
+    if (fsrv->child_pid > 0) { kill(fsrv->child_pid, fsrv->kill_signal); }
     fsrv->last_run_timed_out = 1;
     if (read(fsrv->fsrv_st_fd, &fsrv->child_status, 4) < 4) { exec_ms = 0; }
 
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 0fa8e6ec..f0e1a80d 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -2815,43 +2815,6 @@ void check_binary(afl_state_t *afl, u8 *fname) {
 
 }
 
-/* Trim and possibly create a banner for the run. */
-
-void fix_up_banner(afl_state_t *afl, u8 *name) {
-
-  if (!afl->use_banner) {
-
-    if (afl->sync_id) {
-
-      afl->use_banner = afl->sync_id;
-
-    } else {
-
-      u8 *trim = strrchr(name, '/');
-      if (!trim) {
-
-        afl->use_banner = name;
-
-      } else {
-
-        afl->use_banner = trim + 1;
-
-      }
-
-    }
-
-  }
-
-  if (strlen(afl->use_banner) > 32) {
-
-    u8 *tmp = ck_alloc(36);
-    sprintf(tmp, "%.32s...", afl->use_banner);
-    afl->use_banner = tmp;
-
-  }
-
-}
-
 /* Check if we're on TTY. */
 
 void check_if_tty(afl_state_t *afl) {
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 4173f4e1..da6ba7d9 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -291,8 +291,6 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at,
 u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
                   u32 handicap, u8 from_queue) {
 
-  if (unlikely(afl->shm.cmplog_mode)) { q->exec_cksum = 0; }
-
   u8 fault = 0, new_bits = 0, var_detected = 0, hnb = 0,
      first_run = (q->exec_cksum == 0);
   u64 start_us, stop_us, diff_us;
@@ -300,6 +298,8 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
   u32 use_tmout = afl->fsrv.exec_tmout;
   u8 *old_sn = afl->stage_name;
 
+  if (unlikely(afl->shm.cmplog_mode)) { q->exec_cksum = 0; }
+
   /* Be a bit more generous about timeouts when resuming sessions, or when
      trying to calibrate already-added finds. This helps avoid trouble due
      to intermittent latency. */
@@ -343,6 +343,32 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
 
   }
 
+  /* we need a dummy run if this is LTO + cmplog */
+  if (unlikely(afl->shm.cmplog_mode)) {
+
+    write_to_testcase(afl, use_mem, q->len);
+
+    fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
+
+    /* afl->stop_soon is set by the handler for Ctrl+C. When it's pressed,
+       we want to bail out quickly. */
+
+    if (afl->stop_soon || fault != afl->crash_mode) { goto abort_calibration; }
+
+    if (!afl->non_instrumented_mode && !afl->stage_cur &&
+        !count_bytes(afl, afl->fsrv.trace_bits)) {
+
+      fault = FSRV_RUN_NOINST;
+      goto abort_calibration;
+
+    }
+
+#ifdef INTROSPECTION
+    if (unlikely(!q->bitsmap_size)) q->bitsmap_size = afl->bitsmap_size;
+#endif
+
+  }
+
   if (q->exec_cksum) {
 
     memcpy(afl->first_trace, afl->fsrv.trace_bits, afl->fsrv.map_size);
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 870ba69a..0c06232b 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -441,9 +441,10 @@ void show_stats(afl_state_t *afl) {
   u64 cur_ms;
   u32 t_bytes, t_bits;
 
-  u32 banner_len, banner_pad;
-  u8  tmp[256];
-  u8  time_tmp[64];
+  static u8 banner[128];
+  u32       banner_len, banner_pad;
+  u8        tmp[256];
+  u8        time_tmp[64];
 
   u8 val_buf[8][STRINGIFY_VAL_SIZE_MAX];
 #define IB(i) (val_buf[(i)])
@@ -656,26 +657,34 @@ void show_stats(afl_state_t *afl) {
   }
 
   /* Let's start by drawing a centered banner. */
+  if (unlikely(!banner[0])) {
 
-  banner_len = (afl->crash_mode ? 24 : 22) + strlen(VERSION) +
-               strlen(afl->use_banner) + strlen(afl->power_name) + 3 + 5;
-  banner_pad = (79 - banner_len) / 2;
-  memset(tmp, ' ', banner_pad);
+    char *si = "";
+    if (afl->sync_id) { si = afl->sync_id; }
+    memset(banner, 0, sizeof(banner));
+    banner_len = (afl->crash_mode ? 20 : 18) + strlen(VERSION) + strlen(si) +
+                 strlen(afl->power_name) + 4 + 6;
 
-#ifdef HAVE_AFFINITY
-  sprintf(
-      tmp + banner_pad,
-      "%s " cLCY VERSION cLGN " (%s) " cPIN "[%s]" cBLU " {%d}",
-      afl->crash_mode ? cPIN "peruvian were-rabbit" : cYEL "american fuzzy lop",
-      afl->use_banner, afl->power_name, afl->cpu_aff);
-#else
-  sprintf(
-      tmp + banner_pad, "%s " cLCY VERSION cLGN " (%s) " cPIN "[%s]",
-      afl->crash_mode ? cPIN "peruvian were-rabbit" : cYEL "american fuzzy lop",
-      afl->use_banner, afl->power_name);
-#endif                                                     /* HAVE_AFFINITY */
+    if (strlen(afl->use_banner) + banner_len > 75) {
+
+      afl->use_banner += (strlen(afl->use_banner) + banner_len) - 76;
+      memset(afl->use_banner, '.', 3);
+
+    }
+
+    banner_len += strlen(afl->use_banner);
+    banner_pad = (79 - banner_len) / 2;
+    memset(banner, ' ', banner_pad);
+
+    sprintf(banner + banner_pad,
+            "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
+            afl->crash_mode ? cPIN "peruvian were-rabbit"
+                            : cYEL "american fuzzy lop",
+            si, afl->use_banner, afl->power_name);
+
+  }
 
-  SAYF("\n%s\n", tmp);
+  SAYF("\n%s\n", banner);
 
   /* "Handy" shortcuts for drawing boxes... */
 
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 92a37697..26886a4f 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1189,7 +1189,17 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
-  if (afl->sync_id) { fix_up_sync(afl); }
+  if (afl->sync_id) {
+
+    if (strlen(afl->sync_id) > 24) {
+
+      FATAL("sync_id max length is 24 characters");
+
+    }
+
+    fix_up_sync(afl);
+
+  }
 
   if (!strcmp(afl->in_dir, afl->out_dir)) {
 
@@ -1218,6 +1228,8 @@ int main(int argc, char **argv_orig, char **envp) {
 
   if (unlikely(afl->afl_env.afl_statsd)) { statsd_setup_format(afl); }
 
+  if (!afl->use_banner) { afl->use_banner = argv[optind]; }
+
   if (strchr(argv[optind], '/') == NULL && !afl->unicorn_mode) {
 
     WARNF(cLRD
@@ -1486,9 +1498,6 @@ int main(int argc, char **argv_orig, char **envp) {
   }
 
   save_cmdline(afl, argc, argv);
-
-  fix_up_banner(afl, argv[optind]);
-
   check_if_tty(afl);
   if (afl->afl_env.afl_force_ui) { afl->not_on_tty = 0; }
 
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 75b0ff99..5df07bf2 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -242,9 +242,14 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
   if (cmin_mode &&
       (fsrv->last_run_timed_out || (!caa && child_crashed != cco))) {
 
-    // create empty file to prevent error messages in afl-cmin
-    fd = open(outfile, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
-    close(fd);
+    if (strcmp(outfile, "-")) {
+
+      // create empty file to prevent error messages in afl-cmin
+      fd = open(outfile, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
+      close(fd);
+
+    }
+
     return ret;
 
   }
diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index 0d84243c..cc8d5b34 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-1c47d1ebc7e904ad4efc1370f23e269fb9ac3f93
+d4915053d477dd827b3fe4b494173d3fbf9f456e
diff --git a/unicorn_mode/samples/speedtest/rust/src/main.rs b/unicorn_mode/samples/speedtest/rust/src/main.rs
index 105ba4b4..89e10833 100644
--- a/unicorn_mode/samples/speedtest/rust/src/main.rs
+++ b/unicorn_mode/samples/speedtest/rust/src/main.rs
@@ -12,11 +12,11 @@ use std::{
 
 use unicornafl::{
     unicorn_const::{uc_error, Arch, Mode, Permission},
-    RegisterX86::{self, *},
-    Unicorn, UnicornHandle,
+    RegisterX86::*,
+    Unicorn,
 };
 
-const BINARY: &str = &"../target";
+const BINARY: &str = "../target";
 
 // Memory map for the code to be tested
 // Arbitrary address where code to test will be loaded
@@ -47,7 +47,7 @@ fn read_file(filename: &str) -> Result<Vec<u8>, io::Error> {
 fn parse_locs(loc_name: &str) -> Result<Vec<u64>, io::Error> {
     let contents = &read_file(&format!("../target.offsets.{}", loc_name))?;
     //println!("Read: {:?}", contents);
-    Ok(str_from_u8_unchecked(&contents)
+    Ok(str_from_u8_unchecked(contents)
         .split('\n')
         .map(|x| {
             //println!("Trying to convert {}", &x[2..]);
@@ -87,8 +87,7 @@ fn main() {
 }
 
 fn fuzz(input_file: &str) -> Result<(), uc_error> {
-    let mut unicorn = Unicorn::new(Arch::X86, Mode::MODE_64, 0)?;
-    let mut uc: UnicornHandle<'_, _> = unicorn.borrow();
+    let mut uc = Unicorn::new(Arch::X86, Mode::MODE_64, 0)?;
 
     let binary =
         read_file(BINARY).unwrap_or_else(|_| panic!("Could not read modem image: {}", BINARY));
@@ -105,7 +104,7 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
     // Set the program counter to the start of the code
     let main_locs = parse_locs("main").unwrap();
     //println!("Entry Point: {:x}", main_locs[0]);
-    uc.reg_write(RegisterX86::RIP as i32, main_locs[0])?;
+    uc.reg_write(RIP, main_locs[0])?;
 
     // Setup the stack.
     uc.mem_map(
@@ -114,14 +113,14 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
         Permission::READ | Permission::WRITE,
     )?;
     // Setup the stack pointer, but allocate two pointers for the pointers to input.
-    uc.reg_write(RSP as i32, STACK_ADDRESS + STACK_SIZE - 16)?;
+    uc.reg_write(RSP, STACK_ADDRESS + STACK_SIZE - 16)?;
 
     // Setup our input space, and push the pointer to it in the function params
     uc.mem_map(INPUT_ADDRESS, INPUT_MAX as usize, Permission::READ)?;
     // We have argc = 2
-    uc.reg_write(RDI as i32, 2)?;
+    uc.reg_write(RDI, 2)?;
     // RSI points to our little 2 QWORD space at the beginning of the stack...
-    uc.reg_write(RSI as i32, STACK_ADDRESS + STACK_SIZE - 16)?;
+    uc.reg_write(RSI, STACK_ADDRESS + STACK_SIZE - 16)?;
     // ... which points to the Input. Write the ptr to mem in little endian.
     uc.mem_write(
         STACK_ADDRESS + STACK_SIZE - 16,
@@ -133,13 +132,13 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
     let already_allocated_malloc = already_allocated.clone();
     // We use a very simple malloc/free stub here,
     // that only works for exactly one allocation at a time.
-    let hook_malloc = move |mut uc: UnicornHandle<'_, _>, addr: u64, size: u32| {
+    let hook_malloc = move |uc: &mut Unicorn<'_, _>, addr: u64, size: u32| {
         if already_allocated_malloc.get() {
             println!("Double malloc, not supported right now!");
             abort();
         }
         // read the first param
-        let malloc_size = uc.reg_read(RDI as i32).unwrap();
+        let malloc_size = uc.reg_read(RDI).unwrap();
         if malloc_size > HEAP_SIZE_MAX {
             println!(
                 "Tried to allocate {} bytes, but we may only allocate up to {}",
@@ -147,20 +146,20 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
             );
             abort();
         }
-        uc.reg_write(RAX as i32, HEAP_ADDRESS).unwrap();
-        uc.reg_write(RIP as i32, addr + size as u64).unwrap();
+        uc.reg_write(RAX, HEAP_ADDRESS).unwrap();
+        uc.reg_write(RIP, addr + size as u64).unwrap();
         already_allocated_malloc.set(true);
     };
 
     let already_allocated_free = already_allocated;
     // No real free, just set the "used"-flag to false.
-    let hook_free = move |mut uc: UnicornHandle<'_, _>, addr, size| {
+    let hook_free = move |uc: &mut Unicorn<'_, _>, addr, size| {
         if already_allocated_free.get() {
             println!("Double free detected. Real bug?");
             abort();
         }
         // read the first param
-        let free_ptr = uc.reg_read(RDI as i32).unwrap();
+        let free_ptr = uc.reg_read(RDI).unwrap();
         if free_ptr != HEAP_ADDRESS {
             println!(
                 "Tried to free wrong mem region {:x} at code loc {:x}",
@@ -168,7 +167,7 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
             );
             abort();
         }
-        uc.reg_write(RIP as i32, addr + size as u64).unwrap();
+        uc.reg_write(RIP, addr + size as u64).unwrap();
         already_allocated_free.set(false);
     };
 
@@ -177,8 +176,8 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
     */
 
     // This is a fancy print function that we're just going to skip for fuzzing.
-    let hook_magicfn = move |mut uc: UnicornHandle<'_, _>, addr, size| {
-        uc.reg_write(RIP as i32, addr + size as u64).unwrap();
+    let hook_magicfn = move |uc: &mut Unicorn<'_, _>, addr, size| {
+        uc.reg_write(RIP, addr + size as u64).unwrap();
     };
 
     for addr in parse_locs("malloc").unwrap() {
@@ -195,7 +194,7 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
     }
 
     let place_input_callback =
-        |uc: &mut UnicornHandle<'_, _>, afl_input: &mut [u8], _persistent_round| {
+        |uc: &mut Unicorn<'_, _>, afl_input: &mut [u8], _persistent_round| {
             // apply constraints to the mutated input
             if afl_input.len() > INPUT_MAX as usize {
                 //println!("Skipping testcase with leng {}", afl_input.len());
@@ -209,9 +208,7 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
 
     // return true if the last run should be counted as crash
     let crash_validation_callback =
-        |_uc: &mut UnicornHandle<'_, _>, result, _input: &[u8], _persistent_round| {
-            result != uc_error::OK
-        };
+        |_uc: &mut Unicorn<'_, _>, result, _input: &[u8], _persistent_round| result != uc_error::OK;
 
     let end_addrs = parse_locs("main_ends").unwrap();
 
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
-Subproject c0e03d2c6b55a22025324f121746b41b1e756fb
+Subproject d4915053d477dd827b3fe4b494173d3fbf9f456
diff --git a/utils/socket_fuzzing/README.md b/utils/socket_fuzzing/README.md
index 84398a71..2805fa22 100644
--- a/utils/socket_fuzzing/README.md
+++ b/utils/socket_fuzzing/README.md
@@ -6,6 +6,6 @@ for sending input to stdin which the target binary will think is coming from
 a network socket.
 
 This is desock_dup.c from the amazing preeny project
-https://github.com/zardus/preeny
+[https://github.com/zardus/preeny](https://github.com/zardus/preeny)
 
 It is packaged in AFL++ to have it at hand if needed