- What is an "edge"?
+ What is an "edge"?
A program contains `functions`, `functions` contain the compiled machine code.
The compiled machine code in a `function` can be in a single or many `basic blocks`.
@@ -77,7 +77,7 @@ If you find an interesting or important question missing, submit it via
## Targets
- How can I fuzz a binary-only target?
+ How can I fuzz a binary-only target?
AFL++ is a great fuzzer if you have the source code available.
@@ -87,7 +87,7 @@ If you find an interesting or important question missing, submit it via
- How can I fuzz a network service?
+ How can I fuzz a network service?
The short answer is - you cannot, at least not "out of the box".
@@ -95,7 +95,7 @@ If you find an interesting or important question missing, submit it via
- How can I fuzz a GUI program?
+ How can I fuzz a GUI program?
Not all GUI programs are suitable for fuzzing. If the GUI program can read the fuzz data from a file without needing any user interaction, then it would be suitable for fuzzing.
@@ -105,13 +105,13 @@ If you find an interesting or important question missing, submit it via
## Performance
- How can I improve the fuzzing speed?
+ How can I improve the fuzzing speed?
There are a few things you can do to improve the fuzzing speed, see [best_practices.md#improving-speed](best_practices.md#improving-speed).
- Why is my stability below 100%?
+ Why is my stability below 100%?
Stability is measured by how many percent of the edges in the target are "stable".
Sending the same input again and again should take the exact same path through the target every time.
@@ -131,7 +131,7 @@ If you find an interesting or important question missing, submit it via
## Troubleshooting
- I got a weird compile error from clang.
+ I got a weird compile error from clang.
If you see this kind of error when trying to instrument a target with afl-cc/afl-clang-fast/afl-clang-lto:
From 78d7944bbf4608437563114c0e4291a9a516cfff Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Tue, 7 Sep 2021 14:01:27 +0200
Subject: [PATCH 027/305] Update docs/rpc_statsd.md
---
docs/rpc_statsd.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/rpc_statsd.md b/docs/rpc_statsd.md
index cff93b7c..2d340dd7 100644
--- a/docs/rpc_statsd.md
+++ b/docs/rpc_statsd.md
@@ -66,7 +66,7 @@ For all your fuzzers, only one instance of StatsD, Prometheus, and Grafana is re
You can create and move the infrastructure files into a directory of your choice. The directory will store all the required configuration files.
-To install and set up StatsD, Prometheus, and Grafana:
+To install and set up Prometheus and Grafana:
1. Install Docker and Docker Compose:
From cb01d566167b8c0d02a19485d13fdd05c1b8347b Mon Sep 17 00:00:00 2001
From: Dominik Maier
Date: Tue, 7 Sep 2021 15:49:42 +0200
Subject: [PATCH 028/305] unicornafl clippy
---
unicorn_mode/UNICORNAFL_VERSION | 2 +-
unicorn_mode/unicornafl | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index 0db54339..0d84243c 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-c0e03d2c
+1c47d1ebc7e904ad4efc1370f23e269fb9ac3f93
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index 019b8715..1c47d1eb 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit 019b871539fe9ed3f41d882385a8b02c243d49ad
+Subproject commit 1c47d1ebc7e904ad4efc1370f23e269fb9ac3f93
From f760e80729412a2cd44a12e76b81ccb433626e60 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 7 Sep 2021 17:15:54 +0200
Subject: [PATCH 029/305] add check_binary_signatures for afl-* utils
---
docs/Changelog.md | 3 ++-
include/common.h | 1 +
src/afl-analyze.c | 1 +
src/afl-common.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++
src/afl-showmap.c | 2 ++
src/afl-tmin.c | 1 +
6 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 0ffbef05..de217c2e 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -15,7 +15,8 @@ sending a mail to .
information on how to deal with instrumenting libraries
- fix a regression introduced in 3.10 that resulted in less
coverage being detected. thanks to Collin May for reporting!
-
+ - afl-showmap, afl-tmin and afl-analyze now honor persistent mode
+ for more speed. thanks to dloffre-snl for reporting!
- afl-cc:
- fix for shared linking on MacOS
- llvm and LTO mode verified to work with new llvm 14-dev
diff --git a/include/common.h b/include/common.h
index 7bba9e91..2ca44301 100644
--- a/include/common.h
+++ b/include/common.h
@@ -38,6 +38,7 @@
#define STRINGIFY_VAL_SIZE_MAX (16)
+u32 check_binary_signatures(u8 *fn);
void detect_file_args(char **argv, u8 *prog_in, bool *use_stdin);
void print_suggested_envs(char *mispelled_env);
void check_environment_vars(char **env);
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index e19df3ce..eef08494 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -1093,6 +1093,7 @@ int main(int argc, char **argv_orig, char **envp) {
parse_afl_kill_signal_env(getenv("AFL_KILL_SIGNAL"), SIGKILL);
read_initial_file();
+ (void)check_binary_signatures(fsrv.target_path);
ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
mem_limit, exec_tmout, edges_only ? ", edges only" : "");
diff --git a/src/afl-common.c b/src/afl-common.c
index 9ca2b3e8..db19f0a7 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -25,8 +25,12 @@
#include
#include
+#define _GNU_SOURCE
+#define __USE_GNU
+#include
#include
#include
+#include
#include "debug.h"
#include "alloc-inl.h"
@@ -51,6 +55,66 @@ u8 last_intr = 0;
#define AFL_PATH "/usr/local/lib/afl/"
#endif
+u32 check_binary_signatures(u8 *fn) {
+
+ int ret = 0, fd = open(fn, O_RDONLY);
+ if (fd < 0) { PFATAL("Unable to open '%s'", fn); }
+ struct stat st;
+ if (fstat(fd, &st) < 0) { PFATAL("Unable to fstat '%s'", fn); }
+ u32 f_len = st.st_size;
+ u8 *f_data = mmap(0, f_len, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (f_data == MAP_FAILED) { PFATAL("Unable to mmap file '%s'", fn); }
+ close(fd);
+
+ if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) {
+
+ if (!be_quiet) { OKF(cPIN "Persistent mode binary detected."); }
+ setenv(PERSIST_ENV_VAR, "1", 1);
+ ret = 1;
+
+ } else if (getenv("AFL_PERSISTENT")) {
+
+ if (!be_quiet) {
+
+ WARNF("AFL_PERSISTENT is no longer supported and may misbehave!");
+
+ }
+
+ } else if (getenv("AFL_FRIDA_PERSISTENT_ADDR")) {
+
+ if (!be_quiet) {
+
+ OKF("FRIDA Persistent mode configuration options detected.");
+
+ }
+
+ setenv(PERSIST_ENV_VAR, "1", 1);
+ ret = 1;
+
+ }
+
+ if (memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) {
+
+ if (!be_quiet) { OKF(cPIN "Deferred forkserver binary detected."); }
+ setenv(DEFER_ENV_VAR, "1", 1);
+ ret += 2;
+
+ } else if (getenv("AFL_DEFER_FORKSRV")) {
+
+ if (!be_quiet) {
+
+ WARNF("AFL_DEFER_FORKSRV is no longer supported and may misbehave!");
+
+ }
+
+ }
+
+ if (munmap(f_data, f_len)) { PFATAL("unmap() failed"); }
+
+ return ret;
+
+}
+
void detect_file_args(char **argv, u8 *prog_in, bool *use_stdin) {
u32 i = 0;
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 9122cd25..27b1e14a 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -1189,6 +1189,8 @@ int main(int argc, char **argv_orig, char **envp) {
}
+ (void)check_binary_signatures(fsrv->target_path);
+
shm_fuzz = ck_alloc(sizeof(sharedmem_t));
/* initialize cmplog_mode */
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 792770e0..dff51e84 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -1209,6 +1209,7 @@ int main(int argc, char **argv_orig, char **envp) {
fsrv->shmem_fuzz = map + sizeof(u32);
read_initial_file();
+ (void)check_binary_signatures(fsrv->target_path);
if (!fsrv->qemu_mode && !unicorn_mode) {
From 8af84c203cfe241b5a8321c62387fd107ebf1031 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 7 Sep 2021 19:26:25 +0200
Subject: [PATCH 030/305] fix afl-showmap
---
src/afl-showmap.c | 2 +-
unicorn_mode/unicornafl | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 27b1e14a..e143371e 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -1189,7 +1189,7 @@ int main(int argc, char **argv_orig, char **envp) {
}
- (void)check_binary_signatures(fsrv->target_path);
+ if (in_dir) { (void)check_binary_signatures(fsrv->target_path); }
shm_fuzz = ck_alloc(sizeof(sharedmem_t));
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index 1c47d1eb..019b8715 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit 1c47d1ebc7e904ad4efc1370f23e269fb9ac3f93
+Subproject commit 019b871539fe9ed3f41d882385a8b02c243d49ad
From 6546a0a5fd5532464916c6c4adfbb22d87a5acd5 Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Fri, 10 Sep 2021 14:26:51 +0200
Subject: [PATCH 031/305] Update docs/rpc_statsd.md
---
docs/rpc_statsd.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/rpc_statsd.md b/docs/rpc_statsd.md
index 2d340dd7..288d56cb 100644
--- a/docs/rpc_statsd.md
+++ b/docs/rpc_statsd.md
@@ -62,7 +62,7 @@ The easiest way to install and set up the infrastructure is with Docker and Dock
Depending on your fuzzing setup and infrastructure, you may not want to run these applications on your fuzzer instances. This setup may be modified before use in a production environment; for example, adding passwords, creating volumes for storage, tweaking the metrics gathering to get host metrics (CPU, RAM, and so on).
-For all your fuzzers, only one instance of StatsD, Prometheus, and Grafana is required.
+For all your fuzzing instances, only one instance of Prometheus and Grafana is required. The [statsd exporter](https://registry.hub.docker.com/r/prom/statsd-exporter) converts the StatsD metrics to Prometheus. If you are using a provider that supports StatsD directly, you can skip this part of the setup."
You can create and move the infrastructure files into a directory of your choice. The directory will store all the required configuration files.
From bd4ecd83b1e4126300475d5beb09b4a8327b045a Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Fri, 10 Sep 2021 15:35:29 +0200
Subject: [PATCH 032/305] Update README.md
---
README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index db6a70b5..eb99d9bd 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ You are free to copy, modify, and distribute AFL++ with attribution under the te
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).
+* 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 behaviour 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).
@@ -66,7 +66,7 @@ A common way to do this would be:
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.
+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:
@@ -82,7 +82,7 @@ When fuzzing verbose syntax (SQL, HTTP, etc), create a dictionary as described i
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
+* 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 .
* Or join the [Awesome Fuzzing](https://discord.gg/gCraWct) Discord server.
From 82ef4a90b0ff12a297e1bc3f1c8256ae9ace4f25 Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Fri, 10 Sep 2021 21:37:55 +0200
Subject: [PATCH 033/305] Fix links
---
README.md | 2 +-
docs/best_practices.md | 2 +-
docs/branches.md | 2 +-
docs/fuzzing_expert.md | 2 +-
docs/interpreting_output.md | 2 +-
docs/known_limitations.md | 2 +-
docs/life_pro_tips.md | 20 ++++++++++----------
docs/rpc_statsd.md | 2 +-
docs/triaging_crashes.md | 2 +-
9 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/README.md b/README.md
index eb99d9bd..25e47ef2 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ You are free to copy, modify, and distribute AFL++ with attribution under the te
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 [important behaviour changes in AFL++](docs/important_changes.md).
+* 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).
diff --git a/docs/best_practices.md b/docs/best_practices.md
index 23fa237d..1521748a 100644
--- a/docs/best_practices.md
+++ b/docs/best_practices.md
@@ -59,7 +59,7 @@ 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).
diff --git a/docs/branches.md b/docs/branches.md
index 1e4ebbb2..81c73a0f 100644
--- a/docs/branches.md
+++ b/docs/branches.md
@@ -7,4 +7,4 @@ 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/fuzzing_expert.md b/docs/fuzzing_expert.md
index 23b24ad0..37ab8e2f 100644
--- a/docs/fuzzing_expert.md
+++ b/docs/fuzzing_expert.md
@@ -620,4 +620,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).
\ No newline at end of file
+(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..364d2cf4 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.
diff --git a/docs/known_limitations.md b/docs/known_limitations.md
index deb539e2..b5fc8446 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
diff --git a/docs/life_pro_tips.md b/docs/life_pro_tips.md
index 13ffcea0..e79bcafa 100644
--- a/docs/life_pro_tips.md
+++ b/docs/life_pro_tips.md
@@ -27,16 +27,16 @@ Run the bundled `afl-plot` utility to generate browser-friendly graphs.
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!
+It could be important - consult [status_screen.md](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.
+Consult section #5 in [instrumentation/README.llvm.md](../instrumentation/README.llvm.md) for tips.
## Using clang?
-Check out instrumentation/ for a faster alternative to afl-gcc!
+Check out [instrumentation/](../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.
+Check out [qemu_mode/README.md](../qemu_mode/README.md) and [unicorn_mode/README.md](../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!
@@ -46,7 +46,7 @@ Try the bundled `afl-tmin` tool - and get small repro files fast!
## Trouble dealing with a machine uprising? Relax, we've all been there.
-Find essential survival tips at http://lcamtuf.coredump.cx/prep/.
+Find essential survival tips at [http://lcamtuf.coredump.cx/prep/](http://lcamtuf.coredump.cx/prep/).
## Want to automatically spot non-crashing memory handling bugs?
@@ -54,7 +54,7 @@ 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.
+See [perf_tips.md](perf_tips.md) for pro tips.
## You can improve the odds of automatically spotting stack corruption issues.
@@ -70,18 +70,18 @@ sanity-checking `assert()` / `abort()` statements to effortlessly catch logic bu
## 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!
+Check out [technical_details.md](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.
+Be sure to check out [sister_projects.md](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.
+You can find a simple solution in [utils/argv_fuzzing](../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.
+See `afl_custom_post_process` in [custom_mutators/examples/example.c](../custom_mutators/examples/example.c) for more.
diff --git a/docs/rpc_statsd.md b/docs/rpc_statsd.md
index 898ad099..efbd550b 100644
--- a/docs/rpc_statsd.md
+++ b/docs/rpc_statsd.md
@@ -41,7 +41,7 @@ To enable the StatsD reporting on your fuzzer instances, you need to set the env
Setting `AFL_STATSD_TAGS_FLAVOR` to the provider of your choice will assign tags / labels to each metric based on their format.
The possible values are `dogstatsd`, `librato`, `signalfx` or `influxdb`.
-For more information on these env vars, check out `docs/env_variables.md`.
+For more information on these env vars, check out [env_variables.md](env_variables.md).
The simplest way of using this feature is to use any metric provider and change the host/port of your StatsD daemon,
with `AFL_STATSD_HOST` and `AFL_STATSD_PORT`, if required (defaults are `localhost` and port `8125`).
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
From 51b2e86ec077c0b67ef1b54a9a30288b74c01be0 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 15 Sep 2021 12:28:05 +0200
Subject: [PATCH 034/305] fix links
---
GNUmakefile | 2 +-
afl-system-config | 2 +-
docs/ci_fuzzing.md | 2 +-
docs/fuzzing_binary-only_targets.md | 5 +++--
docs/fuzzing_expert.md | 2 +-
5 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/GNUmakefile b/GNUmakefile
index 376f6e9a..0a6f3950 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -541,7 +541,7 @@ test_build: afl-cc afl-gcc afl-as afl-showmap
# echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr
# @rm -f test-instr
# @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation of afl-gcc does not seem to be behaving correctly!"; \
-# gcc -v 2>&1 | grep -q -- --with-as= && ( echo; echo "Gcc is configured not to use an external assembler with the -B option."; echo "See docs/INSTALL.md section 5 how to build a -B enabled gcc." ) || \
+# gcc -v 2>&1 | grep -q -- --with-as= && ( echo; echo "Gcc is configured not to use an external assembler with the -B option." ) || \
# ( echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue." ); echo; exit 0; fi
# @echo
# @echo "[+] All right, the instrumentation of afl-gcc seems to be working!"
diff --git a/afl-system-config b/afl-system-config
index dbdbbf1f..3c14ba55 100755
--- a/afl-system-config
+++ b/afl-system-config
@@ -52,7 +52,7 @@ if [ "$PLATFORM" = "Linux" ] ; then
echo ' /etc/default/grub:GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=0 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 srbds=off noexec=off noexec32=off tsx=on tsx_async_abort=off arm64.nopauth audit=0 hardened_usercopy=off ssbd=force-off"'
echo
}
- echo If you run fuzzing instances in docker, run them with \"--security-opt seccomp=unconfined\" for more speed
+ echo If you run fuzzing instances in docker, run them with \"--security-opt seccomp=unconfined\" for more speed.
echo
DONE=1
fi
diff --git a/docs/ci_fuzzing.md b/docs/ci_fuzzing.md
index 316059f8..8d1a2f99 100644
--- a/docs/ci_fuzzing.md
+++ b/docs/ci_fuzzing.md
@@ -26,4 +26,4 @@ Some notes on CI Fuzzing - this fuzzing is different to normal fuzzing campaigns
`-M` enables old queue handling etc. which is good for a fuzzing campaign but not good for short CI runs.
How this can look like can e.g. be seen at AFL++'s setup in Google's [oss-fuzz](https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/compile_afl)
-and [clusterfuzz](https://github.com/google/clusterfuzz/blob/master/src/python/bot/fuzzers/afl/launcher.py).
\ No newline at end of file
+and [clusterfuzz](https://github.com/google/clusterfuzz/blob/master/src/clusterfuzz/_internal/bot/fuzzers/afl/launcher.py).
diff --git a/docs/fuzzing_binary-only_targets.md b/docs/fuzzing_binary-only_targets.md
index a39e40a0..8b3bbeff 100644
--- a/docs/fuzzing_binary-only_targets.md
+++ b/docs/fuzzing_binary-only_targets.md
@@ -51,7 +51,7 @@ make
```
For additional instructions and caveats, see [frida_mode/README.md](../frida_mode/README.md).
-If possible you should use the persistent mode, see [qemu_frida/README.persistent.md](../qemu_frida/README.persistent.md).
+If possible you should use the persistent mode, see [qemu_frida/README.md](../qemu_frida/README.md).
The mode is approximately 2-5x slower than compile-time instrumentation, and is
less conducive to parallelization.
@@ -71,7 +71,8 @@ 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.
-Faster is the frida solution: [utils/afl_frida/README.md](../utils/afl_frida/README.md)
+Then you fuzz this with either frida_mode or qemu_mode, and either use
+`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 23b24ad0..7695e21f 100644
--- a/docs/fuzzing_expert.md
+++ b/docs/fuzzing_expert.md
@@ -472,7 +472,7 @@ If you are using AFL spinoffs or AFL conforming fuzzers, then just use the
same -o directory and give it a unique `-S` name.
Examples are:
* [Fuzzolic](https://github.com/season-lab/fuzzolic)
- * [symcc](https://github.com/eurecom-s/symcc/)
+ * [symcc](https://github.com/eurecom-s3/symcc/)
* [Eclipser](https://github.com/SoftSec-KAIST/Eclipser/)
* [AFLsmart](https://github.com/aflsmart/aflsmart)
* [FairFuzz](https://github.com/carolemieux/afl-rb)
From d6500eb298936c18af3f2d6529f23723dbdf67c5 Mon Sep 17 00:00:00 2001
From: mart1n
Date: Mon, 20 Sep 2021 18:55:39 +0800
Subject: [PATCH 035/305] fix a bug in frida_mode/test/libpcap/GNUMakefile
---
frida_mode/test/libpcap/GNUmakefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frida_mode/test/libpcap/GNUmakefile b/frida_mode/test/libpcap/GNUmakefile
index 6f2b58af..f8dc3db7 100644
--- a/frida_mode/test/libpcap/GNUmakefile
+++ b/frida_mode/test/libpcap/GNUmakefile
@@ -59,7 +59,7 @@ GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
-ifeq "$(ARCH)" "aarch64"
+ifeq "$(ARCH)" "arm64"
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000aaaaaaaaa000)
endif
From c8f6a313110db8db033bfbfc4eb3d7043daa430d Mon Sep 17 00:00:00 2001
From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Date: Wed, 22 Sep 2021 23:05:54 +0100
Subject: [PATCH 036/305] Performance improvements (#1094)
---
frida_mode/src/instrument/instrument_x64.c | 202 ++++++++++++++++---
frida_mode/test/freetype2/GNUmakefile | 192 ++++++++++++++++++
frida_mode/test/freetype2/Makefile | 13 ++
frida_mode/test/freetype2/get_symbol_addr.py | 36 ++++
4 files changed, 413 insertions(+), 30 deletions(-)
create mode 100644 frida_mode/test/freetype2/GNUmakefile
create mode 100644 frida_mode/test/freetype2/Makefile
create mode 100755 frida_mode/test/freetype2/get_symbol_addr.py
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index fec8afbb..8948c4df 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -1,6 +1,9 @@
+#include
+
#include "frida-gumjs.h"
#include "config.h"
+#include "debug.h"
#include "instrument.h"
@@ -8,38 +11,120 @@
static GumAddress current_log_impl = GUM_ADDRESS(0);
-static const guint8 afl_log_code[] = {
+ #pragma pack(push, 1)
- 0x9c, /* pushfq */
- 0x51, /* push rcx */
- 0x52, /* push rdx */
+typedef struct {
- 0x48, 0x8b, 0x0d, 0x26,
- 0x00, 0x00, 0x00, /* mov rcx, sym.&previous_pc */
- 0x48, 0x8b, 0x11, /* mov rdx, qword [rcx] */
- 0x48, 0x31, 0xfa, /* xor rdx, rdi */
+ /*
+ * 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
- 0x48, 0x03, 0x15, 0x11,
- 0x00, 0x00, 0x00, /* add rdx, sym._afl_area_ptr_ptr */
+ * pop rdx
+ * popfq
+ */
+ 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];
- 0x80, 0x02, 0x01, /* add byte ptr [rdx], 1 */
- 0x80, 0x12, 0x00, /* adc byte ptr [rdx], 0 */
- 0x66, 0xd1, 0xcf, /* ror di, 1 */
- 0x48, 0x89, 0x39, /* mov qword [rcx], rdi */
+ 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];
- 0x5a, /* pop rdx */
- 0x59, /* pop rcx */
- 0x9d, /* popfq */
+ uint8_t pop_rdx;
+ uint8_t pop_fq;
+ uint8_t ret;
- 0xc3, /* ret */
+} afl_log_code_asm_t;
- 0x90
+ #pragma pack(pop)
- /* Read-only data goes here: */
- /* uint8_t* __afl_area_ptr */
- /* uint64_t* &previous_pc */
+ #pragma pack(push, 8)
+typedef struct {
-};
+ afl_log_code_asm_t assembly;
+ uint64_t current_pc;
+
+} afl_log_code_t;
+
+ #pragma pack(pop)
+
+typedef union {
+
+ afl_log_code_t data;
+ uint8_t bytes[0];
+
+} afl_log_code;
+
+static const afl_log_code_asm_t template = {
+
+ .push_fq = 0x9c,
+ .push_rdx = 0x52,
+ .mov_rdx_rip_off =
+ {
+
+ 0x48, 0x8b, 0x15,
+ /* TBC */
+
+ },
+
+ .xor_rdx_rdi =
+ {
+
+ 0x48,
+ 0x31,
+ 0xfa,
+
+ },
+
+ .shr_rdi = {0x48, 0xd1, 0xef},
+ .mov_rip_off_rdi = {0x48, 0x89, 0x3d},
+
+ .lea_rdi_rip_off =
+ {
+
+ 0x48,
+ 0x8d,
+ 0x3d,
+
+ },
+
+ .add_rdx_rdi = {0x48, 0x01, 0xfA},
+
+ .add_byte_ptr_rdx =
+ {
+
+ 0x80,
+ 0x02,
+ 0x01,
+
+ },
+
+ .adc_byte_ptr_rdx =
+ {
+
+ 0x80,
+ 0x12,
+ 0x00,
+
+ },
+
+ .pop_rdx = 0x5a,
+ .pop_fq = 0x9d,
+ .ret = 0xc3};
+
+static guint8 align_pad[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
gboolean instrument_is_coverage_optimize_supported(void) {
@@ -47,12 +132,19 @@ gboolean instrument_is_coverage_optimize_supported(void) {
}
-static guint8 align_pad[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
+static gboolean instrument_coverage_in_range(gssize offset) {
+
+ return (offset >= G_MININT32 && offset <= G_MAXINT32);
+
+}
static void instrument_coverate_write_function(GumStalkerOutput *output) {
guint64 misalign = 0;
GumX86Writer *cw = output->writer.x86;
+ GumAddress code_addr = 0;
+ afl_log_code code = {0};
+ guint64 instrument_hash_zero = 0;
if (current_log_impl == 0 ||
!gum_x86_writer_can_branch_directly_between(cw->pc, current_log_impl) ||
@@ -71,13 +163,63 @@ static void instrument_coverate_write_function(GumStalkerOutput *output) {
}
current_log_impl = cw->pc;
- gum_x86_writer_put_bytes(cw, afl_log_code, sizeof(afl_log_code));
+ // gum_x86_writer_put_breakpoint(cw);
+ code_addr = cw->pc;
- uint64_t *afl_prev_loc_ptr = &instrument_previous_pc;
- gum_x86_writer_put_bytes(cw, (const guint8 *)&__afl_area_ptr,
- sizeof(__afl_area_ptr));
- gum_x86_writer_put_bytes(cw, (const guint8 *)&afl_prev_loc_ptr,
- sizeof(afl_prev_loc_ptr));
+ code.data.assembly = template;
+ code.data.current_pc = instrument_get_offset_hash(0);
+
+ 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)) {
+
+ FATAL("Patch out of range (current_pc_value1): 0x%016lX",
+ current_pc_value1);
+
+ }
+
+ *((gint *)&code.bytes[patch_offset1]) = (gint)current_pc_value1;
+
+ 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)) {
+
+ FATAL("Patch out of range (current_pc_value2): 0x%016lX",
+ current_pc_value2);
+
+ }
+
+ *((gint *)&code.bytes[patch_offset2]) = (gint)current_pc_value2;
+
+ 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);
+
+ if (!instrument_coverage_in_range(afl_area_ptr_value)) {
+
+ FATAL("Patch out of range (afl_area_ptr_value): 0x%016lX",
+ afl_area_ptr_value);
+
+ }
+
+ *((gint *)&code.bytes[afl_area_ptr_offset]) = (gint)afl_area_ptr_value;
+
+ gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
gum_x86_writer_put_label(cw, after_log_impl);
diff --git a/frida_mode/test/freetype2/GNUmakefile b/frida_mode/test/freetype2/GNUmakefile
new file mode 100644
index 00000000..891660ca
--- /dev/null
+++ b/frida_mode/test/freetype2/GNUmakefile
@@ -0,0 +1,192 @@
+PWD:=$(shell pwd)/
+ROOT:=$(PWD)../../../
+BUILD_DIR:=$(PWD)build/
+
+AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/frida_hook.so
+AFLPP_QEMU_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/qemu_hook.so
+
+# git clone git://git.sv.nongnu.org/freetype/freetype2.git
+# git clone https://github.com/unicode-org/text-rendering-tests.git TRT
+# wget https://github.com/libarchive/libarchive/releases/download/v3.4.3/libarchive-3.4.3.tar.xz
+
+# cp TRT/fonts/TestKERNOne.otf $OUT/seeds/
+# cp TRT/fonts/TestGLYFOne.ttf $OUT/seeds/
+
+# $CXX $CXXFLAGS -std=c++11 -I include -I . src/tools/ftfuzzer/ftfuzzer.cc \
+# objs/.libs/libfreetype.a $FUZZER_LIB -L /usr/local/lib -larchive \
+# -o $OUT/ftfuzzer
+
+LIBARCHIVE_URL:=https://github.com/libarchive/libarchive/releases/download/v3.4.3/libarchive-3.4.3.tar.xz
+LIBARCHIVE_BUILD_DIR:=$(BUILD_DIR)libarchive/
+LIBARCHIVE_TARBALL:=$(LIBARCHIVE_BUILD_DIR)libarchive-3.4.3.tar.xz
+LIBARCHIVE_DIR:=$(LIBARCHIVE_BUILD_DIR)libarchive-3.4.3/
+LIBARCHIVE_LIB:=$(LIBARCHIVE_DIR).libs/libarchive.a
+
+FREETYPE2_GIT_REPO:=git://git.sv.nongnu.org/freetype/freetype2.git
+FREETYPE2_BUILD_DIR:=$(BUILD_DIR)freetype2/
+FREETYPE2_DIR:=$(FREETYPE2_BUILD_DIR)freetype2/
+FREETYPE2_LIB:=$(FREETYPE2_DIR)objs/.libs/libfreetype.a
+
+HARNESS_URL:=https://raw.githubusercontent.com/llvm/llvm-project/main/compiler-rt/lib/fuzzer/standalone/StandaloneFuzzTargetMain.c
+HARNESS_SRC:=$(BUILD_DIR)StandaloneFuzzTargetMain.c
+HARNESS_OBJ:=$(BUILD_DIR)StandaloneFuzzTargetMain.o
+
+TRT_GIT_REPO:=https://github.com/unicode-org/text-rendering-tests.git
+TRT_DIR:=$(BUILD_DIR)TRT/
+
+FUZZER_SRC:=$(FREETYPE2_DIR)src/tools/ftfuzzer/ftfuzzer.cc
+
+
+LDFLAGS += -lpthread
+
+TEST_BIN:=$(BUILD_DIR)test
+ifeq "$(shell uname)" "Darwin"
+TEST_BIN_LDFLAGS:=-undefined dynamic_lookup -Wl,-no_pie
+endif
+
+TEST_DATA_DIR:=$(BUILD_DIR)in/
+TEST_DATA_FILE:=$(TEST_DATA_DIR)default_seed
+
+FRIDA_OUT:=$(BUILD_DIR)frida-out
+QEMU_OUT:=$(BUILD_DIR)qemu-out
+
+ifndef ARCH
+
+ARCH=$(shell uname -m)
+ifeq "$(ARCH)" "aarch64"
+ ARCH:=arm64
+endif
+
+ifeq "$(ARCH)" "i686"
+ ARCH:=x86
+endif
+endif
+
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+
+AFL_QEMU_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x4000000000)
+
+ifeq "$(ARCH)" "aarch64"
+ AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000aaaaaaaaa000)
+endif
+
+ifeq "$(ARCH)" "x86_64"
+ AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x0000555555554000)
+endif
+
+ifeq "$(ARCH)" "x86"
+ AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput 0x56555000)
+endif
+
+.PHONY: all clean frida hook
+
+all: $(TEST_BIN)
+ make -C $(ROOT)frida_mode/
+
+32:
+ CXXFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
+
+$(BUILD_DIR):
+ mkdir -p $@
+
+########## LIBARCHIVE #######
+
+$(LIBARCHIVE_BUILD_DIR): | $(BUILD_DIR)
+ mkdir -p $@
+
+$(LIBARCHIVE_TARBALL): | $(LIBARCHIVE_BUILD_DIR)
+ wget -O $@ $(LIBARCHIVE_URL)
+
+$(LIBARCHIVE_DIR): | $(LIBARCHIVE_TARBALL)
+ tar Jxvf $(LIBARCHIVE_TARBALL) -C $(LIBARCHIVE_BUILD_DIR)
+
+$(LIBARCHIVE_DIR)Makefile: | $(LIBARCHIVE_DIR)
+ cd $(LIBARCHIVE_DIR) && ./configure --disable-shared
+
+$(LIBARCHIVE_LIB): $(LIBARCHIVE_DIR)Makefile
+ make -C $(LIBARCHIVE_DIR) clean all
+
+########## FREETYPE2 #######
+
+$(FREETYPE2_BUILD_DIR): | $(BUILD_DIR)
+ mkdir -p $@
+
+$(FREETYPE2_DIR): | $(FREETYPE2_BUILD_DIR)
+ git clone $(FREETYPE2_GIT_REPO) $@
+ git -C $(FREETYPE2_DIR) checkout cd02d359a6d0455e9d16b87bf9665961c4699538
+
+$(FREETYPE2_LIB): | $(FREETYPE2_DIR)
+ cd $(FREETYPE2_DIR) && ./autogen.sh
+ cd $(FREETYPE2_DIR) && ./configure --with-harfbuzz=no --with-bzip2=no --with-png=no --without-zlib
+ make -C $(FREETYPE2_DIR) all
+
+########## HARNESS #######
+
+$(HARNESS_SRC):
+ wget -O $@ $(HARNESS_URL)
+
+$(HARNESS_OBJ): $(HARNESS_SRC)
+ $(CC) -o $@ -c $<
+
+########## TEST #######
+
+$(TEST_BIN): $(LIBARCHIVE_LIB) $(FREETYPE2_LIB) $(HARNESS_OBJ)
+ $(CXX) \
+ $(CXXFLAGS) \
+ -std=c++11 \
+ -I $(FREETYPE2_DIR)include \
+ -I $(FREETYPE2_DIR) \
+ -I $(LIBARCHIVE_DIR)/libarchive \
+ $(FUZZER_SRC) \
+ $(FREETYPE2_LIB) \
+ $(LIBARCHIVE_LIB) \
+ $(HARNESS_OBJ) \
+ -o $@
+
+########## DUMMY #######
+
+$(TRT_DIR): | $(BUILD_DIR)
+ git clone $(TRT_GIT_REPO) $@
+
+$(TEST_DATA_DIR): | $(TRT_DIR)
+ mkdir -p $@
+ cp $(TRT_DIR)fonts/TestKERNOne.otf $@
+ cp $(TRT_DIR)fonts/TestGLYFOne.ttf $@
+
+$(TEST_DATA_FILE): | $(TEST_DATA_DIR)
+ dd if=/dev/zero bs=1048576 count=1 of=$@
+
+###### TEST DATA #######
+
+clean:
+ rm -rf $(BUILD_DIR)
+
+frida: $(TEST_BIN) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE)
+ AFL_FRIDA_PERSISTENT_CNT=1000000 \
+ AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_FRIDA_DRIVER_HOOK_OBJ) \
+ AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \
+ AFL_ENTRYPOINT=$(AFL_FRIDA_PERSISTENT_ADDR) \
+ $(ROOT)afl-fuzz \
+ -i $(TEST_DATA_DIR) \
+ -o $(FRIDA_OUT) \
+ -m none \
+ -d \
+ -O \
+ -V 30 \
+ -- \
+ $(TEST_BIN) $(TEST_DATA_FILE)
+
+qemu: $(TEST_BIN) $(AFLPP_QEMU_DRIVER_HOOK_OBJ) $(TEST_DATA_FILE)
+ AFL_QEMU_PERSISTENT_CNT=1000000 \
+ AFL_QEMU_PERSISTENT_HOOK=$(AFLPP_QEMU_DRIVER_HOOK_OBJ) \
+ AFL_QEMU_PERSISTENT_ADDR=$(AFL_QEMU_PERSISTENT_ADDR) \
+ AFL_ENTRYPOINT=$(AFL_QEMU_PERSISTENT_ADDR) \
+ $(ROOT)afl-fuzz \
+ -i $(TEST_DATA_DIR) \
+ -o $(QEMU_OUT) \
+ -m none \
+ -d \
+ -Q \
+ -V 30 \
+ -- \
+ $(TEST_BIN) $(TEST_DATA_FILE)
diff --git a/frida_mode/test/freetype2/Makefile b/frida_mode/test/freetype2/Makefile
new file mode 100644
index 00000000..07b139e9
--- /dev/null
+++ b/frida_mode/test/freetype2/Makefile
@@ -0,0 +1,13 @@
+all:
+ @echo trying to use GNU make...
+ @gmake all || echo please install GNUmake
+
+32:
+ @echo trying to use GNU make...
+ @gmake 32 || echo please install GNUmake
+
+clean:
+ @gmake clean
+
+frida:
+ @gmake frida
diff --git a/frida_mode/test/freetype2/get_symbol_addr.py b/frida_mode/test/freetype2/get_symbol_addr.py
new file mode 100755
index 00000000..1c46e010
--- /dev/null
+++ b/frida_mode/test/freetype2/get_symbol_addr.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python3
+import argparse
+from elftools.elf.elffile import ELFFile
+
+def process_file(file, symbol, base):
+ with open(file, 'rb') as f:
+ elf = ELFFile(f)
+ symtab = elf.get_section_by_name('.symtab')
+ mains = symtab.get_symbol_by_name(symbol)
+ if len(mains) != 1:
+ print ("Failed to find main")
+ return 1
+
+ main_addr = mains[0]['st_value']
+ main = base + main_addr
+ print ("0x%016x" % main)
+ return 0
+
+def hex_value(x):
+ return int(x, 16)
+
+def main():
+ parser = argparse.ArgumentParser(description='Process some integers.')
+ parser.add_argument('-f', '--file', dest='file', type=str,
+ help='elf file name', required=True)
+ parser.add_argument('-s', '--symbol', dest='symbol', type=str,
+ help='symbol name', required=True)
+ parser.add_argument('-b', '--base', dest='base', type=hex_value,
+ help='elf base address', required=True)
+
+ args = parser.parse_args()
+ return process_file (args.file, args.symbol, args.base)
+
+if __name__ == "__main__":
+ ret = main()
+ exit(ret)
From 0ed0c9493ee2aeecd1a16a65e48348be8db5c662 Mon Sep 17 00:00:00 2001
From: root
Date: Mon, 27 Sep 2021 06:21:12 +0300
Subject: [PATCH 037/305] Fix null ptr dereference of unresolved symbols on
early init (linking stage)
---
qemu_mode/libcompcov/libcompcov.so.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/qemu_mode/libcompcov/libcompcov.so.c b/qemu_mode/libcompcov/libcompcov.so.c
index 4fc84e62..24867cda 100644
--- a/qemu_mode/libcompcov/libcompcov.so.c
+++ b/qemu_mode/libcompcov/libcompcov.so.c
@@ -41,6 +41,13 @@
#error "Sorry, this library is Linux-specific for now!"
#endif /* !__linux__ */
+#ifndef likely
+# define likely(x) __builtin_expect((!!(x)),1)
+#endif
+#ifndef unlikely
+# define unlikely(x) __builtin_expect((!!(x)),0)
+#endif
+
/* Change this value to tune the compare coverage */
#define MAX_CMP_LENGTH 32
@@ -199,6 +206,7 @@ static u8 __compcov_is_in_bound(const void *ptr) {
int strcmp(const char *str1, const char *str2) {
+ if (unlikely(!__libc_strcmp)) { __libc_strcmp = dlsym(RTLD_NEXT, "strcmp"); }
void *retaddr = __builtin_return_address(0);
if (__compcov_is_in_bound(retaddr) &&
@@ -227,6 +235,7 @@ int strcmp(const char *str1, const char *str2) {
int strncmp(const char *str1, const char *str2, size_t len) {
+ if (unlikely(!__libc_strncmp)) { __libc_strncmp = dlsym(RTLD_NEXT, "strncmp"); }
void *retaddr = __builtin_return_address(0);
if (__compcov_is_in_bound(retaddr) &&
@@ -256,6 +265,7 @@ int strncmp(const char *str1, const char *str2, size_t len) {
int strcasecmp(const char *str1, const char *str2) {
+ if (unlikely(!__libc_strcasecmp)) { __libc_strncasecmp = dlsym(RTLD_NEXT, "strcasecmp"); }
void *retaddr = __builtin_return_address(0);
if (__compcov_is_in_bound(retaddr) &&
@@ -286,6 +296,7 @@ int strcasecmp(const char *str1, const char *str2) {
int strncasecmp(const char *str1, const char *str2, size_t len) {
+ if (unlikely(!__libc_strncasecmp)) { __libc_strncasecmp = dlsym(RTLD_NEXT, "strncasecmp"); }
void *retaddr = __builtin_return_address(0);
if (__compcov_is_in_bound(retaddr) &&
@@ -317,6 +328,7 @@ int strncasecmp(const char *str1, const char *str2, size_t len) {
int memcmp(const void *mem1, const void *mem2, size_t len) {
+ if (unlikely(!__libc_memcmp)) { __libc_memcmp = dlsym(RTLD_NEXT, "memcmp"); }
void *retaddr = __builtin_return_address(0);
if (__compcov_is_in_bound(retaddr) &&
From 4473904bc0de7011a77309d96f7090a51c8fe768 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 1 Oct 2021 13:25:02 +0200
Subject: [PATCH 038/305] fix -n
---
docs/Changelog.md | 1 +
src/afl-fuzz-stats.c | 5 +++--
src/afl-fuzz.c | 2 +-
unicorn_mode/unicornafl | 2 +-
4 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index de217c2e..dad5fee2 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -15,6 +15,7 @@ sending a mail to .
information on how to deal with instrumenting libraries
- 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)
- afl-showmap, afl-tmin and afl-analyze now honor persistent mode
for more speed. thanks to dloffre-snl for reporting!
- afl-cc:
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index eb1fe2d9..870ba69a 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -560,8 +560,9 @@ void show_stats(afl_state_t *afl) {
/* Roughly every minute, update fuzzer stats and save auto tokens. */
- if (unlikely(afl->force_ui_update ||
- cur_ms - afl->stats_last_stats_ms > STATS_UPDATE_SEC * 1000)) {
+ if (unlikely(!afl->non_instrumented_mode &&
+ (afl->force_ui_update ||
+ cur_ms - afl->stats_last_stats_ms > STATS_UPDATE_SEC * 1000))) {
afl->stats_last_stats_ms = cur_ms;
write_stats_file(afl, t_bytes, t_byte_ratio, stab_ratio,
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 8ffc0e77..87da9798 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1918,7 +1918,7 @@ int main(int argc, char **argv_orig, char **envp) {
}
- write_stats_file(afl, 0, 0, 0, 0);
+ if (!afl->non_instrumented_mode) { write_stats_file(afl, 0, 0, 0, 0); }
maybe_update_plot_file(afl, 0, 0, 0);
save_auto(afl);
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index 019b8715..c0e03d2c 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit 019b871539fe9ed3f41d882385a8b02c243d49ad
+Subproject commit c0e03d2c6b55a22025324f121746b41b1e756fb8
From d668f9697cc44a58ca38b42d99aa5143b13b703d Mon Sep 17 00:00:00 2001
From: Andrea Fioraldi
Date: Fri, 1 Oct 2021 16:29:48 +0200
Subject: [PATCH 039/305] update qemuafl
---
qemu_mode/QEMUAFL_VERSION | 2 +-
qemu_mode/qemuafl | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index 215826cc..ade3a779 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-a6758d1cc3
+86dead4dcb
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
index a6758d1c..86dead4d 160000
--- a/qemu_mode/qemuafl
+++ b/qemu_mode/qemuafl
@@ -1 +1 @@
-Subproject commit a6758d1cc3e4dde88fca3f0b3a903581b7c8b2e5
+Subproject commit 86dead4dcb1aae7181fbf6b5f3706eee9f842e3a
From e80131bef50d343e71a08cdf6ae1aa57b4475867 Mon Sep 17 00:00:00 2001
From: hexcoder-
Date: Sat, 2 Oct 2021 22:47:22 +0200
Subject: [PATCH 040/305] fix some compiler warnings in 32-bit linux
---
frida_mode/src/instrument/instrument_x64.c | 11 +++++++----
frida_mode/src/prefetch.c | 8 +++++---
include/config.h | 4 ++--
src/afl-analyze.c | 2 +-
src/afl-fuzz.c | 2 +-
src/afl-showmap.c | 2 +-
src/afl-tmin.c | 2 +-
unicorn_mode/unicornafl | 2 +-
8 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index 8948c4df..1c2cf113 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -144,7 +144,7 @@ static void instrument_coverate_write_function(GumStalkerOutput *output) {
GumX86Writer *cw = output->writer.x86;
GumAddress code_addr = 0;
afl_log_code code = {0};
- guint64 instrument_hash_zero = 0;
+ /*guint64 instrument_hash_zero = 0;*/
if (current_log_impl == 0 ||
!gum_x86_writer_can_branch_directly_between(cw->pc, current_log_impl) ||
@@ -183,7 +183,8 @@ static void instrument_coverate_write_function(GumStalkerOutput *output) {
}
- *((gint *)&code.bytes[patch_offset1]) = (gint)current_pc_value1;
+ gint *dst_pc_value = (gint *)&code.bytes[patch_offset1];
+ *dst_pc_value = (gint)current_pc_value1;
gssize current_pc_value2 =
GPOINTER_TO_SIZE(&instrument_previous_pc) -
@@ -200,7 +201,8 @@ static void instrument_coverate_write_function(GumStalkerOutput *output) {
}
- *((gint *)&code.bytes[patch_offset2]) = (gint)current_pc_value2;
+ dst_pc_value = (gint *)&code.bytes[patch_offset2];
+ *dst_pc_value = (gint)current_pc_value2;
gsize afl_area_ptr_value =
GPOINTER_TO_SIZE(__afl_area_ptr) -
@@ -217,7 +219,8 @@ static void instrument_coverate_write_function(GumStalkerOutput *output) {
}
- *((gint *)&code.bytes[afl_area_ptr_offset]) = (gint)afl_area_ptr_value;
+ gint *dst_afl_area_ptr_value = (gint *)&code.bytes[afl_area_ptr_offset];
+ *dst_afl_area_ptr_value = (gint)afl_area_ptr_value;
gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
diff --git a/frida_mode/src/prefetch.c b/frida_mode/src/prefetch.c
index 0efbc9bf..c30ca65c 100644
--- a/frida_mode/src/prefetch.c
+++ b/frida_mode/src/prefetch.c
@@ -44,8 +44,9 @@ static void gum_afl_stalker_backpatcher_notify(GumStalkerObserver *self,
sizeof(prefetch_data->backpatch_data) - prefetch_data->backpatch_size;
if (sizeof(gsize) + size > remaining) { return; }
- *(gsize *)(&prefetch_data->backpatch_data[prefetch_data->backpatch_size]) =
- size;
+ gsize *dst_backpatch_size = (gsize *)
+ &prefetch_data->backpatch_data[prefetch_data->backpatch_size];
+ *dst_backpatch_size = size;
prefetch_data->backpatch_size += sizeof(gsize);
memcpy(&prefetch_data->backpatch_data[prefetch_data->backpatch_size],
@@ -115,7 +116,8 @@ static void prefetch_read_patches(void) {
remaining > sizeof(gsize);
remaining = prefetch_data->backpatch_size - offset) {
- gsize size = *(gsize *)(&prefetch_data->backpatch_data[offset]);
+ gsize *src_backpatch_data = (gsize *)&prefetch_data->backpatch_data[offset];
+ gsize size = *src_backpatch_data;
offset += sizeof(gsize);
if (prefetch_data->backpatch_size - offset < size) {
diff --git a/include/config.h b/include/config.h
index da74989e..4630da0c 100644
--- a/include/config.h
+++ b/include/config.h
@@ -237,11 +237,11 @@
(note that if this value is changed, several areas in afl-cc.c, afl-fuzz.c
and afl-fuzz-state.c have to be changed as well! */
-#define MAX_FILE (1 * 1024 * 1024U)
+#define MAX_FILE (1 * 1024 * 1024L)
/* The same, for the test case minimizer: */
-#define TMIN_MAX_FILE (10 * 1024 * 1024)
+#define TMIN_MAX_FILE (10 * 1024 * 1024L)
/* Block normalization steps for afl-tmin: */
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index eef08494..8295488d 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -184,7 +184,7 @@ static void read_initial_file(void) {
if (st.st_size >= TMIN_MAX_FILE) {
- FATAL("Input file is too large (%u MB max)", TMIN_MAX_FILE / 1024 / 1024);
+ FATAL("Input file is too large (%ld MB max)", TMIN_MAX_FILE / 1024 / 1024);
}
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 87da9798..92a37697 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1348,7 +1348,7 @@ int main(int argc, char **argv_orig, char **envp) {
} else if (afl->q_testcase_max_cache_size < 2 * MAX_FILE) {
- FATAL("AFL_TESTCACHE_SIZE must be set to %u or more, or 0 to disable",
+ FATAL("AFL_TESTCACHE_SIZE must be set to %ld or more, or 0 to disable",
(2 * MAX_FILE) % 1048576 == 0 ? (2 * MAX_FILE) / 1048576
: 1 + ((2 * MAX_FILE) / 1048576));
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index e143371e..75b0ff99 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -413,7 +413,7 @@ static u32 read_file(u8 *in_file) {
if (!be_quiet && !quiet_mode) {
- WARNF("Input file '%s' is too large, only reading %u bytes.", in_file,
+ WARNF("Input file '%s' is too large, only reading %ld bytes.", in_file,
MAX_FILE);
}
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index dff51e84..4f3a6b80 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -221,7 +221,7 @@ static void read_initial_file(void) {
if (st.st_size >= TMIN_MAX_FILE) {
- FATAL("Input file is too large (%u MB max)", TMIN_MAX_FILE / 1024 / 1024);
+ FATAL("Input file is too large (%ld MB max)", TMIN_MAX_FILE / 1024 / 1024);
}
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index c0e03d2c..1c47d1eb 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit c0e03d2c6b55a22025324f121746b41b1e756fb8
+Subproject commit 1c47d1ebc7e904ad4efc1370f23e269fb9ac3f93
From 1a79a36762ccb5cac6da8ce09fd681166d02352b Mon Sep 17 00:00:00 2001
From: hexcoder-
Date: Sun, 3 Oct 2021 00:32:59 +0200
Subject: [PATCH 041/305] fix compiler warning in 32-Bit
---
frida_mode/src/seccomp/seccomp_callback.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/frida_mode/src/seccomp/seccomp_callback.c b/frida_mode/src/seccomp/seccomp_callback.c
index 4af2ed0c..7e1e2070 100644
--- a/frida_mode/src/seccomp/seccomp_callback.c
+++ b/frida_mode/src/seccomp/seccomp_callback.c
@@ -14,8 +14,12 @@ static void seccomp_callback_filter(struct seccomp_notif * req,
GumDebugSymbolDetails details = {0};
if (req->data.nr == SYS_OPENAT) {
+#if UINTPTR_MAX == 0xffffffffffffffffu
seccomp_print("SYS_OPENAT: (%s)\n", (char *)req->data.args[1]);
-
+#endif
+#if UINTPTR_MAX == 0xffffffff
+ seccomp_print("SYS_OPENAT: (%s)\n", (char *)(__u32)req->data.args[1]);
+#endif
}
seccomp_print(
From fc48a58e64b8c5abafa83b50ea68bf8e47d00552 Mon Sep 17 00:00:00 2001
From: David CARLIER
Date: Sun, 3 Oct 2021 07:35:13 +0100
Subject: [PATCH 042/305] frida mode macOs warning fix, syscall being
deprecated, using pthread_threadid_np available since snow leopard
---
frida_mode/src/instrument/instrument.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c
index fd0982f8..71d9bdf6 100644
--- a/frida_mode/src/instrument/instrument.c
+++ b/frida_mode/src/instrument/instrument.c
@@ -341,8 +341,14 @@ void instrument_init(void) {
* parallel fuzzing. The seed itself, doesn't have to be random, it
* just needs to be different for each instance.
*/
+ guint64 tid;
+#if defined(__APPLE__)
+ pthread_threadid_np(NULL, &tid);
+#else
+ tid = syscall(SYS_gettid);
+#endif
instrument_hash_seed = g_get_monotonic_time() ^
- (((guint64)getpid()) << 32) ^ syscall(SYS_gettid);
+ (((guint64)getpid()) << 32) ^ tid;
}
From 716d2029c0c2557486488ce6bb7910df9ce4ffcb Mon Sep 17 00:00:00 2001
From: David Carlier
Date: Sun, 3 Oct 2021 15:58:03 +0100
Subject: [PATCH 043/305] LLVM LTO plugin using smart pointer for
__afl_internal_directory variable
---
.../afl-llvm-lto-instrumentation.so.cc | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc
index e300044c..4a5738de 100644
--- a/instrumentation/afl-llvm-lto-instrumentation.so.cc
+++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc
@@ -28,6 +28,7 @@
#include
#include
+#include
#include
#include
#include
@@ -1015,13 +1016,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
if (count) {
- if ((ptr = (char *)malloc(memlen + count)) == NULL) {
-
- fprintf(stderr, "Error: malloc for %zu bytes failed!\n",
- memlen + count);
- exit(-1);
-
- }
+ auto ptrhld = std::unique_ptr(new char[memlen + count]);
count = 0;
@@ -1030,8 +1025,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
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++;
@@ -1051,10 +1046,10 @@ bool AFLLTOPass::runOnModule(Module &M) {
GlobalVariable *AFLInternalDictionary = new GlobalVariable(
M, ArrayTy, true, GlobalValue::ExternalLinkage,
ConstantDataArray::get(C,
- *(new ArrayRef((char *)ptr, offset))),
+ *(new ArrayRef(ptrhld.get(), offset))),
"__afl_internal_dictionary");
AFLInternalDictionary->setInitializer(ConstantDataArray::get(
- C, *(new ArrayRef((char *)ptr, offset))));
+ C, *(new ArrayRef(ptrhld.get(), offset))));
AFLInternalDictionary->setConstant(true);
GlobalVariable *AFLDictionary = new GlobalVariable(
From 46683d651656f1876f6d4aeb24807ed71fa91237 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 4 Oct 2021 08:19:42 +0200
Subject: [PATCH 044/305] update docs
---
README.md | 20 ++++++++++++++++----
docs/fuzzing_expert.md | 7 ++++++-
qemu_mode/qemuafl | 2 +-
unicorn_mode/unicornafl | 2 +-
4 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index db6a70b5..76ef8448 100644
--- a/README.md
+++ b/README.md
@@ -66,17 +66,29 @@ A common way to do this would be:
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.
+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:
- ./afl-fuzz -i testcase_dir -o findings_dir -- \
- /path/to/tested/program [...program's cmdline...]
+```
+ ./afl-fuzz -i seeds_dir -o output_dir -- \
+ /path/to/tested/program [...program's cmdline...]
+```
- 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.
+ 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
+ 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).
+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?
diff --git a/docs/fuzzing_expert.md b/docs/fuzzing_expert.md
index 7695e21f..ca884159 100644
--- a/docs/fuzzing_expert.md
+++ b/docs/fuzzing_expert.md
@@ -540,6 +540,11 @@ To have only the summary use the `-s` switch e.g.: `afl-whatsup -s out/`
If you have multiple servers then use the command after a sync, or you have
to execute this script per server.
+Another tool to inspect the current state and history of a specific instance
+is afl-plot, which generates an index.html file and a graphs that show how
+the fuzzing instance is performing.
+The syntax is `afl-plot instance_dir web_dir`, e.g. `afl-plot out/default /srv/www/htdocs/plot`
+
#### e) Stopping fuzzing, restarting fuzzing, adding new seeds
To stop an afl-fuzz run, simply press Control-C.
@@ -620,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).
\ No newline at end of file
+(some might be deprecated or unsupported), see [links_tools.md](links_tools.md).
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
index 86dead4d..a6758d1c 160000
--- a/qemu_mode/qemuafl
+++ b/qemu_mode/qemuafl
@@ -1 +1 @@
-Subproject commit 86dead4dcb1aae7181fbf6b5f3706eee9f842e3a
+Subproject commit a6758d1cc3e4dde88fca3f0b3a903581b7c8b2e5
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index 1c47d1eb..c0e03d2c 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit 1c47d1ebc7e904ad4efc1370f23e269fb9ac3f93
+Subproject commit c0e03d2c6b55a22025324f121746b41b1e756fb8
From b9f88ab166bd798d25d3acdbc6b5c305d7875482 Mon Sep 17 00:00:00 2001
From: Daniel Ebert
Date: Tue, 5 Oct 2021 17:40:23 -0700
Subject: [PATCH 045/305] fix stack-use-after-return in libfuzzer custom
mutator
---
custom_mutators/libfuzzer/libfuzzer.inc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/custom_mutators/libfuzzer/libfuzzer.inc b/custom_mutators/libfuzzer/libfuzzer.inc
index 01f21dbe..8c4bdbf6 100644
--- a/custom_mutators/libfuzzer/libfuzzer.inc
+++ b/custom_mutators/libfuzzer/libfuzzer.inc
@@ -2,7 +2,7 @@
extern "C" ATTRIBUTE_INTERFACE void
LLVMFuzzerMyInit(int (*Callback)(const uint8_t *Data, size_t Size), unsigned int Seed) {
- Random Rand(Seed);
+ auto *Rand = new Random(Seed);
FuzzingOptions Options;
Options.Verbosity = 3;
Options.MaxLen = 1024000;
@@ -30,7 +30,7 @@ LLVMFuzzerMyInit(int (*Callback)(const uint8_t *Data, size_t Size), unsigned int
struct EntropicOptions Entropic;
Entropic.Enabled = Options.Entropic;
EF = new ExternalFunctions();
- auto *MD = new MutationDispatcher(Rand, Options);
+ auto *MD = new MutationDispatcher(*Rand, Options);
auto *Corpus = new InputCorpus(Options.OutputCorpus, Entropic);
auto *F = new Fuzzer(Callback, *Corpus, *MD, Options);
}
From 65e63b9cf107ae914630a4fff7381cee150df5fe Mon Sep 17 00:00:00 2001
From: Andrea Fioraldi
Date: Wed, 6 Oct 2021 13:49:13 +0200
Subject: [PATCH 046/305] update qemu
---
qemu_mode/QEMUAFL_VERSION | 2 +-
qemu_mode/qemuafl | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index ade3a779..7bdedf7b 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-86dead4dcb
+71ed0d206f
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
index a6758d1c..71ed0d20 160000
--- a/qemu_mode/qemuafl
+++ b/qemu_mode/qemuafl
@@ -1 +1 @@
-Subproject commit a6758d1cc3e4dde88fca3f0b3a903581b7c8b2e5
+Subproject commit 71ed0d206fd3d877420dceb4993a1011a4637ae6
From f0e6a7a4f8a387cd295a132ef0723f3257bed658 Mon Sep 17 00:00:00 2001
From: Daniel Ebert
Date: Wed, 6 Oct 2021 14:19:22 -0700
Subject: [PATCH 047/305] fix memory leak in libfuzzer custom mutator
---
custom_mutators/libfuzzer/FuzzerLoop.cpp | 1 +
1 file changed, 1 insertion(+)
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();
From 0a88a6c53071e9c203fa602e99e6510de14dacc0 Mon Sep 17 00:00:00 2001
From: Dominik Maier
Date: Thu, 7 Oct 2021 15:02:04 +0200
Subject: [PATCH 048/305] get rid of i32 need for unicornafl regs in rust
---
unicorn_mode/UNICORNAFL_VERSION | 2 +-
.../samples/speedtest/rust/src/main.rs | 20 +++++++++----------
unicorn_mode/unicornafl | 2 +-
3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index 0d84243c..cbca63e5 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-1c47d1ebc7e904ad4efc1370f23e269fb9ac3f93
+f1c853648a74b0157d233a2ef9f1693cfee78c11
diff --git a/unicorn_mode/samples/speedtest/rust/src/main.rs b/unicorn_mode/samples/speedtest/rust/src/main.rs
index 105ba4b4..77356a67 100644
--- a/unicorn_mode/samples/speedtest/rust/src/main.rs
+++ b/unicorn_mode/samples/speedtest/rust/src/main.rs
@@ -105,7 +105,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 +114,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,
@@ -139,7 +139,7 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
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,8 +147,8 @@ 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);
};
@@ -160,7 +160,7 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
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 +168,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);
};
@@ -178,7 +178,7 @@ 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();
+ uc.reg_write(RIP, addr + size as u64).unwrap();
};
for addr in parse_locs("malloc").unwrap() {
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index c0e03d2c..f1c85364 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit c0e03d2c6b55a22025324f121746b41b1e756fb8
+Subproject commit f1c853648a74b0157d233a2ef9f1693cfee78c11
From 580401591f36b0f6f7ba3ee08c867e12415e5cc5 Mon Sep 17 00:00:00 2001
From: David Carlier
Date: Sat, 9 Oct 2021 17:23:32 +0100
Subject: [PATCH 049/305] LLVM passes making slightly more C++
---
instrumentation/SanitizerCoverageLTO.so.cc | 17 +++++---------
instrumentation/afl-llvm-dict2file.so.cc | 23 ++++++++++---------
.../afl-llvm-lto-instrumentation.so.cc | 13 +++++------
3 files changed, 24 insertions(+), 29 deletions(-)
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index e06f8b93..eb0f06b2 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,7 +446,8 @@ bool ModuleSanitizerCoverage::instrumentModule(
if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) {
- if ((documentFile = fopen(ptr, "a")) == NULL)
+ dFile.open(ptr, std::ofstream::out | std::ofstream::app);
+ if (dFile.is_open())
WARNF("Cannot access document file %s", ptr);
}
@@ -1003,12 +1004,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) {
@@ -1509,12 +1505,11 @@ 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/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc
index 4622e488..c4ad1783 100644
--- a/instrumentation/afl-llvm-dict2file.so.cc
+++ b/instrumentation/afl-llvm-dict2file.so.cc
@@ -65,7 +65,8 @@ using namespace llvm;
namespace {
class AFLdict2filePass : public ModulePass {
-
+ std::ofstream of;
+ void dict2file(u8 *, u32);
public:
static char ID;
@@ -81,7 +82,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 +114,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 +125,7 @@ bool AFLdict2filePass::runOnModule(Module &M) {
DenseMap valueMap;
char * ptr;
- int fd, found = 0;
+ int found = 0;
/* Show a banner */
setvbuf(stdout, NULL, _IONBF, 0);
@@ -146,7 +146,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)
+ 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 +265,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 +631,7 @@ bool AFLdict2filePass::runOnModule(Module &M) {
ptr = (char *)thestring.c_str();
- dict2file(fd, (u8 *)ptr, optLen);
+ dict2file((u8 *)ptr, optLen);
found++;
}
@@ -641,7 +642,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 e300044c..d685e76c 100644
--- a/instrumentation/afl-llvm-lto-instrumentation.so.cc
+++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc
@@ -107,8 +107,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
// std::vector calls;
DenseMap valueMap;
std::vector BlockList;
+ std::ofstream dFile;
char * ptr;
- FILE * documentFile = NULL;
size_t found = 0;
srand((unsigned int)time(NULL));
@@ -136,7 +136,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) {
- if ((documentFile = fopen(ptr, "a")) == NULL)
+ dFile.open(ptr, std::ofstream::out | std::ofstream::app);
+ if (!dFile.is_open())
WARNF("Cannot access document file %s", ptr);
}
@@ -844,10 +845,9 @@ 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";
}
@@ -919,8 +919,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
From 65afe5addc7d5bd741a5283eeba4813849e99836 Mon Sep 17 00:00:00 2001
From: David Carlier
Date: Sat, 9 Oct 2021 18:31:12 +0100
Subject: [PATCH 050/305] LLVM coverage making it more C++ too.
---
instrumentation/SanitizerCoverageLTO.so.cc | 17 +++++------------
1 file changed, 5 insertions(+), 12 deletions(-)
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index eb0f06b2..960eb783 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -1065,7 +1065,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());
@@ -1085,13 +1084,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(new char[memlen + count]);
count = 0;
@@ -1099,8 +1092,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++;
@@ -1120,10 +1113,10 @@ bool ModuleSanitizerCoverage::instrumentModule(
GlobalVariable *AFLInternalDictionary = new GlobalVariable(
M, ArrayTy, true, GlobalValue::ExternalLinkage,
ConstantDataArray::get(Ctx,
- *(new ArrayRef((char *)ptr, offset))),
+ *(new ArrayRef(ptrhld.get(), offset))),
"__afl_internal_dictionary");
AFLInternalDictionary->setInitializer(ConstantDataArray::get(
- Ctx, *(new ArrayRef((char *)ptr, offset))));
+ Ctx, *(new ArrayRef(ptrhld.get(), offset))));
AFLInternalDictionary->setConstant(true);
GlobalVariable *AFLDictionary = new GlobalVariable(
From f6fbbf8150c8a41b7cd40a2413b1c6f66b24c6c8 Mon Sep 17 00:00:00 2001
From: Kuang-che Wu
Date: Sun, 10 Oct 2021 21:03:43 +0800
Subject: [PATCH 051/305] Fix document paths.
---
README.md | 8 ++++----
docs/best_practices.md | 6 +++---
docs/branches.md | 2 +-
docs/env_variables.md | 4 ++--
docs/fuzzing_expert.md | 4 ++--
docs/interpreting_output.md | 4 ++--
docs/known_limitations.md | 4 ++--
docs/parallel_fuzzing.md | 2 +-
docs/rpc_statsd.md | 4 ++--
docs/triaging_crashes.md | 2 +-
instrumentation/README.laf-intel.md | 5 ++---
instrumentation/README.llvm.md | 2 +-
12 files changed, 23 insertions(+), 24 deletions(-)
diff --git a/README.md b/README.md
index 76ef8448..1a22dd12 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ You are free to copy, modify, and distribute AFL++ with attribution under the te
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).
+* 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 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).
@@ -67,7 +67,7 @@ A common way to do this would be:
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.
+in [dictionaries/README.md](dictionaries/README.md), too.
3. If the program reads from stdin, run `afl-fuzz` like so:
@@ -94,7 +94,7 @@ in [dictionaries/README.md](../dictionaries/README.md), too.
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
+* 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 .
* Or join the [Awesome Fuzzing](https://discord.gg/gCraWct) Discord server.
@@ -191,4 +191,4 @@ If you use AFL++ in scientific work, consider citing [our paper](https://www.use
}
```
-
\ No newline at end of file
+
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..98fd6827 100644
--- a/docs/branches.md
+++ b/docs/branches.md
@@ -7,4 +7,4 @@ 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 [major changes in AFL++](important_changes.md).
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_expert.md b/docs/fuzzing_expert.md
index ca884159..ef3f8a4e 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).
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/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..b0015c90 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).
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
From 228f6c5dad1a593b4113006e587e9885459a53c2 Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Sun, 10 Oct 2021 16:00:21 +0200
Subject: [PATCH 052/305] Update fuzzing_binary-only_targets.md
---
docs/fuzzing_binary-only_targets.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/fuzzing_binary-only_targets.md b/docs/fuzzing_binary-only_targets.md
index a39e40a0..d568b976 100644
--- a/docs/fuzzing_binary-only_targets.md
+++ b/docs/fuzzing_binary-only_targets.md
@@ -71,7 +71,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.
-Faster is the frida solution: [utils/afl_frida/README.md](../utils/afl_frida/README.md)
+Faster is the frida solution: [frida_mode/README.md](../frida_mode/README.md)
Another, less precise and slower option is using ptrace with debugger interrupt
instrumentation: [utils/afl_untracer/README.md](../utils/afl_untracer/README.md).
From 659366ac6007eb679bc96c8e619afbb2f1d3ad50 Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Sun, 10 Oct 2021 16:09:39 +0200
Subject: [PATCH 053/305] Delete life_pro_tips.md
---
docs/life_pro_tips.md | 87 -------------------------------------------
1 file changed, 87 deletions(-)
delete mode 100644 docs/life_pro_tips.md
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.
-
From a8844eaceb1df92635a327fc4edba082b102a2ff Mon Sep 17 00:00:00 2001
From: Kuang-che Wu
Date: Mon, 11 Oct 2021 15:47:20 +0800
Subject: [PATCH 054/305] afl-showmap don't create empty "-" file
---
src/afl-showmap.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 75b0ff99..a04c1f5b 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -242,9 +242,11 @@ 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;
}
From 00aa689f40a3c8276af257cf0b54dc655cb0423e Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 11 Oct 2021 14:28:17 +0200
Subject: [PATCH 055/305] fix accidental bystander kills
---
docs/Changelog.md | 2 ++
qemu_mode/qemuafl | 2 +-
src/afl-forkserver.c | 6 +++---
unicorn_mode/unicornafl | 2 +-
4 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index dad5fee2..1c3830f9 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -18,6 +18,8 @@ sending a mail to .
- fix -n dumb mode (nobody should use this)
- 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
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
index 71ed0d20..a6758d1c 160000
--- a/qemu_mode/qemuafl
+++ b/qemu_mode/qemuafl
@@ -1 +1 @@
-Subproject commit 71ed0d206fd3d877420dceb4993a1011a4637ae6
+Subproject commit a6758d1cc3e4dde88fca3f0b3a903581b7c8b2e5
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/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index f1c85364..c0e03d2c 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit f1c853648a74b0157d233a2ef9f1693cfee78c11
+Subproject commit c0e03d2c6b55a22025324f121746b41b1e756fb8
From d0fc985e22328504dd0c4e21770ae2b31e63421a Mon Sep 17 00:00:00 2001
From: hexcoder-
Date: Tue, 12 Oct 2021 00:00:05 +0200
Subject: [PATCH 056/305] prototype compiles
---
instrumentation/split-compares-pass.so.cc | 71 ++++++++++++++++-------
1 file changed, 51 insertions(+), 20 deletions(-)
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index 13f45b69..a0dbba7a 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -28,7 +28,11 @@
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/IR/LegacyPassManager.h"
+
+#include "llvm/Passes/PassPlugin.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/IR/PassManager.h"
+//#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/IR/Module.h"
@@ -53,27 +57,17 @@ using namespace llvm;
namespace {
-class SplitComparesTransform : public ModulePass {
+//class SplitComparesTransform : public ModulePass {
+class SplitComparesTransform : public PassInfoMixin {
public:
static char ID;
- SplitComparesTransform() : ModulePass(ID), enableFPSplit(0) {
+ SplitComparesTransform() : enableFPSplit(0) {
initInstrumentList();
-
}
- bool runOnModule(Module &M) override;
-#if LLVM_VERSION_MAJOR >= 4
- StringRef getPassName() const override {
-
-#else
- const char *getPassName() const override {
-
-#endif
- return "AFL_SplitComparesTransform";
-
- }
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
private:
int enableFPSplit;
@@ -162,6 +156,37 @@ class SplitComparesTransform : public ModulePass {
} // namespace
+extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
+llvmGetPassPluginInfo() {
+ return {
+ LLVM_PLUGIN_API_VERSION, "SplitCompares", "v0.1",
+ /* lambda to insert our pass into the pass pipeline. */
+ [](PassBuilder &PB) {
+#if 1
+ using OptimizationLevel = typename PassBuilder::OptimizationLevel;
+ PB.registerOptimizerLastEPCallback(
+ [](ModulePassManager &MPM, OptimizationLevel OL) {
+ MPM.addPass(SplitComparesTransform());
+ }
+ );
+/* TODO LTO registration */
+#else
+ using PipelineElement = typename PassBuilder::PipelineElement;
+ PB.registerPipelineParsingCallback(
+ [](StringRef Name, ModulePassManager &MPM, ArrayRef) {
+ if ( Name == "splitcompares" ) {
+ MPM.addPass(SplitComparesTransform);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ );
+#endif
+ }
+ };
+}
+
char SplitComparesTransform::ID = 0;
/// This function splits FCMP instructions with xGE or xLE predicates into two
@@ -1316,7 +1341,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
}
-bool SplitComparesTransform::runOnModule(Module &M) {
+PreservedAnalyses SplitComparesTransform::run(Module &M, ModuleAnalysisManager &MAM) {
char *bitw_env = getenv("AFL_LLVM_LAF_SPLIT_COMPARES_BITW");
if (!bitw_env) bitw_env = getenv("LAF_SPLIT_COMPARES_BITW");
@@ -1339,6 +1364,8 @@ bool SplitComparesTransform::runOnModule(Module &M) {
}
+ auto PA = PreservedAnalyses::all();
+
if (enableFPSplit) {
count = splitFPCompares(M);
@@ -1371,7 +1398,7 @@ bool SplitComparesTransform::runOnModule(Module &M) {
auto op0 = CI->getOperand(0);
auto op1 = CI->getOperand(1);
- if (!op0 || !op1) { return false; }
+ if (!op0 || !op1) { return PA; }
auto iTy1 = dyn_cast(op0->getType());
if (iTy1 && isa(op1->getType())) {
@@ -1420,10 +1447,14 @@ bool SplitComparesTransform::runOnModule(Module &M) {
}
- return true;
+/* if (modified) {
+ PA.abandon();
+ }*/
+
+ return PA;
}
-
+#if 0
static void registerSplitComparesPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
@@ -1447,4 +1478,4 @@ static RegisterPass X("splitcompares",
"AFL++ split compares",
true /* Only looks at CFG */,
true /* Analysis Pass */);
-
+#endif
From d22b28d17b8cffabbb59c9e82373338a6343c648 Mon Sep 17 00:00:00 2001
From: Your Name
Date: Tue, 12 Oct 2021 08:13:29 +0100
Subject: [PATCH 057/305] Minimize inline assembly
---
frida_mode/GNUmakefile | 3 +-
frida_mode/include/instrument.h | 1 +
frida_mode/include/ranges.h | 2 +
frida_mode/src/instrument/instrument.c | 1 +
frida_mode/src/instrument/instrument_x64.c | 414 +++++++++++----------
frida_mode/src/ranges.c | 13 +-
6 files changed, 237 insertions(+), 197 deletions(-)
diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile
index 3e35e2f6..ab6efecf 100644
--- a/frida_mode/GNUmakefile
+++ b/frida_mode/GNUmakefile
@@ -31,7 +31,8 @@ AFL_CFLAGS:=-Wno-unused-parameter \
LDFLAGS+=-shared \
-lpthread \
-lresolv \
- -ldl
+ -ldl \
+ -lrt
ifdef DEBUG
CFLAGS+=-Werror \
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_x64.c b/frida_mode/src/instrument/instrument_x64.c
index 1c2cf113..dc040a20 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -1,4 +1,9 @@
+#include
#include
+#include
+#include
+#include
+#include
#include "frida-gumjs.h"
@@ -6,126 +11,10 @@
#include "debug.h"
#include "instrument.h"
+#include "ranges.h"
#if defined(__x86_64__)
-static GumAddress current_log_impl = GUM_ADDRESS(0);
-
- #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
- */
- 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 pop_fq;
- uint8_t ret;
-
-} afl_log_code_asm_t;
-
- #pragma pack(pop)
-
- #pragma pack(push, 8)
-typedef struct {
-
- afl_log_code_asm_t assembly;
- uint64_t current_pc;
-
-} afl_log_code_t;
-
- #pragma pack(pop)
-
-typedef union {
-
- afl_log_code_t data;
- uint8_t bytes[0];
-
-} afl_log_code;
-
-static const afl_log_code_asm_t template = {
-
- .push_fq = 0x9c,
- .push_rdx = 0x52,
- .mov_rdx_rip_off =
- {
-
- 0x48, 0x8b, 0x15,
- /* TBC */
-
- },
-
- .xor_rdx_rdi =
- {
-
- 0x48,
- 0x31,
- 0xfa,
-
- },
-
- .shr_rdi = {0x48, 0xd1, 0xef},
- .mov_rip_off_rdi = {0x48, 0x89, 0x3d},
-
- .lea_rdi_rip_off =
- {
-
- 0x48,
- 0x8d,
- 0x3d,
-
- },
-
- .add_rdx_rdi = {0x48, 0x01, 0xfA},
-
- .add_byte_ptr_rdx =
- {
-
- 0x80,
- 0x02,
- 0x01,
-
- },
-
- .adc_byte_ptr_rdx =
- {
-
- 0x80,
- 0x12,
- 0x00,
-
- },
-
- .pop_rdx = 0x5a,
- .pop_fq = 0x9d,
- .ret = 0xc3};
-
-static guint8 align_pad[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
-
gboolean instrument_is_coverage_optimize_supported(void) {
return true;
@@ -138,113 +27,258 @@ static gboolean instrument_coverage_in_range(gssize offset) {
}
-static void instrument_coverate_write_function(GumStalkerOutput *output) {
+ #pragma pack(push, 1)
+typedef struct {
- guint64 misalign = 0;
- GumX86Writer *cw = output->writer.x86;
- GumAddress code_addr = 0;
- afl_log_code code = {0};
- /*guint64 instrument_hash_zero = 0;*/
+ // cur_location = (block_address >> 4) ^ (block_address << 8);
+ // shared_mem[cur_location ^ prev_location]++;
+ // prev_location = cur_location >> 1;
- 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)) {
+ // => 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]
- gconstpointer after_log_impl = cw->code + 1;
- gum_x86_writer_put_jmp_near_label(cw, after_log_impl);
+ uint8_t lea_rsp_rsp_sub_rz[5];
+ uint8_t push_fq;
+ uint8_t push_rsi;
- misalign = (cw->pc & 0x7);
- if (misalign != 0) {
+ 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];
- gum_x86_writer_put_bytes(cw, align_pad, 8 - misalign);
+ uint8_t add_rsi_1[7];
+ uint8_t adc_rsi_0[7];
- }
+ uint8_t pop_rsi;
+ uint8_t pop_fq;
+ uint8_t lsa_rsp_rsp_add_rz[8];
- current_log_impl = cw->pc;
- // gum_x86_writer_put_breakpoint(cw);
- code_addr = cw->pc;
+} afl_log_code_asm_t;
- code.data.assembly = template;
- code.data.current_pc = instrument_get_offset_hash(0);
+ #pragma pack(pop)
- 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)) {
+typedef union {
- FATAL("Patch out of range (current_pc_value1): 0x%016lX",
- current_pc_value1);
+ afl_log_code_asm_t code;
+ uint8_t bytes[0];
- }
+} afl_log_code;
- gint *dst_pc_value = (gint *)&code.bytes[patch_offset1];
- *dst_pc_value = (gint)current_pc_value1;
+static const afl_log_code_asm_t template =
+ {
- 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);
+ .lea_rsp_rsp_sub_rz = {0x48, 0x8D, 0x64, 0x24, 0x80},
+ .push_fq = 0x9c,
+ .push_rsi = 0x56,
- if (!instrument_coverage_in_range(current_pc_value2)) {
+ .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},
- FATAL("Patch out of range (current_pc_value2): 0x%016lX",
- current_pc_value2);
+ .add_rsi_1 = {0x80, 0x86, 0x00, 0x00, 0x00, 0x00, 0x01},
+ .adc_rsi_0 = {0x80, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00},
- }
+ .pop_rsi = 0x5E,
+ .pop_fq = 0x9D,
+ .lsa_rsp_rsp_add_rz = {0x48, 0x8D, 0xA4, 0x24, 0x80, 0x00, 0x00, 0x00},
- dst_pc_value = (gint *)&code.bytes[patch_offset2];
- *dst_pc_value = (gint)current_pc_value2;
+}
- 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);
+;
- if (!instrument_coverage_in_range(afl_area_ptr_value)) {
+static gboolean instrument_coverage_find_low(const GumRangeDetails *details,
+ gpointer user_data) {
- FATAL("Patch out of range (afl_area_ptr_value): 0x%016lX",
- afl_area_ptr_value);
+ static GumAddress last_limit = (64ULL << 10);
+ gpointer * address = (gpointer *)user_data;
- }
+ if ((details->range->base_address - last_limit) > __afl_map_size) {
- gint *dst_afl_area_ptr_value = (gint *)&code.bytes[afl_area_ptr_offset];
- *dst_afl_area_ptr_value = (gint)afl_area_ptr_value;
-
- gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
-
- gum_x86_writer_put_label(cw, after_log_impl);
+ *address = GSIZE_TO_POINTER(last_limit);
+ return FALSE;
}
+ if (details->range->base_address > ((2ULL << 20) - __afl_map_size)) {
+
+ return FALSE;
+
+ }
+
+ last_limit = details->range->base_address + details->range->size;
+ return TRUE;
+
+}
+
+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) {
+
+ FATAL("Failed to map mmap __afl_area_ptr: %d", errno);
+
+ }
+
+}
+
+static void instrument_coverage_optimize_map_mmap(char * shm_file_path,
+ gpointer address) {
+
+ int shm_fd = -1;
+
+ if (munmap(__afl_area_ptr, __afl_map_size) != 0) {
+
+ FATAL("Failed to unmap previous __afl_area_ptr");
+
+ }
+
+ __afl_area_ptr = NULL;
+
+ shm_fd = shm_open(shm_file_path, O_RDWR, DEFAULT_PERMISSION);
+ if (shm_fd == -1) { FATAL("shm_open() failed\n"); }
+
+ __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_coverage_optimize_map_shm(guint64 shm_env_val,
+ gpointer address) {
+
+ if (shmdt(__afl_area_ptr) != 0) {
+
+ FATAL("Failed to detach previous __afl_area_ptr");
+
+ }
+
+ __afl_area_ptr = shmat(shm_env_val, address, 0);
+ if (__afl_area_ptr != address) {
+
+ FATAL("Failed to map shm __afl_area_ptr: %d", errno);
+
+ }
+
+}
+
+void instrument_coverage_optimize_init(void) {
+
+ gpointer low_address = NULL;
+
+ gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, instrument_coverage_find_low,
+ &low_address);
+
+ OKF("Low address: %p", low_address);
+
+ if (low_address == 0 ||
+ GPOINTER_TO_SIZE(low_address) > ((2UL << 20) - __afl_map_size)) {
+
+ FATAL("Invalid low_address: %p", low_address);
+
+ }
+
+ ranges_print_debug_maps();
+
+ char *shm_env = getenv(SHM_ENV_VAR);
+ OKF("SHM_ENV_VAR: %s", shm_env);
+
+ if (shm_env == NULL) {
+
+ WARNF("SHM_ENV_VAR not set, using anonymous map for debugging purposes");
+
+ instrument_coverage_optimize_map_mmap_anon(low_address);
+
+ } else {
+
+ guint64 shm_env_val = g_ascii_strtoull(shm_env, NULL, 10);
+
+ if (shm_env_val == 0) {
+
+ instrument_coverage_optimize_map_mmap(shm_env, low_address);
+
+ } else {
+
+ 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);
+ GumAddress code_addr = 0;
- 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);
+ // 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/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");
From 269dc29efe920abf3935d2052e11dfb94ec799e2 Mon Sep 17 00:00:00 2001
From: David Carlier
Date: Tue, 12 Oct 2021 12:48:54 +0100
Subject: [PATCH 058/305] frida mode fix on x86_64 archs
---
frida_mode/GNUmakefile | 8 ++++----
frida_mode/src/instrument/instrument_arm32.c | 4 ++++
frida_mode/src/instrument/instrument_arm64.c | 3 +++
frida_mode/src/instrument/instrument_x64.c | 7 +++++--
frida_mode/src/instrument/instrument_x86.c | 3 +++
5 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile
index ab6efecf..4d6d7147 100644
--- a/frida_mode/GNUmakefile
+++ b/frida_mode/GNUmakefile
@@ -30,9 +30,7 @@ AFL_CFLAGS:=-Wno-unused-parameter \
LDFLAGS+=-shared \
-lpthread \
- -lresolv \
- -ldl \
- -lrt
+ -lresolv
ifdef DEBUG
CFLAGS+=-Werror \
@@ -72,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
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 dc040a20..60f443e0 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -1,10 +1,13 @@
#include
#include
-#include
#include
-#include
#include
+#if defined(__linux__)
+#include
+#include
+#endif
+
#include "frida-gumjs.h"
#include "config.h"
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);
From 8e662898095ed6ba283a87119e383948b83b8d75 Mon Sep 17 00:00:00 2001
From: hexcoder-
Date: Tue, 12 Oct 2021 19:04:35 +0200
Subject: [PATCH 059/305] adapt compiler driver to laod new pass manager passes
---
instrumentation/split-compares-pass.so.cc | 20 +++++++++++++-------
src/afl-cc.c | 11 ++++++-----
2 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index a0dbba7a..2ae6f893 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -1,6 +1,7 @@
/*
* Copyright 2016 laf-intel
* extended for floating point by Heiko Eißfeldt
+ * adapted to new pass manager by Heiko Eißfeldt
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,7 +34,7 @@
#include "llvm/Passes/PassBuilder.h"
#include "llvm/IR/PassManager.h"
//#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+//#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/IR/Module.h"
@@ -61,7 +62,7 @@ namespace {
class SplitComparesTransform : public PassInfoMixin {
public:
- static char ID;
+// static char ID;
SplitComparesTransform() : enableFPSplit(0) {
initInstrumentList();
@@ -159,7 +160,7 @@ class SplitComparesTransform : public PassInfoMixin {
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo() {
return {
- LLVM_PLUGIN_API_VERSION, "SplitCompares", "v0.1",
+ LLVM_PLUGIN_API_VERSION, "splitcompares", "v0.1",
/* lambda to insert our pass into the pass pipeline. */
[](PassBuilder &PB) {
#if 1
@@ -187,7 +188,7 @@ llvmGetPassPluginInfo() {
};
}
-char SplitComparesTransform::ID = 0;
+//char SplitComparesTransform::ID = 0;
/// This function splits FCMP instructions with xGE or xLE predicates into two
/// FCMP instructions with predicate xGT or xLT and EQ
@@ -700,7 +701,7 @@ bool SplitComparesTransform::splitCompare(CmpInst *cmp_inst, Module &M,
ReplaceInstWithInst(cmp_inst->getParent()->getInstList(), ii, PN);
// We split the comparison into low and high. If this isn't our target
- // bitwidth we recursivly split the low and high parts again until we have
+ // bitwidth we recursively split the low and high parts again until we have
// target bitwidth.
if ((bitw / 2) > target_bitwidth) {
@@ -1352,7 +1353,7 @@ PreservedAnalyses SplitComparesTransform::run(Module &M, ModuleAnalysisManager &
if ((isatty(2) && getenv("AFL_QUIET") == NULL) ||
getenv("AFL_DEBUG") != NULL) {
- errs() << "Split-compare-pass by laf.intel@gmail.com, extended by "
+ errs() << "Split-compare-newpass by laf.intel@gmail.com, extended by "
"heiko@hexco.de (splitting icmp to "
<< target_bitwidth << " bit)\n";
@@ -1364,7 +1365,7 @@ PreservedAnalyses SplitComparesTransform::run(Module &M, ModuleAnalysisManager &
}
- auto PA = PreservedAnalyses::all();
+ auto PA = PreservedAnalyses::none();
if (enableFPSplit) {
@@ -1447,6 +1448,11 @@ PreservedAnalyses SplitComparesTransform::run(Module &M, ModuleAnalysisManager &
}
+ if ((isatty(2) && getenv("AFL_QUIET") == NULL) ||
+ getenv("AFL_DEBUG") != NULL) {
+ errs() << count << " comparisons found\n";
+ }
+
/* if (modified) {
PA.abandon();
}*/
diff --git a/src/afl-cc.c b/src/afl-cc.c
index e49addc4..f8621d72 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -500,11 +500,12 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} else {
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
+// cc_params[cc_par_cnt++] = "-Xclang";
+// cc_params[cc_par_cnt++] = "-load";
+// cc_params[cc_par_cnt++] = "-Xclang";
+ cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
cc_params[cc_par_cnt++] =
- alloc_printf("%s/split-compares-pass.so", obj_path);
+ alloc_printf("-fpass-plugin=%s/split-compares-pass.so", obj_path);
}
@@ -548,7 +549,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
#if LLVM_MAJOR >= 13
// fuck you llvm 13
- cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager";
+// cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager";
#endif
if (lto_mode && !have_c) {
From 544a65db5470359c18436eca123282d74fa47f2e Mon Sep 17 00:00:00 2001
From: hexcoder-
Date: Tue, 12 Oct 2021 23:02:15 +0200
Subject: [PATCH 060/305] converted afl-llvm-pass to new pass manager
---
instrumentation/afl-llvm-pass.so.cc | 59 +++++++++++++++++++++++------
src/afl-cc.c | 10 ++---
2 files changed, 51 insertions(+), 18 deletions(-)
diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc
index ecf28f31..c2b87ecb 100644
--- a/instrumentation/afl-llvm-pass.so.cc
+++ b/instrumentation/afl-llvm-pass.so.cc
@@ -45,12 +45,15 @@ typedef long double max_align_t;
#endif
#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/Passes/PassPlugin.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/IR/PassManager.h"
+//#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+//#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#if LLVM_VERSION_MAJOR > 3 || \
(LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
@@ -68,17 +71,18 @@ using namespace llvm;
namespace {
-class AFLCoverage : public ModulePass {
+//class AFLCoverage : public ModulePass {
+class AFLCoverage : public PassInfoMixin {
public:
- static char ID;
- AFLCoverage() : ModulePass(ID) {
+// static char ID;
+ AFLCoverage() {
initInstrumentList();
}
- bool runOnModule(Module &M) override;
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
protected:
uint32_t ngram_size = 0;
@@ -92,7 +96,38 @@ class AFLCoverage : public ModulePass {
} // namespace
-char AFLCoverage::ID = 0;
+extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
+llvmGetPassPluginInfo() {
+ return {
+ LLVM_PLUGIN_API_VERSION, "AFLCoverage", "v0.1",
+ /* lambda to insert our pass into the pass pipeline. */
+ [](PassBuilder &PB) {
+#if 1
+ using OptimizationLevel = typename PassBuilder::OptimizationLevel;
+ PB.registerOptimizerLastEPCallback(
+ [](ModulePassManager &MPM, OptimizationLevel OL) {
+ MPM.addPass(AFLCoverage());
+ }
+ );
+/* TODO LTO registration */
+#else
+ using PipelineElement = typename PassBuilder::PipelineElement;
+ PB.registerPipelineParsingCallback(
+ [](StringRef Name, ModulePassManager &MPM, ArrayRef) {
+ if ( Name == "AFLCoverage" ) {
+ MPM.addPass(AFLCoverage);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ );
+#endif
+ }
+ };
+}
+
+//char AFLCoverage::ID = 0;
/* needed up to 3.9.0 */
#if LLVM_VERSION_MAJOR == 3 && \
@@ -118,7 +153,7 @@ uint64_t PowerOf2Ceil(unsigned in) {
(LLVM_VERSION_MAJOR == 4 && LLVM_VERSION_PATCH >= 1)
#define AFL_HAVE_VECTOR_INTRINSICS 1
#endif
-bool AFLCoverage::runOnModule(Module &M) {
+PreservedAnalyses AFLCoverage::run(Module &M, ModuleAnalysisManager &MAM) {
LLVMContext &C = M.getContext();
@@ -133,6 +168,8 @@ bool AFLCoverage::runOnModule(Module &M) {
u32 rand_seed;
unsigned int cur_loc = 0;
+ auto PA = PreservedAnalyses::none();
+
/* Setup random() so we get Actually Random(TM) outputs from AFL_R() */
gettimeofday(&tv, &tz);
rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
@@ -969,10 +1006,10 @@ bool AFLCoverage::runOnModule(Module &M) {
}
- return true;
+ return PA;
}
-
+#if 0
static void registerAFLPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
@@ -985,4 +1022,4 @@ static RegisterStandardPasses RegisterAFLPass(
static RegisterStandardPasses RegisterAFLPass0(
PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLPass);
-
+#endif
diff --git a/src/afl-cc.c b/src/afl-cc.c
index f8621d72..bbe548d9 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -500,12 +500,10 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} else {
-// cc_params[cc_par_cnt++] = "-Xclang";
-// cc_params[cc_par_cnt++] = "-load";
-// cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
cc_params[cc_par_cnt++] =
alloc_printf("-fpass-plugin=%s/split-compares-pass.so", obj_path);
+// cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager";
}
@@ -629,10 +627,8 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} else {
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path);
+ cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
+ cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/afl-llvm-pass.so", obj_path);
}
From 6e08e809074763a9c4b35b65805e628689a2d562 Mon Sep 17 00:00:00 2001
From: hexcoder-
Date: Tue, 12 Oct 2021 23:24:28 +0200
Subject: [PATCH 061/305] converted compare-transform-pass to new pass manager
---
instrumentation/compare-transform-pass.so.cc | 69 ++++++++++++++------
src/afl-cc.c | 6 +-
2 files changed, 52 insertions(+), 23 deletions(-)
diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc
index 288e8282..e6695185 100644
--- a/instrumentation/compare-transform-pass.so.cc
+++ b/instrumentation/compare-transform-pass.so.cc
@@ -26,7 +26,10 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/Passes/PassPlugin.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/IR/PassManager.h"
+//#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@@ -52,28 +55,16 @@ using namespace llvm;
namespace {
-class CompareTransform : public ModulePass {
+class CompareTransform : public PassInfoMixin {
public:
- static char ID;
- CompareTransform() : ModulePass(ID) {
+ CompareTransform() {
initInstrumentList();
}
- bool runOnModule(Module &M) override;
-
-#if LLVM_VERSION_MAJOR < 4
- const char *getPassName() const override {
-
-#else
- StringRef getPassName() const override {
-
-#endif
- return "transforms compare functions";
-
- }
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
private:
bool transformCmps(Module &M, const bool processStrcmp,
@@ -85,7 +76,37 @@ class CompareTransform : public ModulePass {
} // namespace
-char CompareTransform::ID = 0;
+extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
+llvmGetPassPluginInfo() {
+ return {
+ LLVM_PLUGIN_API_VERSION, "comparetransform", "v0.1",
+ /* lambda to insert our pass into the pass pipeline. */
+ [](PassBuilder &PB) {
+#if 1
+ using OptimizationLevel = typename PassBuilder::OptimizationLevel;
+ PB.registerOptimizerLastEPCallback(
+ [](ModulePassManager &MPM, OptimizationLevel OL) {
+ MPM.addPass(CompareTransform());
+ }
+ );
+/* TODO LTO registration */
+#else
+ using PipelineElement = typename PassBuilder::PipelineElement;
+ PB.registerPipelineParsingCallback(
+ [](StringRef Name, ModulePassManager &MPM, ArrayRef) {
+ if ( Name == "comparetransform" ) {
+ MPM.addPass(CompareTransform);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ );
+#endif
+ }
+ };
+}
+
bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
const bool processMemcmp,
@@ -592,7 +613,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
}
-bool CompareTransform::runOnModule(Module &M) {
+PreservedAnalyses CompareTransform::run(Module &M, ModuleAnalysisManager &MAM) {
if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
printf(
@@ -601,13 +622,22 @@ bool CompareTransform::runOnModule(Module &M) {
else
be_quiet = 1;
+ auto PA = PreservedAnalyses::none();
+
transformCmps(M, true, true, true, true, true);
verifyModule(M);
- return true;
+/* if (modified) {
+ PA.abandon();
+ }*/
+
+ return PA;
+
+// return true;
}
+#if 0
static void registerCompTransPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
@@ -626,4 +656,5 @@ static RegisterStandardPasses RegisterCompTransPass0(
static RegisterStandardPasses RegisterCompTransPassLTO(
PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerCompTransPass);
#endif
+#endif
diff --git a/src/afl-cc.c b/src/afl-cc.c
index bbe548d9..a51632a2 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -480,11 +480,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} else {
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
+ cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
cc_params[cc_par_cnt++] =
- alloc_printf("%s/compare-transform-pass.so", obj_path);
+ alloc_printf("-fpass-plugin=%s/compare-transform-pass.so", obj_path);
}
From 379c5806580dd58824df0f4fb7d215841d1bd459 Mon Sep 17 00:00:00 2001
From: hexcoder-
Date: Tue, 12 Oct 2021 23:40:05 +0200
Subject: [PATCH 062/305] converted split-switches-pass to new pass manager
---
instrumentation/split-compares-pass.so.cc | 2 +-
instrumentation/split-switches-pass.so.cc | 71 ++++++++++++++++-------
src/afl-cc.c | 12 ++--
3 files changed, 54 insertions(+), 31 deletions(-)
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index 2ae6f893..8d4935f5 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -176,7 +176,7 @@ llvmGetPassPluginInfo() {
PB.registerPipelineParsingCallback(
[](StringRef Name, ModulePassManager &MPM, ArrayRef) {
if ( Name == "splitcompares" ) {
- MPM.addPass(SplitComparesTransform);
+ MPM.addPass(SplitComparesTransform());
return true;
} else {
return false;
diff --git a/instrumentation/split-switches-pass.so.cc b/instrumentation/split-switches-pass.so.cc
index 82f198aa..ba143dca 100644
--- a/instrumentation/split-switches-pass.so.cc
+++ b/instrumentation/split-switches-pass.so.cc
@@ -27,11 +27,14 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/Passes/PassPlugin.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/IR/PassManager.h"
+//#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+//#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Pass.h"
#include "llvm/Analysis/ValueTracking.h"
@@ -54,28 +57,16 @@ using namespace llvm;
namespace {
-class SplitSwitchesTransform : public ModulePass {
+class SplitSwitchesTransform : public PassInfoMixin {
public:
- static char ID;
- SplitSwitchesTransform() : ModulePass(ID) {
+ SplitSwitchesTransform() {
initInstrumentList();
}
- bool runOnModule(Module &M) override;
-
-#if LLVM_VERSION_MAJOR >= 4
- StringRef getPassName() const override {
-
-#else
- const char *getPassName() const override {
-
-#endif
- return "splits switch constructs";
-
- }
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
struct CaseExpr {
@@ -103,7 +94,36 @@ class SplitSwitchesTransform : public ModulePass {
} // namespace
-char SplitSwitchesTransform::ID = 0;
+extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
+llvmGetPassPluginInfo() {
+ return {
+ LLVM_PLUGIN_API_VERSION, "splitswitches", "v0.1",
+ /* lambda to insert our pass into the pass pipeline. */
+ [](PassBuilder &PB) {
+#if 1
+ using OptimizationLevel = typename PassBuilder::OptimizationLevel;
+ PB.registerOptimizerLastEPCallback(
+ [](ModulePassManager &MPM, OptimizationLevel OL) {
+ MPM.addPass(SplitSwitchesTransform());
+ }
+ );
+/* TODO LTO registration */
+#else
+ using PipelineElement = typename PassBuilder::PipelineElement;
+ PB.registerPipelineParsingCallback(
+ [](StringRef Name, ModulePassManager &MPM, ArrayRef) {
+ if ( Name == "splitswitches" ) {
+ MPM.addPass(SplitSwitchesTransform());
+ return true;
+ } else {
+ return false;
+ }
+ }
+ );
+#endif
+ }
+ };
+}
/* switchConvert - Transform simple list of Cases into list of CaseRange's */
BasicBlock *SplitSwitchesTransform::switchConvert(
@@ -415,19 +435,26 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
}
-bool SplitSwitchesTransform::runOnModule(Module &M) {
+PreservedAnalyses SplitSwitchesTransform::run(Module &M, ModuleAnalysisManager &MAM) {
if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
printf("Running split-switches-pass by laf.intel@gmail.com\n");
else
be_quiet = 1;
+
+ auto PA = PreservedAnalyses::none();
+
splitSwitches(M);
verifyModule(M);
- return true;
+/* if (modified) {
+ PA.abandon();
+ }*/
+
+ return PA;
}
-
+#if 0
static void registerSplitSwitchesTransPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
@@ -447,4 +474,4 @@ static RegisterStandardPasses RegisterSplitSwitchesTransPassLTO(
PassManagerBuilder::EP_FullLinkTimeOptimizationLast,
registerSplitSwitchesTransPass);
#endif
-
+#endif
diff --git a/src/afl-cc.c b/src/afl-cc.c
index a51632a2..e8584d50 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -460,11 +460,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} else {
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
+ cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
cc_params[cc_par_cnt++] =
- alloc_printf("%s/split-switches-pass.so", obj_path);
+ alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path);
}
@@ -531,11 +529,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
alloc_printf("%s/cmplog-switches-pass.so", obj_path);
// reuse split switches from laf
- cc_params[cc_par_cnt++] = "-Xclang";
- cc_params[cc_par_cnt++] = "-load";
- cc_params[cc_par_cnt++] = "-Xclang";
+ cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
cc_params[cc_par_cnt++] =
- alloc_printf("%s/split-switches-pass.so", obj_path);
+ alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path);
}
From e0c052cad70b5cf2c86e1bda1d279a2ac1440077 Mon Sep 17 00:00:00 2001
From: Dominik Maier
Date: Tue, 12 Oct 2021 23:46:47 +0200
Subject: [PATCH 063/305] unicornafl bindings improved
---
docs/Changelog.md | 1 +
unicorn_mode/UNICORNAFL_VERSION | 2 +-
.../samples/speedtest/rust/src/main.rs | 23 ++++++++-----------
unicorn_mode/unicornafl | 2 +-
4 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 1c3830f9..ea58a386 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -34,6 +34,7 @@ sending a mail to .
- 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/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index cbca63e5..e76da957 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-f1c853648a74b0157d233a2ef9f1693cfee78c11
+d06e3d5113dd96799a765a6514f7f5c45f071ca3
diff --git a/unicorn_mode/samples/speedtest/rust/src/main.rs b/unicorn_mode/samples/speedtest/rust/src/main.rs
index 77356a67..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, io::Error> {
fn parse_locs(loc_name: &str) -> Result, 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));
@@ -133,7 +132,7 @@ 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();
@@ -154,7 +153,7 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
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();
@@ -177,7 +176,7 @@ 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| {
+ let hook_magicfn = move |uc: &mut Unicorn<'_, _>, addr, size| {
uc.reg_write(RIP, addr + size as u64).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
index c0e03d2c..d06e3d51 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit c0e03d2c6b55a22025324f121746b41b1e756fb8
+Subproject commit d06e3d5113dd96799a765a6514f7f5c45f071ca3
From 319db6759ba9dfaac454d5669214ae3aa65831fe Mon Sep 17 00:00:00 2001
From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Date: Wed, 13 Oct 2021 18:41:45 +0100
Subject: [PATCH 064/305] Fix missing MAP_FIXED_NOREPLACE (#1116)
Co-authored-by: Your Name
---
frida_mode/src/instrument/instrument_x64.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index 60f443e0..ebdf1440 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -18,6 +18,14 @@
#if defined(__x86_64__)
+#ifndef MAP_FIXED_NOREPLACE
+ #ifdef MAP_EXCL
+ #define MAP_FIXED_NOREPLACE MAP_EXCL | MAP_FIXED
+ #else
+ #define MAP_FIXED_NOREPLACE MAP_FIXED
+ #endif
+#endif
+
gboolean instrument_is_coverage_optimize_supported(void) {
return true;
From 17c59de1c2ea73f358ff6d0df4c572c62ee650aa Mon Sep 17 00:00:00 2001
From: Dominik Maier
Date: Wed, 13 Oct 2021 19:53:32 +0200
Subject: [PATCH 065/305] updated uc
---
unicorn_mode/UNICORNAFL_VERSION | 2 +-
unicorn_mode/unicornafl | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index e76da957..cc8d5b34 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-d06e3d5113dd96799a765a6514f7f5c45f071ca3
+d4915053d477dd827b3fe4b494173d3fbf9f456e
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index d06e3d51..d4915053 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit d06e3d5113dd96799a765a6514f7f5c45f071ca3
+Subproject commit d4915053d477dd827b3fe4b494173d3fbf9f456e
From 3deca3b09b46130c9e23320c0b98f60543f9b5ba Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 15 Oct 2021 11:25:02 +0200
Subject: [PATCH 066/305] fix lto cmplog stability issue
---
.../grammar_mutator/grammar_mutator | 2 +-
docs/Changelog.md | 1 +
qemu_mode/qemuafl | 2 +-
src/afl-fuzz-run.c | 30 +++++++++++++++++--
unicorn_mode/unicornafl | 2 +-
5 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/custom_mutators/grammar_mutator/grammar_mutator b/custom_mutators/grammar_mutator/grammar_mutator
index eedf07dd..b79d51a8 160000
--- a/custom_mutators/grammar_mutator/grammar_mutator
+++ b/custom_mutators/grammar_mutator/grammar_mutator
@@ -1 +1 @@
-Subproject commit eedf07ddb0fb1f437f5e76b77cfd4064cf6a5d63
+Subproject commit b79d51a8daccbd7a693f9b6765c81ead14f28e26
diff --git a/docs/Changelog.md b/docs/Changelog.md
index ea58a386..df4d343a 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -16,6 +16,7 @@ sending a mail to .
- 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
- 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
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
index a6758d1c..71ed0d20 160000
--- a/qemu_mode/qemuafl
+++ b/qemu_mode/qemuafl
@@ -1 +1 @@
-Subproject commit a6758d1cc3e4dde88fca3f0b3a903581b7c8b2e5
+Subproject commit 71ed0d206fd3d877420dceb4993a1011a4637ae6
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/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index d4915053..f1c85364 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit d4915053d477dd827b3fe4b494173d3fbf9f456e
+Subproject commit f1c853648a74b0157d233a2ef9f1693cfee78c11
From 8b1910e2689876c8ed4d0b9529296dc144692d35 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 15 Oct 2021 12:55:40 +0200
Subject: [PATCH 067/305] fix submodules
---
unicorn_mode/unicornafl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index f1c85364..d4915053 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit f1c853648a74b0157d233a2ef9f1693cfee78c11
+Subproject commit d4915053d477dd827b3fe4b494173d3fbf9f456e
From c49b30879474042f16dcf8de200c603a47965ea4 Mon Sep 17 00:00:00 2001
From: hexcoder-
Date: Sat, 16 Oct 2021 12:56:31 +0200
Subject: [PATCH 068/305] switch PreservedAnalyses from none to all
---
instrumentation/afl-llvm-pass.so.cc | 4 ++--
instrumentation/compare-transform-pass.so.cc | 4 ++--
instrumentation/split-compares-pass.so.cc | 2 +-
instrumentation/split-switches-pass.so.cc | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc
index c2b87ecb..92999443 100644
--- a/instrumentation/afl-llvm-pass.so.cc
+++ b/instrumentation/afl-llvm-pass.so.cc
@@ -115,7 +115,7 @@ llvmGetPassPluginInfo() {
PB.registerPipelineParsingCallback(
[](StringRef Name, ModulePassManager &MPM, ArrayRef) {
if ( Name == "AFLCoverage" ) {
- MPM.addPass(AFLCoverage);
+ MPM.addPass(AFLCoverage());
return true;
} else {
return false;
@@ -168,7 +168,7 @@ PreservedAnalyses AFLCoverage::run(Module &M, ModuleAnalysisManager &MAM) {
u32 rand_seed;
unsigned int cur_loc = 0;
- auto PA = PreservedAnalyses::none();
+ auto PA = PreservedAnalyses::all();
/* Setup random() so we get Actually Random(TM) outputs from AFL_R() */
gettimeofday(&tv, &tz);
diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc
index e6695185..ce8efaa7 100644
--- a/instrumentation/compare-transform-pass.so.cc
+++ b/instrumentation/compare-transform-pass.so.cc
@@ -95,7 +95,7 @@ llvmGetPassPluginInfo() {
PB.registerPipelineParsingCallback(
[](StringRef Name, ModulePassManager &MPM, ArrayRef) {
if ( Name == "comparetransform" ) {
- MPM.addPass(CompareTransform);
+ MPM.addPass(CompareTransform());
return true;
} else {
return false;
@@ -622,7 +622,7 @@ PreservedAnalyses CompareTransform::run(Module &M, ModuleAnalysisManager &MAM) {
else
be_quiet = 1;
- auto PA = PreservedAnalyses::none();
+ auto PA = PreservedAnalyses::all();
transformCmps(M, true, true, true, true, true);
verifyModule(M);
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index 8d4935f5..75a9c35c 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -1365,7 +1365,7 @@ PreservedAnalyses SplitComparesTransform::run(Module &M, ModuleAnalysisManager &
}
- auto PA = PreservedAnalyses::none();
+ auto PA = PreservedAnalyses::all();
if (enableFPSplit) {
diff --git a/instrumentation/split-switches-pass.so.cc b/instrumentation/split-switches-pass.so.cc
index ba143dca..b8cd61c3 100644
--- a/instrumentation/split-switches-pass.so.cc
+++ b/instrumentation/split-switches-pass.so.cc
@@ -442,7 +442,7 @@ PreservedAnalyses SplitSwitchesTransform::run(Module &M, ModuleAnalysisManager &
else
be_quiet = 1;
- auto PA = PreservedAnalyses::none();
+ auto PA = PreservedAnalyses::all();
splitSwitches(M);
verifyModule(M);
From 1f2fa22dad4440bf053e24811b5ece89ca276afc Mon Sep 17 00:00:00 2001
From: hexcoder-
Date: Sat, 16 Oct 2021 14:37:54 +0200
Subject: [PATCH 069/305] make new pass manager interface compiler version
dependent (>=7)
---
instrumentation/afl-llvm-pass.so.cc | 43 ++++++++++++++----
instrumentation/compare-transform-pass.so.cc | 38 +++++++++++++---
instrumentation/split-compares-pass.so.cc | 48 ++++++++++++++++----
instrumentation/split-switches-pass.so.cc | 46 +++++++++++++++++--
src/afl-cc.c | 43 ++++++++++++++++--
5 files changed, 190 insertions(+), 28 deletions(-)
diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc
index 92999443..75f8621b 100644
--- a/instrumentation/afl-llvm-pass.so.cc
+++ b/instrumentation/afl-llvm-pass.so.cc
@@ -45,15 +45,18 @@ typedef long double max_align_t;
#endif
#include "llvm/IR/IRBuilder.h"
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/IR/PassManager.h"
-//#include "llvm/IR/LegacyPassManager.h"
+#else
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#endif
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
-//#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#if LLVM_VERSION_MAJOR > 3 || \
(LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
@@ -71,18 +74,26 @@ using namespace llvm;
namespace {
-//class AFLCoverage : public ModulePass {
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
class AFLCoverage : public PassInfoMixin {
-
- public:
-// static char ID;
AFLCoverage() {
+ public:
+#else
+class AFLCoverage : public ModulePass {
+ public:
+ static char ID;
+ AFLCoverage() : ModulePass(ID) {
+#endif
initInstrumentList();
}
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+#else
+ bool runOnModule(Module &M) override;
+#endif
protected:
uint32_t ngram_size = 0;
@@ -96,6 +107,7 @@ class AFLCoverage : public PassInfoMixin {
} // namespace
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo() {
return {
@@ -126,8 +138,10 @@ llvmGetPassPluginInfo() {
}
};
}
+#else
-//char AFLCoverage::ID = 0;
+char AFLCoverage::ID = 0;
+#endif
/* needed up to 3.9.0 */
#if LLVM_VERSION_MAJOR == 3 && \
@@ -153,7 +167,13 @@ uint64_t PowerOf2Ceil(unsigned in) {
(LLVM_VERSION_MAJOR == 4 && LLVM_VERSION_PATCH >= 1)
#define AFL_HAVE_VECTOR_INTRINSICS 1
#endif
+
+
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
PreservedAnalyses AFLCoverage::run(Module &M, ModuleAnalysisManager &MAM) {
+#else
+bool AFLCoverage::runOnModule(Module &M) {
+#endif
LLVMContext &C = M.getContext();
@@ -168,7 +188,9 @@ PreservedAnalyses AFLCoverage::run(Module &M, ModuleAnalysisManager &MAM) {
u32 rand_seed;
unsigned int cur_loc = 0;
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
auto PA = PreservedAnalyses::all();
+#endif
/* Setup random() so we get Actually Random(TM) outputs from AFL_R() */
gettimeofday(&tv, &tz);
@@ -1006,10 +1028,15 @@ PreservedAnalyses AFLCoverage::run(Module &M, ModuleAnalysisManager &MAM) {
}
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
return PA;
+#else
+ return true;
+#endif
}
-#if 0
+
+#if LLVM_VERSION_MAJOR < 7 /* use old pass manager */
static void registerAFLPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc
index ce8efaa7..3c975fe8 100644
--- a/instrumentation/compare-transform-pass.so.cc
+++ b/instrumentation/compare-transform-pass.so.cc
@@ -26,14 +26,17 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/IRBuilder.h"
+#if LLVM_MAJOR >= 7 /* use new pass manager */
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/IR/PassManager.h"
-//#include "llvm/IR/LegacyPassManager.h"
+#else
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#endif
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Pass.h"
#include "llvm/Analysis/ValueTracking.h"
@@ -55,16 +58,28 @@ using namespace llvm;
namespace {
+#if LLVM_MAJOR >= 7 /* use new pass manager */
class CompareTransform : public PassInfoMixin {
public:
CompareTransform() {
+#else
+class CompareTransform : public ModulePass {
+
+ public:
+ static char ID;
+ CompareTransform() : ModulePass(ID) {
+#endif
initInstrumentList();
}
+#if LLVM_MAJOR >= 7 /* use new pass manager */
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+#else
+ bool runOnModule(Module &M) override;
+#endif
private:
bool transformCmps(Module &M, const bool processStrcmp,
@@ -76,6 +91,7 @@ class CompareTransform : public PassInfoMixin {
} // namespace
+#if LLVM_MAJOR >= 7 /* use new pass manager */
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo() {
return {
@@ -106,7 +122,9 @@ llvmGetPassPluginInfo() {
}
};
}
-
+#else
+char CompareTransform::ID = 0;
+#endif
bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
const bool processMemcmp,
@@ -613,7 +631,11 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
}
+#if LLVM_MAJOR >= 7 /* use new pass manager */
PreservedAnalyses CompareTransform::run(Module &M, ModuleAnalysisManager &MAM) {
+#else
+bool CompareTransform::runOnModule(Module &M) {
+#endif
if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
printf(
@@ -622,22 +644,26 @@ PreservedAnalyses CompareTransform::run(Module &M, ModuleAnalysisManager &MAM) {
else
be_quiet = 1;
+#if LLVM_MAJOR >= 7 /* use new pass manager */
auto PA = PreservedAnalyses::all();
+#endif
transformCmps(M, true, true, true, true, true);
verifyModule(M);
+#if LLVM_MAJOR >= 7 /* use new pass manager */
/* if (modified) {
PA.abandon();
}*/
return PA;
-
-// return true;
+#else
+ return true;
+#endif
}
-#if 0
+#if LLVM_MAJOR < 7 /* use old pass manager */
static void registerCompTransPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index 75a9c35c..ed7e111e 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -30,11 +30,14 @@
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
+#if LLVM_MAJOR >= 7
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/IR/PassManager.h"
-//#include "llvm/IR/LegacyPassManager.h"
-//#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#else
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#endif
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/IR/Module.h"
@@ -58,17 +61,26 @@ using namespace llvm;
namespace {
-//class SplitComparesTransform : public ModulePass {
+#if LLVM_MAJOR >= 7
class SplitComparesTransform : public PassInfoMixin {
-
public:
// static char ID;
SplitComparesTransform() : enableFPSplit(0) {
+#else
+class SplitComparesTransform : public ModulePass {
+ public:
+ static char ID;
+ SplitComparesTransform() : ModulePass(ID), enableFPSplit(0) {
+#endif
initInstrumentList();
}
+#if LLVM_MAJOR >= 7
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+#else
+ bool runOnModule(Module &M) override;
+#endif
private:
int enableFPSplit;
@@ -157,6 +169,7 @@ class SplitComparesTransform : public PassInfoMixin {
} // namespace
+#if LLVM_MAJOR >= 7
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo() {
return {
@@ -187,8 +200,9 @@ llvmGetPassPluginInfo() {
}
};
}
-
-//char SplitComparesTransform::ID = 0;
+#else
+char SplitComparesTransform::ID = 0;
+#endif
/// This function splits FCMP instructions with xGE or xLE predicates into two
/// FCMP instructions with predicate xGT or xLT and EQ
@@ -1342,7 +1356,11 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
}
+#if LLVM_MAJOR >= 7
PreservedAnalyses SplitComparesTransform::run(Module &M, ModuleAnalysisManager &MAM) {
+#else
+bool SplitComparesTransform::runOnModule(Module &M) {
+#endif
char *bitw_env = getenv("AFL_LLVM_LAF_SPLIT_COMPARES_BITW");
if (!bitw_env) bitw_env = getenv("LAF_SPLIT_COMPARES_BITW");
@@ -1365,7 +1383,9 @@ PreservedAnalyses SplitComparesTransform::run(Module &M, ModuleAnalysisManager &
}
+#if LLVM_MAJOR >= 7
auto PA = PreservedAnalyses::all();
+#endif
if (enableFPSplit) {
@@ -1399,7 +1419,13 @@ PreservedAnalyses SplitComparesTransform::run(Module &M, ModuleAnalysisManager &
auto op0 = CI->getOperand(0);
auto op1 = CI->getOperand(1);
- if (!op0 || !op1) { return PA; }
+ if (!op0 || !op1) {
+#if LLVM_MAJOR >= 7
+ return PA;
+#else
+ return false;
+#endif
+ }
auto iTy1 = dyn_cast(op0->getType());
if (iTy1 && isa(op1->getType())) {
@@ -1453,14 +1479,20 @@ PreservedAnalyses SplitComparesTransform::run(Module &M, ModuleAnalysisManager &
errs() << count << " comparisons found\n";
}
+#if LLVM_MAJOR >= 7
/* if (modified) {
PA.abandon();
}*/
return PA;
+#else
+ return true;
+#endif
}
-#if 0
+
+#if LLVM_MAJOR < 7 /* use old pass manager */
+
static void registerSplitComparesPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
diff --git a/instrumentation/split-switches-pass.so.cc b/instrumentation/split-switches-pass.so.cc
index b8cd61c3..42441de1 100644
--- a/instrumentation/split-switches-pass.so.cc
+++ b/instrumentation/split-switches-pass.so.cc
@@ -27,14 +27,17 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/IRBuilder.h"
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/IR/PassManager.h"
-//#include "llvm/IR/LegacyPassManager.h"
+#else
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#endif
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-//#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Pass.h"
#include "llvm/Analysis/ValueTracking.h"
@@ -57,16 +60,38 @@ using namespace llvm;
namespace {
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
class SplitSwitchesTransform : public PassInfoMixin {
public:
SplitSwitchesTransform() {
+#else
+class SplitSwitchesTransform : public ModulePass {
+ public:
+ static char ID;
+ SplitSwitchesTransform() : ModulePass(ID) {
+#endif
initInstrumentList();
}
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+#else
+ bool runOnModule(Module &M) override;
+
+#if LLVM_VERSION_MAJOR >= 4
+ StringRef getPassName() const override {
+
+#else
+ const char *getPassName() const override {
+
+#endif
+ return "splits switch constructs";
+
+ }
+#endif
struct CaseExpr {
@@ -94,6 +119,7 @@ class SplitSwitchesTransform : public PassInfoMixin {
} // namespace
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo() {
return {
@@ -124,6 +150,9 @@ llvmGetPassPluginInfo() {
}
};
}
+#else
+char SplitSwitchesTransform::ID = 0;
+#endif
/* switchConvert - Transform simple list of Cases into list of CaseRange's */
BasicBlock *SplitSwitchesTransform::switchConvert(
@@ -435,26 +464,37 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
}
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
PreservedAnalyses SplitSwitchesTransform::run(Module &M, ModuleAnalysisManager &MAM) {
+#else
+bool SplitSwitchesTransform::runOnModule(Module &M) {
+#endif
if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
printf("Running split-switches-pass by laf.intel@gmail.com\n");
else
be_quiet = 1;
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
auto PA = PreservedAnalyses::all();
+#endif
splitSwitches(M);
verifyModule(M);
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
/* if (modified) {
PA.abandon();
}*/
return PA;
+#else
+ return true;
+#endif
}
-#if 0
+
+#if LLVM_VERSION_MAJOR < 7 /* use old pass manager */
static void registerSplitSwitchesTransPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
diff --git a/src/afl-cc.c b/src/afl-cc.c
index e8584d50..7549e17b 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -460,10 +460,17 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} else {
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
cc_params[cc_par_cnt++] =
alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path);
-
+#else
+ cc_params[cc_par_cnt++] = "-Xclang";
+ cc_params[cc_par_cnt++] = "-load";
+ cc_params[cc_par_cnt++] = "-Xclang";
+ cc_params[cc_par_cnt++] =
+ alloc_printf("%s/split-switches-pass.so", obj_path);
+#endif
}
}
@@ -478,9 +485,17 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} else {
+#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
cc_params[cc_par_cnt++] =
alloc_printf("-fpass-plugin=%s/compare-transform-pass.so", obj_path);
+#else
+ cc_params[cc_par_cnt++] = "-Xclang";
+ cc_params[cc_par_cnt++] = "-load";
+ cc_params[cc_par_cnt++] = "-Xclang";
+ cc_params[cc_par_cnt++] =
+ alloc_printf("%s/compare-transform-pass.so", obj_path);
+#endif
}
@@ -496,10 +511,18 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} else {
+#if LLVM_MAJOR >= 7
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
cc_params[cc_par_cnt++] =
alloc_printf("-fpass-plugin=%s/split-compares-pass.so", obj_path);
// cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager";
+#else
+ cc_params[cc_par_cnt++] = "-Xclang";
+ cc_params[cc_par_cnt++] = "-load";
+ cc_params[cc_par_cnt++] = "-Xclang";
+ cc_params[cc_par_cnt++] =
+ alloc_printf("%s/split-compares-pass.so", obj_path);
+#endif
}
@@ -529,9 +552,17 @@ static void edit_params(u32 argc, char **argv, char **envp) {
alloc_printf("%s/cmplog-switches-pass.so", obj_path);
// reuse split switches from laf
+#if LLVM_MAJOR >= 7
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
cc_params[cc_par_cnt++] =
alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path);
+#else
+ cc_params[cc_par_cnt++] = "-Xclang";
+ cc_params[cc_par_cnt++] = "-load";
+ cc_params[cc_par_cnt++] = "-Xclang";
+ cc_params[cc_par_cnt++] =
+ alloc_printf("%s/split-switches-pass.so", obj_path);
+#endif
}
@@ -541,7 +572,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
#if LLVM_MAJOR >= 13
// fuck you llvm 13
-// cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager";
+ cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager";
#endif
if (lto_mode && !have_c) {
@@ -621,9 +652,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} else {
+#if LLVM_MAJOR >= 7
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/afl-llvm-pass.so", obj_path);
-
+#else
+ cc_params[cc_par_cnt++] = "-Xclang";
+ cc_params[cc_par_cnt++] = "-load";
+ cc_params[cc_par_cnt++] = "-Xclang";
+ cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path);
+#endif
}
}
From 7d0e0cde0ad8c5b89eaf72a9751e3fb7513cc0e9 Mon Sep 17 00:00:00 2001
From: hexcoder-
Date: Sat, 16 Oct 2021 14:51:51 +0200
Subject: [PATCH 070/305] fix declaration for new pass manager
---
instrumentation/afl-llvm-pass.so.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc
index 75f8621b..67abc36a 100644
--- a/instrumentation/afl-llvm-pass.so.cc
+++ b/instrumentation/afl-llvm-pass.so.cc
@@ -76,8 +76,8 @@ namespace {
#if LLVM_VERSION_MAJOR >= 7 /* use new pass manager */
class AFLCoverage : public PassInfoMixin {
- AFLCoverage() {
public:
+ AFLCoverage() {
#else
class AFLCoverage : public ModulePass {
public:
From c96fdfac01829a5f6a9e98968817d6b6588389b8 Mon Sep 17 00:00:00 2001
From: David Carlier
Date: Sat, 16 Oct 2021 12:44:25 +0100
Subject: [PATCH 071/305] frida mode android build fix proposal.
also protecting seccomp the other way around in case it is ported
in another platform supported by frida.
---
frida_mode/GNUmakefile | 16 ++++++++++++++++
frida_mode/README.md | 14 ++++++++++++++
frida_mode/src/instrument/instrument_x64.c | 12 ++++++++++++
frida_mode/src/seccomp/seccomp_atomic.c | 2 +-
frida_mode/src/seccomp/seccomp_callback.c | 2 +-
frida_mode/src/seccomp/seccomp_child.c | 2 +-
frida_mode/src/seccomp/seccomp_event.c | 2 +-
frida_mode/src/seccomp/seccomp_filter.c | 2 +-
frida_mode/src/seccomp/seccomp_print.c | 2 +-
frida_mode/src/seccomp/seccomp_socket.c | 2 +-
frida_mode/src/seccomp/seccomp_syscall.c | 2 +-
11 files changed, 50 insertions(+), 8 deletions(-)
diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile
index 4d6d7147..ed35c9f6 100644
--- a/frida_mode/GNUmakefile
+++ b/frida_mode/GNUmakefile
@@ -80,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/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index ebdf1440..a7eb650a 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -4,8 +4,12 @@
#include
#if defined(__linux__)
+#if !defined(__ANDROID__)
#include
#include
+#else
+#include
+#endif
#endif
#include "frida-gumjs.h"
@@ -156,8 +160,16 @@ static void instrument_coverage_optimize_map_mmap(char * shm_file_path,
__afl_area_ptr = NULL;
+#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);
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
#include
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
#include
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
#include
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
#include
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
#include
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
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
#include
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
#include
From 34f1074ba308e850feb08c51aad781f7d307a260 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sat, 16 Oct 2021 18:44:29 +0200
Subject: [PATCH 072/305] changelog
---
docs/Changelog.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index df4d343a..d8dac557 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -17,6 +17,7 @@ sending a mail to .
coverage being detected. thanks to Collin May for reporting!
- fix -n dumb mode (nobody should use this)
- fix stability issue with LTO and cmplog
+ - 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
From 8bc2b52f6579ab44f536d1ccb818acf37b047ec7 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 17 Oct 2021 13:03:01 +0200
Subject: [PATCH 073/305] format
---
src/afl-showmap.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index a04c1f5b..5df07bf2 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -243,10 +243,13 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
(fsrv->last_run_timed_out || (!caa && child_crashed != cco))) {
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;
}
From ed10f3783bd8fab33ab5750f56bf87ed008f28ed Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 17 Oct 2021 13:05:33 +0200
Subject: [PATCH 074/305] new rtn cmplog: instrumentation side + supporting
functions
---
include/afl-fuzz.h | 1 +
include/cmplog.h | 12 +-
include/config.h | 4 +-
instrumentation/afl-compiler-rt.o.c | 202 ++++++++++++++++++++-
instrumentation/cmplog-routines-pass.cc | 225 +++++++++++++++++++++++-
src/afl-fuzz-one.c | 25 ++-
src/afl-fuzz-queue.c | 91 +++++++++-
src/afl-fuzz-stats.c | 3 +-
src/afl-fuzz.c | 14 ++
9 files changed, 551 insertions(+), 26 deletions(-)
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 4b19e698..5e52c0f0 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -1136,6 +1136,7 @@ void setup_signal_handlers(void);
void save_cmdline(afl_state_t *, u32, char **);
void read_foreign_testcases(afl_state_t *, int);
void write_crash_readme(afl_state_t *afl);
+u8 check_if_text_buf(u8 *buf, u32 len);
/* CmpLog */
diff --git a/include/cmplog.h b/include/cmplog.h
index 878ed60c..88aa0a61 100644
--- a/include/cmplog.h
+++ b/include/cmplog.h
@@ -33,7 +33,7 @@
#define CMPLOG_LVL_MAX 3
#define CMP_MAP_W 65536
-#define CMP_MAP_H 32
+#define CMP_MAP_H 64
#define CMP_MAP_RTN_H (CMP_MAP_H / 4)
#define SHAPE_BYTES(x) (x + 1)
@@ -59,14 +59,16 @@ struct cmp_operands {
u64 v0_128;
u64 v1_128;
-};
+} __attribute__((packed));
struct cmpfn_operands {
- u8 v0[32];
- u8 v1[32];
+ u8 v0[31];
+ u8 v0_len;
+ u8 v1[31];
+ u8 v1_len;
-};
+} __attribute__((packed));
typedef struct cmp_operands cmp_map_list[CMP_MAP_H];
diff --git a/include/config.h b/include/config.h
index 4630da0c..3b3b6daa 100644
--- a/include/config.h
+++ b/include/config.h
@@ -267,8 +267,8 @@
(first value), and to keep in memory as candidates. The latter should be much
higher than the former. */
-#define USE_AUTO_EXTRAS 128
-#define MAX_AUTO_EXTRAS (USE_AUTO_EXTRAS * 64)
+#define USE_AUTO_EXTRAS 4096
+#define MAX_AUTO_EXTRAS (USE_AUTO_EXTRAS * 8)
/* Scaling factor for the effector map used to skip some of the more
expensive deterministic steps. The actual divisor is set to
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 9acab4e7..21772ca0 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -1880,6 +1880,191 @@ static int area_is_valid(void *ptr, size_t len) {
}
+void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u32 len) {
+
+ /*
+ u32 i;
+ if (area_is_valid(ptr1, 32) <= 0 || area_is_valid(ptr2, 32) <= 0) return;
+ fprintf(stderr, "rtn_n len=%u arg0=", len);
+ for (i = 0; i < len; i++)
+ fprintf(stderr, "%02x", ptr1[i]);
+ fprintf(stderr, " arg1=");
+ for (i = 0; i < len; i++)
+ fprintf(stderr, "%02x", ptr2[i]);
+ fprintf(stderr, "\n");
+ */
+
+ if (likely(!__afl_cmp_map)) return;
+ // fprintf(stderr, "RTN1 %p %p %u\n", ptr1, ptr2, len);
+ if (unlikely(!len)) return;
+ int l = MIN(31, len);
+
+ // fprintf(stderr, "RTN2 %u\n", l);
+ uintptr_t k = (uintptr_t)__builtin_return_address(0);
+ k = (k >> 4) ^ (k << 8);
+ k &= CMP_MAP_W - 1;
+
+ u32 hits, reset = 1;
+
+ if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
+
+ __afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
+ __afl_cmp_map->headers[k].hits = 1;
+ __afl_cmp_map->headers[k].shape = l - 1;
+ reset = hits = 0;
+
+ } else {
+
+ hits = __afl_cmp_map->headers[k].hits++;
+
+ if (__afl_cmp_map->headers[k].shape < l) {
+
+ __afl_cmp_map->headers[k].shape = l - 1;
+
+ }
+
+ }
+
+ struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
+ hits &= CMP_MAP_RTN_H - 1;
+ if (unlikely(reset && !hits)) {
+
+ __builtin_memset(cmpfn, 0, sizeof(struct cmpfn_operands));
+
+ }
+
+ cmpfn[hits].v0_len = l;
+ cmpfn[hits].v1_len = l;
+ __builtin_memcpy(cmpfn[hits].v0, ptr1, l);
+ __builtin_memcpy(cmpfn[hits].v1, ptr2, l);
+ // fprintf(stderr, "RTN3\n");
+
+}
+
+void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u32 len) {
+
+ /*
+ u32 i;
+ if (area_is_valid(ptr1, 32) <= 0 || area_is_valid(ptr2, 32) <= 0) return;
+ fprintf(stderr, "rtn_strn len=%u arg0=", len);
+ for (i = 0; i < len; i++)
+ fprintf(stderr, "%02x", ptr1[i]);
+ fprintf(stderr, " arg1=");
+ for (i = 0; i < len; i++)
+ fprintf(stderr, "%02x", ptr2[i]);
+ fprintf(stderr, "\n");
+ */
+
+ if (likely(!__afl_cmp_map)) return;
+ // fprintf(stderr, "RTN1 %p %p %u\n", ptr1, ptr2, len);
+ if (unlikely(!len)) return;
+ int l = MIN(31, len + 1);
+
+ // fprintf(stderr, "RTN2 %u\n", l);
+ uintptr_t k = (uintptr_t)__builtin_return_address(0);
+ k = (k >> 4) ^ (k << 8);
+ k &= CMP_MAP_W - 1;
+
+ u32 hits, reset = 1;
+
+ if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
+
+ __afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
+ __afl_cmp_map->headers[k].hits = 1;
+ __afl_cmp_map->headers[k].shape = l - 1;
+ reset = hits = 0;
+
+ } else {
+
+ hits = __afl_cmp_map->headers[k].hits++;
+
+ if (__afl_cmp_map->headers[k].shape < l) {
+
+ __afl_cmp_map->headers[k].shape = l - 1;
+
+ }
+
+ }
+
+ struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
+ hits &= CMP_MAP_RTN_H - 1;
+ if (unlikely(reset && !hits)) {
+
+ __builtin_memset(cmpfn, 0, sizeof(struct cmpfn_operands));
+
+ }
+
+ cmpfn[hits].v0_len = 0x80 + l;
+ cmpfn[hits].v1_len = 0x80 + l;
+ __builtin_memcpy(cmpfn[hits].v0, ptr1, l);
+ __builtin_memcpy(cmpfn[hits].v1, ptr2, l);
+ // fprintf(stderr, "RTN3\n");
+
+}
+
+void __cmplog_rtn_hook_str(u8 *ptr1, u8 *ptr2) {
+
+ /*
+ u32 i;
+ if (area_is_valid(ptr1, 32) <= 0 || area_is_valid(ptr2, 32) <= 0) return;
+ fprintf(stderr, "rtn_str arg0=");
+ for (i = 0; i < len; i++)
+ fprintf(stderr, "%02x", ptr1[i]);
+ fprintf(stderr, " arg1=");
+ for (i = 0; i < len; i++)
+ fprintf(stderr, "%02x", ptr2[i]);
+ fprintf(stderr, "\n");
+ */
+
+ if (likely(!__afl_cmp_map)) return;
+ // fprintf(stderr, "RTN1 %p %p\n", ptr1, ptr2);
+ if (unlikely(!ptr1 || !ptr2)) return;
+ int len1 = MIN(31, strlen(ptr1) + 1);
+ int len2 = MIN(31, strlen(ptr2) + 1);
+ int l = MIN(MAX(len1, len2), 31);
+
+ // fprintf(stderr, "RTN2 %u\n", l);
+ uintptr_t k = (uintptr_t)__builtin_return_address(0);
+ k = (k >> 4) ^ (k << 8);
+ k &= CMP_MAP_W - 1;
+
+ u32 hits, reset = 1;
+
+ if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
+
+ __afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
+ __afl_cmp_map->headers[k].hits = 1;
+ __afl_cmp_map->headers[k].shape = l - 1;
+ reset = hits = 0;
+
+ } else {
+
+ hits = __afl_cmp_map->headers[k].hits++;
+
+ if (__afl_cmp_map->headers[k].shape < l) {
+
+ __afl_cmp_map->headers[k].shape = l - 1;
+
+ }
+
+ }
+
+ struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
+ hits &= CMP_MAP_RTN_H - 1;
+ if (unlikely(reset && !hits)) {
+
+ __builtin_memset(cmpfn, 0, sizeof(struct cmpfn_operands));
+
+ }
+
+ cmpfn[hits].v0_len = 0x80 + len1;
+ cmpfn[hits].v1_len = 0x80 + len2;
+ __builtin_memcpy(cmpfn[hits].v0, ptr1, len1);
+ __builtin_memcpy(cmpfn[hits].v1, ptr2, len2);
+ // fprintf(stderr, "RTN3\n");
+
+}
+
void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
/*
@@ -1907,14 +2092,14 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
- u32 hits;
+ u32 hits, reset = 1;
if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
__afl_cmp_map->headers[k].hits = 1;
__afl_cmp_map->headers[k].shape = len - 1;
- hits = 0;
+ reset = hits = 0;
} else {
@@ -1928,11 +2113,16 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
}
+ struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
hits &= CMP_MAP_RTN_H - 1;
- __builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0,
- ptr1, len);
- __builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1,
- ptr2, len);
+ if (unlikely(reset && !hits)) {
+
+ __builtin_memset(cmpfn, 0, sizeof(struct cmpfn_operands));
+
+ }
+
+ __builtin_memcpy(cmpfn[hits].v0, ptr1, len);
+ __builtin_memcpy(cmpfn[hits].v1, ptr2, len);
// fprintf(stderr, "RTN3\n");
}
diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc
index 1e2610f2..56f1a083 100644
--- a/instrumentation/cmplog-routines-pass.cc
+++ b/instrumentation/cmplog-routines-pass.cc
@@ -87,12 +87,14 @@ char CmpLogRoutines::ID = 0;
bool CmpLogRoutines::hookRtns(Module &M) {
- std::vector calls, llvmStdStd, llvmStdC, gccStdStd, gccStdC;
- LLVMContext & C = M.getContext();
+ std::vector calls, llvmStdStd, llvmStdC, gccStdStd, gccStdC,
+ Memcmp, Strcmp, Strncmp;
+ LLVMContext &C = M.getContext();
Type *VoidTy = Type::getVoidTy(C);
// PointerType *VoidPtrTy = PointerType::get(VoidTy, 0);
IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
+ IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
PointerType *i8PtrTy = PointerType::get(Int8Ty, 0);
#if LLVM_VERSION_MAJOR < 9
@@ -184,6 +186,60 @@ bool CmpLogRoutines::hookRtns(Module &M) {
FunctionCallee cmplogGccStdC = c4;
#endif
+#if LLVM_VERSION_MAJOR < 9
+ Constant *
+#else
+ FunctionCallee
+#endif
+ c5 = M.getOrInsertFunction("__cmplog_rtn_hook_n", VoidTy, i8PtrTy,
+ i8PtrTy, Int32Ty
+#if LLVM_VERSION_MAJOR < 5
+ ,
+ NULL
+#endif
+ );
+#if LLVM_VERSION_MAJOR < 9
+ Function *cmplogHookFnN = cast(c5);
+#else
+ FunctionCallee cmplogHookFnN = c5;
+#endif
+
+#if LLVM_VERSION_MAJOR < 9
+ Constant *
+#else
+ FunctionCallee
+#endif
+ c6 = M.getOrInsertFunction("__cmplog_rtn_hook_strn", VoidTy, i8PtrTy,
+ i8PtrTy, Int32Ty
+#if LLVM_VERSION_MAJOR < 5
+ ,
+ NULL
+#endif
+ );
+#if LLVM_VERSION_MAJOR < 9
+ Function *cmplogHookFnStrN = cast(c6);
+#else
+ FunctionCallee cmplogHookFnStrN = c6;
+#endif
+
+#if LLVM_VERSION_MAJOR < 9
+ Constant *
+#else
+ FunctionCallee
+#endif
+ c7 = M.getOrInsertFunction("__cmplog_rtn_hook_str", VoidTy, i8PtrTy,
+ i8PtrTy
+#if LLVM_VERSION_MAJOR < 5
+ ,
+ NULL
+#endif
+ );
+#if LLVM_VERSION_MAJOR < 9
+ Function *cmplogHookFnStr = cast(c7);
+#else
+ FunctionCallee cmplogHookFnStr = c7;
+#endif
+
GlobalVariable *AFLCmplogPtr = M.getNamedGlobal("__afl_cmp_map");
if (!AFLCmplogPtr) {
@@ -214,12 +270,77 @@ bool CmpLogRoutines::hookRtns(Module &M) {
if (callInst->getCallingConv() != llvm::CallingConv::C) continue;
FunctionType *FT = Callee->getFunctionType();
+ std::string FuncName = Callee->getName().str();
bool isPtrRtn = FT->getNumParams() >= 2 &&
!FT->getReturnType()->isVoidTy() &&
FT->getParamType(0) == FT->getParamType(1) &&
FT->getParamType(0)->isPointerTy();
+ bool isPtrRtnN = FT->getNumParams() >= 3 &&
+ !FT->getReturnType()->isVoidTy() &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ FT->getParamType(0)->isPointerTy() &&
+ FT->getParamType(2)->isIntegerTy();
+
+ bool isMemcmp =
+ (!FuncName.compare("memcmp") || !FuncName.compare("bcmp") ||
+ !FuncName.compare("CRYPTO_memcmp") ||
+ !FuncName.compare("OPENSSL_memcmp") ||
+ !FuncName.compare("memcmp_const_time") ||
+ !FuncName.compare("memcmpct"));
+ isMemcmp &= FT->getNumParams() == 3 &&
+ FT->getReturnType()->isIntegerTy(32) &&
+ FT->getParamType(0)->isPointerTy() &&
+ FT->getParamType(1)->isPointerTy() &&
+ FT->getParamType(2)->isIntegerTy();
+
+ bool isStrcmp =
+ (!FuncName.compare("strcmp") || !FuncName.compare("xmlStrcmp") ||
+ !FuncName.compare("xmlStrEqual") ||
+ !FuncName.compare("g_strcmp0") ||
+ !FuncName.compare("curl_strequal") ||
+ !FuncName.compare("strcsequal") ||
+ !FuncName.compare("strcasecmp") ||
+ !FuncName.compare("stricmp") ||
+ !FuncName.compare("ap_cstr_casecmp") ||
+ !FuncName.compare("OPENSSL_strcasecmp") ||
+ !FuncName.compare("xmlStrcasecmp") ||
+ !FuncName.compare("g_strcasecmp") ||
+ !FuncName.compare("g_ascii_strcasecmp") ||
+ !FuncName.compare("Curl_strcasecompare") ||
+ !FuncName.compare("Curl_safe_strcasecompare") ||
+ !FuncName.compare("cmsstrcasecmp") ||
+ !FuncName.compare("strstr") ||
+ !FuncName.compare("g_strstr_len") ||
+ !FuncName.compare("ap_strcasestr") ||
+ !FuncName.compare("xmlStrstr") ||
+ !FuncName.compare("xmlStrcasestr") ||
+ !FuncName.compare("g_str_has_prefix") ||
+ !FuncName.compare("g_str_has_suffix"));
+ isStrcmp &=
+ FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ FT->getParamType(0) == IntegerType::getInt8PtrTy(M.getContext());
+
+ bool isStrncmp = (!FuncName.compare("strncmp") ||
+ !FuncName.compare("xmlStrncmp") ||
+ !FuncName.compare("curl_strnequal") ||
+ !FuncName.compare("strncasecmp") ||
+ !FuncName.compare("strnicmp") ||
+ !FuncName.compare("ap_cstr_casecmpn") ||
+ !FuncName.compare("OPENSSL_strncasecmp") ||
+ !FuncName.compare("xmlStrncasecmp") ||
+ !FuncName.compare("g_ascii_strncasecmp") ||
+ !FuncName.compare("Curl_strncasecompare") ||
+ !FuncName.compare("g_strncasecmp"));
+ isStrncmp &= FT->getNumParams() == 3 &&
+ FT->getReturnType()->isIntegerTy(32) &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ FT->getParamType(0) ==
+ IntegerType::getInt8PtrTy(M.getContext()) &&
+ FT->getParamType(2)->isIntegerTy();
+
bool isGccStdStringStdString =
Callee->getName().find("__is_charIT_EE7__value") !=
std::string::npos &&
@@ -267,13 +388,19 @@ bool CmpLogRoutines::hookRtns(Module &M) {
*/
if (isGccStdStringCString || isGccStdStringStdString ||
- isLlvmStdStringStdString || isLlvmStdStringCString) {
+ isLlvmStdStringStdString || isLlvmStdStringCString || isMemcmp ||
+ isStrcmp || isStrncmp) {
- isPtrRtn = false;
+ isPtrRtnN = isPtrRtn = false;
}
+ if (isPtrRtnN) { isPtrRtn = false; }
+
if (isPtrRtn) { calls.push_back(callInst); }
+ if (isMemcmp || isPtrRtnN) { Memcmp.push_back(callInst); }
+ if (isStrcmp) { Strcmp.push_back(callInst); }
+ if (isStrncmp) { Strncmp.push_back(callInst); }
if (isGccStdStringStdString) { gccStdStd.push_back(callInst); }
if (isGccStdStringCString) { gccStdC.push_back(callInst); }
if (isLlvmStdStringStdString) { llvmStdStd.push_back(callInst); }
@@ -288,7 +415,8 @@ bool CmpLogRoutines::hookRtns(Module &M) {
}
if (!calls.size() && !gccStdStd.size() && !gccStdC.size() &&
- !llvmStdStd.size() && !llvmStdC.size())
+ !llvmStdStd.size() && !llvmStdC.size() && !Memcmp.size() &&
+ Strcmp.size() && Strncmp.size())
return false;
/*
@@ -323,6 +451,93 @@ bool CmpLogRoutines::hookRtns(Module &M) {
}
+ for (auto &callInst : Memcmp) {
+
+ Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1),
+ *v3P = callInst->getArgOperand(2);
+
+ IRBuilder<> IRB2(callInst->getParent());
+ IRB2.SetInsertPoint(callInst);
+
+ LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr);
+ CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
+ auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null);
+ auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false);
+
+ IRBuilder<> IRB(ThenTerm);
+
+ std::vector args;
+ Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
+ Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
+ Value * v3Pcasted = IRB.CreateZExtOrBitCast(v3P, Int32Ty);
+ args.push_back(v1Pcasted);
+ args.push_back(v2Pcasted);
+ args.push_back(v3Pcasted);
+
+ IRB.CreateCall(cmplogHookFnN, args);
+
+ // errs() << callInst->getCalledFunction()->getName() << "\n";
+
+ }
+
+ for (auto &callInst : Strcmp) {
+
+ Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1),
+ *v3P = callInst->getArgOperand(2);
+
+ IRBuilder<> IRB2(callInst->getParent());
+ IRB2.SetInsertPoint(callInst);
+
+ LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr);
+ CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
+ auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null);
+ auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false);
+
+ IRBuilder<> IRB(ThenTerm);
+
+ std::vector args;
+ Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
+ Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
+ Value * v3Pcasted = IRB.CreateZExtOrBitCast(v3P, Int32Ty);
+ args.push_back(v1Pcasted);
+ args.push_back(v2Pcasted);
+ args.push_back(v3Pcasted);
+
+ IRB.CreateCall(cmplogHookFnStr, args);
+
+ // errs() << callInst->getCalledFunction()->getName() << "\n";
+
+ }
+
+ for (auto &callInst : Strncmp) {
+
+ Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1),
+ *v3P = callInst->getArgOperand(2);
+
+ IRBuilder<> IRB2(callInst->getParent());
+ IRB2.SetInsertPoint(callInst);
+
+ LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr);
+ CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
+ auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null);
+ auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false);
+
+ IRBuilder<> IRB(ThenTerm);
+
+ std::vector args;
+ Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
+ Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
+ Value * v3Pcasted = IRB.CreateZExtOrBitCast(v3P, Int32Ty);
+ args.push_back(v1Pcasted);
+ args.push_back(v2Pcasted);
+ args.push_back(v3Pcasted);
+
+ IRB.CreateCall(cmplogHookFnStrN, args);
+
+ // errs() << callInst->getCalledFunction()->getName() << "\n";
+
+ }
+
for (auto &callInst : gccStdStd) {
Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1);
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 17749601..3217fb0f 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -448,11 +448,11 @@ u8 fuzz_one_original(afl_state_t *afl) {
ACTF(
"Fuzzing test case #%u (%u total, %llu uniq crashes found, "
- "perf_score=%0.0f, exec_us=%llu, hits=%u, map=%u)...",
+ "perf_score=%0.0f, exec_us=%llu, hits=%u, map=%u, ascii=%u)...",
afl->current_entry, afl->queued_paths, afl->unique_crashes,
afl->queue_cur->perf_score, afl->queue_cur->exec_us,
likely(afl->n_fuzz) ? afl->n_fuzz[afl->queue_cur->n_fuzz_entry] : 0,
- afl->queue_cur->bitmap_size);
+ afl->queue_cur->bitmap_size, afl->queue_cur->is_ascii);
fflush(stdout);
}
@@ -2003,11 +2003,16 @@ havoc_stage:
where we take the input file and make random stacked tweaks. */
#define MAX_HAVOC_ENTRY 59 /* 55 to 60 */
+#define MUTATE_ASCII_DICT 64
u32 r_max, r;
r_max = (MAX_HAVOC_ENTRY + 1) + (afl->extras_cnt ? 4 : 0) +
- (afl->a_extras_cnt ? 4 : 0);
+ (afl->a_extras_cnt
+ ? (unlikely(afl->cmplog_binary && afl->queue_cur->is_ascii)
+ ? MUTATE_ASCII_DICT
+ : 4)
+ : 0);
if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) {
@@ -2592,7 +2597,15 @@ havoc_stage:
if (afl->a_extras_cnt) {
- if (r < 2) {
+ u32 r_cmp = 2;
+
+ if (unlikely(afl->cmplog_binary && afl->queue_cur->is_ascii)) {
+
+ r_cmp = MUTATE_ASCII_DICT >> 1;
+
+ }
+
+ if (r < r_cmp) {
/* Use the dictionary. */
@@ -2612,7 +2625,7 @@ havoc_stage:
break;
- } else if (r < 4) {
+ } else if (r < (r_cmp << 1)) {
u32 use_extra = rand_below(afl, afl->a_extras_cnt);
u32 extra_len = afl->a_extras[use_extra].len;
@@ -2641,7 +2654,7 @@ havoc_stage:
} else {
- r -= 4;
+ r -= (r_cmp << 1);
}
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index 16af2c6b..718f7cb6 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -315,7 +315,96 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) {
}
-/* check if ascii or UTF-8 */
+/* check if pointer is ascii or UTF-8 */
+
+u8 check_if_text_buf(u8 *buf, u32 len) {
+
+ u32 offset = 0, ascii = 0, utf8 = 0;
+
+ while (offset < len) {
+
+ // ASCII: <= 0x7F to allow ASCII control characters
+ if ((buf[offset + 0] == 0x09 || buf[offset + 0] == 0x0A ||
+ buf[offset + 0] == 0x0D ||
+ (0x20 <= buf[offset + 0] && buf[offset + 0] <= 0x7E))) {
+
+ offset++;
+ utf8++;
+ ascii++;
+ continue;
+
+ }
+
+ if (isascii((int)buf[offset]) || isprint((int)buf[offset])) {
+
+ ascii++;
+ // we continue though as it can also be a valid utf8
+
+ }
+
+ // non-overlong 2-byte
+ if (len - offset > 1 &&
+ ((0xC2 <= buf[offset + 0] && buf[offset + 0] <= 0xDF) &&
+ (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF))) {
+
+ offset += 2;
+ utf8++;
+ continue;
+
+ }
+
+ // excluding overlongs
+ if ((len - offset > 2) &&
+ ((buf[offset + 0] == 0xE0 &&
+ (0xA0 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) &&
+ (0x80 <= buf[offset + 2] &&
+ buf[offset + 2] <= 0xBF)) || // straight 3-byte
+ (((0xE1 <= buf[offset + 0] && buf[offset + 0] <= 0xEC) ||
+ buf[offset + 0] == 0xEE || buf[offset + 0] == 0xEF) &&
+ (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) &&
+ (0x80 <= buf[offset + 2] &&
+ buf[offset + 2] <= 0xBF)) || // excluding surrogates
+ (buf[offset + 0] == 0xED &&
+ (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x9F) &&
+ (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF)))) {
+
+ offset += 3;
+ utf8++;
+ continue;
+
+ }
+
+ // planes 1-3
+ if ((len - offset > 3) &&
+ ((buf[offset + 0] == 0xF0 &&
+ (0x90 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) &&
+ (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) &&
+ (0x80 <= buf[offset + 3] &&
+ buf[offset + 3] <= 0xBF)) || // planes 4-15
+ ((0xF1 <= buf[offset + 0] && buf[offset + 0] <= 0xF3) &&
+ (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) &&
+ (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) &&
+ (0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF)) || // plane 16
+ (buf[offset + 0] == 0xF4 &&
+ (0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x8F) &&
+ (0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) &&
+ (0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF)))) {
+
+ offset += 4;
+ utf8++;
+ continue;
+
+ }
+
+ offset++;
+
+ }
+
+ return (utf8 > ascii ? utf8 : ascii);
+
+}
+
+/* check if queue entry is ascii or UTF-8 */
static u8 check_if_text(afl_state_t *afl, struct queue_entry *q) {
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 870ba69a..7796036b 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -278,6 +278,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
"total_edges : %u\n"
"var_byte_count : %u\n"
"havoc_expansion : %u\n"
+ "auto_dict_entries : %u\n"
"testcache_size : %llu\n"
"testcache_count : %u\n"
"testcache_evict : %u\n"
@@ -316,7 +317,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
-1,
#endif
t_bytes, afl->fsrv.real_map_size, afl->var_byte_count,
- afl->expand_havoc, afl->q_testcase_cache_size,
+ afl->expand_havoc, afl->a_extras_cnt, afl->q_testcase_cache_size,
afl->q_testcase_cache_count, afl->q_testcase_evictions,
afl->use_banner, afl->unicorn_mode ? "unicorn" : "",
afl->fsrv.qemu_mode ? "qemu " : "",
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 92a37697..6ec033b2 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -2261,6 +2261,20 @@ stop_fuzzing:
}
+ if (afl->not_on_tty) {
+
+ u32 t_bytes = count_non_255_bytes(afl, afl->virgin_bits);
+ u8 time_tmp[64];
+ u_stringify_time_diff(time_tmp, get_cur_time(), afl->start_time);
+ ACTF(
+ "Statistics: %u new paths found, %.02f%% coverage achieved, %llu "
+ "crashes found, %llu timeouts found, total runtime %s",
+ afl->queued_discovered,
+ ((double)t_bytes * 100) / afl->fsrv.real_map_size, afl->unique_crashes,
+ afl->unique_hangs, time_tmp);
+
+ }
+
#ifdef PROFILING
SAYF(cYEL "[!] " cRST
"Profiling information: %llu ms total work, %llu ns/run\n",
From e8cf04c90d730381eab3ef6c64ab957ab5ebc400 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 17 Oct 2021 13:20:32 +0200
Subject: [PATCH 075/305] fix
---
instrumentation/cmplog-routines-pass.cc | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc
index 56f1a083..3d6467ba 100644
--- a/instrumentation/cmplog-routines-pass.cc
+++ b/instrumentation/cmplog-routines-pass.cc
@@ -482,8 +482,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
for (auto &callInst : Strcmp) {
- Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1),
- *v3P = callInst->getArgOperand(2);
+ Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1);
IRBuilder<> IRB2(callInst->getParent());
IRB2.SetInsertPoint(callInst);
@@ -498,10 +497,8 @@ bool CmpLogRoutines::hookRtns(Module &M) {
std::vector args;
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
- Value * v3Pcasted = IRB.CreateZExtOrBitCast(v3P, Int32Ty);
args.push_back(v1Pcasted);
args.push_back(v2Pcasted);
- args.push_back(v3Pcasted);
IRB.CreateCall(cmplogHookFnStr, args);
@@ -527,7 +524,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
std::vector args;
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
- Value * v3Pcasted = IRB.CreateZExtOrBitCast(v3P, Int32Ty);
+ Value * v3Pcasted = IRB.CreateTruncOrBitCast(v3P, Int32Ty);
args.push_back(v1Pcasted);
args.push_back(v2Pcasted);
args.push_back(v3Pcasted);
From 2363a047500c133996e40808f1974e4aa97ed5bf Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 17 Oct 2021 14:21:08 +0200
Subject: [PATCH 076/305] simplify SHAPE_BYTES(h->shape)
---
src/afl-fuzz-redqueen.c | 97 ++++++++++++++++++++++-------------------
1 file changed, 51 insertions(+), 46 deletions(-)
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 268f726c..2d610132 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -64,6 +64,8 @@ struct range {
};
+static u32 hshape;
+
static struct range *add_range(struct range *ranges, u32 start, u32 end) {
struct range *r = ck_alloc_nozero(sizeof(struct range));
@@ -763,7 +765,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
// "Encode: %llx->%llx into %llx(<-%llx) at idx=%u "
// "taint_len=%u shape=%u attr=%u\n",
// o_pattern, pattern, repl, changed_val, idx, taint_len,
- // h->shape + 1, attr);
+ // hshape, attr);
//#ifdef CMPLOG_SOLVE_TRANSFORM
// reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3
@@ -845,7 +847,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
u64 b_val, o_b_val, mask;
u8 bytes;
- switch (SHAPE_BYTES(h->shape)) {
+ switch (hshape) {
case 0:
case 1:
@@ -924,7 +926,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
s64 diff = pattern - b_val;
s64 o_diff = o_pattern - o_b_val;
/* fprintf(stderr, "DIFF1 idx=%03u shape=%02u %llx-%llx=%lx\n", idx,
- h->shape + 1, o_pattern, o_b_val, o_diff);
+ hshape, o_pattern, o_b_val, o_diff);
fprintf(stderr, "DIFF1 %016llx %llx-%llx=%lx\n", repl, pattern,
b_val, diff); */
if (diff == o_diff && diff) {
@@ -953,7 +955,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
s64 o_diff = o_pattern ^ o_b_val;
/* fprintf(stderr, "DIFF2 idx=%03u shape=%02u %llx-%llx=%lx\n",
- idx, h->shape + 1, o_pattern, o_b_val, o_diff);
+ idx, hshape, o_pattern, o_b_val, o_diff);
fprintf(stderr,
"DIFF2 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);
*/
@@ -1002,7 +1004,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
/* fprintf(stderr, "DIFF3 idx=%03u shape=%02u %llx-%llx=%lx\n",
- idx, h->shape + 1, o_pattern, o_b_val, o_diff);
+ idx, hshape, o_pattern, o_b_val, o_diff);
fprintf(stderr,
"DIFF3 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);
*/
@@ -1051,7 +1053,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
/* fprintf(stderr, "DIFF4 idx=%03u shape=%02u %llx-%llx=%lx\n",
- idx, h->shape + 1, o_pattern, o_b_val, o_diff);
+ idx, hshape, o_pattern, o_b_val, o_diff);
fprintf(stderr,
"DIFF4 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);
*/
@@ -1089,7 +1091,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
if ((lvl & LVL1) || attr >= IS_FP_MOD) {
- if (SHAPE_BYTES(h->shape) >= 8 && *status != 1) {
+ if (hshape >= 8 && *status != 1) {
// if (its_len >= 8)
// fprintf(stderr,
@@ -1132,7 +1134,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
- if (SHAPE_BYTES(h->shape) >= 4 && *status != 1) {
+ if (hshape >= 4 && *status != 1) {
// if (its_len >= 4 && (attr <= 1 || attr >= 8))
// fprintf(stderr,
@@ -1173,7 +1175,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
- if (SHAPE_BYTES(h->shape) >= 2 && *status != 1) {
+ if (hshape >= 2 && *status != 1) {
if (its_len >= 2 &&
((*buf_16 == (u16)pattern && *o_buf_16 == (u16)o_pattern) ||
@@ -1244,7 +1246,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
- if (!(attr & (IS_GREATER | IS_LESSER)) || SHAPE_BYTES(h->shape) < 4) {
+ if (!(attr & (IS_GREATER | IS_LESSER)) || hshape < 4) {
return 0;
@@ -1272,7 +1274,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
if (attr & IS_GREATER) {
- if (SHAPE_BYTES(h->shape) == 4 && its_len >= 4) {
+ if (hshape == 4 && its_len >= 4) {
float *f = (float *)&repl;
float g = *f;
@@ -1280,7 +1282,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
u32 *r = (u32 *)&g;
repl_new = (u32)*r;
- } else if (SHAPE_BYTES(h->shape) == 8 && its_len >= 8) {
+ } else if (hshape == 8 && its_len >= 8) {
double *f = (double *)&repl;
double g = *f;
@@ -1307,7 +1309,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
} else {
- if (SHAPE_BYTES(h->shape) == 4) {
+ if (hshape == 4) {
float *f = (float *)&repl;
float g = *f;
@@ -1315,7 +1317,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
u32 *r = (u32 *)&g;
repl_new = (u32)*r;
- } else if (SHAPE_BYTES(h->shape) == 8) {
+ } else if (hshape == 8) {
double *f = (double *)&repl;
double g = *f;
@@ -1342,7 +1344,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
// transform double to float, llvm likes to do that internally ...
- if (SHAPE_BYTES(h->shape) == 8 && its_len >= 4) {
+ if (hshape == 8 && its_len >= 4) {
double *f = (double *)&repl;
float g = (float)*f;
@@ -1353,7 +1355,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
memcpy(((char *)&repl_new) + 4, (char *)&g, 4);
#endif
changed_val = repl_new;
- h->shape = 3; // modify shape
+ hshape = 4; // modify shape
// fprintf(stderr, "DOUBLE2FLOAT %llx\n", repl_new);
@@ -1361,12 +1363,12 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx,
taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) {
- h->shape = 7; // recover shape
+ hshape = 8; // recover shape
return 1;
}
- h->shape = 7; // recover shape
+ hshape = 7; // recover shape
}
@@ -1428,14 +1430,13 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h,
u8 *r = (u8 *)&repl;
u8 backup[16];
u32 its_len = MIN(len - idx, taint_len);
- u32 shape = h->shape + 1;
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
size_t off = 0;
#else
- size_t off = 16 - shape;
+ size_t off = 16 - hshape;
#endif
- if (its_len >= shape) {
+ if (its_len >= hshape) {
#ifdef _DEBUG
fprintf(stderr, "TestUN: %u>=%u (len=%u idx=%u attr=%u off=%lu) (%u) ",
@@ -1462,18 +1463,18 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h,
fprintf(stderr, "\n");
#endif
- if (!memcmp(ptr, p + off, shape) && !memcmp(o_ptr, o_p + off, shape)) {
+ if (!memcmp(ptr, p + off, hshape) && !memcmp(o_ptr, o_p + off, hshape)) {
- memcpy(backup, ptr, shape);
- memcpy(ptr, r + off, shape);
+ memcpy(backup, ptr, hshape);
+ memcpy(ptr, r + off, hshape);
if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
#ifdef CMPLOG_COMBINE
- if (*status == 1) { memcpy(cbuf + idx, r, shape); }
+ if (*status == 1) { memcpy(cbuf + idx, r, hshape); }
#endif
- memcpy(ptr, backup, shape);
+ memcpy(ptr, backup, hshape);
#ifdef _DEBUG
fprintf(stderr, "Status=%u\n", *status);
@@ -1485,8 +1486,8 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h,
if (do_reverse && *status != 1) {
if (unlikely(cmp_extend_encodingN(
- afl, h, SWAPN(pattern, (shape << 3)), SWAPN(repl, (shape << 3)),
- SWAPN(o_pattern, (shape << 3)), SWAPN(changed_val, (shape << 3)),
+ afl, h, SWAPN(pattern, (hshape << 3)), SWAPN(repl, (hshape << 3)),
+ SWAPN(o_pattern, (hshape << 3)), SWAPN(changed_val, (hshape << 3)),
attr, idx, taint_len, orig_buf, buf, cbuf, len, 0, lvl,
status))) {
@@ -1615,6 +1616,8 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
u8 s_v0_inc = 1, s_v1_inc = 1;
u8 s_v0_dec = 1, s_v1_dec = 1;
+ hshape = SHAPE_BYTES(h->shape);
+
if (h->hits > CMP_MAP_H) {
loggeds = CMP_MAP_H;
@@ -1626,7 +1629,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
#ifdef WORD_SIZE_64
- switch (SHAPE_BYTES(h->shape)) {
+ switch (hshape) {
case 1:
case 2:
@@ -1680,7 +1683,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
#ifdef _DEBUG
fprintf(stderr, "Handling: %llx->%llx vs %llx->%llx attr=%u shape=%u\n",
orig_o->v0, o->v0, orig_o->v1, o->v1, h->attribute,
- SHAPE_BYTES(h->shape));
+ hshape);
#endif
t = taint;
@@ -1830,7 +1833,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
"END: %llx->%llx vs %llx->%llx attr=%u i=%u found=%u "
"isN=%u size=%u\n",
orig_o->v0, o->v0, orig_o->v1, o->v1, h->attribute, i, found_one,
- is_n, SHAPE_BYTES(h->shape));
+ is_n, hshape);
#endif
// If failed, add to dictionary
@@ -1841,16 +1844,16 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
#ifdef WORD_SIZE_64
if (unlikely(is_n)) {
- try_to_add_to_dictN(afl, s128_v0, SHAPE_BYTES(h->shape));
- try_to_add_to_dictN(afl, s128_v1, SHAPE_BYTES(h->shape));
+ try_to_add_to_dictN(afl, s128_v0, hshape);
+ try_to_add_to_dictN(afl, s128_v1, hshape);
} else
#endif
{
- try_to_add_to_dict(afl, o->v0, SHAPE_BYTES(h->shape));
- try_to_add_to_dict(afl, o->v1, SHAPE_BYTES(h->shape));
+ try_to_add_to_dict(afl, o->v0, hshape);
+ try_to_add_to_dict(afl, o->v1, hshape);
}
@@ -2322,6 +2325,8 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
u32 i, j, idx, have_taint = 1, taint_len, loggeds;
u8 status = 0, found_one = 0;
+ hshape = SHAPE_BYTES(h->shape);
+
if (h->hits > CMP_MAP_RTN_H) {
loggeds = CMP_MAP_RTN_H;
@@ -2355,12 +2360,12 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
/*
struct cmp_header *hh = &afl->orig_cmp_map->headers[key];
fprintf(stderr, "RTN N hits=%u id=%u shape=%u attr=%u v0=", h->hits,
- h->id, h->shape, h->attribute);
+ h->id, hshape, h->attribute);
for (j = 0; j < 8; j++) fprintf(stderr, "%02x", o->v0[j]);
fprintf(stderr, " v1=");
for (j = 0; j < 8; j++) fprintf(stderr, "%02x", o->v1[j]);
fprintf(stderr, "\nRTN O hits=%u id=%u shape=%u attr=%u o0=",
- hh->hits, hh->id, hh->shape, hh->attribute);
+ hh->hits, hh->id, hshape, hh->attribute);
for (j = 0; j < 8; j++) fprintf(stderr, "%02x", orig_o->v0[j]);
fprintf(stderr, " o1=");
for (j = 0; j < 8; j++) fprintf(stderr, "%02x", orig_o->v1[j]);
@@ -2401,23 +2406,23 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
#ifdef _DEBUG
int w;
fprintf(stderr, "key=%u idx=%u len=%u o0=", key, idx,
- SHAPE_BYTES(h->shape));
- for (w = 0; w < SHAPE_BYTES(h->shape); ++w)
+ hshape);
+ for (w = 0; w < hshape; ++w)
fprintf(stderr, "%02x", orig_o->v0[w]);
fprintf(stderr, " v0=");
- for (w = 0; w < SHAPE_BYTES(h->shape); ++w)
+ for (w = 0; w < hshape; ++w)
fprintf(stderr, "%02x", o->v0[w]);
fprintf(stderr, " o1=");
- for (w = 0; w < SHAPE_BYTES(h->shape); ++w)
+ for (w = 0; w < hshape; ++w)
fprintf(stderr, "%02x", orig_o->v1[w]);
fprintf(stderr, " v1=");
- for (w = 0; w < SHAPE_BYTES(h->shape); ++w)
+ for (w = 0; w < hshape; ++w)
fprintf(stderr, "%02x", o->v1[w]);
fprintf(stderr, "\n");
#endif
if (unlikely(rtn_extend_encoding(
- afl, o->v0, o->v1, orig_o->v0, orig_o->v1, SHAPE_BYTES(h->shape),
+ afl, o->v0, o->v1, orig_o->v0, orig_o->v1, hshape,
idx, taint_len, orig_buf, buf, cbuf, len, lvl, &status))) {
return 1;
@@ -2434,7 +2439,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
status = 0;
if (unlikely(rtn_extend_encoding(
- afl, o->v1, o->v0, orig_o->v1, orig_o->v0, SHAPE_BYTES(h->shape),
+ afl, o->v1, o->v0, orig_o->v1, orig_o->v0, hshape,
idx, taint_len, orig_buf, buf, cbuf, len, lvl, &status))) {
return 1;
@@ -2455,8 +2460,8 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
if (unlikely(!afl->pass_stats[key].total)) {
- maybe_add_auto(afl, o->v0, SHAPE_BYTES(h->shape));
- maybe_add_auto(afl, o->v1, SHAPE_BYTES(h->shape));
+ maybe_add_auto(afl, o->v0, hshape);
+ maybe_add_auto(afl, o->v1, hshape);
}
From bf0fbc24ad32b0ec5421f4d2090c85d87aeceee3 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 17 Oct 2021 15:44:48 +0200
Subject: [PATCH 077/305] new cmplog add dict strategy
---
src/afl-fuzz-redqueen.c | 170 +++++++++++++++++++++++++++++++---------
1 file changed, 131 insertions(+), 39 deletions(-)
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 2d610132..30de12c1 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -45,6 +45,23 @@ enum {
};
+// add to dictionary enum
+// DEFAULT = 1, notTXT = 2, FOUND = 4, notSAME = 8
+enum {
+
+ DICT_ADD_NEVER = 0,
+ DICT_ADD_NOTFOUND_SAME_TXT = 1,
+ DICT_ADD_NOTFOUND_SAME = 3,
+ DICT_ADD_FOUND_SAME_TXT = 5,
+ DICT_ADD_FOUND_SAME = 7,
+ DICT_ADD_NOTFOUND_TXT = 9,
+ DICT_ADD_NOTFOUND = 11,
+ DICT_ADD_FOUND_TXT = 13,
+ DICT_ADD_FOUND = 15,
+ DICT_ADD_ANY = DICT_ADD_FOUND
+
+};
+
// CMPLOG LVL
enum {
@@ -54,6 +71,8 @@ enum {
};
+#define DICT_ADD_STRATEGY DICT_ADD_FOUND_SAME
+
struct range {
u32 start;
@@ -1246,11 +1265,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
- if (!(attr & (IS_GREATER | IS_LESSER)) || hshape < 4) {
-
- return 0;
-
- }
+ if (!(attr & (IS_GREATER | IS_LESSER)) || hshape < 4) { return 0; }
// transform >= to < and <= to >
if ((attr & IS_EQUAL) && (attr & (IS_GREATER | IS_LESSER))) {
@@ -1487,9 +1502,9 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h,
if (unlikely(cmp_extend_encodingN(
afl, h, SWAPN(pattern, (hshape << 3)), SWAPN(repl, (hshape << 3)),
- SWAPN(o_pattern, (hshape << 3)), SWAPN(changed_val, (hshape << 3)),
- attr, idx, taint_len, orig_buf, buf, cbuf, len, 0, lvl,
- status))) {
+ SWAPN(o_pattern, (hshape << 3)),
+ SWAPN(changed_val, (hshape << 3)), attr, idx, taint_len, orig_buf,
+ buf, cbuf, len, 0, lvl, status))) {
return 1;
@@ -1682,8 +1697,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
#ifdef _DEBUG
fprintf(stderr, "Handling: %llx->%llx vs %llx->%llx attr=%u shape=%u\n",
- orig_o->v0, o->v0, orig_o->v1, o->v1, h->attribute,
- hshape);
+ orig_o->v0, o->v0, orig_o->v1, o->v1, h->attribute, hshape);
#endif
t = taint;
@@ -1836,26 +1850,39 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
is_n, hshape);
#endif
- // If failed, add to dictionary
- if (!found_one) {
-
- if (afl->pass_stats[key].total == 0) {
+ u8 same0 = 0, same1 = 0, result = 1 + 2 + (found_one << 2);
+ if (o->v0 != orig_o->v0) { same0 = 8; }
+ if (o->v1 != orig_o->v1) { same1 = 8; }
#ifdef WORD_SIZE_64
- if (unlikely(is_n)) {
+ if (unlikely(is_n)) {
- try_to_add_to_dictN(afl, s128_v0, hshape);
- try_to_add_to_dictN(afl, s128_v1, hshape);
+ if (DICT_ADD_STRATEGY >= same0 + result) {
- } else
+ try_to_add_to_dictN(afl, s128_v0, hshape);
+
+ }
+
+ if (DICT_ADD_STRATEGY >= same1 + result) {
+
+ try_to_add_to_dictN(afl, s128_v1, hshape);
+
+ }
+
+ } else
#endif
- {
+ {
- try_to_add_to_dict(afl, o->v0, hshape);
- try_to_add_to_dict(afl, o->v1, hshape);
+ if (DICT_ADD_STRATEGY >= same0 + result) {
- }
+ try_to_add_to_dict(afl, o->v0, hshape);
+
+ }
+
+ if (DICT_ADD_STRATEGY >= same1 + result) {
+
+ try_to_add_to_dict(afl, o->v1, hshape);
}
@@ -1885,8 +1912,9 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
-static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
- u8 *o_pattern, u8 *changed_val, u8 plen, u32 idx,
+static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
+ struct cmpfn_operands *o,
+ struct cmpfn_operands *orig_o, u32 idx,
u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf,
u32 len, u8 lvl, u8 *status) {
@@ -1897,9 +1925,50 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
// (void)(changed_val);
//#endif
+ u8 *pattern, *repl, *o_pattern, *changed_val;
+ u8 l0, l1, ol0, ol1;
+
+ if (entry == 0) {
+
+ pattern = o->v0;
+ repl = o->v1;
+ o_pattern = orig_o->v0;
+ changed_val = orig_o->v1;
+ l0 = o->v0_len;
+ ol0 = orig_o->v0_len;
+ l1 = o->v1_len;
+ ol1 = orig_o->v1_len;
+
+ } else {
+
+ pattern = o->v1;
+ repl = o->v0;
+ o_pattern = orig_o->v1;
+ changed_val = orig_o->v0;
+ l0 = o->v1_len;
+ ol0 = orig_o->v1_len;
+ l1 = o->v0_len;
+ ol1 = orig_o->v0_len;
+
+ }
+
+ if (l0 >= 0x80) {
+
+ l0 -= 0x80;
+ l1 -= 0x80;
+ ol0 -= 0x80;
+ ol1 -= 0x80;
+
+ } else if (l0 == 0 || l1 == 0 || ol0 == 0 || ol1 == 0) {
+
+ l0 = l1 = ol0 = ol1 = hshape;
+
+ }
+
+ u8 lmax = MAX(l0, ol0);
u8 save[40];
u32 saved_idx = idx, pre, from = 0, to = 0, i, j;
- u32 its_len = MIN((u32)plen, len - idx);
+ u32 its_len = MIN(MIN(lmax, hshape), len - idx);
its_len = MIN(its_len, taint_len);
u32 saved_its_len = its_len;
@@ -1915,7 +1984,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
(void)(j);
#ifdef _DEBUG
- fprintf(stderr, "RTN T idx=%u lvl=%02x ", idx, lvl);
+ fprintf(stderr, "RTN T idx=%u lvl=%02x is_txt=%u shape=%u/%u ", idx, lvl,
+ o->v0_len >= 0x80 ? 1 : 0, hshape, l0);
for (j = 0; j < 8; j++)
fprintf(stderr, "%02x", orig_buf[idx + j]);
fprintf(stderr, " -> ");
@@ -2405,8 +2475,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
#ifdef _DEBUG
int w;
- fprintf(stderr, "key=%u idx=%u len=%u o0=", key, idx,
- hshape);
+ fprintf(stderr, "key=%u idx=%u len=%u o0=", key, idx, hshape);
for (w = 0; w < hshape; ++w)
fprintf(stderr, "%02x", orig_o->v0[w]);
fprintf(stderr, " v0=");
@@ -2421,9 +2490,9 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
fprintf(stderr, "\n");
#endif
- if (unlikely(rtn_extend_encoding(
- afl, o->v0, o->v1, orig_o->v0, orig_o->v1, hshape,
- idx, taint_len, orig_buf, buf, cbuf, len, lvl, &status))) {
+ if (unlikely(rtn_extend_encoding(afl, 0, o, orig_o, idx, taint_len,
+ orig_buf, buf, cbuf, len, lvl,
+ &status))) {
return 1;
@@ -2438,9 +2507,9 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
status = 0;
- if (unlikely(rtn_extend_encoding(
- afl, o->v1, o->v0, orig_o->v1, orig_o->v0, hshape,
- idx, taint_len, orig_buf, buf, cbuf, len, lvl, &status))) {
+ if (unlikely(rtn_extend_encoding(afl, 1, o, orig_o, idx, taint_len,
+ orig_buf, buf, cbuf, len, lvl,
+ &status))) {
return 1;
@@ -2455,13 +2524,36 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
- // If failed, add to dictionary
- if (!found_one && (lvl & LVL1)) {
+ // if (unlikely(!afl->pass_stats[key].total)) {
- if (unlikely(!afl->pass_stats[key].total)) {
+ if (lvl & LVL1) {
- maybe_add_auto(afl, o->v0, hshape);
- maybe_add_auto(afl, o->v1, hshape);
+ u8 is_txt = 0, l0 = o->v0_len, ol0 = orig_o->v0_len, l1 = o->v1_len,
+ ol1 = orig_o->v1_len;
+ if (l0 >= 0x80) {
+
+ is_txt = 1;
+ l0 -= 0x80;
+ l1 -= 0x80;
+ ol0 -= 0x80;
+ ol1 -= 0x80;
+
+ }
+
+ u8 same0 = 0, same1 = 0, result = 1 + (found_one << 2);
+ if (!is_txt) result += 2;
+ if (l0 != ol0 || memcmp(o->v0, orig_o->v0, l0) != 0) { same0 = 8; }
+ if (l1 != ol1 || memcmp(o->v1, orig_o->v1, l1) != 0) { same1 = 8; }
+
+ if (DICT_ADD_STRATEGY >= same0 + result) {
+
+ maybe_add_auto(afl, o->v0, l0);
+
+ }
+
+ if (DICT_ADD_STRATEGY >= same1 + result) {
+
+ maybe_add_auto(afl, o->v1, l1);
}
From 65c94d914db9930eaae50c6d36bdcb4ed16ea908 Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Sun, 17 Oct 2021 20:29:24 +0200
Subject: [PATCH 078/305] Change line length to max. 80 characters
---
README.md | 109 +++++++++++++++++++++++++++++++++++-------------------
1 file changed, 70 insertions(+), 39 deletions(-)
diff --git a/README.md b/README.md
index 9fe1da7e..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,56 +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 [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.
+* 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:
@@ -77,42 +96,52 @@ When fuzzing verbose syntax (SQL, HTTP, etc), create a dictionary as described i
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 .
+* 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 .
* 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
+:-)
@@ -171,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.
From 462149de642451024199557c7a7bb7ea76e5b8fa Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 17 Oct 2021 20:31:02 +0200
Subject: [PATCH 079/305] fix
---
instrumentation/afl-compiler-rt.o.c | 18 +-----
src/afl-fuzz-redqueen.c | 87 +++++++++++++++++------------
2 files changed, 53 insertions(+), 52 deletions(-)
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 21772ca0..38beafb7 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -1944,15 +1944,8 @@ void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u32 len) {
void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u32 len) {
/*
- u32 i;
if (area_is_valid(ptr1, 32) <= 0 || area_is_valid(ptr2, 32) <= 0) return;
- fprintf(stderr, "rtn_strn len=%u arg0=", len);
- for (i = 0; i < len; i++)
- fprintf(stderr, "%02x", ptr1[i]);
- fprintf(stderr, " arg1=");
- for (i = 0; i < len; i++)
- fprintf(stderr, "%02x", ptr2[i]);
- fprintf(stderr, "\n");
+ fprintf(stderr, "rtn_strn len=%u arg0=%s arg1=%s\n", len, ptr1, ptr2);
*/
if (likely(!__afl_cmp_map)) return;
@@ -2005,15 +1998,8 @@ void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u32 len) {
void __cmplog_rtn_hook_str(u8 *ptr1, u8 *ptr2) {
/*
- u32 i;
if (area_is_valid(ptr1, 32) <= 0 || area_is_valid(ptr2, 32) <= 0) return;
- fprintf(stderr, "rtn_str arg0=");
- for (i = 0; i < len; i++)
- fprintf(stderr, "%02x", ptr1[i]);
- fprintf(stderr, " arg1=");
- for (i = 0; i < len; i++)
- fprintf(stderr, "%02x", ptr2[i]);
- fprintf(stderr, "\n");
+ fprintf(stderr, "rtn_str arg0=%s arg1=%s\n", ptr1, ptr2);
*/
if (likely(!__afl_cmp_map)) return;
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 30de12c1..65d21b0a 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -1455,25 +1455,25 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h,
#ifdef _DEBUG
fprintf(stderr, "TestUN: %u>=%u (len=%u idx=%u attr=%u off=%lu) (%u) ",
- its_len, shape, len, idx, attr, off, do_reverse);
+ its_len, hshape, len, idx, attr, off, do_reverse);
u32 i;
u8 *o_r = (u8 *)&changed_val;
- for (i = 0; i < shape; i++)
+ for (i = 0; i < hshape; i++)
fprintf(stderr, "%02x", ptr[i]);
fprintf(stderr, "==");
- for (i = 0; i < shape; i++)
+ for (i = 0; i < hshape; i++)
fprintf(stderr, "%02x", p[off + i]);
fprintf(stderr, " ");
- for (i = 0; i < shape; i++)
+ for (i = 0; i < hshape; i++)
fprintf(stderr, "%02x", o_ptr[i]);
fprintf(stderr, "==");
- for (i = 0; i < shape; i++)
+ for (i = 0; i < hshape; i++)
fprintf(stderr, "%02x", o_p[off + i]);
fprintf(stderr, " <= ");
- for (i = 0; i < shape; i++)
+ for (i = 0; i < hshape; i++)
fprintf(stderr, "%02x", r[off + i]);
fprintf(stderr, "<-");
- for (i = 0; i < shape; i++)
+ for (i = 0; i < hshape; i++)
fprintf(stderr, "%02x", o_r[off + i]);
fprintf(stderr, "\n");
#endif
@@ -1850,39 +1850,46 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
is_n, hshape);
#endif
- u8 same0 = 0, same1 = 0, result = 1 + 2 + (found_one << 2);
- if (o->v0 != orig_o->v0) { same0 = 8; }
- if (o->v1 != orig_o->v1) { same1 = 8; }
+ // we only learn 16 bit +
+ if (hshape > 1) {
+
+ u8 same0 = 0, same1 = 0, result = 1 + 2 + (found_one << 2);
+ if (o->v0 != orig_o->v0) { same0 = 8; }
+ if (o->v1 != orig_o->v1) { same1 = 8; }
#ifdef WORD_SIZE_64
- if (unlikely(is_n)) {
+ if (unlikely(is_n)) {
- if (DICT_ADD_STRATEGY >= same0 + result) {
+ if (DICT_ADD_STRATEGY >= same0 + result) {
- try_to_add_to_dictN(afl, s128_v0, hshape);
+ try_to_add_to_dictN(afl, s128_v0, hshape);
- }
+ }
- if (DICT_ADD_STRATEGY >= same1 + result) {
+ if (DICT_ADD_STRATEGY >= same1 + result) {
- try_to_add_to_dictN(afl, s128_v1, hshape);
+ try_to_add_to_dictN(afl, s128_v1, hshape);
- }
+ }
- } else
+ } else
#endif
- {
+ {
- if (DICT_ADD_STRATEGY >= same0 + result) {
+ if (DICT_ADD_STRATEGY >= same0 + result) {
- try_to_add_to_dict(afl, o->v0, hshape);
+ // fprintf(stderr, "add v0 0x%llx\n", o->v0);
+ try_to_add_to_dict(afl, o->v0, hshape);
- }
+ }
- if (DICT_ADD_STRATEGY >= same1 + result) {
+ if (DICT_ADD_STRATEGY >= same1 + result) {
- try_to_add_to_dict(afl, o->v1, hshape);
+ // fprintf(stderr, "add v1 0x%llx\n", o->v1);
+ try_to_add_to_dict(afl, o->v1, hshape);
+
+ }
}
@@ -2428,18 +2435,22 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
/*
- struct cmp_header *hh = &afl->orig_cmp_map->headers[key];
- fprintf(stderr, "RTN N hits=%u id=%u shape=%u attr=%u v0=", h->hits,
- h->id, hshape, h->attribute);
- for (j = 0; j < 8; j++) fprintf(stderr, "%02x", o->v0[j]);
- fprintf(stderr, " v1=");
- for (j = 0; j < 8; j++) fprintf(stderr, "%02x", o->v1[j]);
- fprintf(stderr, "\nRTN O hits=%u id=%u shape=%u attr=%u o0=",
- hh->hits, hh->id, hshape, hh->attribute);
- for (j = 0; j < 8; j++) fprintf(stderr, "%02x", orig_o->v0[j]);
- fprintf(stderr, " o1=");
- for (j = 0; j < 8; j++) fprintf(stderr, "%02x", orig_o->v1[j]);
- fprintf(stderr, "\n");
+ struct cmp_header *hh = &afl->orig_cmp_map->headers[key];
+ fprintf(stderr, "RTN N hits=%u id=%u shape=%u attr=%u v0=", h->hits, h->id,
+ hshape, h->attribute);
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", o->v0[j]);
+ fprintf(stderr, " v1=");
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", o->v1[j]);
+ fprintf(stderr, "\nRTN O hits=%u id=%u shape=%u attr=%u o0=", hh->hits,
+ hh->id, hshape, hh->attribute);
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", orig_o->v0[j]);
+ fprintf(stderr, " o1=");
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", orig_o->v1[j]);
+ fprintf(stderr, "\n");
*/
t = taint;
@@ -2547,12 +2558,14 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
if (DICT_ADD_STRATEGY >= same0 + result) {
+ // fprintf(stderr, "add v0 [%u]\"%s\"\n", l0, o->v0);
maybe_add_auto(afl, o->v0, l0);
}
if (DICT_ADD_STRATEGY >= same1 + result) {
+ // fprintf(stderr, "add v1 [%u]\"%s\"\n", l1, o->v1);
maybe_add_auto(afl, o->v1, l1);
}
@@ -2727,11 +2740,13 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS) {
+ // fprintf(stderr, "INS %u\n", k);
afl->stage_max +=
MIN((u32)(afl->shm.cmp_map->headers[k].hits), (u32)CMP_MAP_H);
} else {
+ // fprintf(stderr, "RTN %u\n", k);
afl->stage_max +=
MIN((u32)(afl->shm.cmp_map->headers[k].hits), (u32)CMP_MAP_RTN_H);
From efda11024016c70fb00e85661e6aa42506f81557 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 17 Oct 2021 20:49:19 +0200
Subject: [PATCH 080/305] fix
---
GNUmakefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/GNUmakefile b/GNUmakefile
index 0a6f3950..f5d35c0c 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -32,7 +32,7 @@ VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f
# PROGS intentionally omit afl-as, which gets installed elsewhere.
PROGS = afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze
-SH_PROGS = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-system-config afl-persistent-config
+SH_PROGS = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-system-config afl-persistent-config afl-cc
MANPAGES=$(foreach p, $(PROGS) $(SH_PROGS), $(p).8) afl-as.8
ASAN_OPTIONS=detect_leaks=0
From fb481231b7493b7d22035598bb6d77167725f8cd Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 17 Oct 2021 21:20:00 +0200
Subject: [PATCH 081/305] update test
---
test/test-cmplog.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/test/test-cmplog.c b/test/test-cmplog.c
index b077e3ab..262df6bd 100644
--- a/test/test-cmplog.c
+++ b/test/test-cmplog.c
@@ -1,15 +1,13 @@
#include
#include
+#include
#include
#include
#include
#include
-int main(int argc, char *argv[]) {
- char buf[1024];
- ssize_t i;
- if ((i = read(0, buf, sizeof(buf) - 1)) < 24) return 0;
- buf[i] = 0;
+int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t i) {
+ if (i < 24) return 0;
if (buf[0] != 'A') return 0;
if (buf[1] != 'B') return 0;
if (buf[2] != 'C') return 0;
@@ -18,6 +16,17 @@ int main(int argc, char *argv[]) {
if (strncmp(buf + 12, "IJKL", 4) == 0 && strcmp(buf + 16, "DEADBEEF") == 0)
abort();
return 0;
-
}
+#ifdef __AFL_COMPILER
+int main(int argc, char *argv[]) {
+ unsigned char buf[1024];
+ ssize_t i;
+ while(__AFL_LOOP(1000)) {
+ i = read(0, (char*)buf, sizeof(buf) - 1);
+ if (i > 0) buf[i] = 0;
+ LLVMFuzzerTestOneInput(buf, i);
+ }
+ return 0;
+}
+#endif
From 4b4244bcf6cad5fdc897edef6ea810647a54ca9f Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 17 Oct 2021 21:47:08 +0200
Subject: [PATCH 082/305] fix
---
instrumentation/cmplog-routines-pass.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc
index 3d6467ba..50ced5d8 100644
--- a/instrumentation/cmplog-routines-pass.cc
+++ b/instrumentation/cmplog-routines-pass.cc
@@ -469,7 +469,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
std::vector args;
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
- Value * v3Pcasted = IRB.CreateZExtOrBitCast(v3P, Int32Ty);
+ Value * v3Pcasted = IRB.CreateTruncOrBitCast(v3P, Int32Ty);
args.push_back(v1Pcasted);
args.push_back(v2Pcasted);
args.push_back(v3Pcasted);
From 9c278df0385afb03a078e25e27a4763512d8831a Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 18 Oct 2021 00:21:33 +0200
Subject: [PATCH 083/305] try fix
---
instrumentation/afl-compiler-rt.o.c | 4 ++--
instrumentation/cmplog-routines-pass.cc | 19 ++++++++++++++-----
2 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 38beafb7..5caf57b3 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -1880,7 +1880,7 @@ static int area_is_valid(void *ptr, size_t len) {
}
-void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u32 len) {
+void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u64 len) {
/*
u32 i;
@@ -1941,7 +1941,7 @@ void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u32 len) {
}
-void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u32 len) {
+void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u64 len) {
/*
if (area_is_valid(ptr1, 32) <= 0 || area_is_valid(ptr2, 32) <= 0) return;
diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc
index 50ced5d8..854492b1 100644
--- a/instrumentation/cmplog-routines-pass.cc
+++ b/instrumentation/cmplog-routines-pass.cc
@@ -94,7 +94,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
Type *VoidTy = Type::getVoidTy(C);
// PointerType *VoidPtrTy = PointerType::get(VoidTy, 0);
IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
- IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
+ IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
PointerType *i8PtrTy = PointerType::get(Int8Ty, 0);
#if LLVM_VERSION_MAJOR < 9
@@ -192,7 +192,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
FunctionCallee
#endif
c5 = M.getOrInsertFunction("__cmplog_rtn_hook_n", VoidTy, i8PtrTy,
- i8PtrTy, Int32Ty
+ i8PtrTy, Int64Ty
#if LLVM_VERSION_MAJOR < 5
,
NULL
@@ -210,7 +210,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
FunctionCallee
#endif
c6 = M.getOrInsertFunction("__cmplog_rtn_hook_strn", VoidTy, i8PtrTy,
- i8PtrTy, Int32Ty
+ i8PtrTy, Int64Ty
#if LLVM_VERSION_MAJOR < 5
,
NULL
@@ -282,6 +282,15 @@ bool CmpLogRoutines::hookRtns(Module &M) {
FT->getParamType(0) == FT->getParamType(1) &&
FT->getParamType(0)->isPointerTy() &&
FT->getParamType(2)->isIntegerTy();
+ if (isPtrRtnN) {
+ auto intTyOp = dyn_cast(callInst->getArgOperand(2)->getType());
+ if (intTyOp) {
+ if (intTyOp->getBitWidth() != 32 && intTyOp->getBitWidth() != 64) {
+ isPtrRtnN = false;
+ }
+ }
+ }
+
bool isMemcmp =
(!FuncName.compare("memcmp") || !FuncName.compare("bcmp") ||
@@ -469,7 +478,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
std::vector args;
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
- Value * v3Pcasted = IRB.CreateTruncOrBitCast(v3P, Int32Ty);
+ Value * v3Pcasted = IRB.CreateTruncOrBitCast(v3P, Int64Ty);
args.push_back(v1Pcasted);
args.push_back(v2Pcasted);
args.push_back(v3Pcasted);
@@ -524,7 +533,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
std::vector args;
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
- Value * v3Pcasted = IRB.CreateTruncOrBitCast(v3P, Int32Ty);
+ Value * v3Pcasted = IRB.CreateTruncOrBitCast(v3P, Int64Ty);
args.push_back(v1Pcasted);
args.push_back(v2Pcasted);
args.push_back(v3Pcasted);
From 6403fa4f70ebb9c475a5debe027e210b171f478e Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 18 Oct 2021 00:41:16 +0200
Subject: [PATCH 084/305] fix
---
instrumentation/cmplog-routines-pass.cc | 31 ++++++++++++++++++-------
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc
index 854492b1..5dd5dc39 100644
--- a/instrumentation/cmplog-routines-pass.cc
+++ b/instrumentation/cmplog-routines-pass.cc
@@ -283,14 +283,21 @@ bool CmpLogRoutines::hookRtns(Module &M) {
FT->getParamType(0)->isPointerTy() &&
FT->getParamType(2)->isIntegerTy();
if (isPtrRtnN) {
- auto intTyOp = dyn_cast(callInst->getArgOperand(2)->getType());
- if (intTyOp) {
- if (intTyOp->getBitWidth() != 32 && intTyOp->getBitWidth() != 64) {
- isPtrRtnN = false;
- }
- }
- }
+ auto intTyOp =
+ dyn_cast(callInst->getArgOperand(2)->getType());
+ if (intTyOp) {
+
+ if (intTyOp->getBitWidth() != 32 &&
+ intTyOp->getBitWidth() != 64) {
+
+ isPtrRtnN = false;
+
+ }
+
+ }
+
+ }
bool isMemcmp =
(!FuncName.compare("memcmp") || !FuncName.compare("bcmp") ||
@@ -478,7 +485,10 @@ bool CmpLogRoutines::hookRtns(Module &M) {
std::vector args;
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
- Value * v3Pcasted = IRB.CreateTruncOrBitCast(v3P, Int64Ty);
+ Value * v3Pbitcast = IRB.CreateBitCast(
+ v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits()));
+ Value *v3Pcasted =
+ IRB.CreateIntCast(v3Pbitcast, IntegerType::get(C, 64), false);
args.push_back(v1Pcasted);
args.push_back(v2Pcasted);
args.push_back(v3Pcasted);
@@ -533,7 +543,10 @@ bool CmpLogRoutines::hookRtns(Module &M) {
std::vector args;
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
- Value * v3Pcasted = IRB.CreateTruncOrBitCast(v3P, Int64Ty);
+ Value * v3Pbitcast = IRB.CreateBitCast(
+ v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits()));
+ Value *v3Pcasted =
+ IRB.CreateIntCast(v3Pbitcast, IntegerType::get(C, 64), false);
args.push_back(v1Pcasted);
args.push_back(v2Pcasted);
args.push_back(v3Pcasted);
From 72d10fee407f32d4041573d1906a047a67277eff Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 18 Oct 2021 10:03:39 +0200
Subject: [PATCH 085/305] dict enhancement
---
src/afl-fuzz-redqueen.c | 64 +++++++++++++++++++++++++----------------
1 file changed, 39 insertions(+), 25 deletions(-)
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 65d21b0a..10bcd63d 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -1853,41 +1853,48 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
// we only learn 16 bit +
if (hshape > 1) {
- u8 same0 = 0, same1 = 0, result = 1 + 2 + (found_one << 2);
+ u8 same0 = 0, same1 = 0, same2 = 0, same3 = 0,
+ result = 1 + 2 + (found_one << 2);
if (o->v0 != orig_o->v0) { same0 = 8; }
if (o->v1 != orig_o->v1) { same1 = 8; }
+ if (o->v0 != o->v1) { same2 = 8; }
+ if (orig_o->v0 != orig_o->v1) { same3 = 8; }
+
+ if (!(same0 && same1) && !same2 && !same3) {
#ifdef WORD_SIZE_64
- if (unlikely(is_n)) {
+ if (unlikely(is_n)) {
- if (DICT_ADD_STRATEGY >= same0 + result) {
+ if (DICT_ADD_STRATEGY >= same0 + result) {
- try_to_add_to_dictN(afl, s128_v0, hshape);
+ try_to_add_to_dictN(afl, s128_v0, hshape);
- }
+ }
- if (DICT_ADD_STRATEGY >= same1 + result) {
+ if (DICT_ADD_STRATEGY >= same1 + result) {
- try_to_add_to_dictN(afl, s128_v1, hshape);
+ try_to_add_to_dictN(afl, s128_v1, hshape);
- }
+ }
- } else
+ } else
#endif
- {
+ {
- if (DICT_ADD_STRATEGY >= same0 + result) {
+ if (DICT_ADD_STRATEGY >= same0 + result) {
- // fprintf(stderr, "add v0 0x%llx\n", o->v0);
- try_to_add_to_dict(afl, o->v0, hshape);
+ // fprintf(stderr, "add v0 0x%llx\n", o->v0);
+ try_to_add_to_dict(afl, o->v0, hshape);
- }
+ }
- if (DICT_ADD_STRATEGY >= same1 + result) {
+ if (DICT_ADD_STRATEGY >= same1 + result) {
- // fprintf(stderr, "add v1 0x%llx\n", o->v1);
- try_to_add_to_dict(afl, o->v1, hshape);
+ // fprintf(stderr, "add v1 0x%llx\n", o->v1);
+ try_to_add_to_dict(afl, o->v1, hshape);
+
+ }
}
@@ -2551,22 +2558,29 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
- u8 same0 = 0, same1 = 0, result = 1 + (found_one << 2);
+ u8 same0 = 0, same1 = 0, same2 = 0, same3 = 0,
+ result = 1 + (found_one << 2);
if (!is_txt) result += 2;
if (l0 != ol0 || memcmp(o->v0, orig_o->v0, l0) != 0) { same0 = 8; }
if (l1 != ol1 || memcmp(o->v1, orig_o->v1, l1) != 0) { same1 = 8; }
+ if (l0 != l1 || memcmp(o->v0, o->v1, l0) != 0) { same2 = 8; }
+ if (ol0 != ol1 || memcmp(orig_o->v0, orig_o->v1, l0) != 0) { same3 = 8; }
- if (DICT_ADD_STRATEGY >= same0 + result) {
+ if (!(same0 && same1) && !same2 && !same3) {
- // fprintf(stderr, "add v0 [%u]\"%s\"\n", l0, o->v0);
- maybe_add_auto(afl, o->v0, l0);
+ if (DICT_ADD_STRATEGY >= same0 + result) {
- }
+ // fprintf(stderr, "add v0 [%u]\"%s\"\n", l0, o->v0);
+ maybe_add_auto(afl, o->v0, l0);
- if (DICT_ADD_STRATEGY >= same1 + result) {
+ }
- // fprintf(stderr, "add v1 [%u]\"%s\"\n", l1, o->v1);
- maybe_add_auto(afl, o->v1, l1);
+ if (DICT_ADD_STRATEGY >= same1 + result) {
+
+ // fprintf(stderr, "add v1 [%u]\"%s\"\n", l1, o->v1);
+ maybe_add_auto(afl, o->v1, l1);
+
+ }
}
From 699df8f8ce4cc5de56510f72ebff611d26710557 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 18 Oct 2021 11:11:56 +0200
Subject: [PATCH 086/305] fix
---
src/afl-fuzz-redqueen.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 10bcd63d..30bad557 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -1860,18 +1860,18 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
if (o->v0 != o->v1) { same2 = 8; }
if (orig_o->v0 != orig_o->v1) { same3 = 8; }
- if (!(same0 && same1) && !same2 && !same3) {
+ if (!same2 && !same3) {
#ifdef WORD_SIZE_64
if (unlikely(is_n)) {
- if (DICT_ADD_STRATEGY >= same0 + result) {
+ if (!(!same0 && same1) && DICT_ADD_STRATEGY >= same0 + result) {
try_to_add_to_dictN(afl, s128_v0, hshape);
}
- if (DICT_ADD_STRATEGY >= same1 + result) {
+ if (!(same0 && !same1) && DICT_ADD_STRATEGY >= same1 + result) {
try_to_add_to_dictN(afl, s128_v1, hshape);
@@ -2566,16 +2566,16 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
if (l0 != l1 || memcmp(o->v0, o->v1, l0) != 0) { same2 = 8; }
if (ol0 != ol1 || memcmp(orig_o->v0, orig_o->v1, l0) != 0) { same3 = 8; }
- if (!(same0 && same1) && !same2 && !same3) {
+ if (!same2 && !same3) {
- if (DICT_ADD_STRATEGY >= same0 + result) {
+ if (!(same0 && !same1) && DICT_ADD_STRATEGY >= same0 + result) {
// fprintf(stderr, "add v0 [%u]\"%s\"\n", l0, o->v0);
maybe_add_auto(afl, o->v0, l0);
}
- if (DICT_ADD_STRATEGY >= same1 + result) {
+ if (!(!same0 && same1) && DICT_ADD_STRATEGY >= same1 + result) {
// fprintf(stderr, "add v1 [%u]\"%s\"\n", l1, o->v1);
maybe_add_auto(afl, o->v1, l1);
From 7cd98f565ffdf3e0c0ccd34c04ed2f3126ab4189 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 18 Oct 2021 12:16:58 +0200
Subject: [PATCH 087/305] lto and llvm14-dev
---
docs/Changelog.md | 2 +-
instrumentation/SanitizerCoveragePCGUARD.so.cc | 2 --
instrumentation/afl-llvm-lto-instrumentation.so.cc | 4 ++++
instrumentation/afl-llvm-lto-instrumentlist.so.cc | 5 +++++
4 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index d8dac557..6db013cf 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -24,7 +24,7 @@ sending a mail to .
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
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 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-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc
index 73e41f60..4eb8424f 100644
--- a/instrumentation/afl-llvm-lto-instrumentation.so.cc
+++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc
@@ -244,7 +244,11 @@ 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,
diff --git a/instrumentation/afl-llvm-lto-instrumentlist.so.cc b/instrumentation/afl-llvm-lto-instrumentlist.so.cc
index 416dbb88..0ec0e427 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();
+#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
}
From 45d668a671316821c3f9793381cb54956b535491 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 18 Oct 2021 13:17:07 +0200
Subject: [PATCH 088/305] better ui banner
---
docs/Changelog.md | 1 +
include/afl-fuzz.h | 1 -
src/afl-fuzz-init.c | 37 ---------------------------------
src/afl-fuzz-stats.c | 49 ++++++++++++++++++++++++++------------------
src/afl-fuzz.c | 17 +++++++++++----
5 files changed, 43 insertions(+), 62 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 6db013cf..63896622 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -17,6 +17,7 @@ sending a mail to .
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!
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/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 9bb25785..9c45f08a 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-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) {
- SAYF("\n%s\n", tmp);
+ 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", 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; }
From fd43daee6a2146e95059b7ea670c6bf24b3704ed Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 18 Oct 2021 17:21:26 +0200
Subject: [PATCH 089/305] md url
---
utils/socket_fuzzing/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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
From bb8a4d71da8f2b748a78ccc4416df6bffb393d80 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 18 Oct 2021 20:53:54 +0200
Subject: [PATCH 090/305] format and remove warning
---
instrumentation/SanitizerCoverageLTO.so.cc | 8 ++++----
instrumentation/afl-llvm-dict2file.so.cc | 7 ++++---
instrumentation/afl-llvm-lto-instrumentation.so.cc | 11 +++++++----
instrumentation/afl-llvm-lto-instrumentlist.so.cc | 2 +-
instrumentation/split-compares-pass.so.cc | 10 +++++-----
5 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index 960eb783..d90fa867 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -447,8 +447,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) {
dFile.open(ptr, std::ofstream::out | std::ofstream::app);
- if (dFile.is_open())
- WARNF("Cannot access document file %s", ptr);
+ if (dFile.is_open()) WARNF("Cannot access document file %s", ptr);
}
@@ -1084,7 +1083,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
if (count) {
- auto ptrhld = std::unique_ptr(new char[memlen + count]);
+ auto ptrhld = std::unique_ptr(new char[memlen + count]);
count = 0;
@@ -1502,7 +1501,8 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
unsigned long long int moduleID =
(((unsigned long long int)(rand() & 0xffffffff)) << 32) | getpid();
- dFile << "ModuleID=" << moduleID << " Function=" << F.getName().str() << " edgeID=" << afl_global_id << "\n";
+ dFile << "ModuleID=" << moduleID << " Function=" << F.getName().str()
+ << " edgeID=" << afl_global_id << "\n";
}
diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc
index c4ad1783..0a3e74b9 100644
--- a/instrumentation/afl-llvm-dict2file.so.cc
+++ b/instrumentation/afl-llvm-dict2file.so.cc
@@ -65,8 +65,10 @@ using namespace llvm;
namespace {
class AFLdict2filePass : public ModulePass {
+
std::ofstream of;
- void dict2file(u8 *, u32);
+ void dict2file(u8 *, u32);
+
public:
static char ID;
@@ -147,8 +149,7 @@ bool AFLdict2filePass::runOnModule(Module &M) {
FATAL("AFL_LLVM_DICT2FILE is not set to an absolute path: %s", ptr);
of.open(ptr, std::ofstream::out | std::ofstream::app);
- if (!of.is_open())
- PFATAL("Could not open/create %s.", ptr);
+ if (!of.is_open()) PFATAL("Could not open/create %s.", ptr);
/* Instrument all the things! */
diff --git a/instrumentation/afl-llvm-lto-instrumentation.so.cc b/instrumentation/afl-llvm-lto-instrumentation.so.cc
index 4eb8424f..c2f61d34 100644
--- a/instrumentation/afl-llvm-lto-instrumentation.so.cc
+++ b/instrumentation/afl-llvm-lto-instrumentation.so.cc
@@ -138,8 +138,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) {
dFile.open(ptr, std::ofstream::out | std::ofstream::app);
- if (!dFile.is_open())
- WARNF("Cannot access document file %s", ptr);
+ if (!dFile.is_open()) WARNF("Cannot access document file %s", ptr);
}
@@ -246,8 +245,10 @@ bool AFLLTOPass::runOnModule(Module &M) {
AttributeList Attrs = F.getAttributes();
#if LLVM_VERSION_MAJOR < 14
if (Attrs.hasAttribute(-1, StringRef("skipinstrument"))) {
+
#else
if (Attrs.hasFnAttr(StringRef("skipinstrument"))) {
+
#endif
if (debug)
@@ -852,7 +853,9 @@ bool AFLLTOPass::runOnModule(Module &M) {
if (dFile.is_open()) {
- dFile << "ModuleID=" << moduleID << " Function=" << F.getName().str() << " edgeID=" << afl_global_id << "\n";
+ dFile << "ModuleID=" << moduleID
+ << " Function=" << F.getName().str()
+ << " edgeID=" << afl_global_id << "\n";
}
@@ -1019,7 +1022,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
if (count) {
- auto ptrhld = std::unique_ptr(new char[memlen + count]);
+ auto ptrhld = std::unique_ptr(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 0ec0e427..ee2e5dd3 100644
--- a/instrumentation/afl-llvm-lto-instrumentlist.so.cc
+++ b/instrumentation/afl-llvm-lto-instrumentlist.so.cc
@@ -117,7 +117,7 @@ bool AFLcheckIfInstrument::runOnModule(Module &M) {
auto & Ctx = F.getContext();
AttributeList Attrs = F.getAttributes();
#if LLVM_VERSION_MAJOR < 14
- AttrBuilder NewAttrs;
+ AttrBuilder NewAttrs;
NewAttrs.addAttribute("skipinstrument");
F.setAttributes(
Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
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);
}
From 77a63d8ccfd4b409c35227e174f1d6e809256e41 Mon Sep 17 00:00:00 2001
From: Andrea Fioraldi
Date: Tue, 19 Oct 2021 13:59:31 +0200
Subject: [PATCH 091/305] execs field in filenames
---
src/afl-fuzz-bitmap.c | 5 +++--
src/afl-fuzz-init.c | 4 ++--
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 0ae4d607..316067e4 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -317,8 +317,9 @@ u8 *describe_op(afl_state_t *afl, u8 new_bits, size_t max_description_len) {
}
- sprintf(ret + strlen(ret), ",time:%llu",
- get_cur_time() + afl->prev_run_time - afl->start_time);
+ sprintf(ret + strlen(ret), ",time:%llu,execs:%llu",
+ get_cur_time() + afl->prev_run_time - afl->start_time,
+ afl->fsrv.total_execs);
if (afl->current_custom_fuzz &&
afl->current_custom_fuzz->afl_custom_describe) {
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 9bb25785..0fa8e6ec 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -1325,8 +1325,8 @@ void pivot_inputs(afl_state_t *afl) {
}
- nfn = alloc_printf("%s/queue/id:%06u,time:0,orig:%s", afl->out_dir, id,
- use_name);
+ nfn = alloc_printf("%s/queue/id:%06u,time:0,execs:%llu,orig:%s", afl->out_dir, id,
+ afl->fsrv.total_execs, use_name);
#else
From 0bc3367b55b2f08c7c2588576af27567044dc0b6 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 19 Oct 2021 14:46:15 +0200
Subject: [PATCH 092/305] remove race condition
---
src/afl-forkserver.c | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 54f510c4..94ca3009 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -610,12 +610,24 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if (!time_ms) {
- if (fsrv->fsrv_pid > 0) { kill(fsrv->fsrv_pid, fsrv->kill_signal); }
+ s32 tmp_pid = fsrv->fsrv_pid;
+ if (tmp_pid > 0) {
+
+ kill(tmp_pid, fsrv->kill_signal);
+ fsrv->fsrv_pid = 1;
+
+ }
} else if (time_ms > fsrv->init_tmout) {
fsrv->last_run_timed_out = 1;
- if (fsrv->fsrv_pid > 0) { kill(fsrv->fsrv_pid, fsrv->kill_signal); }
+ s32 tmp_pid = fsrv->fsrv_pid;
+ if (tmp_pid > 0) {
+
+ kill(tmp_pid, fsrv->kill_signal);
+ fsrv->fsrv_pid = 1;
+
+ }
} else {
@@ -1248,7 +1260,14 @@ 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 */
- if (fsrv->child_pid > 0) { kill(fsrv->child_pid, fsrv->kill_signal); }
+ s32 tmp_pid = srv->child_pid;
+ if (tmp_pid > 0) {
+
+ kill(tmp_pid, fsrv->kill_signal);
+ fsrv->child_pid = -1
+
+ }
+
fsrv->last_run_timed_out = 1;
if (read(fsrv->fsrv_st_fd, &fsrv->child_status, 4) < 4) { exec_ms = 0; }
From 90786e2ce9970c52e661c0fe290cb78a1a063004 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 19 Oct 2021 15:20:59 +0200
Subject: [PATCH 093/305] fix
---
src/afl-forkserver.c | 4 ++--
test/test-pre.sh | 2 ++
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 94ca3009..71667262 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -1260,11 +1260,11 @@ 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 */
- s32 tmp_pid = srv->child_pid;
+ s32 tmp_pid = fsrv->child_pid;
if (tmp_pid > 0) {
kill(tmp_pid, fsrv->kill_signal);
- fsrv->child_pid = -1
+ fsrv->child_pid = -1;
}
diff --git a/test/test-pre.sh b/test/test-pre.sh
index 7819da47..e12d95be 100755
--- a/test/test-pre.sh
+++ b/test/test-pre.sh
@@ -88,6 +88,8 @@ unset AFL_QEMU_PERSISTENT_GPR
unset AFL_QEMU_PERSISTENT_RET
unset AFL_QEMU_PERSISTENT_HOOK
unset AFL_QEMU_PERSISTENT_CNT
+unset AFL_QEMU_PERSISTENT_MEM
+unset AFL_QEMU_PERSISTENT_EXITS
unset AFL_CUSTOM_MUTATOR_LIBRARY
unset AFL_PYTHON_MODULE
unset AFL_PRELOAD
From 47a333af4d7c64209570e7459b1bd5259c207dc9 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 19 Oct 2021 15:42:26 +0200
Subject: [PATCH 094/305] add ninja to apt install readme
---
docs/INSTALL.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index b60a7048..960de1af 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -22,6 +22,7 @@ sudo apt-get install -y build-essential python3-dev automake git flex bison libg
# try to install llvm 11 and install the distro default if that fails
sudo apt-get install -y lld-11 llvm-11 llvm-11-dev clang-11 || sudo apt-get install -y lld llvm llvm-dev clang
sudo apt-get install -y gcc-$(gcc --version|head -n1|sed 's/.* //'|sed 's/\..*//')-plugin-dev libstdc++-$(gcc --version|head -n1|sed 's/.* //'|sed 's/\..*//')-dev
+sudo apt-get install -y ninja-build # for qemu_mode
git clone https://github.com/AFLplusplus/AFLplusplus
cd AFLplusplus
make distrib
From 4e3fec2666c3d317db275f4af8875b56009621e1 Mon Sep 17 00:00:00 2001
From: Stefan Nagy
Date: Wed, 20 Oct 2021 17:09:18 -0400
Subject: [PATCH 095/305] Update binaryonly_fuzzing.md with zafl
---
docs/binaryonly_fuzzing.md | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/docs/binaryonly_fuzzing.md b/docs/binaryonly_fuzzing.md
index 90ea3b66..903afb70 100644
--- a/docs/binaryonly_fuzzing.md
+++ b/docs/binaryonly_fuzzing.md
@@ -95,13 +95,28 @@
utils/afl_untracer/, use afl-untracer.c as a template.
It is slower than AFL FRIDA (see above).
+## ZAFL
+ ZAFL is a static rewriting platform for fast, space-efficient, and inlined
+ binary fuzzing instrumentation. It currently supports x86-64 C and C++,
+ stripped and unstripped, and PIE and non-PIE binaries of all sizes and complexity.
+
+ Beyond conventional instrumentation, ZAFL's API enables transformation passes
+ for more effective/efficient fuzzing. Some built-in transformations include
+ laf-Intel-style constraint unrolling, Angora-style context sensitivity, and
+ InsTrim-style CFG optimizations.
+
+ ZAFL's baseline instrumentation speed averages about 90-95% that of afl-clang-fast's
+ conventional LLVM instrumentation (but is even faster when enabling CFG optimizations).
+
+ [https://git.zephyr-software.com/opensrc/zafl](https://git.zephyr-software.com/opensrc/zafl)
+
## DYNINST
Dyninst is a binary instrumentation framework similar to Pintool and
Dynamorio (see far below). However whereas Pintool and Dynamorio work at
runtime, dyninst instruments the target at load time, and then let it run -
- or save the binary with the changes.
+ or save the binary with the changes.
This is great for some things, e.g. fuzzing, and not so effective for others,
e.g. malware analysis.
@@ -116,13 +131,10 @@
The speed decrease is about 15-35%, depending on the optimization options
used with afl-dyninst.
- So if Dyninst works, it is the best option available. Otherwise it just
- doesn't work well.
-
[https://github.com/vanhauser-thc/afl-dyninst](https://github.com/vanhauser-thc/afl-dyninst)
-## RETROWRITE, ZAFL, ... other binary rewriter
+## RETROWRITE
If you have an x86/x86_64 binary that still has its symbols, is compiled
with position independant code (PIC/PIE) and does not use most of the C++
@@ -131,7 +143,6 @@
It is at about 80-85% performance.
- [https://git.zephyr-software.com/opensrc/zafl](https://git.zephyr-software.com/opensrc/zafl)
[https://github.com/HexHive/retrowrite](https://github.com/HexHive/retrowrite)
From e637ca216e4559960feec6b7f887571efde4f0ba Mon Sep 17 00:00:00 2001
From: Stefan Nagy
Date: Thu, 21 Oct 2021 04:52:38 -0400
Subject: [PATCH 096/305] Tidy-up zafl info
---
docs/binaryonly_fuzzing.md | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/docs/binaryonly_fuzzing.md b/docs/binaryonly_fuzzing.md
index 903afb70..de360543 100644
--- a/docs/binaryonly_fuzzing.md
+++ b/docs/binaryonly_fuzzing.md
@@ -95,18 +95,13 @@
utils/afl_untracer/, use afl-untracer.c as a template.
It is slower than AFL FRIDA (see above).
+
## ZAFL
- ZAFL is a static rewriting platform for fast, space-efficient, and inlined
- binary fuzzing instrumentation. It currently supports x86-64 C and C++,
- stripped and unstripped, and PIE and non-PIE binaries of all sizes and complexity.
-
- Beyond conventional instrumentation, ZAFL's API enables transformation passes
- for more effective/efficient fuzzing. Some built-in transformations include
- laf-Intel-style constraint unrolling, Angora-style context sensitivity, and
- InsTrim-style CFG optimizations.
-
- ZAFL's baseline instrumentation speed averages about 90-95% that of afl-clang-fast's
- conventional LLVM instrumentation (but is even faster when enabling CFG optimizations).
+ ZAFL is a static rewriting platform supporting x86-64 C/C++, stripped/unstripped,
+ and PIE/non-PIE binaries. Beyond conventional instrumentation, ZAFL's API enables
+ transformation passes (e.g., laf-Intel, context sensitivity, InsTrim, etc.).
+
+ Its baseline instrumentation speed typically averages 90-95% of afl-clang-fast's.
[https://git.zephyr-software.com/opensrc/zafl](https://git.zephyr-software.com/opensrc/zafl)
From e03897a0703673aa0de7772185a5b5230641cb6a Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sat, 23 Oct 2021 20:54:24 +0200
Subject: [PATCH 097/305] fix timeout bug in afl tools
---
docs/Changelog.md | 6 ++++--
src/afl-analyze.c | 12 ++++++++++++
src/afl-fuzz-init.c | 4 ++--
src/afl-showmap.c | 13 +++++++++++++
src/afl-tmin.c | 12 ++++++++++++
5 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 63896622..04b2fb2e 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -19,8 +19,10 @@ sending a mail to .
- 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!
+ - afl-showmap, afl-tmin and afl-analyze:
+ - honor persistent mode for more speed. thanks to dloffre-snl for
+ reporting!
+ - fix bug where targets are not killed on timeouts
- Prevent accidently killing non-afl/fuzz services when aborting
afl-showmap and other tools.
- afl-cc:
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index 8295488d..09b01541 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -120,6 +120,17 @@ static u8 count_class_lookup[256] = {
#undef TIMES8
#undef TIMES4
+static void kill_child() {
+
+ if (fsrv.child_pid > 0) {
+
+ kill(fsrv.child_pid, fsrv.kill_signal);
+ fsrv.child_pid = -1;
+
+ }
+
+}
+
static void classify_counts(u8 *mem) {
u32 i = map_size;
@@ -1053,6 +1064,7 @@ int main(int argc, char **argv_orig, char **envp) {
fsrv.target_path = find_binary(argv[optind]);
fsrv.trace_bits = afl_shm_init(&shm, map_size, 0);
detect_file_args(argv + optind, fsrv.out_file, &use_stdin);
+ signal(SIGALRM, kill_child);
if (qemu_mode) {
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index f0e1a80d..1170715f 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -1325,8 +1325,8 @@ void pivot_inputs(afl_state_t *afl) {
}
- nfn = alloc_printf("%s/queue/id:%06u,time:0,execs:%llu,orig:%s", afl->out_dir, id,
- afl->fsrv.total_execs, use_name);
+ nfn = alloc_printf("%s/queue/id:%06u,time:0,execs:%llu,orig:%s",
+ afl->out_dir, id, afl->fsrv.total_execs, use_name);
#else
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 5df07bf2..3a244c04 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -146,6 +146,17 @@ static const u8 count_class_binary[256] = {
#undef TIMES8
#undef TIMES4
+static void kill_child() {
+
+ if (fsrv->child_pid > 0) {
+
+ kill(fsrv->child_pid, fsrv->kill_signal);
+ fsrv->child_pid = -1;
+
+ }
+
+}
+
static void classify_counts(afl_forkserver_t *fsrv) {
u8 * mem = fsrv->trace_bits;
@@ -526,6 +537,8 @@ static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) {
}
+ signal(SIGALRM, kill_child);
+
setitimer(ITIMER_REAL, &it, NULL);
if (waitpid(fsrv->child_pid, &status, 0) <= 0) { FATAL("waitpid() failed"); }
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 4f3a6b80..ce2a0b8f 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -120,6 +120,17 @@ static const u8 count_class_lookup[256] = {
#undef TIMES8
#undef TIMES4
+static void kill_child() {
+
+ if (fsrv->child_pid > 0) {
+
+ kill(fsrv->child_pid, fsrv->kill_signal);
+ fsrv->child_pid = -1;
+
+ }
+
+}
+
static sharedmem_t *deinit_shmem(afl_forkserver_t *fsrv,
sharedmem_t * shm_fuzz) {
@@ -1125,6 +1136,7 @@ int main(int argc, char **argv_orig, char **envp) {
fsrv->target_path = find_binary(argv[optind]);
fsrv->trace_bits = afl_shm_init(&shm, map_size, 0);
detect_file_args(argv + optind, out_file, &fsrv->use_stdin);
+ signal(SIGALRM, kill_child);
if (fsrv->qemu_mode) {
From f68b9f5110f75068b65be35bd73d458f048f3fa1 Mon Sep 17 00:00:00 2001
From: David CARLIER
Date: Sat, 23 Oct 2021 20:09:36 +0100
Subject: [PATCH 098/305] frida mode display command line on mac
---
frida_mode/src/main.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c
index c0de9c6b..c8183d8f 100644
--- a/frida_mode/src/main.c
+++ b/frida_mode/src/main.c
@@ -6,6 +6,7 @@
#ifdef __APPLE__
#include
#include
+ #include
#else
#include
#include
@@ -90,6 +91,7 @@ static void embedded_init(void) {
static void afl_print_cmdline(void) {
+#if defined(__linux__)
char * buffer = g_malloc0(PROC_MAX);
gchar *fname = g_strdup_printf("/proc/%d/cmdline", getppid());
int fd = open(fname, O_RDONLY);
@@ -123,6 +125,17 @@ static void afl_print_cmdline(void) {
close(fd);
g_free(fname);
g_free(buffer);
+#elif defined(__APPLE__)
+ int idx;
+ char **argv = *_NSGetArgv();
+ int nargv = *_NSGetArgc();
+
+ for (idx = 0; idx < nargv; idx ++) {
+
+ OKF("AFL - COMMANDLINE: argv[%d] = %s", idx, argv[idx]);
+
+ }
+#endif
}
From b12864b0beb04a3cc75f341ec96050644a252ce0 Mon Sep 17 00:00:00 2001
From: Dominik Maier
Date: Sat, 23 Oct 2021 22:20:40 +0200
Subject: [PATCH 099/305] updated unicorn bindings
---
unicorn_mode/UNICORNAFL_VERSION | 2 +-
unicorn_mode/unicornafl | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index cc8d5b34..e03b60c7 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-d4915053d477dd827b3fe4b494173d3fbf9f456e
+c347275f5c720aa7cba40fdd6b3b095f65901b76
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index d4915053..c347275f 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit d4915053d477dd827b3fe4b494173d3fbf9f456e
+Subproject commit c347275f5c720aa7cba40fdd6b3b095f65901b76
From 4dfb7bfe4f0055683d8c0c31ac823537bb5367c8 Mon Sep 17 00:00:00 2001
From: Dominik Maier
Date: Sat, 23 Oct 2021 23:11:33 +0200
Subject: [PATCH 100/305] updated uc dependencies
---
unicorn_mode/UNICORNAFL_VERSION | 2 +-
unicorn_mode/unicornafl | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index e03b60c7..d6acbf91 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-c347275f5c720aa7cba40fdd6b3b095f65901b76
+94617f5b
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index c347275f..94617f5b 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit c347275f5c720aa7cba40fdd6b3b095f65901b76
+Subproject commit 94617f5bee0c08a5cbd1a1aa73f59cd973dfb17f
From a7ee11a1747347847b06a4226f2800dd780f7c16 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 24 Oct 2021 19:35:58 +0200
Subject: [PATCH 101/305] fix
---
src/afl-forkserver.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 71667262..c570a2bb 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -603,7 +603,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
/* Wait for the fork server to come up, but don't wait too long. */
rlen = 0;
- if (fsrv->exec_tmout) {
+ if (fsrv->init_tmout) {
u32 time_ms = read_s32_timed(fsrv->fsrv_st_fd, &status, fsrv->init_tmout,
stop_soon_p);
@@ -614,7 +614,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if (tmp_pid > 0) {
kill(tmp_pid, fsrv->kill_signal);
- fsrv->fsrv_pid = 1;
+ fsrv->fsrv_pid = -1;
}
@@ -625,7 +625,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if (tmp_pid > 0) {
kill(tmp_pid, fsrv->kill_signal);
- fsrv->fsrv_pid = 1;
+ fsrv->fsrv_pid = -1;
}
@@ -1301,7 +1301,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
}
- if (!WIFSTOPPED(fsrv->child_status)) { fsrv->child_pid = 0; }
+ if (!WIFSTOPPED(fsrv->child_status)) { fsrv->child_pid = -1 ; }
fsrv->total_execs++;
From 0f49463edec0c019bd098659fa74c58a2d28c439 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 24 Oct 2021 19:41:06 +0200
Subject: [PATCH 102/305] fix
---
src/afl-forkserver.c | 2 +-
src/afl-showmap.c | 9 ++++++---
unicorn_mode/unicornafl | 2 +-
3 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index c570a2bb..80b295e0 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -1301,7 +1301,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
}
- if (!WIFSTOPPED(fsrv->child_status)) { fsrv->child_pid = -1 ; }
+ if (!WIFSTOPPED(fsrv->child_status)) { fsrv->child_pid = -1; }
fsrv->total_execs++;
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 3a244c04..3826e385 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -77,7 +77,7 @@ static u32 tcnt, highest; /* tuple content information */
static u32 in_len; /* Input data length */
-static u32 map_size = MAP_SIZE;
+static u32 map_size = MAP_SIZE, timed_out = 0;
static bool quiet_mode, /* Hide non-essential messages? */
edges_only, /* Ignore hit counts? */
@@ -148,6 +148,7 @@ static const u8 count_class_binary[256] = {
static void kill_child() {
+ timed_out = 1;
if (fsrv->child_pid > 0) {
kill(fsrv->child_pid, fsrv->kill_signal);
@@ -373,9 +374,10 @@ static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, u8 *mem,
if (!quiet_mode) {
- if (fsrv->last_run_timed_out) {
+ if (timed_out || fsrv->last_run_timed_out) {
SAYF(cLRD "\n+++ Program timed off +++\n" cRST);
+ timed_out = 0;
} else if (stop_soon) {
@@ -581,9 +583,10 @@ static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) {
if (!quiet_mode) {
- if (fsrv->last_run_timed_out) {
+ if (timed_out || fsrv->last_run_timed_out) {
SAYF(cLRD "\n+++ Program timed off +++\n" cRST);
+ timed_out = 0;
} else if (stop_soon) {
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index 94617f5b..d4915053 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit 94617f5bee0c08a5cbd1a1aa73f59cd973dfb17f
+Subproject commit d4915053d477dd827b3fe4b494173d3fbf9f456e
From 0348ede4bc47264473efdac86415b9c805bdda40 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 24 Oct 2021 19:53:07 +0200
Subject: [PATCH 103/305] fix gcc warning
---
src/afl-cc.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/afl-cc.c b/src/afl-cc.c
index e49addc4..77407a98 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -1007,7 +1007,11 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
// prevent unnecessary build errors
- cc_params[cc_par_cnt++] = "-Wno-unused-command-line-argument";
+ if (compiler_mode != GCC_PLUGIN && compiler_mode != GCC) {
+
+ cc_params[cc_par_cnt++] = "-Wno-unused-command-line-argument";
+
+ }
if (preprocessor_only || have_c) {
From 85ca0df98988cdb235e1d0cb9b156affc5afc80e Mon Sep 17 00:00:00 2001
From: David Carlier
Date: Mon, 25 Oct 2021 06:53:45 +0100
Subject: [PATCH 104/305] frida mode musl build fix
---
frida_mode/GNUmakefile | 3 +++
frida_mode/src/seccomp/seccomp_callback.c | 4 ++++
2 files changed, 7 insertions(+)
diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile
index ed35c9f6..b5fee7a6 100644
--- a/frida_mode/GNUmakefile
+++ b/frida_mode/GNUmakefile
@@ -78,6 +78,9 @@ endif
ifeq "$(shell uname)" "Linux"
OS:=linux
+ ifneq "$(findstring musl, $(shell ldd --version 2>&1 | head -n 1))" ""
+ CFLAGS+= -D__MUSL__
+ endif
endif
ifneq "$(findstring android, $(shell $(CC) --version 2>/dev/null))" ""
diff --git a/frida_mode/src/seccomp/seccomp_callback.c b/frida_mode/src/seccomp/seccomp_callback.c
index a88196ac..bc488489 100644
--- a/frida_mode/src/seccomp/seccomp_callback.c
+++ b/frida_mode/src/seccomp/seccomp_callback.c
@@ -1,6 +1,8 @@
#if defined(__linux__) && !defined(__ANDROID__)
+#if !defined(__MUSL__)
#include
+#endif
#include
#include "seccomp.h"
@@ -29,6 +31,7 @@ static void seccomp_callback_filter(struct seccomp_notif * req,
req->data.args[0], req->data.args[1], req->data.args[2],
req->data.args[3], req->data.args[4], req->data.args[5]);
+#if !defined(__MUSL__)
seccomp_print("FRAMES: (%u)\n", frames->len);
char **syms = backtrace_symbols(frames->items, frames->len);
if (syms == NULL) { FATAL("Failed to get symbols"); }
@@ -49,6 +52,7 @@ static void seccomp_callback_filter(struct seccomp_notif * req,
}
free(syms);
+#endif
resp->error = 0;
resp->val = 0;
From 7407e2fb11675261173c625c3010ce9571a7d6f6 Mon Sep 17 00:00:00 2001
From: David Carlier
Date: Mon, 25 Oct 2021 09:37:51 +0100
Subject: [PATCH 105/305] frida mode musl further changes display stack trace
---
frida_mode/src/seccomp/seccomp_callback.c | 16 ++++++++++++++++
frida_mode/src/seccomp/seccomp_filter.c | 2 ++
2 files changed, 18 insertions(+)
diff --git a/frida_mode/src/seccomp/seccomp_callback.c b/frida_mode/src/seccomp/seccomp_callback.c
index bc488489..4232d842 100644
--- a/frida_mode/src/seccomp/seccomp_callback.c
+++ b/frida_mode/src/seccomp/seccomp_callback.c
@@ -52,6 +52,22 @@ static void seccomp_callback_filter(struct seccomp_notif * req,
}
free(syms);
+#else
+ void **syms = (void **)__builtin_frame_address(0);
+ void *framep = __builtin_frame_address(1);
+ int i = 0;
+
+ syms = framep;
+ while (syms) {
+
+ framep = *syms;
+ syms = framep;
+
+ if (!syms) break;
+
+ seccomp_print("\%3d. %s\n", i ++, (char *)framep);
+
+ }
#endif
resp->error = 0;
diff --git a/frida_mode/src/seccomp/seccomp_filter.c b/frida_mode/src/seccomp/seccomp_filter.c
index 8d56c367..7ee5ead1 100644
--- a/frida_mode/src/seccomp/seccomp_filter.c
+++ b/frida_mode/src/seccomp/seccomp_filter.c
@@ -2,7 +2,9 @@
#include
#include
+#if !defined(__MUSL__)
#include
+#endif
#include
#include
#include
From efec2b5a99d8f229eec4123e28c79a15389fe6bb Mon Sep 17 00:00:00 2001
From: lazymio
Date: Mon, 25 Oct 2021 16:05:58 +0200
Subject: [PATCH 106/305] Update real_map_size when doing a realloc
---
src/afl-fuzz.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 26886a4f..34f3377b 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1706,7 +1706,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->non_instrumented_mode || afl->fsrv.qemu_mode ||
afl->fsrv.frida_mode || afl->unicorn_mode) {
- map_size = afl->fsrv.map_size = MAP_SIZE;
+ map_size = afl->fsrv.real_map_size = afl->fsrv.map_size = MAP_SIZE;
afl->virgin_bits = ck_realloc(afl->virgin_bits, map_size);
afl->virgin_tmout = ck_realloc(afl->virgin_tmout, map_size);
afl->virgin_crash = ck_realloc(afl->virgin_crash, map_size);
From b4e328803c4e61c81fdf0e0412f013fcf0e72e0d Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 26 Oct 2021 18:10:57 +0200
Subject: [PATCH 107/305] variants
---
include/cmplog.h | 2 +-
src/afl-fuzz-redqueen.c | 93 ++++++++++++++++++++++++++++++-----------
2 files changed, 70 insertions(+), 25 deletions(-)
diff --git a/include/cmplog.h b/include/cmplog.h
index 88aa0a61..b95a8e43 100644
--- a/include/cmplog.h
+++ b/include/cmplog.h
@@ -33,7 +33,7 @@
#define CMPLOG_LVL_MAX 3
#define CMP_MAP_W 65536
-#define CMP_MAP_H 64
+#define CMP_MAP_H 32
#define CMP_MAP_RTN_H (CMP_MAP_H / 4)
#define SHAPE_BYTES(x) (x + 1)
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 30bad557..6002703e 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -28,6 +28,8 @@
#include "afl-fuzz.h"
#include "cmplog.h"
+#define VARIANT 0
+
//#define _DEBUG
//#define CMPLOG_INTROSPECTION
@@ -461,10 +463,10 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len,
fprintf(
f,
"Colorization: fname=%s len=%u ms=%llu result=%u execs=%u found=%llu "
- "taint=%u\n",
+ "taint=%u ascii=%u auto_extra_before=%u\n",
afl->queue_cur->fname, len, get_cur_time() - start_time,
afl->queue_cur->colorized, afl->stage_cur, new_hit_cnt - orig_hit_cnt,
- positions);
+ positions, afl->queue_cur->is_ascii ? 1 : 0, afl->a_extras_cnt);
#ifndef _DEBUG
if (afl->not_on_tty) { fclose(f); }
@@ -1854,24 +1856,34 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
if (hshape > 1) {
u8 same0 = 0, same1 = 0, same2 = 0, same3 = 0,
- result = 1 + 2 + (found_one << 2);
+ result = 1 + (found_one << 2);
if (o->v0 != orig_o->v0) { same0 = 8; }
if (o->v1 != orig_o->v1) { same1 = 8; }
if (o->v0 != o->v1) { same2 = 8; }
if (orig_o->v0 != orig_o->v1) { same3 = 8; }
+ if (check_if_text_buf((u8 *)o->v0, hshape) < hshape) same0 += 2;
+ if (check_if_text_buf((u8 *)o->v1, hshape) < hshape) same1 += 2;
if (!same2 && !same3) {
#ifdef WORD_SIZE_64
if (unlikely(is_n)) {
- if (!(!same0 && same1) && DICT_ADD_STRATEGY >= same0 + result) {
+ if (
+ #if VARIANT == 1
+ !(!same0 && same1) &&
+ #endif
+ DICT_ADD_STRATEGY >= same0 + result) {
try_to_add_to_dictN(afl, s128_v0, hshape);
}
- if (!(same0 && !same1) && DICT_ADD_STRATEGY >= same1 + result) {
+ if (
+ #if VARIANT == 1
+ !(same0 && !same1) &&
+ #endif
+ DICT_ADD_STRATEGY >= same1 + result) {
try_to_add_to_dictN(afl, s128_v1, hshape);
@@ -1882,14 +1894,22 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
#endif
{
- if (DICT_ADD_STRATEGY >= same0 + result) {
+ if (
+#if VARIANT == 1
+ !(!same0 && same1) &&
+#endif
+ DICT_ADD_STRATEGY >= same0 + result) {
// fprintf(stderr, "add v0 0x%llx\n", o->v0);
try_to_add_to_dict(afl, o->v0, hshape);
}
- if (DICT_ADD_STRATEGY >= same1 + result) {
+ if (
+#if VARIANT == 1
+ !(same0 && !same1) &&
+#endif
+ DICT_ADD_STRATEGY >= same1 + result) {
// fprintf(stderr, "add v1 0x%llx\n", o->v1);
try_to_add_to_dict(afl, o->v1, hshape);
@@ -1966,14 +1986,17 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- if (l0 >= 0x80) {
+ if (l0 >= 0x80 || ol0 >= 0x80) {
l0 -= 0x80;
l1 -= 0x80;
ol0 -= 0x80;
ol1 -= 0x80;
- } else if (l0 == 0 || l1 == 0 || ol0 == 0 || ol1 == 0) {
+ }
+
+ if (l0 == 0 || l1 == 0 || ol0 == 0 || ol1 == 0 || l0 > 31 || l1 > 31 ||
+ ol0 > 31 || ol1 > 31) {
l0 = l1 = ol0 = ol1 = hshape;
@@ -2059,10 +2082,10 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- //#ifdef CMPLOG_SOLVE_TRANSFORM
-
if (*status == 1) return 0;
+ // transform solving
+
if (afl->cmplog_enable_transform && (lvl & LVL3)) {
u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, fromhex = 0;
@@ -2548,7 +2571,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
u8 is_txt = 0, l0 = o->v0_len, ol0 = orig_o->v0_len, l1 = o->v1_len,
ol1 = orig_o->v1_len;
- if (l0 >= 0x80) {
+ if (l0 >= 0x80 || ol0 >= 0x80) {
is_txt = 1;
l0 -= 0x80;
@@ -2558,29 +2581,51 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
+ if (l0 == 0 || l1 == 0 || ol0 == 0 || ol1 == 0 || l0 > 31 || l1 > 31 ||
+ ol0 > 31 || ol1 > 31) {
+
+ l0 = l1 = ol0 = ol1 = hshape;
+
+ }
+
u8 same0 = 0, same1 = 0, same2 = 0, same3 = 0,
result = 1 + (found_one << 2);
- if (!is_txt) result += 2;
if (l0 != ol0 || memcmp(o->v0, orig_o->v0, l0) != 0) { same0 = 8; }
if (l1 != ol1 || memcmp(o->v1, orig_o->v1, l1) != 0) { same1 = 8; }
if (l0 != l1 || memcmp(o->v0, o->v1, l0) != 0) { same2 = 8; }
if (ol0 != ol1 || memcmp(orig_o->v0, orig_o->v1, l0) != 0) { same3 = 8; }
+ if (!is_txt && check_if_text_buf((u8 *)&o->v0, l0) < l0) { same0 += 2; }
+ if (!is_txt && check_if_text_buf((u8 *)&o->v1, l1) < l1) { same1 += 2; }
- if (!same2 && !same3) {
+ if (
+#if VARIANT < 3
+ !(same0 && !same1) &&
+#endif
+#if VARIANT == 4
+ (!same2 && same3)
+#else
+ (DICT_ADD_STRATEGY >= same0 + result)
+#endif
+ ) {
- if (!(same0 && !same1) && DICT_ADD_STRATEGY >= same0 + result) {
+ // fprintf(stderr, "add v0 [%u]\"%s\"\n", l0, o->v0);
+ maybe_add_auto(afl, o->v0, l0);
- // fprintf(stderr, "add v0 [%u]\"%s\"\n", l0, o->v0);
- maybe_add_auto(afl, o->v0, l0);
+ }
- }
+ if (
+#if VARIANT < 3
+ !(!same0 && same1) &&
+#endif
+#if VARIANT == 4
+ (same2 && !same3)
+#else
+ (DICT_ADD_STRATEGY >= same1 + result)
+#endif
+ ) {
- if (!(!same0 && same1) && DICT_ADD_STRATEGY >= same1 + result) {
-
- // fprintf(stderr, "add v1 [%u]\"%s\"\n", l1, o->v1);
- maybe_add_auto(afl, o->v1, l1);
-
- }
+ // fprintf(stderr, "add v1 [%u]\"%s\"\n", l1, o->v1);
+ maybe_add_auto(afl, o->v1, l1);
}
From f14b3bd9de4570a30c0f89bac2879ee3a7cfbcae Mon Sep 17 00:00:00 2001
From: Your Name
Date: Tue, 26 Oct 2021 18:48:13 +0100
Subject: [PATCH 108/305] Fix issues with Yama restrictions in FRIDA mode
---
frida_mode/README.md | 6 ++++++
frida_mode/frida.map | 1 +
frida_mode/include/entry.h | 3 +++
frida_mode/src/entry.c | 32 ++++++++++++++++++++++++++++++++
frida_mode/src/js/api.js | 7 +++++++
frida_mode/src/js/js_api.c | 6 ++++++
frida_mode/ts/lib/afl.ts | 12 ++++++++++++
include/envs.h | 1 +
8 files changed, 68 insertions(+)
diff --git a/frida_mode/README.md b/frida_mode/README.md
index df40c771..bb194080 100644
--- a/frida_mode/README.md
+++ b/frida_mode/README.md
@@ -288,6 +288,12 @@ ucomisd 2 ( 0.86%)
* `AFL_FRIDA_STATS_INTERVAL` - The maximum frequency to output statistics
information. Stats will be written whenever they are updated if the given
interval has elapsed since last time they were written.
+* `AFL_FRIDA_TRACEABLE` - Set the child process to be traceable by any process
+to aid debugging and overcome the restrictions imposed by YAMA. Supported on
+Linux only. Permits a non-root user to use `gcore` or similar to collect a core
+dump of the instrumented target. Note that in order to capture the core dump you
+must set a sufficient timeout (using `-t`) to avoid `afl-fuzz` killing the
+process whilst it is being dumped.
## FASAN - Frida Address Sanitizer Mode
Frida mode also supports FASAN. The design of this is actually quite simple and
diff --git a/frida_mode/frida.map b/frida_mode/frida.map
index 0fc48aa6..e2ae87a7 100644
--- a/frida_mode/frida.map
+++ b/frida_mode/frida.map
@@ -33,6 +33,7 @@
js_api_set_stats_interval;
js_api_set_stderr;
js_api_set_stdout;
+ js_api_set_traceable;
local:
*;
diff --git a/frida_mode/include/entry.h b/frida_mode/include/entry.h
index 3f0a4ecc..edc41467 100644
--- a/frida_mode/include/entry.h
+++ b/frida_mode/include/entry.h
@@ -4,6 +4,7 @@
#include "frida-gumjs.h"
extern guint64 entry_point;
+extern gboolean traceable;
extern gboolean entry_compiled;
extern gboolean entry_run;
@@ -15,5 +16,7 @@ void entry_start(void);
void entry_prologue(GumStalkerIterator *iterator, GumStalkerOutput *output);
+void entry_on_fork(void);
+
#endif
diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c
index 186ddd3a..0ce2f3c3 100644
--- a/frida_mode/src/entry.c
+++ b/frida_mode/src/entry.c
@@ -1,5 +1,9 @@
#include
+#if defined(__linux__) && !defined(__ANDROID__)
+ #include
+#endif
+
#include "frida-gumjs.h"
#include "debug.h"
@@ -16,6 +20,7 @@
extern void __afl_manual_init();
guint64 entry_point = 0;
+gboolean traceable = FALSE;
gboolean entry_compiled = FALSE;
gboolean entry_run = FALSE;
@@ -26,21 +31,48 @@ static void entry_launch(void) {
/* Child here */
entry_run = TRUE;
+ entry_on_fork();
instrument_on_fork();
seccomp_on_fork();
stats_on_fork();
}
+#if defined(__linux__) && !defined(__ANDROID__)
+void entry_on_fork(void) {
+
+ if (traceable) {
+
+ if (prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY) < 0) {
+
+ FATAL("Failed to PR_SET_PTRACER");
+
+ }
+
+ }
+
+}
+
+#else
+void entry_on_fork(void) {
+
+ if (set_dumpable) { WARNF("AFL_FRIDA_TRACEABLE unsupported"); }
+
+}
+
+#endif
+
void entry_config(void) {
entry_point = util_read_address("AFL_ENTRYPOINT");
+ if (getenv("AFL_FRIDA_TRACEABLE") != NULL) { traceable = TRUE; }
}
void entry_init(void) {
OKF("entry_point: 0x%016" G_GINT64_MODIFIER "X", entry_point);
+ OKF("dumpable: [%c]", traceable ? 'X' : ' ');
if (dlopen(NULL, RTLD_NOW) == NULL) { FATAL("Failed to dlopen: %d", errno); }
diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js
index 40bb4a16..6f9f05d8 100644
--- a/frida_mode/src/js/api.js
+++ b/frida_mode/src/js/api.js
@@ -243,6 +243,12 @@ class Afl {
const buf = Memory.allocUtf8String(file);
Afl.jsApiSetStdOut(buf);
}
+ /**
+ * See `AFL_FRIDA_TRACEABLE`.
+ */
+ static setTraceable() {
+ Afl.jsApiSetTraceable();
+ }
static jsApiGetFunction(name, retType, argTypes) {
const addr = Afl.module.getExportByName(name);
return new NativeFunction(addr, retType, argTypes);
@@ -286,6 +292,7 @@ Afl.jsApiSetStatsFile = Afl.jsApiGetFunction("js_api_set_stats_file", "void", ["
Afl.jsApiSetStatsInterval = Afl.jsApiGetFunction("js_api_set_stats_interval", "void", ["uint64"]);
Afl.jsApiSetStdErr = Afl.jsApiGetFunction("js_api_set_stderr", "void", ["pointer"]);
Afl.jsApiSetStdOut = Afl.jsApiGetFunction("js_api_set_stdout", "void", ["pointer"]);
+Afl.jsApiSetTraceable = Afl.jsApiGetFunction("js_api_set_traceable", "void", []);
Afl.jsApiWrite = new NativeFunction(
/* tslint:disable-next-line:no-null-keyword */
Module.getExportByName(null, "write"), "int", ["int", "pointer", "int"]);
diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c
index 9dba79aa..f3d81a32 100644
--- a/frida_mode/src/js/js_api.c
+++ b/frida_mode/src/js/js_api.c
@@ -231,3 +231,9 @@ __attribute__((visibility("default"))) void js_api_set_stalker_ic_entries(
}
+__attribute__((visibility("default"))) void js_api_set_traceable(void) {
+
+ traceable = TRUE;
+
+}
+
diff --git a/frida_mode/ts/lib/afl.ts b/frida_mode/ts/lib/afl.ts
index 8a1ebf1b..538d9b70 100644
--- a/frida_mode/ts/lib/afl.ts
+++ b/frida_mode/ts/lib/afl.ts
@@ -284,6 +284,13 @@ class Afl {
Afl.jsApiSetStdOut(buf);
}
+ /**
+ * See `AFL_FRIDA_TRACEABLE`.
+ */
+ public static setTraceable(): void {
+ Afl.jsApiSetTraceable();
+ }
+
private static readonly jsApiAddExcludeRange = Afl.jsApiGetFunction(
"js_api_add_exclude_range",
"void",
@@ -431,6 +438,11 @@ class Afl {
"void",
["pointer"]);
+ private static readonly jsApiSetTraceable = Afl.jsApiGetFunction(
+ "js_api_set_traceable",
+ "void",
+ []);
+
private static readonly jsApiWrite = new NativeFunction(
/* tslint:disable-next-line:no-null-keyword */
Module.getExportByName(null, "write"),
diff --git a/include/envs.h b/include/envs.h
index e3957147..61267a0d 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -76,6 +76,7 @@ static char *afl_environment_variables[] = {
"AFL_FRIDA_PERSISTENT_RET",
"AFL_FRIDA_STATS_FILE",
"AFL_FRIDA_STATS_INTERVAL",
+ "AFL_FRIDA_TRACEABLE",
"AFL_FUZZER_ARGS", // oss-fuzz
"AFL_GDB",
"AFL_GCC_ALLOWLIST",
From 245e91eb27f1572e00c6664477d588c540c30ed6 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 26 Oct 2021 21:30:08 +0200
Subject: [PATCH 109/305] fix
---
src/afl-fuzz-redqueen.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 6002703e..800a0753 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -28,7 +28,7 @@
#include "afl-fuzz.h"
#include "cmplog.h"
-#define VARIANT 0
+#define VARIANT 4
//#define _DEBUG
//#define CMPLOG_INTROSPECTION
@@ -1861,8 +1861,8 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
if (o->v1 != orig_o->v1) { same1 = 8; }
if (o->v0 != o->v1) { same2 = 8; }
if (orig_o->v0 != orig_o->v1) { same3 = 8; }
- if (check_if_text_buf((u8 *)o->v0, hshape) < hshape) same0 += 2;
- if (check_if_text_buf((u8 *)o->v1, hshape) < hshape) same1 += 2;
+ if (check_if_text_buf((u8 *)&o->v0, hshape) < hshape) same0 += 2;
+ if (check_if_text_buf((u8 *)&o->v1, hshape) < hshape) same1 += 2;
if (!same2 && !same3) {
From 9a11c8ac24f8b2c2dcd78aa3a27e5416a717ce4f Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 26 Oct 2021 22:06:01 +0200
Subject: [PATCH 110/305] fix
---
src/afl-fuzz-redqueen.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 800a0753..928cab59 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -28,7 +28,7 @@
#include "afl-fuzz.h"
#include "cmplog.h"
-#define VARIANT 4
+#define VARIANT 0
//#define _DEBUG
//#define CMPLOG_INTROSPECTION
From d85f5d4d62d2ca986b077aef06e8cb32148d9361 Mon Sep 17 00:00:00 2001
From: David CARLIER
Date: Tue, 26 Oct 2021 22:30:44 +0100
Subject: [PATCH 111/305] frida mode macOs build fix proposal
---
frida_mode/src/entry.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c
index 0ce2f3c3..c51e202f 100644
--- a/frida_mode/src/entry.c
+++ b/frida_mode/src/entry.c
@@ -56,7 +56,7 @@ void entry_on_fork(void) {
#else
void entry_on_fork(void) {
- if (set_dumpable) { WARNF("AFL_FRIDA_TRACEABLE unsupported"); }
+ if (traceable) { WARNF("AFL_FRIDA_TRACEABLE unsupported"); }
}
From 69d82cf9d7e007ed9508034d2c0acaeb027d2b47 Mon Sep 17 00:00:00 2001
From: Adrian Herrera
Date: Wed, 27 Oct 2021 10:16:24 +0000
Subject: [PATCH 112/305] optimin: fix cmake flags
Disable RTTI. Fixes issue #1133
---
utils/optimin/src/CMakeLists.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/utils/optimin/src/CMakeLists.txt b/utils/optimin/src/CMakeLists.txt
index f31ceeaf..693f63f2 100644
--- a/utils/optimin/src/CMakeLists.txt
+++ b/utils/optimin/src/CMakeLists.txt
@@ -1,4 +1,5 @@
add_executable(optimin OptiMin.cpp)
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
foreach(LIB MaLib EvalMaxSAT glucose)
target_include_directories(optimin PRIVATE
From e2ca7a63972ef3c245395bea7bb89d873ad757af Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 28 Oct 2021 18:02:57 +0200
Subject: [PATCH 113/305] variant 6
---
instrumentation/afl-compiler-rt.o.c | 44 +++++-----
src/afl-fuzz-redqueen.c | 126 +++++++++++++++++++++++-----
2 files changed, 125 insertions(+), 45 deletions(-)
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 5caf57b3..17724e74 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -22,6 +22,10 @@
#include "cmplog.h"
#include "llvm-alternative-coverage.h"
+#define XXH_INLINE_ALL
+#include "xxhash.h"
+#undef XXH_INLINE_ALL
+
#include
#include
#include
@@ -154,6 +158,12 @@ static void at_exit(int signal) {
}
+#ifdef WORD_SIZE_64
+ #define default_hash(a, b) XXH64(a, b, HASH_CONST)
+#else
+ #define default_hash(a, b) XXH64(a, b, HASH_CONST)
+#endif
+
/* Uninspired gcc plugin instrumentation */
void __afl_trace(const u32 x) {
@@ -1499,8 +1509,7 @@ void __cmplog_ins_hook1(uint8_t arg1, uint8_t arg2, uint8_t attr) {
if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
- k = (k >> 4) ^ (k << 8);
- k &= CMP_MAP_W - 1;
+ k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
@@ -1530,8 +1539,7 @@ void __cmplog_ins_hook2(uint16_t arg1, uint16_t arg2, uint8_t attr) {
if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
- k = (k >> 4) ^ (k << 8);
- k &= CMP_MAP_W - 1;
+ k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
@@ -1569,8 +1577,7 @@ void __cmplog_ins_hook4(uint32_t arg1, uint32_t arg2, uint8_t attr) {
if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
- k = (k >> 4) ^ (k << 8);
- k &= CMP_MAP_W - 1;
+ k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
@@ -1608,8 +1615,7 @@ void __cmplog_ins_hook8(uint64_t arg1, uint64_t arg2, uint8_t attr) {
if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
- k = (k >> 4) ^ (k << 8);
- k &= CMP_MAP_W - 1;
+ k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
@@ -1652,8 +1658,7 @@ void __cmplog_ins_hookN(uint128_t arg1, uint128_t arg2, uint8_t attr,
if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
- k = (k >> 4) ^ (k << 8);
- k &= CMP_MAP_W - 1;
+ k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
@@ -1696,8 +1701,7 @@ void __cmplog_ins_hook16(uint128_t arg1, uint128_t arg2, uint8_t attr) {
if (likely(!__afl_cmp_map)) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
- k = (k >> 4) ^ (k << 8);
- k &= CMP_MAP_W - 1;
+ k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
@@ -1802,8 +1806,8 @@ void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) {
for (uint64_t i = 0; i < cases[0]; i++) {
uintptr_t k = (uintptr_t)__builtin_return_address(0) + i;
- k = (k >> 4) ^ (k << 8);
- k &= CMP_MAP_W - 1;
+ k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) &
+ (CMP_MAP_W - 1));
u32 hits;
@@ -1901,8 +1905,7 @@ void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u64 len) {
// fprintf(stderr, "RTN2 %u\n", l);
uintptr_t k = (uintptr_t)__builtin_return_address(0);
- k = (k >> 4) ^ (k << 8);
- k &= CMP_MAP_W - 1;
+ k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits, reset = 1;
@@ -1955,8 +1958,7 @@ void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u64 len) {
// fprintf(stderr, "RTN2 %u\n", l);
uintptr_t k = (uintptr_t)__builtin_return_address(0);
- k = (k >> 4) ^ (k << 8);
- k &= CMP_MAP_W - 1;
+ k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits, reset = 1;
@@ -2011,8 +2013,7 @@ void __cmplog_rtn_hook_str(u8 *ptr1, u8 *ptr2) {
// fprintf(stderr, "RTN2 %u\n", l);
uintptr_t k = (uintptr_t)__builtin_return_address(0);
- k = (k >> 4) ^ (k << 8);
- k &= CMP_MAP_W - 1;
+ k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits, reset = 1;
@@ -2075,8 +2076,7 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
// fprintf(stderr, "RTN2 %u\n", len);
uintptr_t k = (uintptr_t)__builtin_return_address(0);
- k = (k >> 4) ^ (k << 8);
- k &= CMP_MAP_W - 1;
+ k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits, reset = 1;
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 928cab59..b5dc23c2 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -28,7 +28,7 @@
#include "afl-fuzz.h"
#include "cmplog.h"
-#define VARIANT 0
+#define VARIANT 6
//#define _DEBUG
//#define CMPLOG_INTROSPECTION
@@ -1855,6 +1855,43 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
// we only learn 16 bit +
if (hshape > 1) {
+#if VARIANT == 6
+ if (!found_one || afl->queue_cur->is_ascii) {
+
+ #ifdef WORD_SIZE_64
+ if (unlikely(is_n)) {
+
+ if (!found_one ||
+ check_if_text_buf((u8 *)&s128_v0, SHAPE_BYTES(h->shape)) ==
+ SHAPE_BYTES(h->shape))
+ try_to_add_to_dictN(afl, s128_v0, SHAPE_BYTES(h->shape));
+ if (!found_one ||
+ check_if_text_buf((u8 *)&s128_v1, SHAPE_BYTES(h->shape)) ==
+ SHAPE_BYTES(h->shape))
+ try_to_add_to_dictN(afl, s128_v1, SHAPE_BYTES(h->shape));
+
+ } else
+
+ #endif
+ {
+
+ if (!memcmp((u8 *)&o->v0, (u8 *)&orig_o->v0, SHAPE_BYTES(h->shape)) &&
+ (!found_one ||
+ check_if_text_buf((u8 *)&o->v0, SHAPE_BYTES(h->shape)) ==
+ SHAPE_BYTES(h->shape)))
+ try_to_add_to_dict(afl, o->v0, SHAPE_BYTES(h->shape));
+ if (!memcmp((u8 *)&o->v1, (u8 *)&orig_o->v1, SHAPE_BYTES(h->shape)) &&
+ (!found_one ||
+ check_if_text_buf((u8 *)&o->v1, SHAPE_BYTES(h->shape)) ==
+ SHAPE_BYTES(h->shape)))
+ try_to_add_to_dict(afl, o->v1, SHAPE_BYTES(h->shape));
+
+ }
+
+ }
+
+#else
+
u8 same0 = 0, same1 = 0, same2 = 0, same3 = 0,
result = 1 + (found_one << 2);
if (o->v0 != orig_o->v0) { same0 = 8; }
@@ -1866,13 +1903,13 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
if (!same2 && !same3) {
-#ifdef WORD_SIZE_64
+ #ifdef WORD_SIZE_64
if (unlikely(is_n)) {
if (
- #if VARIANT == 1
+ #if VARIANT == 1
!(!same0 && same1) &&
- #endif
+ #endif
DICT_ADD_STRATEGY >= same0 + result) {
try_to_add_to_dictN(afl, s128_v0, hshape);
@@ -1880,9 +1917,9 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
if (
- #if VARIANT == 1
+ #if VARIANT == 1
!(same0 && !same1) &&
- #endif
+ #endif
DICT_ADD_STRATEGY >= same1 + result) {
try_to_add_to_dictN(afl, s128_v1, hshape);
@@ -1891,13 +1928,13 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
} else
-#endif
+ #endif
{
if (
-#if VARIANT == 1
+ #if VARIANT == 1
!(!same0 && same1) &&
-#endif
+ #endif
DICT_ADD_STRATEGY >= same0 + result) {
// fprintf(stderr, "add v0 0x%llx\n", o->v0);
@@ -1906,9 +1943,9 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
if (
-#if VARIANT == 1
+ #if VARIANT == 1
!(same0 && !same1) &&
-#endif
+ #endif
DICT_ADD_STRATEGY >= same1 + result) {
// fprintf(stderr, "add v1 0x%llx\n", o->v1);
@@ -1920,6 +1957,8 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
+#endif
+
}
cmp_fuzz_next_iter:
@@ -2567,6 +2606,44 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
// if (unlikely(!afl->pass_stats[key].total)) {
+#if VARIANT == 6
+ if ((!found_one && (lvl & LVL1)) || afl->queue_cur->is_ascii) {
+
+ // if (unlikely(!afl->pass_stats[key].total)) {
+
+ u32 shape_len = SHAPE_BYTES(h->shape);
+ u32 v0_len = shape_len, v1_len = shape_len;
+ if (afl->queue_cur->is_ascii ||
+ check_if_text_buf((u8 *)&o->v0, shape_len) == shape_len) {
+
+ if (strlen(o->v0)) v0_len = strlen(o->v0);
+
+ }
+
+ if (afl->queue_cur->is_ascii ||
+ check_if_text_buf((u8 *)&o->v1, shape_len) == shape_len) {
+
+ if (strlen(o->v1)) v1_len = strlen(o->v1);
+
+ }
+
+ // fprintf(stderr, "SHOULD: found:%u ascii:%u text?%u:%u %u:%s %u:%s \n",
+ // found_one, afl->queue_cur->is_ascii, check_if_text_buf((u8 *)&o->v0,
+ // shape_len), check_if_text_buf((u8 *)&o->v1, shape_len), v0_len,
+ // o->v0, v1_len, o->v1);
+
+ if (!memcmp(o->v0, orig_o->v0, v0_len) ||
+ (!found_one || check_if_text_buf((u8 *)&o->v0, v0_len) == v0_len))
+ maybe_add_auto(afl, o->v0, v0_len);
+ if (!memcmp(o->v1, orig_o->v1, v1_len) ||
+ (!found_one || check_if_text_buf((u8 *)&o->v1, v1_len) == v1_len))
+ maybe_add_auto(afl, o->v1, v1_len);
+
+ //}
+
+ }
+
+#else
if (lvl & LVL1) {
u8 is_txt = 0, l0 = o->v0_len, ol0 = orig_o->v0_len, l1 = o->v1_len,
@@ -2598,14 +2675,14 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
if (!is_txt && check_if_text_buf((u8 *)&o->v1, l1) < l1) { same1 += 2; }
if (
-#if VARIANT < 3
+ #if VARIANT < 3
!(same0 && !same1) &&
-#endif
-#if VARIANT == 4
+ #endif
+ #if VARIANT == 4
(!same2 && same3)
-#else
+ #else
(DICT_ADD_STRATEGY >= same0 + result)
-#endif
+ #endif
) {
// fprintf(stderr, "add v0 [%u]\"%s\"\n", l0, o->v0);
@@ -2614,14 +2691,14 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
if (
-#if VARIANT < 3
+ #if VARIANT < 3
!(!same0 && same1) &&
-#endif
-#if VARIANT == 4
+ #endif
+ #if VARIANT == 4
(same2 && !same3)
-#else
+ #else
(DICT_ADD_STRATEGY >= same1 + result)
-#endif
+ #endif
) {
// fprintf(stderr, "add v1 [%u]\"%s\"\n", l1, o->v1);
@@ -2631,6 +2708,8 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
+#endif
+
rtn_fuzz_next_iter:
afl->stage_cur++;
@@ -2966,9 +3045,10 @@ exit_its:
if (f) {
fprintf(f,
- "Cmplog: fname=%s len=%u ms=%llu result=%u finds=%llu entries=%u\n",
+ "Cmplog: fname=%s len=%u ms=%llu result=%u finds=%llu entries=%u "
+ "auto_extra_after=%u\n",
afl->queue_cur->fname, len, get_cur_time() - start_time, r,
- new_hit_cnt - orig_hit_cnt, cmp_locations);
+ new_hit_cnt - orig_hit_cnt, cmp_locations, afl->a_extras_cnt);
#ifndef _DEBUG
if (afl->not_on_tty) { fclose(f); }
From 45b8e057934b5f565013f29f4f461aaca051a56d Mon Sep 17 00:00:00 2001
From: Kuang-che Wu
Date: Sat, 30 Oct 2021 22:27:49 +0800
Subject: [PATCH 114/305] fix off by one bug of PCGUARD instrumentation
fix bug #1120
---
instrumentation/SanitizerCoverageLTO.so.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index d90fa867..7a3d8c4d 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -1049,7 +1049,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
uint32_t write_loc = afl_global_id;
- if (afl_global_id % 8) write_loc = (((afl_global_id + 8) >> 3) << 3);
+ write_loc = (((afl_global_id + 8) >> 3) << 3);
GlobalVariable *AFLFinalLoc =
new GlobalVariable(M, Int32Tyi, true, GlobalValue::ExternalLinkage, 0,
From b1aecf4ff0d2f82168619d40d59fcf959e7eb0f6 Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Sat, 30 Oct 2021 21:38:13 +0200
Subject: [PATCH 115/305] Edit list of environment variables
---
docs/env_variables.md | 777 ++++++++++++++++++++----------------------
1 file changed, 372 insertions(+), 405 deletions(-)
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 5f5c2510..bd66ce38 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -1,83 +1,63 @@
-# Environmental variables
+# Environment variables
- 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
- instruction manual.
+ This document discusses the environment variables used by AFL++ to expose various exotic functions that may be (rarely) useful for power users or for some types of custom fuzzing setups.
+ For general information about AFL++, see [README.md](../README.md).
- Note that most tools will warn on any unknown AFL environment variables.
- This is for warning on typos that can happen. If you want to disable this
- check then set the `AFL_IGNORE_UNKNOWN_ENVS` environment variable.
+ Note: Most tools will warn on any unknown AFL++ environment variables; for example, because of typos. If you want to disable this check, then set the `AFL_IGNORE_UNKNOWN_ENVS` environment variable.
## 1) Settings for all compilers
-Starting with AFL++ 3.0 there is only one compiler: afl-cc
-To select the different instrumentation modes this can be done by
- 1. passing the --afl-MODE command line option to the compiler
- 2. or using a symlink to afl-cc: afl-gcc, afl-g++, afl-clang, afl-clang++,
- afl-clang-fast, afl-clang-fast++, afl-clang-lto, afl-clang-lto++,
- afl-gcc-fast, afl-g++-fast
- 3. or using the environment variable `AFL_CC_COMPILER` with `MODE`
+Starting with AFL++ 3.0, there is only one compiler: afl-cc.
-`MODE` can be one of `LTO` (afl-clang-lto*), `LLVM` (afl-clang-fast*), `GCC_PLUGIN`
-(afl-g*-fast) or `GCC` (afl-gcc/afl-g++).
+To select the different instrumentation modes, use one of the following options:
-Because (with the exception of the --afl-MODE command line option) the
-compile-time tools do not accept AFL specific command-line options, they
-make fairly broad use of environmental variables instead:
+ - Pass the --afl-MODE command-line option to the compiler. Only this option accepts further AFL-specific command-line options.
+ - Use a symlink to afl-cc: afl-clang, afl-clang++, afl-clang-fast, afl-clang-fast++, afl-clang-lto, afl-clang-lto++, afl-gcc, afl-g++, afl-gcc-fast, afl-g++-fast. This option does not accept AFL-specific command-line options. Instead, use environment variables.
+ - Use the `AFL_CC_COMPILER` environment variable with `MODE`. To select `MODE`, use one of the following values:
- - Some build/configure scripts break with AFL++ compilers. To be able to
- pass them, do:
-```
- export CC=afl-cc
- export CXX=afl-c++
- export AFL_NOOPT=1
- ./configure --disable-shared --disabler-werror
- unset AFL_NOOPT
- make
-```
+ - `GCC` (afl-gcc/afl-g++)
+ - `GCC_PLUGIN` (afl-g*-fast)
+ - `LLVM` (afl-clang-fast*)
+ - `LTO` (afl-clang-lto*).
- - Most AFL tools do not print any output if stdout/stderr are redirected.
- If you want to get the output into a file then set the `AFL_DEBUG`
- environment variable.
- This is sadly necessary for various build processes which fail otherwise.
+The compile-time tools do not accept AFL-specific command-line options. The --afl-MODE command line option is the only exception. The other options make fairly broad use of environment variables instead:
- - Setting `AFL_HARDEN` automatically adds code hardening options when invoking
- the downstream compiler. This currently includes `-D_FORTIFY_SOURCE=2` and
- `-fstack-protector-all`. The setting is useful for catching non-crashing
- memory bugs at the expense of a very slight (sub-5%) performance loss.
+ - Some build/configure scripts break with AFL++ compilers.
+ To be able to pass them, do:
- - By default, the wrapper appends `-O3` to optimize builds. Very rarely, this
- will cause problems in programs built with -Werror, simply because `-O3`
- enables more thorough code analysis and can spew out additional warnings.
- To disable optimizations, set `AFL_DONT_OPTIMIZE`.
- However if `-O...` and/or `-fno-unroll-loops` are set, these are not
- overridden.
+ ```
+ export CC=afl-cc
+ export CXX=afl-c++
+ export AFL_NOOPT=1
+ ./configure --disable-shared --disabler-werror
+ unset AFL_NOOPT
+ make
+ ```
- - Setting `AFL_USE_ASAN` automatically enables ASAN, provided that your
- compiler supports it.
-
- (You can also enable MSAN via `AFL_USE_MSAN`; ASAN and MSAN come with the
- same gotchas; the modes are mutually exclusive. UBSAN can be enabled
- similarly by setting the environment variable `AFL_USE_UBSAN=1`. Finally
- there is the Control Flow Integrity sanitizer that can be activated by
- `AFL_USE_CFISAN=1`)
-
- - Setting `AFL_USE_LSAN` automatically enables Leak-Sanitizer, provided
- that your compiler supports it. To perform a leak check within your
- program at a certain point (such as at the end of an __AFL_LOOP),
- you can run the macro __AFL_LEAK_CHECK(); which will cause
- an abort if any memory is leaked (you can combine this with the
- LSAN_OPTIONS=suppressions option to supress some known leaks).
+ - If you are a weird person that wants to compile and instrument asm
+ text files, then use the `AFL_AS_FORCE_INSTRUMENT` variable:
+ `AFL_AS_FORCE_INSTRUMENT=1 afl-gcc foo.s -o foo`
- Setting `AFL_CC`, `AFL_CXX`, and `AFL_AS` lets you use alternate downstream
compilation tools, rather than the default 'clang', 'gcc', or 'as' binaries
in your `$PATH`.
- - `AFL_PATH` can be used to point afl-gcc to an alternate location of afl-as.
- One possible use of this is utils/clang_asm_normalize/, which lets
- you instrument hand-written assembly when compiling clang code by plugging
- a normalizer into the chain. (There is no equivalent feature for GCC.)
+ - Most AFL tools do not print any output if stdout/stderr are redirected.
+ If you want to get the output into a file, then set the `AFL_DEBUG`
+ environment variable.
+ This is sadly necessary for various build processes which fail otherwise.
+
+ - By default, the wrapper appends `-O3` to optimize builds. Very rarely, this
+ will cause problems in programs built with -Werror, simply because `-O3`
+ enables more thorough code analysis and can spew out additional warnings.
+ To disable optimizations, set `AFL_DONT_OPTIMIZE`.
+ However, if `-O...` and/or `-fno-unroll-loops` are set, these are not
+ overridden.
+
+ - Setting `AFL_HARDEN` automatically adds code hardening options when invoking
+ the downstream compiler. This currently includes `-D_FORTIFY_SOURCE=2` and
+ `-fstack-protector-all`. The setting is useful for catching non-crashing
+ memory bugs at the expense of a very slight (sub-5%) performance loss.
- Setting `AFL_INST_RATIO` to a percentage between 0 and 100 controls the
probability of instrumenting every branch. This is (very rarely) useful
@@ -97,20 +77,37 @@ make fairly broad use of environmental variables instead:
- `AFL_NO_BUILTIN` causes the compiler to generate code suitable for use with
libtokencap.so (but perhaps running a bit slower than without the flag).
- - `TMPDIR` is used by afl-as for temporary files; if this variable is not set,
- the tool defaults to /tmp.
-
- - If you are a weird person that wants to compile and instrument asm
- text files then use the `AFL_AS_FORCE_INSTRUMENT` variable:
- `AFL_AS_FORCE_INSTRUMENT=1 afl-gcc foo.s -o foo`
+ - `AFL_PATH` can be used to point afl-gcc to an alternate location of afl-as.
+ One possible use of this is utils/clang_asm_normalize/, which lets
+ you instrument hand-written assembly when compiling clang code by plugging
+ a normalizer into the chain.
+ (There is no equivalent feature for GCC.)
- Setting `AFL_QUIET` will prevent afl-cc and afl-as banners from being
displayed during compilation, in case you find them distracting.
+ - Setting `AFL_USE_ASAN` automatically enables ASAN, provided that your
+ compiler supports it.
+
+ (You can also enable MSAN via `AFL_USE_MSAN`; ASAN and MSAN come with the
+ same gotchas; the modes are mutually exclusive. UBSAN can be enabled
+ similarly by setting the environment variable `AFL_USE_UBSAN=1`. Finally,
+ there is the Control Flow Integrity sanitizer that can be activated by
+ `AFL_USE_CFISAN=1`.)
+
+ - Setting `AFL_USE_LSAN` automatically enables Leak-Sanitizer, provided
+ that your compiler supports it. To perform a leak check within your
+ program at a certain point (such as at the end of an __AFL_LOOP),
+ you can run the macro __AFL_LEAK_CHECK(); which will cause
+ an abort if any memory is leaked (you can combine this with the
+ LSAN_OPTIONS=suppressions option to supress some known leaks).
+
+ - `TMPDIR` is used by afl-as for temporary files; if this variable is not set,
+ the tool defaults to /tmp.
+
## 2) Settings for LLVM and LTO: afl-clang-fast / afl-clang-fast++ / afl-clang-lto / afl-clang-lto++
-The native instrumentation helpers (instrumentation and gcc_plugin) accept a subset
-of the settings discussed in section 1, with the exception of:
+The native instrumentation helpers (instrumentation and gcc_plugin) accept a subset of the settings discussed in section 1, with the exception of:
- LLVM modes support `AFL_LLVM_DICT2FILE=/absolute/path/file.txt` which will
write all constant string comparisons to this file to be used later with
@@ -121,253 +118,167 @@ of the settings discussed in section 1, with the exception of:
- `TMPDIR` and `AFL_KEEP_ASSEMBLY`, since no temporary assembly files are
created.
- - `AFL_INST_RATIO`, as we by default use collision free instrumentation.
+ - `AFL_INST_RATIO`, as we use collision free instrumentation by default.
Not all passes support this option though as it is an outdated feature.
Then there are a few specific features that are only available in instrumentation mode:
### Select the instrumentation mode
- - `AFL_LLVM_INSTRUMENT` - this configures the instrumentation mode.
- Available options:
- PCGUARD - our own pcgard based instrumentation (default)
- NATIVE - clang's original pcguard based instrumentation
- CLASSIC - classic AFL (map[cur_loc ^ prev_loc >> 1]++) (default)
- LTO - LTO instrumentation (see below)
- CTX - context sensitive instrumentation (see below)
- NGRAM-x - deeper previous location coverage (from NGRAM-2 up to NGRAM-16)
- GCC - outdated gcc instrumentation
- CLANG - outdated clang instrumentation
- In CLASSIC you can also specify CTX and/or NGRAM, seperate the options
- with a comma "," then, e.g.:
- `AFL_LLVM_INSTRUMENT=CLASSIC,CTX,NGRAM-4`
- Note that this is actually not a good idea to use both CTX and NGRAM :)
+`AFL_LLVM_INSTRUMENT` - this configures the instrumentation mode.
-### LTO
+Available options:
- This is a different kind way of instrumentation: first it compiles all
- code in LTO (link time optimization) and then performs an edge inserting
- instrumentation which is 100% collision free (collisions are a big issue
- in AFL and AFL-like instrumentations). This is performed by using
- afl-clang-lto/afl-clang-lto++ instead of afl-clang-fast, but is only
- built if LLVM 11 or newer is used.
+ - CLANG - outdated clang instrumentation
+ - CLASSIC - classic AFL (map[cur_loc ^ prev_loc >> 1]++) (default)
- - `AFL_LLVM_INSTRUMENT=CFG` will use Control Flow Graph instrumentation.
- (not recommended for afl-clang-fast, default for afl-clang-lto as there
- it is a different and better kind of instrumentation.)
+ You can also specify CTX and/or NGRAM, seperate the options with a comma "," then, e.g.: `AFL_LLVM_INSTRUMENT=CLASSIC,CTX,NGRAM-4`
- None of the following options are necessary to be used and are rather for
- manual use (which only ever the author of this LTO implementation will use).
- These are used if several separated instrumentations are performed which
- are then later combined.
+ Note: It is actually not a good idea to use both CTX and NGRAM. :)
+ - CTX - context sensitive instrumentation (see below)
+ - GCC - outdated gcc instrumentation
+ - LTO - LTO instrumentation (see below)
+ - NATIVE - clang's original pcguard based instrumentation
+ - NGRAM-x - deeper previous location coverage (from NGRAM-2 up to NGRAM-16)
+ - PCGUARD - our own pcgard based instrumentation (default)
- - `AFL_LLVM_DOCUMENT_IDS=file` will document to a file which edge ID was given
- to which function. This helps to identify functions with variable bytes
- or which functions were touched by an input.
- - `AFL_LLVM_MAP_ADDR` sets the fixed map address to a different address than
- the default `0x10000`. A value of 0 or empty sets the map address to be
- dynamic (the original AFL way, which is slower)
- - `AFL_LLVM_MAP_DYNAMIC` sets the shared memory address to be dynamic
- - `AFL_LLVM_LTO_STARTID` sets the starting location ID for the instrumentation.
- This defaults to 1
- - `AFL_LLVM_LTO_DONTWRITEID` prevents that the highest location ID written
- into the instrumentation is set in a global variable
+#### CTX
- See [instrumentation/README.lto.md](../instrumentation/README.lto.md) for more information.
+Setting `AFL_LLVM_CTX` or `AFL_LLVM_INSTRUMENT=CTX` activates context sensitive branch coverage - meaning that each edge is additionally combined with its caller.
+It is highly recommended to increase the `MAP_SIZE_POW2` definition in config.h to at least 18 and maybe up to 20 for this as otherwise too many map collisions occur.
-### NGRAM
+For more information, see [instrumentation/README.ctx.md](../instrumentation/README.ctx.md).
- - Setting `AFL_LLVM_NGRAM_SIZE` or `AFL_LLVM_INSTRUMENT=NGRAM-{value}`
- activates ngram prev_loc coverage, good values are 2, 4 or 8
- (any value between 2 and 16 is valid).
- It is highly recommended to increase the `MAP_SIZE_POW2` definition in
- config.h to at least 18 and maybe up to 20 for this as otherwise too
- many map collisions occur.
+#### LTO
- See [instrumentation/README.ngram.md](../instrumentation/README.ngram.md)
+This is a different kind way of instrumentation: first it compiles all code in LTO (link time optimization) and then performs an edge inserting instrumentation which is 100% collision free (collisions are a big issue in AFL and AFL-like instrumentations).
+This is performed by using afl-clang-lto/afl-clang-lto++ instead of afl-clang-fast, but is only built if LLVM 11 or newer is used.
-### CTX
+ - `AFL_LLVM_INSTRUMENT=CFG` will use Control Flow Graph instrumentation.
+ (not recommended for afl-clang-fast, default for afl-clang-lto as there
+ it is a different and better kind of instrumentation.)
- - Setting `AFL_LLVM_CTX` or `AFL_LLVM_INSTRUMENT=CTX`
- activates context sensitive branch coverage - meaning that each edge
- is additionally combined with its caller.
- It is highly recommended to increase the `MAP_SIZE_POW2` definition in
- config.h to at least 18 and maybe up to 20 for this as otherwise too
- many map collisions occur.
+None of the following options are necessary to be used and are rather for manual use (which only ever the author of this LTO implementation will use).
+These are used if several separated instrumentations are performed which are then later combined.
- See [instrumentation/README.ctx.md](../instrumentation/README.ctx.md)
+ - `AFL_LLVM_DOCUMENT_IDS=file` will document to a file which edge ID was given
+ to which function. This helps to identify functions with variable bytes
+ or which functions were touched by an input.
+ - `AFL_LLVM_MAP_ADDR` sets the fixed map address to a different address than
+ the default `0x10000`. A value of 0 or empty sets the map address to be
+ dynamic (the original AFL way, which is slower)
+ - `AFL_LLVM_MAP_DYNAMIC` sets the shared memory address to be dynamic
+ - `AFL_LLVM_LTO_STARTID` sets the starting location ID for the instrumentation.
+ This defaults to 1
+ - `AFL_LLVM_LTO_DONTWRITEID` prevents that the highest location ID written
+ into the instrumentation is set in a global variable
+
+ For more information, see [instrumentation/README.lto.md](../instrumentation/README.lto.md).
+
+#### NGRAM
+
+Setting `AFL_LLVM_NGRAM_SIZE` or `AFL_LLVM_INSTRUMENT=NGRAM-{value}` activates ngram prev_loc coverage, good values are 2, 4 or 8 (any value between 2 and 16 is valid).
+It is highly recommended to increase the `MAP_SIZE_POW2` definition in config.h to at least 18 and maybe up to 20 for this as otherwise too many map collisions occur.
+
+For more information, see [instrumentation/README.ngram.md](../instrumentation/README.ngram.md).
### LAF-INTEL
- This great feature will split compares into series of single byte comparisons
- to allow afl-fuzz to find otherwise rather impossible paths. It is not
- restricted to Intel CPUs ;-)
+This great feature will split compares into series of single byte comparisons to allow afl-fuzz to find otherwise rather impossible paths.
+It is not restricted to Intel CPUs. ;-)
- - Setting `AFL_LLVM_LAF_TRANSFORM_COMPARES` will split string compare functions
+ - Setting `AFL_LLVM_LAF_TRANSFORM_COMPARES` will split string compare functions
- - Setting `AFL_LLVM_LAF_SPLIT_SWITCHES` will split all `switch` constructs
+ - Setting `AFL_LLVM_LAF_SPLIT_SWITCHES` will split all `switch` constructs
- - Setting `AFL_LLVM_LAF_SPLIT_COMPARES` will split all floating point and
- 64, 32 and 16 bit integer CMP instructions
+ - Setting `AFL_LLVM_LAF_SPLIT_COMPARES` will split all floating point and
+ 64, 32 and 16 bit integer CMP instructions
- - Setting `AFL_LLVM_LAF_SPLIT_FLOATS` will split floating points, needs
- AFL_LLVM_LAF_SPLIT_COMPARES to be set
+ - Setting `AFL_LLVM_LAF_SPLIT_FLOATS` will split floating points, needs
+ AFL_LLVM_LAF_SPLIT_COMPARES to be set
- - Setting `AFL_LLVM_LAF_ALL` sets all of the above
+ - Setting `AFL_LLVM_LAF_ALL` sets all of the above
- See [instrumentation/README.laf-intel.md](../instrumentation/README.laf-intel.md) for more information.
+For more information, see [instrumentation/README.laf-intel.md](../instrumentation/README.laf-intel.md).
### INSTRUMENT LIST (selectively instrument files and functions)
- This feature allows selective instrumentation of the source
+This feature allows selective instrumentation of the source.
- - Setting `AFL_LLVM_ALLOWLIST` or `AFL_LLVM_DENYLIST` with a filenames and/or
- function will only instrument (or skip) those files that match the names
- listed in the specified file.
+Setting `AFL_LLVM_ALLOWLIST` or `AFL_LLVM_DENYLIST` with a filenames and/or function will only instrument (or skip) those files that match the names listed in the specified file.
- See [instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md) for more information.
+For more information, see [instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md).
### Thread safe instrumentation counters (in all modes)
- - Setting `AFL_LLVM_THREADSAFE_INST` will inject code that implements thread
- safe counters. The overhead is a little bit higher compared to the older
- non-thread safe case. Note that this disables neverzero (see below).
+Setting `AFL_LLVM_THREADSAFE_INST` will inject code that implements thread
+safe counters. The overhead is a little bit higher compared to the older
+non-thread safe case. Note that this disables neverzero (see below).
### NOT_ZERO
- - Setting `AFL_LLVM_NOT_ZERO=1` during compilation will use counters
- that skip zero on overflow. This is the default for llvm >= 9,
- however for llvm versions below that this will increase an unnecessary
- slowdown due a performance issue that is only fixed in llvm 9+.
- This feature increases path discovery by a little bit.
+ - Setting `AFL_LLVM_NOT_ZERO=1` during compilation will use counters
+ that skip zero on overflow. This is the default for llvm >= 9,
+ however, for llvm versions below that this will increase an unnecessary
+ slowdown due a performance issue that is only fixed in llvm 9+.
+ This feature increases path discovery by a little bit.
- - Setting `AFL_LLVM_SKIP_NEVERZERO=1` will not implement the skip zero
- test. If the target performs only few loops then this will give a
- small performance boost.
+ - Setting `AFL_LLVM_SKIP_NEVERZERO=1` will not implement the skip zero
+ test. If the target performs only few loops, then this will give a
+ small performance boost.
- See [instrumentation/README.neverzero.md](../instrumentation/README.neverzero.md)
+For more information, see [instrumentation/README.neverzero.md](../instrumentation/README.neverzero.md).
### CMPLOG
- - Setting `AFL_LLVM_CMPLOG=1` during compilation will tell afl-clang-fast to
- produce a CmpLog binary.
+ - Setting `AFL_LLVM_CMPLOG=1` during compilation will tell afl-clang-fast to
+ produce a CmpLog binary.
- See [instrumentation/README.cmplog.md](../instrumentation/README.cmplog.md)
+For more information, see [instrumentation/README.cmplog.md](../instrumentation/README.cmplog.md).
## 3) Settings for GCC / GCC_PLUGIN modes
Then there are a few specific features that are only available in GCC and
GCC_PLUGIN mode.
- - Setting `AFL_KEEP_ASSEMBLY` prevents afl-as from deleting instrumented
- assembly files. Useful for troubleshooting problems or understanding how
- the tool works. (GCC mode only)
- To get them in a predictable place, try something like:
-```
- mkdir assembly_here
- TMPDIR=$PWD/assembly_here AFL_KEEP_ASSEMBLY=1 make clean all
-```
- Setting `AFL_GCC_INSTRUMENT_FILE` with a filename will only instrument those
files that match the names listed in this file (one filename per line).
See [instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md) for more information.
(GCC_PLUGIN mode only)
+ - Setting `AFL_KEEP_ASSEMBLY` prevents afl-as from deleting instrumented
+ assembly files. Useful for troubleshooting problems or understanding how
+ the tool works. (GCC mode only)
+ To get them in a predictable place, try something like:
+
+ ```
+ mkdir assembly_here
+ TMPDIR=$PWD/assembly_here AFL_KEEP_ASSEMBLY=1 make clean all
+ ```
+
## 4) Settings for afl-fuzz
The main fuzzer binary accepts several options that disable a couple of sanity
checks or alter some of the more exotic semantics of the tool:
- - Setting `AFL_SKIP_CPUFREQ` skips the check for CPU scaling policy. This is
- useful if you can't change the defaults (e.g., no root access to the
- system) and are OK with some performance loss.
+ - Setting `AFL_AUTORESUME` will resume a fuzz run (same as providing `-i -`)
+ for an existing out folder, even if a different `-i` was provided.
+ Without this setting, afl-fuzz will refuse execution for a long-fuzzed out dir.
- - `AFL_EXIT_WHEN_DONE` causes afl-fuzz to terminate when all existing paths
- have been fuzzed and there were no new finds for a while. This would be
- normally indicated by the cycle counter in the UI turning green. May be
- convenient for some types of automated jobs.
-
- - `AFL_EXIT_ON_TIME` Causes afl-fuzz to terminate if no new paths were
- found within a specified period of time (in seconds). May be convenient
- for some types of automated jobs.
-
- - `AFL_EXIT_ON_SEED_ISSUES` will restore the vanilla afl-fuzz behaviour
- which does not allow crashes or timeout seeds in the initial -i corpus.
-
- - `AFL_MAP_SIZE` sets the size of the shared map that afl-fuzz, afl-showmap,
- afl-tmin and afl-analyze create to gather instrumentation data from
- the target. This must be equal or larger than the size the target was
- compiled with.
+ - Benchmarking only: `AFL_BENCH_JUST_ONE` causes the fuzzer to exit after
+ processing the first queue entry; and `AFL_BENCH_UNTIL_CRASH` causes it to
+ exit soon after the first crash is found.
- `AFL_CMPLOG_ONLY_NEW` will only perform the expensive cmplog feature for
newly found testcases and not for testcases that are loaded on startup
- (`-i in`). This is an important feature to set when resuming a fuzzing
- session.
+ (`-i in`).
+ This is an important feature to set when resuming a fuzzing session.
- - `AFL_TESTCACHE_SIZE` allows you to override the size of `#define TESTCASE_CACHE`
- in config.h. Recommended values are 50-250MB - or more if your fuzzing
- finds a huge amount of paths for large inputs.
-
- - Setting `AFL_DISABLE_TRIM` tells afl-fuzz not to trim test cases. This is
- usually a bad idea!
-
- - Setting `AFL_NO_AFFINITY` disables attempts to bind to a specific CPU core
- on Linux systems. This slows things down, but lets you run more instances
- of afl-fuzz than would be prudent (if you really want to).
-
- - Setting `AFL_TRY_AFFINITY` tries to attempt binding to a specific CPU core
- on Linux systems, but will not terminate if that fails.
-
- - Setting `AFL_NO_AUTODICT` will not load an LTO generated auto dictionary
- that is compiled into the target.
-
- - Setting `AFL_HANG_TMOUT` allows you to specify a different timeout for
- deciding if a particular test case is a "hang". The default is 1 second
- or the value of the `-t` parameter, whichever is larger. Dialing the value
- down can be useful if you are very concerned about slow inputs, or if you
- don't want AFL++ to spend too much time classifying that stuff and just
- rapidly put all timeouts in that bin.
-
- - Setting `AFL_FORKSRV_INIT_TMOUT` allows you to specify a different timeout
- to wait for the forkserver to spin up. The default is the `-t` value times
- `FORK_WAIT_MULT` from `config.h` (usually 10), so for a `-t 100`, the
- default would wait for `1000` milliseconds. Setting a different time here is useful
- if the target has a very slow startup time, for example when doing
- full-system fuzzing or emulation, but you don't want the actual runs
- to wait too long for timeouts.
-
- - `AFL_NO_ARITH` causes AFL++ to skip most of the deterministic arithmetics.
- This can be useful to speed up the fuzzing of text-based file formats.
-
- - `AFL_NO_SNAPSHOT` will advice afl-fuzz not to use the snapshot feature
- if the snapshot lkm is loaded
-
- - `AFL_SHUFFLE_QUEUE` randomly reorders the input queue on startup. Requested
- by some users for unorthodox parallelized fuzzing setups, but not
- advisable otherwise.
-
- - `AFL_TMPDIR` is used to write the `.cur_input` file to if exists, and in
- the normal output directory otherwise. You would use this to point to
- a ramdisk/tmpfs. This increases the speed by a small value but also
- reduces the stress on SSDs.
-
- - When developing custom instrumentation on top of afl-fuzz, you can use
- `AFL_SKIP_BIN_CHECK` to inhibit the checks for non-instrumented binaries
- and shell scripts; and `AFL_DUMB_FORKSRV` in conjunction with the `-n`
- setting to instruct afl-fuzz to still follow the fork server protocol
- without expecting any instrumentation data in return.
- Note that this also turns off auto map size detection.
-
- - When running in the `-M` or `-S` mode, setting `AFL_IMPORT_FIRST` causes the
- fuzzer to import test cases from other instances before doing anything
- else. This makes the "own finds" counter in the UI more accurate.
- Beyond counter aesthetics, not much else should change.
-
- - Note that `AFL_POST_LIBRARY` is deprecated, use `AFL_CUSTOM_MUTATOR_LIBRARY`
- instead (see below).
-
- - `AFL_KILL_SIGNAL`: Set the signal ID to be delivered to child processes on timeout.
- Unless you implement your own targets or instrumentation, you likely don't have to set it.
- By default, on timeout and on exit, `SIGKILL` (`AFL_KILL_SIGNAL=9`) will be delivered to the child.
+ - Setting `AFL_CRASH_EXITCODE` sets the exit code AFL treats as crash.
+ For example, if `AFL_CRASH_EXITCODE='-1'` is set, each input resulting
+ in an `-1` return code (i.e. `exit(-1)` got called), will be treated
+ as if a crash had ocurred.
+ This may be beneficial if you look for higher-level faulty conditions in which your target still exits gracefully.
- Setting `AFL_CUSTOM_MUTATOR_LIBRARY` to a shared library with
afl_custom_fuzz() creates additional mutations through this library.
@@ -380,70 +291,9 @@ checks or alter some of the more exotic semantics of the tool:
e.g. fuzzing XML or other highly flexible structured input.
Please see [custom_mutators.md](custom_mutators.md).
- - `AFL_FAST_CAL` keeps the calibration stage about 2.5x faster (albeit less
- precise), which can help when starting a session against a slow target.
- `AFL_CAL_FAST` works too.
-
- - The CPU widget shown at the bottom of the screen is fairly simplistic and
- may complain of high load prematurely, especially on systems with low core
- counts. To avoid the alarming red color, you can set `AFL_NO_CPU_RED`.
-
- - In QEMU mode (-Q) and Frida mode (-O), `AFL_PATH` will
- be searched for afl-qemu-trace and afl-frida-trace.so.
-
- - In QEMU mode (-Q), setting `AFL_QEMU_CUSTOM_BIN` cause afl-fuzz to skip
- prepending `afl-qemu-trace` to your command line. Use this if you wish to use a
- custom afl-qemu-trace or if you need to modify the afl-qemu-trace arguments.
-
- Setting `AFL_CYCLE_SCHEDULES` will switch to a different schedule everytime
a cycle is finished.
- - Setting `AFL_EXPAND_HAVOC_NOW` will start in the extended havoc mode that
- includes costly mutations. afl-fuzz automatically enables this mode when
- deemed useful otherwise.
-
- - Setting `AFL_PRELOAD` causes AFL++ to set `LD_PRELOAD` for the target binary
- without disrupting the afl-fuzz process itself. This is useful, among other
- things, for bootstrapping libdislocator.so.
-
- - Setting `AFL_TARGET_ENV` causes AFL++ to set extra environment variables
- for the target binary. Example: `AFL_TARGET_ENV="VAR1=1 VAR2='a b c'" afl-fuzz ... `
- This exists mostly for things like `LD_LIBRARY_PATH` but it would theoretically
- allow fuzzing of AFL++ itself (with 'target' AFL++ using some AFL_ vars that
- would disrupt work of 'fuzzer' AFL++).
-
- - Setting `AFL_NO_UI` inhibits the UI altogether, and just periodically prints
- some basic stats. This behavior is also automatically triggered when the
- output from afl-fuzz is redirected to a file or to a pipe.
-
- - Setting `AFL_NO_COLOR` or `AFL_NO_COLOUR` will omit control sequences for
- coloring console output when configured with USE_COLOR and not ALWAYS_COLORED.
-
- - 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))
- 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
- with a value of how many previous fuzz cases to keep prio a crash.
- if set to e.g. 10, then the 9 previous inputs are written to
- out/default/crashes as RECORD:000000,cnt:000000 to RECORD:000000,cnt:000008
- and RECORD:000000,cnt:000009 being the crash case.
- NOTE: This option needs to be enabled in config.h first!
-
- - If afl-fuzz encounters an incorrect fuzzing setup during a fuzzing session
- (not at startup), it will terminate. If you do not want this then you can
- set `AFL_IGNORE_PROBLEMS`.
-
- - If you are Jakub, you may need `AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES`.
- Others need not apply, unless they also want to disable the
- `/proc/sys/kernel/core_pattern` check.
-
- - Benchmarking only: `AFL_BENCH_JUST_ONE` causes the fuzzer to exit after
- processing the first queue entry; and `AFL_BENCH_UNTIL_CRASH` causes it to
- exit soon after the first crash is found.
-
- Setting `AFL_DEBUG_CHILD` will not suppress the child output.
This lets you see all output of the child, making setup issues obvious.
For example, in an unicornafl harness, you might see python stacktraces.
@@ -451,64 +301,175 @@ checks or alter some of the more exotic semantics of the tool:
Not pretty but good for debugging purposes.
Note that `AFL_DEBUG_CHILD_OUTPUT` is deprecated.
- - Setting `AFL_NO_CPU_RED` will not display very high cpu usages in red color.
+ - Setting `AFL_DISABLE_TRIM` tells afl-fuzz not to trim test cases. This is
+ usually a bad idea!
- - Setting `AFL_AUTORESUME` will resume a fuzz run (same as providing `-i -`)
- for an existing out folder, even if a different `-i` was provided.
- Without this setting, afl-fuzz will refuse execution for a long-fuzzed out dir.
+ - `AFL_EXIT_ON_SEED_ISSUES` will restore the vanilla afl-fuzz behaviour
+ which does not allow crashes or timeout seeds in the initial -i corpus.
- - Setting `AFL_MAX_DET_EXRAS` will change the threshold at what number of elements
- in the `-x` dictionary and LTO autodict (combined) the probabilistic mode will
- kick off. In probabilistic mode, not all dictionary entries will be used all
- of the time for fuzzing mutations to not slow down fuzzing.
- The default count is `200` elements. So for the 200 + 1st element, there is a
- 1 in 201 chance, that one of the dictionary entries will not be used directly.
+ - `AFL_EXIT_ON_TIME` Causes afl-fuzz to terminate if no new paths were
+ found within a specified period of time (in seconds). May be convenient
+ for some types of automated jobs.
+
+ - `AFL_EXIT_WHEN_DONE` causes afl-fuzz to terminate when all existing paths
+ have been fuzzed and there were no new finds for a while. This would be
+ normally indicated by the cycle counter in the UI turning green. May be
+ convenient for some types of automated jobs.
+
+ - Setting `AFL_EXPAND_HAVOC_NOW` will start in the extended havoc mode that
+ includes costly mutations. afl-fuzz automatically enables this mode when
+ deemed useful otherwise.
+
+ - `AFL_FAST_CAL` keeps the calibration stage about 2.5x faster (albeit less
+ precise), which can help when starting a session against a slow target.
+ `AFL_CAL_FAST` works too.
+
+ - Setting `AFL_FORCE_UI` will force painting the UI on the screen even if
+ no valid terminal was detected (for virtual consoles).
+
+ - Setting `AFL_FORKSRV_INIT_TMOUT` allows you to specify a different timeout
+ to wait for the forkserver to spin up.
+ The default is the `-t` value times `FORK_WAIT_MULT` from `config.h` (usually 10), so for a `-t 100`, the default would wait for `1000` milliseconds.
+ Setting a different time here is useful if the target has a very slow startup time, for example when doing full-system fuzzing or emulation, but you don't want the actual runs to wait too long for timeouts.
+
+ - Setting `AFL_HANG_TMOUT` allows you to specify a different timeout for
+ deciding if a particular test case is a "hang". The default is 1 second
+ or the value of the `-t` parameter, whichever is larger. Dialing the value
+ down can be useful if you are very concerned about slow inputs, or if you
+ don't want AFL++ to spend too much time classifying that stuff and just
+ rapidly put all timeouts in that bin.
+
+ - If you are Jakub, you may need `AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES`.
+ Others need not apply, unless they also want to disable the
+ `/proc/sys/kernel/core_pattern` check.
+
+ - If afl-fuzz encounters an incorrect fuzzing setup during a fuzzing session
+ (not at startup), it will terminate. If you do not want this, then you can
+ set `AFL_IGNORE_PROBLEMS`.
+
+ - When running in the `-M` or `-S` mode, setting `AFL_IMPORT_FIRST` causes the
+ fuzzer to import test cases from other instances before doing anything
+ else.
+ This makes the "own finds" counter in the UI more accurate.
+ Beyond counter aesthetics, not much else should change.
+
+ - `AFL_KILL_SIGNAL`: Set the signal ID to be delivered to child processes on timeout.
+ Unless you implement your own targets or instrumentation, you likely don't have to set it.
+ By default, on timeout and on exit, `SIGKILL` (`AFL_KILL_SIGNAL=9`) will be delivered to the child.
+
+ - `AFL_MAP_SIZE` sets the size of the shared map that afl-fuzz, afl-showmap,
+ afl-tmin and afl-analyze create to gather instrumentation data from
+ the target. This must be equal or larger than the size the target was
+ compiled with.
+
+ - Setting `AFL_MAX_DET_EXRAS` will change the threshold at what number of elements in the `-x` dictionary and LTO autodict (combined) the probabilistic mode will kick off.
+ In probabilistic mode, not all dictionary entries will be used all of the time for fuzzing mutations to not slow down fuzzing.
+ The default count is `200` elements.
+ So for the 200 + 1st element, there is a 1 in 201 chance, that one of the dictionary entries will not be used directly.
+
+ - Setting `AFL_NO_AFFINITY` disables attempts to bind to a specific CPU core
+ on Linux systems. This slows things down, but lets you run more instances
+ of afl-fuzz than would be prudent (if you really want to).
+
+ - `AFL_NO_ARITH` causes AFL++ to skip most of the deterministic arithmetics.
+ This can be useful to speed up the fuzzing of text-based file formats.
+
+ - Setting `AFL_NO_AUTODICT` will not load an LTO generated auto dictionary
+ that is compiled into the target.
+
+ - The CPU widget shown at the bottom of the screen is fairly simplistic and
+ may complain of high load prematurely, especially on systems with low core
+ counts.
+ To avoid the alarming red color for very high cpu usages, you can set `AFL_NO_CPU_RED`.
+
+ - Setting `AFL_NO_COLOR` or `AFL_NO_COLOUR` will omit control sequences for
+ coloring console output when configured with USE_COLOR and not ALWAYS_COLORED.
- Setting `AFL_NO_FORKSRV` disables the forkserver optimization, reverting to
- fork + execve() call for every tested input. This is useful mostly when
- working with unruly libraries that create threads or do other crazy
- things when initializing (before the instrumentation has a chance to run).
+ fork + execve() call for every tested input.
+ This is useful mostly when working with unruly libraries that create threads or do other crazy things when initializing (before the instrumentation has a chance to run).
Note that this setting inhibits some of the user-friendly diagnostics
normally done when starting up the forkserver and causes a pretty
significant performance drop.
+ - `AFL_NO_SNAPSHOT` will advice afl-fuzz not to use the snapshot feature
+ if the snapshot lkm is loaded.
+
+ - Setting `AFL_NO_UI` inhibits the UI altogether, and just periodically prints
+ some basic stats.
+ This behavior is also automatically triggered when the output from afl-fuzz is redirected to a file or to a pipe.
+
+ - In QEMU mode (-Q) and Frida mode (-O), `AFL_PATH` will be searched for afl-qemu-trace and afl-frida-trace.so.
+
+ - 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 with a value of how many previous fuzz cases to keep prio a crash.
+ If set to e.g. 10, then the 9 previous inputs are written to out/default/crashes as RECORD:000000,cnt:000000 to RECORD:000000,cnt:000008 and RECORD:000000,cnt:000009 being the crash case.
+ NOTE: This option needs to be enabled in config.h first!
+
+ - Note that `AFL_POST_LIBRARY` is deprecated, use `AFL_CUSTOM_MUTATOR_LIBRARY`
+ instead (see below).
+
+ - Setting `AFL_PRELOAD` causes AFL++ to set `LD_PRELOAD` for the target binary
+ without disrupting the afl-fuzz process itself.
+ This is useful, among other things, for bootstrapping libdislocator.so.
+
+ - In QEMU mode (-Q), setting `AFL_QEMU_CUSTOM_BIN` will cause afl-fuzz to skip
+ prepending `afl-qemu-trace` to your command line.
+ Use this if you wish to use a custom afl-qemu-trace or if you need to modify the afl-qemu-trace arguments.
+
+ - `AFL_SHUFFLE_QUEUE` randomly reorders the input queue on startup.
+ Requested by some users for unorthodox parallelized fuzzing setups, but not
+ advisable otherwise.
+
+ - When developing custom instrumentation on top of afl-fuzz, you can use
+ `AFL_SKIP_BIN_CHECK` to inhibit the checks for non-instrumented binaries
+ and shell scripts; and `AFL_DUMB_FORKSRV` in conjunction with the `-n`
+ setting to instruct afl-fuzz to still follow the fork server protocol
+ without expecting any instrumentation data in return.
+ Note that this also turns off auto map size detection.
+
+ - Setting `AFL_SKIP_CPUFREQ` skips the check for CPU scaling policy. This is
+ useful if you can't change the defaults (e.g., no root access to the
+ system) and are OK with some performance loss.
+
- Setting `AFL_STATSD` enables StatsD metrics collection.
- By default AFL++ will send these metrics over UDP to 127.0.0.1:8125.
+ By default, AFL++ will send these metrics over UDP to 127.0.0.1:8125.
The host and port are configurable with `AFL_STATSD_HOST` and `AFL_STATSD_PORT` respectively.
- To enable tags (banner and afl_version) you should provide `AFL_STATSD_TAGS_FLAVOR` that matches
- your StatsD server (see `AFL_STATSD_TAGS_FLAVOR`)
+ To enable tags (banner and afl_version), you should provide `AFL_STATSD_TAGS_FLAVOR` that matches your StatsD server (see `AFL_STATSD_TAGS_FLAVOR`).
- - Setting `AFL_STATSD_TAGS_FLAVOR` to one of `dogstatsd`, `librato`, `signalfx` or `influxdb`
- allows you to add tags to your fuzzing instances. This is especially useful when running
- multiple instances (`-M/-S` for example). Applied tags are `banner` and `afl_version`.
+ - Setting `AFL_STATSD_TAGS_FLAVOR` to one of `dogstatsd`, `librato`, `signalfx` or `influxdb` allows you to add tags to your fuzzing instances.
+ This is especially useful when running multiple instances (`-M/-S` for example).
+ Applied tags are `banner` and `afl_version`.
`banner` corresponds to the name of the fuzzer provided through `-M/-S`.
- `afl_version` corresponds to the currently running AFL version (e.g `++3.0c`).
+ `afl_version` corresponds to the currently running AFL version (e.g. `++3.0c`).
Default (empty/non present) will add no tags to the metrics.
- See [rpc_statsd.md](rpc_statsd.md) for more information.
+ For more information, see [rpc_statsd.md](rpc_statsd.md).
- - Setting `AFL_CRASH_EXITCODE` sets the exit code AFL treats as crash.
- For example, if `AFL_CRASH_EXITCODE='-1'` is set, each input resulting
- in an `-1` return code (i.e. `exit(-1)` got called), will be treated
- as if a crash had ocurred.
- This may be beneficial if you look for higher-level faulty conditions in which your
- target still exits gracefully.
+ - Setting `AFL_TARGET_ENV` causes AFL++ to set extra environment variables
+ for the target binary. Example: `AFL_TARGET_ENV="VAR1=1 VAR2='a b c'" afl-fuzz ... `.
+ This exists mostly for things like `LD_LIBRARY_PATH` but it would theoretically allow fuzzing of AFL++ itself (with 'target' AFL++ using some AFL_ vars that would disrupt work of 'fuzzer' AFL++).
+
+ - `AFL_TESTCACHE_SIZE` allows you to override the size of `#define TESTCASE_CACHE`
+ in config.h. Recommended values are 50-250MB - or more if your fuzzing
+ finds a huge amount of paths for large inputs.
+
+ - `AFL_TMPDIR` is used to write the `.cur_input` file to if exists, and in
+ the normal output directory otherwise.
+ You would use this to point to a ramdisk/tmpfs.
+ This increases the speed by a small value but also reduces the stress on SSDs.
+
+ - Setting `AFL_TRY_AFFINITY` tries to attempt binding to a specific CPU core
+ on Linux systems, but will not terminate if that fails.
- Outdated environment variables that are not supported anymore:
- `AFL_DEFER_FORKSRV`
- `AFL_PERSISTENT`
+ - `AFL_DEFER_FORKSRV`
+ - `AFL_PERSISTENT`
## 5) Settings for afl-qemu-trace
The QEMU wrapper used to instrument binary-only code supports several settings:
- - It is possible to set `AFL_INST_RATIO` to skip the instrumentation on some
- of the basic blocks, which can be useful when dealing with very complex
- binaries.
-
- - Setting `AFL_INST_LIBS` causes the translator to also instrument the code
- inside any dynamically linked libraries (notably including glibc).
-
- Setting `AFL_COMPCOV_LEVEL` enables the CompareCoverage tracing of all cmp
and sub in x86 and x86_64 and memory comparions functions (e.g. strcmp,
memcmp, ...) when libcompcov is preloaded using `AFL_PRELOAD`.
@@ -518,74 +479,77 @@ The QEMU wrapper used to instrument binary-only code supports several settings:
`AFL_COMPCOV_LEVEL=2` that instruments all the comparions. Level 2 is more
accurate but may need a larger shared memory.
- - Setting `AFL_QEMU_COMPCOV` enables the CompareCoverage tracing of all
- cmp and sub in x86 and x86_64.
- This is an alias of `AFL_COMPCOV_LEVEL=1` when `AFL_COMPCOV_LEVEL` is
- not specified.
-
- - The underlying QEMU binary will recognize any standard "user space
- emulation" variables (e.g., `QEMU_STACK_SIZE`), but there should be no
- reason to touch them.
-
- `AFL_DEBUG` will print the found entrypoint for the binary to stderr.
Use this if you are unsure if the entrypoint might be wrong - but
- use it directly, e.g. `afl-qemu-trace ./program`
+ use it directly, e.g. `afl-qemu-trace ./program`.
- `AFL_ENTRYPOINT` allows you to specify a specific entrypoint into the
binary (this can be very good for the performance!).
The entrypoint is specified as hex address, e.g. `0x4004110`
Note that the address must be the address of a basic block.
+ - Setting `AFL_INST_LIBS` causes the translator to also instrument the code
+ inside any dynamically linked libraries (notably including glibc).
+
+ - It is possible to set `AFL_INST_RATIO` to skip the instrumentation on some
+ of the basic blocks, which can be useful when dealing with very complex
+ binaries.
+
+ - Setting `AFL_QEMU_COMPCOV` enables the CompareCoverage tracing of all
+ cmp and sub in x86 and x86_64.
+ This is an alias of `AFL_COMPCOV_LEVEL=1` when `AFL_COMPCOV_LEVEL` is
+ not specified.
+
+ - With `AFL_QEMU_FORCE_DFL` you force QEMU to ignore the registered signal
+ handlers of the target.
+
- When the target is i386/x86_64 you can specify the address of the function
that has to be the body of the persistent loop using
`AFL_QEMU_PERSISTENT_ADDR=start addr`.
+ - `AFL_QEMU_PERSISTENT_GPR=1` QEMU will save the original value of general
+ purpose registers and restore them in each persistent cycle.
+
- Another modality to execute the persistent loop is to specify also the
`AFL_QEMU_PERSISTENT_RET=end addr` env variable.
With this variable assigned, instead of patching the return address, the
specified instruction is transformed to a jump towards `start addr`.
- - `AFL_QEMU_PERSISTENT_GPR=1` QEMU will save the original value of general
- purpose registers and restore them in each persistent cycle.
-
- - With `AFL_QEMU_PERSISTENT_RETADDR_OFFSET` you can specify the offset from the
- stack pointer in which QEMU can find the return address when `start addr` is
- hit.
+ - With `AFL_QEMU_PERSISTENT_RETADDR_OFFSET` you can specify the offset from the stack pointer in which QEMU can find the return address when `start addr` is hit.
- With `AFL_USE_QASAN` you can enable QEMU AddressSanitizer for dynamically
linked binaries.
- - With `AFL_QEMU_FORCE_DFL` you force QEMU to ignore the registered signal
- handlers of the target.
+ - The underlying QEMU binary will recognize any standard "user space
+ emulation" variables (e.g., `QEMU_STACK_SIZE`), but there should be no
+ reason to touch them.
## 6) Settings for afl-cmin
The corpus minimization script offers very little customization:
- - Setting `AFL_PATH` offers a way to specify the location of afl-showmap
- and afl-qemu-trace (the latter only in `-Q` mode).
+ - `AFL_ALLOW_TMP` permits this and some other scripts to run in /tmp.
+ This is a modest security risk on multi-user systems with rogue users, but should be safe on dedicated fuzzing boxes.
- `AFL_KEEP_TRACES` makes the tool keep traces and other metadata used for
- minimization and normally deleted at exit. The files can be found in the
- `/.traces/` directory.
+ minimization and normally deleted at exit.
+ The files can be found in the `/.traces/` directory.
- - `AFL_ALLOW_TMP` permits this and some other scripts to run in /tmp. This is
- a modest security risk on multi-user systems with rogue users, but should
- be safe on dedicated fuzzing boxes.
+ - Setting `AFL_PATH` offers a way to specify the location of afl-showmap
+ and afl-qemu-trace (the latter only in `-Q` mode).
- `AFL_PRINT_FILENAMES` prints each filename to stdout, as it gets processed.
This can help when embedding `afl-cmin` or `afl-showmap` in other scripts scripting.
## 7) Settings for afl-tmin
-Virtually nothing to play with. Well, in QEMU mode (`-Q`), `AFL_PATH` will be
-searched for afl-qemu-trace. In addition to this, `TMPDIR` may be used if a
-temporary file can't be created in the current working directory.
+Virtually nothing to play with.
+Well, in QEMU mode (`-Q`), `AFL_PATH` will be searched for afl-qemu-trace.
+In addition to this, `TMPDIR` may be used if a temporary file can't be created in the current working directory.
-You can specify `AFL_TMIN_EXACT` if you want afl-tmin to require execution paths
-to match when minimizing crashes. This will make minimization less useful, but
-may prevent the tool from "jumping" from one crashing condition to another in
-very buggy software. You probably want to combine it with the `-e` flag.
+You can specify `AFL_TMIN_EXACT` if you want afl-tmin to require execution paths to match when minimizing crashes.
+This will make minimization less useful, but may prevent the tool from "jumping" from one crashing condition to another in very buggy software.
+You probably want to combine it with the `-e` flag.
## 8) Settings for afl-analyze
@@ -596,23 +560,23 @@ of decimal.
The library honors these environmental variables:
- - `AFL_LD_LIMIT_MB` caps the size of the maximum heap usage permitted by the
- library, in megabytes. The default value is 1 GB. Once this is exceeded,
- allocations will return NULL.
+ - `AFL_ALIGNED_ALLOC=1` will force the alignment of the allocation size to
+ `max_align_t` to be compliant with the C standard.
- `AFL_LD_HARD_FAIL` alters the behavior by calling `abort()` on excessive
allocations, thus causing what AFL++ would perceive as a crash. Useful for
programs that are supposed to maintain a specific memory footprint.
- - `AFL_LD_VERBOSE` causes the library to output some diagnostic messages
- that may be useful for pinpointing the cause of any observed issues.
+ - `AFL_LD_LIMIT_MB` caps the size of the maximum heap usage permitted by the
+ library, in megabytes. The default value is 1 GB. Once this is exceeded,
+ allocations will return NULL.
- `AFL_LD_NO_CALLOC_OVER` inhibits `abort()` on `calloc()` overflows. Most
of the common allocators check for that internally and return NULL, so
it's a security risk only in more exotic setups.
- - `AFL_ALIGNED_ALLOC=1` will force the alignment of the allocation size to
- `max_align_t` to be compliant with the C standard.
+ - `AFL_LD_VERBOSE` causes the library to output some diagnostic messages
+ that may be useful for pinpointing the cause of any observed issues.
## 10) Settings for libtokencap
@@ -630,34 +594,37 @@ optimal values if not already present in the environment:
certainly pointless.
- By default, `ASAN_OPTIONS` are set to (among others):
-```
+
+ ```
abort_on_error=1
detect_leaks=0
malloc_context_size=0
symbolize=0
allocator_may_return_null=1
-```
- If you want to set your own options, be sure to include `abort_on_error=1` -
+ ```
+
+ If you want to set your own options, be sure to include `abort_on_error=1` -
otherwise, the fuzzer will not be able to detect crashes in the tested
app. Similarly, include `symbolize=0`, since without it, AFL++ may have
difficulty telling crashes and hangs apart.
+ - Similarly, the default `LSAN_OPTIONS` are set to:
+
+ ```
+ exit_code=23
+ fast_unwind_on_malloc=0
+ symbolize=0
+ print_suppressions=0
+ ```
+
+ Be sure to include the first ones for LSAN and MSAN when customizing anything, since some MSAN and LSAN versions don't call `abort()` on error, and we need a way to detect faults.
+
- In the same vein, by default, `MSAN_OPTIONS` are set to:
-```
+
+ ```
exit_code=86 (required for legacy reasons)
abort_on_error=1
symbolize=0
msan_track_origins=0
allocator_may_return_null=1
-```
- - Similarly, the default `LSAN_OPTIONS` are set to:
-```
- exit_code=23
- fast_unwind_on_malloc=0
- symbolize=0
- print_suppressions=0
-```
- Be sure to include the first ones for LSAN and MSAN when customizing
- anything, since some MSAN and LSAN versions don't call `abort()` on
- error, and we need a way to detect faults.
-
+ ```
\ No newline at end of file
From bb255fdd790dfa4027f511ae3a8eebbbfd6b42e8 Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Sat, 30 Oct 2021 21:42:21 +0200
Subject: [PATCH 116/305] Fix line breaks
---
docs/env_variables.md | 527 +++++++++++++++++++++++-------------------
1 file changed, 292 insertions(+), 235 deletions(-)
diff --git a/docs/env_variables.md b/docs/env_variables.md
index bd66ce38..6fb687e2 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -1,9 +1,13 @@
# Environment variables
- This document discusses the environment variables used by AFL++ to expose various exotic functions that may be (rarely) useful for power users or for some types of custom fuzzing setups.
- For general information about AFL++, see [README.md](../README.md).
+ This document discusses the environment variables used by AFL++ to expose
+ various exotic functions that may be (rarely) useful for power users or for
+ some types of custom fuzzing setups. For general information about AFL++, see
+ [README.md](../README.md).
- Note: Most tools will warn on any unknown AFL++ environment variables; for example, because of typos. If you want to disable this check, then set the `AFL_IGNORE_UNKNOWN_ENVS` environment variable.
+ Note: Most tools will warn on any unknown AFL++ environment variables; for
+ example, because of typos. If you want to disable this check, then set the
+ `AFL_IGNORE_UNKNOWN_ENVS` environment variable.
## 1) Settings for all compilers
@@ -11,19 +15,26 @@ Starting with AFL++ 3.0, there is only one compiler: afl-cc.
To select the different instrumentation modes, use one of the following options:
- - Pass the --afl-MODE command-line option to the compiler. Only this option accepts further AFL-specific command-line options.
- - Use a symlink to afl-cc: afl-clang, afl-clang++, afl-clang-fast, afl-clang-fast++, afl-clang-lto, afl-clang-lto++, afl-gcc, afl-g++, afl-gcc-fast, afl-g++-fast. This option does not accept AFL-specific command-line options. Instead, use environment variables.
- - Use the `AFL_CC_COMPILER` environment variable with `MODE`. To select `MODE`, use one of the following values:
+ - Pass the --afl-MODE command-line option to the compiler. Only this option
+ accepts further AFL-specific command-line options.
+ - Use a symlink to afl-cc: afl-clang, afl-clang++, afl-clang-fast,
+ afl-clang-fast++, afl-clang-lto, afl-clang-lto++, afl-gcc, afl-g++,
+ afl-gcc-fast, afl-g++-fast. This option does not accept AFL-specific
+ command-line options. Instead, use environment variables.
+ - Use the `AFL_CC_COMPILER` environment variable with `MODE`. To select
+ `MODE`, use one of the following values:
- `GCC` (afl-gcc/afl-g++)
- `GCC_PLUGIN` (afl-g*-fast)
- `LLVM` (afl-clang-fast*)
- `LTO` (afl-clang-lto*).
-The compile-time tools do not accept AFL-specific command-line options. The --afl-MODE command line option is the only exception. The other options make fairly broad use of environment variables instead:
+The compile-time tools do not accept AFL-specific command-line options. The
+--afl-MODE command line option is the only exception. The other options make
+fairly broad use of environment variables instead:
- - Some build/configure scripts break with AFL++ compilers.
- To be able to pass them, do:
+ - Some build/configure scripts break with AFL++ compilers. To be able to pass
+ them, do:
```
export CC=afl-cc
@@ -34,25 +45,24 @@ The compile-time tools do not accept AFL-specific command-line options. The --af
make
```
- - If you are a weird person that wants to compile and instrument asm
- text files, then use the `AFL_AS_FORCE_INSTRUMENT` variable:
+ - If you are a weird person that wants to compile and instrument asm text
+ files, then use the `AFL_AS_FORCE_INSTRUMENT` variable:
`AFL_AS_FORCE_INSTRUMENT=1 afl-gcc foo.s -o foo`
- Setting `AFL_CC`, `AFL_CXX`, and `AFL_AS` lets you use alternate downstream
compilation tools, rather than the default 'clang', 'gcc', or 'as' binaries
in your `$PATH`.
- - Most AFL tools do not print any output if stdout/stderr are redirected.
- If you want to get the output into a file, then set the `AFL_DEBUG`
- environment variable.
- This is sadly necessary for various build processes which fail otherwise.
+ - Most AFL tools do not print any output if stdout/stderr are redirected. If
+ you want to get the output into a file, then set the `AFL_DEBUG` environment
+ variable. This is sadly necessary for various build processes which fail
+ otherwise.
- By default, the wrapper appends `-O3` to optimize builds. Very rarely, this
will cause problems in programs built with -Werror, simply because `-O3`
- enables more thorough code analysis and can spew out additional warnings.
- To disable optimizations, set `AFL_DONT_OPTIMIZE`.
- However, if `-O...` and/or `-fno-unroll-loops` are set, these are not
- overridden.
+ enables more thorough code analysis and can spew out additional warnings. To
+ disable optimizations, set `AFL_DONT_OPTIMIZE`. However, if `-O...` and/or
+ `-fno-unroll-loops` are set, these are not overridden.
- Setting `AFL_HARDEN` automatically adds code hardening options when invoking
the downstream compiler. This currently includes `-D_FORTIFY_SOURCE=2` and
@@ -60,9 +70,9 @@ The compile-time tools do not accept AFL-specific command-line options. The --af
memory bugs at the expense of a very slight (sub-5%) performance loss.
- Setting `AFL_INST_RATIO` to a percentage between 0 and 100 controls the
- probability of instrumenting every branch. This is (very rarely) useful
- when dealing with exceptionally complex programs that saturate the output
- bitmap. Examples include v8, ffmpeg, and perl.
+ probability of instrumenting every branch. This is (very rarely) useful when
+ dealing with exceptionally complex programs that saturate the output bitmap.
+ Examples include v8, ffmpeg, and perl.
(If this ever happens, afl-fuzz will warn you ahead of the time by
displaying the "bitmap density" field in fiery red.)
@@ -70,18 +80,17 @@ The compile-time tools do not accept AFL-specific command-line options. The --af
Setting `AFL_INST_RATIO` to 0 is a valid choice. This will instrument only
the transitions between function entry points, but not individual branches.
- Note that this is an outdated variable. A few instances (e.g. afl-gcc)
- still support these, but state-of-the-art (e.g. LLVM LTO and LLVM PCGUARD)
- do not need this.
+ Note that this is an outdated variable. A few instances (e.g. afl-gcc) still
+ support these, but state-of-the-art (e.g. LLVM LTO and LLVM PCGUARD) do not
+ need this.
- `AFL_NO_BUILTIN` causes the compiler to generate code suitable for use with
libtokencap.so (but perhaps running a bit slower than without the flag).
- `AFL_PATH` can be used to point afl-gcc to an alternate location of afl-as.
- One possible use of this is utils/clang_asm_normalize/, which lets
- you instrument hand-written assembly when compiling clang code by plugging
- a normalizer into the chain.
- (There is no equivalent feature for GCC.)
+ One possible use of this is utils/clang_asm_normalize/, which lets you
+ instrument hand-written assembly when compiling clang code by plugging a
+ normalizer into the chain. (There is no equivalent feature for GCC.)
- Setting `AFL_QUIET` will prevent afl-cc and afl-as banners from being
displayed during compilation, in case you find them distracting.
@@ -95,19 +104,20 @@ The compile-time tools do not accept AFL-specific command-line options. The --af
there is the Control Flow Integrity sanitizer that can be activated by
`AFL_USE_CFISAN=1`.)
- - Setting `AFL_USE_LSAN` automatically enables Leak-Sanitizer, provided
- that your compiler supports it. To perform a leak check within your
- program at a certain point (such as at the end of an __AFL_LOOP),
- you can run the macro __AFL_LEAK_CHECK(); which will cause
- an abort if any memory is leaked (you can combine this with the
- LSAN_OPTIONS=suppressions option to supress some known leaks).
+ - Setting `AFL_USE_LSAN` automatically enables Leak-Sanitizer, provided that
+ your compiler supports it. To perform a leak check within your program at a
+ certain point (such as at the end of an __AFL_LOOP), you can run the macro
+ __AFL_LEAK_CHECK(); which will cause an abort if any memory is leaked (you
+ can combine this with the LSAN_OPTIONS=suppressions option to supress some
+ known leaks).
- `TMPDIR` is used by afl-as for temporary files; if this variable is not set,
the tool defaults to /tmp.
## 2) Settings for LLVM and LTO: afl-clang-fast / afl-clang-fast++ / afl-clang-lto / afl-clang-lto++
-The native instrumentation helpers (instrumentation and gcc_plugin) accept a subset of the settings discussed in section 1, with the exception of:
+The native instrumentation helpers (instrumentation and gcc_plugin) accept a
+subset of the settings discussed in section 1, with the exception of:
- LLVM modes support `AFL_LLVM_DICT2FILE=/absolute/path/file.txt` which will
write all constant string comparisons to this file to be used later with
@@ -118,10 +128,11 @@ The native instrumentation helpers (instrumentation and gcc_plugin) accept a sub
- `TMPDIR` and `AFL_KEEP_ASSEMBLY`, since no temporary assembly files are
created.
- - `AFL_INST_RATIO`, as we use collision free instrumentation by default.
- Not all passes support this option though as it is an outdated feature.
+ - `AFL_INST_RATIO`, as we use collision free instrumentation by default. Not
+ all passes support this option though as it is an outdated feature.
-Then there are a few specific features that are only available in instrumentation mode:
+Then there are a few specific features that are only available in
+instrumentation mode:
### Select the instrumentation mode
@@ -132,7 +143,8 @@ Available options:
- CLANG - outdated clang instrumentation
- CLASSIC - classic AFL (map[cur_loc ^ prev_loc >> 1]++) (default)
- You can also specify CTX and/or NGRAM, seperate the options with a comma "," then, e.g.: `AFL_LLVM_INSTRUMENT=CLASSIC,CTX,NGRAM-4`
+ You can also specify CTX and/or NGRAM, seperate the options with a comma ","
+ then, e.g.: `AFL_LLVM_INSTRUMENT=CLASSIC,CTX,NGRAM-4`
Note: It is actually not a good idea to use both CTX and NGRAM. :)
- CTX - context sensitive instrumentation (see below)
@@ -144,97 +156,119 @@ Available options:
#### CTX
-Setting `AFL_LLVM_CTX` or `AFL_LLVM_INSTRUMENT=CTX` activates context sensitive branch coverage - meaning that each edge is additionally combined with its caller.
-It is highly recommended to increase the `MAP_SIZE_POW2` definition in config.h to at least 18 and maybe up to 20 for this as otherwise too many map collisions occur.
+Setting `AFL_LLVM_CTX` or `AFL_LLVM_INSTRUMENT=CTX` activates context sensitive
+branch coverage - meaning that each edge is additionally combined with its
+caller. It is highly recommended to increase the `MAP_SIZE_POW2` definition in
+config.h to at least 18 and maybe up to 20 for this as otherwise too many map
+collisions occur.
-For more information, see [instrumentation/README.ctx.md](../instrumentation/README.ctx.md).
+For more information, see
+[instrumentation/README.ctx.md](../instrumentation/README.ctx.md).
#### LTO
-This is a different kind way of instrumentation: first it compiles all code in LTO (link time optimization) and then performs an edge inserting instrumentation which is 100% collision free (collisions are a big issue in AFL and AFL-like instrumentations).
-This is performed by using afl-clang-lto/afl-clang-lto++ instead of afl-clang-fast, but is only built if LLVM 11 or newer is used.
+This is a different kind way of instrumentation: first it compiles all code in
+LTO (link time optimization) and then performs an edge inserting instrumentation
+which is 100% collision free (collisions are a big issue in AFL and AFL-like
+instrumentations). This is performed by using afl-clang-lto/afl-clang-lto++
+instead of afl-clang-fast, but is only built if LLVM 11 or newer is used.
- - `AFL_LLVM_INSTRUMENT=CFG` will use Control Flow Graph instrumentation.
- (not recommended for afl-clang-fast, default for afl-clang-lto as there
- it is a different and better kind of instrumentation.)
+ - `AFL_LLVM_INSTRUMENT=CFG` will use Control Flow Graph instrumentation. (not
+ recommended for afl-clang-fast, default for afl-clang-lto as there it is a
+ different and better kind of instrumentation.)
-None of the following options are necessary to be used and are rather for manual use (which only ever the author of this LTO implementation will use).
-These are used if several separated instrumentations are performed which are then later combined.
+None of the following options are necessary to be used and are rather for manual
+use (which only ever the author of this LTO implementation will use). These are
+used if several separated instrumentations are performed which are then later
+combined.
- `AFL_LLVM_DOCUMENT_IDS=file` will document to a file which edge ID was given
- to which function. This helps to identify functions with variable bytes
- or which functions were touched by an input.
+ to which function. This helps to identify functions with variable bytes or
+ which functions were touched by an input.
- `AFL_LLVM_MAP_ADDR` sets the fixed map address to a different address than
the default `0x10000`. A value of 0 or empty sets the map address to be
dynamic (the original AFL way, which is slower)
- `AFL_LLVM_MAP_DYNAMIC` sets the shared memory address to be dynamic
- - `AFL_LLVM_LTO_STARTID` sets the starting location ID for the instrumentation.
- This defaults to 1
+ - `AFL_LLVM_LTO_STARTID` sets the starting location ID for the
+ instrumentation. This defaults to 1
- `AFL_LLVM_LTO_DONTWRITEID` prevents that the highest location ID written
into the instrumentation is set in a global variable
- For more information, see [instrumentation/README.lto.md](../instrumentation/README.lto.md).
+ For more information, see
+ [instrumentation/README.lto.md](../instrumentation/README.lto.md).
#### NGRAM
-Setting `AFL_LLVM_NGRAM_SIZE` or `AFL_LLVM_INSTRUMENT=NGRAM-{value}` activates ngram prev_loc coverage, good values are 2, 4 or 8 (any value between 2 and 16 is valid).
-It is highly recommended to increase the `MAP_SIZE_POW2` definition in config.h to at least 18 and maybe up to 20 for this as otherwise too many map collisions occur.
+Setting `AFL_LLVM_NGRAM_SIZE` or `AFL_LLVM_INSTRUMENT=NGRAM-{value}` activates
+ngram prev_loc coverage, good values are 2, 4 or 8 (any value between 2 and 16
+is valid). It is highly recommended to increase the `MAP_SIZE_POW2` definition
+in config.h to at least 18 and maybe up to 20 for this as otherwise too many map
+collisions occur.
-For more information, see [instrumentation/README.ngram.md](../instrumentation/README.ngram.md).
+For more information, see
+[instrumentation/README.ngram.md](../instrumentation/README.ngram.md).
### LAF-INTEL
-This great feature will split compares into series of single byte comparisons to allow afl-fuzz to find otherwise rather impossible paths.
-It is not restricted to Intel CPUs. ;-)
+This great feature will split compares into series of single byte comparisons to
+allow afl-fuzz to find otherwise rather impossible paths. It is not restricted
+to Intel CPUs. ;-)
- - Setting `AFL_LLVM_LAF_TRANSFORM_COMPARES` will split string compare functions
+ - Setting `AFL_LLVM_LAF_TRANSFORM_COMPARES` will split string compare
+ functions
- Setting `AFL_LLVM_LAF_SPLIT_SWITCHES` will split all `switch` constructs
- - Setting `AFL_LLVM_LAF_SPLIT_COMPARES` will split all floating point and
- 64, 32 and 16 bit integer CMP instructions
+ - Setting `AFL_LLVM_LAF_SPLIT_COMPARES` will split all floating point and 64,
+ 32 and 16 bit integer CMP instructions
- Setting `AFL_LLVM_LAF_SPLIT_FLOATS` will split floating points, needs
AFL_LLVM_LAF_SPLIT_COMPARES to be set
- Setting `AFL_LLVM_LAF_ALL` sets all of the above
-For more information, see [instrumentation/README.laf-intel.md](../instrumentation/README.laf-intel.md).
+For more information, see
+[instrumentation/README.laf-intel.md](../instrumentation/README.laf-intel.md).
### INSTRUMENT LIST (selectively instrument files and functions)
This feature allows selective instrumentation of the source.
-Setting `AFL_LLVM_ALLOWLIST` or `AFL_LLVM_DENYLIST` with a filenames and/or function will only instrument (or skip) those files that match the names listed in the specified file.
+Setting `AFL_LLVM_ALLOWLIST` or `AFL_LLVM_DENYLIST` with a filenames and/or
+function will only instrument (or skip) those files that match the names listed
+in the specified file.
-For more information, see [instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md).
+For more information, see
+[instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md).
### Thread safe instrumentation counters (in all modes)
-Setting `AFL_LLVM_THREADSAFE_INST` will inject code that implements thread
-safe counters. The overhead is a little bit higher compared to the older
-non-thread safe case. Note that this disables neverzero (see below).
+Setting `AFL_LLVM_THREADSAFE_INST` will inject code that implements thread safe
+counters. The overhead is a little bit higher compared to the older non-thread
+safe case. Note that this disables neverzero (see below).
### NOT_ZERO
- - Setting `AFL_LLVM_NOT_ZERO=1` during compilation will use counters
- that skip zero on overflow. This is the default for llvm >= 9,
- however, for llvm versions below that this will increase an unnecessary
- slowdown due a performance issue that is only fixed in llvm 9+.
- This feature increases path discovery by a little bit.
+ - Setting `AFL_LLVM_NOT_ZERO=1` during compilation will use counters that skip
+ zero on overflow. This is the default for llvm >= 9, however, for llvm
+ versions below that this will increase an unnecessary slowdown due a
+ performance issue that is only fixed in llvm 9+. This feature increases path
+ discovery by a little bit.
- - Setting `AFL_LLVM_SKIP_NEVERZERO=1` will not implement the skip zero
- test. If the target performs only few loops, then this will give a
- small performance boost.
+ - Setting `AFL_LLVM_SKIP_NEVERZERO=1` will not implement the skip zero test.
+ If the target performs only few loops, then this will give a small
+ performance boost.
-For more information, see [instrumentation/README.neverzero.md](../instrumentation/README.neverzero.md).
+For more information, see
+[instrumentation/README.neverzero.md](../instrumentation/README.neverzero.md).
### CMPLOG
- Setting `AFL_LLVM_CMPLOG=1` during compilation will tell afl-clang-fast to
produce a CmpLog binary.
-For more information, see [instrumentation/README.cmplog.md](../instrumentation/README.cmplog.md).
+For more information, see
+[instrumentation/README.cmplog.md](../instrumentation/README.cmplog.md).
## 3) Settings for GCC / GCC_PLUGIN modes
@@ -242,14 +276,14 @@ Then there are a few specific features that are only available in GCC and
GCC_PLUGIN mode.
- Setting `AFL_GCC_INSTRUMENT_FILE` with a filename will only instrument those
- files that match the names listed in this file (one filename per line).
- See [instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md) for more information.
- (GCC_PLUGIN mode only)
+ files that match the names listed in this file (one filename per line). See
+ [instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md)
+ for more information. (GCC_PLUGIN mode only)
- Setting `AFL_KEEP_ASSEMBLY` prevents afl-as from deleting instrumented
- assembly files. Useful for troubleshooting problems or understanding how
- the tool works. (GCC mode only)
- To get them in a predictable place, try something like:
+ assembly files. Useful for troubleshooting problems or understanding how the
+ tool works. (GCC mode only) To get them in a predictable place, try
+ something like:
```
mkdir assembly_here
@@ -262,54 +296,52 @@ The main fuzzer binary accepts several options that disable a couple of sanity
checks or alter some of the more exotic semantics of the tool:
- Setting `AFL_AUTORESUME` will resume a fuzz run (same as providing `-i -`)
- for an existing out folder, even if a different `-i` was provided.
- Without this setting, afl-fuzz will refuse execution for a long-fuzzed out dir.
+ for an existing out folder, even if a different `-i` was provided. Without
+ this setting, afl-fuzz will refuse execution for a long-fuzzed out dir.
- Benchmarking only: `AFL_BENCH_JUST_ONE` causes the fuzzer to exit after
processing the first queue entry; and `AFL_BENCH_UNTIL_CRASH` causes it to
exit soon after the first crash is found.
- `AFL_CMPLOG_ONLY_NEW` will only perform the expensive cmplog feature for
- newly found testcases and not for testcases that are loaded on startup
- (`-i in`).
- This is an important feature to set when resuming a fuzzing session.
+ newly found testcases and not for testcases that are loaded on startup (`-i
+ in`). This is an important feature to set when resuming a fuzzing session.
- - Setting `AFL_CRASH_EXITCODE` sets the exit code AFL treats as crash.
- For example, if `AFL_CRASH_EXITCODE='-1'` is set, each input resulting
- in an `-1` return code (i.e. `exit(-1)` got called), will be treated
- as if a crash had ocurred.
- This may be beneficial if you look for higher-level faulty conditions in which your target still exits gracefully.
+ - Setting `AFL_CRASH_EXITCODE` sets the exit code AFL treats as crash. For
+ example, if `AFL_CRASH_EXITCODE='-1'` is set, each input resulting in an
+ `-1` return code (i.e. `exit(-1)` got called), will be treated as if a crash
+ had ocurred. This may be beneficial if you look for higher-level faulty
+ conditions in which your target still exits gracefully.
- Setting `AFL_CUSTOM_MUTATOR_LIBRARY` to a shared library with
- afl_custom_fuzz() creates additional mutations through this library.
- If afl-fuzz is compiled with Python (which is autodetected during building
+ afl_custom_fuzz() creates additional mutations through this library. If
+ afl-fuzz is compiled with Python (which is autodetected during building
afl-fuzz), setting `AFL_PYTHON_MODULE` to a Python module can also provide
- additional mutations.
- If `AFL_CUSTOM_MUTATOR_ONLY` is also set, all mutations will solely be
- performed with the custom mutator.
- This feature allows to configure custom mutators which can be very helpful,
- e.g. fuzzing XML or other highly flexible structured input.
- Please see [custom_mutators.md](custom_mutators.md).
+ additional mutations. If `AFL_CUSTOM_MUTATOR_ONLY` is also set, all
+ mutations will solely be performed with the custom mutator. This feature
+ allows to configure custom mutators which can be very helpful, e.g. fuzzing
+ XML or other highly flexible structured input. Please see
+ [custom_mutators.md](custom_mutators.md).
- Setting `AFL_CYCLE_SCHEDULES` will switch to a different schedule everytime
a cycle is finished.
- - Setting `AFL_DEBUG_CHILD` will not suppress the child output.
- This lets you see all output of the child, making setup issues obvious.
- For example, in an unicornafl harness, you might see python stacktraces.
- You may also see other logs that way, indicating why the forkserver won't start.
- Not pretty but good for debugging purposes.
- Note that `AFL_DEBUG_CHILD_OUTPUT` is deprecated.
+ - Setting `AFL_DEBUG_CHILD` will not suppress the child output. This lets you
+ see all output of the child, making setup issues obvious. For example, in an
+ unicornafl harness, you might see python stacktraces. You may also see other
+ logs that way, indicating why the forkserver won't start. Not pretty but
+ good for debugging purposes. Note that `AFL_DEBUG_CHILD_OUTPUT` is
+ deprecated.
- Setting `AFL_DISABLE_TRIM` tells afl-fuzz not to trim test cases. This is
usually a bad idea!
- - `AFL_EXIT_ON_SEED_ISSUES` will restore the vanilla afl-fuzz behaviour
- which does not allow crashes or timeout seeds in the initial -i corpus.
+ - `AFL_EXIT_ON_SEED_ISSUES` will restore the vanilla afl-fuzz behaviour which
+ does not allow crashes or timeout seeds in the initial -i corpus.
- - `AFL_EXIT_ON_TIME` Causes afl-fuzz to terminate if no new paths were
- found within a specified period of time (in seconds). May be convenient
- for some types of automated jobs.
+ - `AFL_EXIT_ON_TIME` Causes afl-fuzz to terminate if no new paths were found
+ within a specified period of time (in seconds). May be convenient for some
+ types of automated jobs.
- `AFL_EXIT_WHEN_DONE` causes afl-fuzz to terminate when all existing paths
have been fuzzed and there were no new finds for a while. This would be
@@ -324,20 +356,23 @@ checks or alter some of the more exotic semantics of the tool:
precise), which can help when starting a session against a slow target.
`AFL_CAL_FAST` works too.
- - Setting `AFL_FORCE_UI` will force painting the UI on the screen even if
- no valid terminal was detected (for virtual consoles).
+ - Setting `AFL_FORCE_UI` will force painting the UI on the screen even if no
+ valid terminal was detected (for virtual consoles).
- Setting `AFL_FORKSRV_INIT_TMOUT` allows you to specify a different timeout
- to wait for the forkserver to spin up.
- The default is the `-t` value times `FORK_WAIT_MULT` from `config.h` (usually 10), so for a `-t 100`, the default would wait for `1000` milliseconds.
- Setting a different time here is useful if the target has a very slow startup time, for example when doing full-system fuzzing or emulation, but you don't want the actual runs to wait too long for timeouts.
+ to wait for the forkserver to spin up. The default is the `-t` value times
+ `FORK_WAIT_MULT` from `config.h` (usually 10), so for a `-t 100`, the
+ default would wait for `1000` milliseconds. Setting a different time here is
+ useful if the target has a very slow startup time, for example when doing
+ full-system fuzzing or emulation, but you don't want the actual runs to wait
+ too long for timeouts.
- Setting `AFL_HANG_TMOUT` allows you to specify a different timeout for
- deciding if a particular test case is a "hang". The default is 1 second
- or the value of the `-t` parameter, whichever is larger. Dialing the value
- down can be useful if you are very concerned about slow inputs, or if you
- don't want AFL++ to spend too much time classifying that stuff and just
- rapidly put all timeouts in that bin.
+ deciding if a particular test case is a "hang". The default is 1 second or
+ the value of the `-t` parameter, whichever is larger. Dialing the value down
+ can be useful if you are very concerned about slow inputs, or if you don't
+ want AFL++ to spend too much time classifying that stuff and just rapidly
+ put all timeouts in that bin.
- If you are Jakub, you may need `AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES`.
Others need not apply, unless they also want to disable the
@@ -348,28 +383,31 @@ checks or alter some of the more exotic semantics of the tool:
set `AFL_IGNORE_PROBLEMS`.
- When running in the `-M` or `-S` mode, setting `AFL_IMPORT_FIRST` causes the
- fuzzer to import test cases from other instances before doing anything
- else.
- This makes the "own finds" counter in the UI more accurate.
- Beyond counter aesthetics, not much else should change.
+ fuzzer to import test cases from other instances before doing anything else.
+ This makes the "own finds" counter in the UI more accurate. Beyond counter
+ aesthetics, not much else should change.
- - `AFL_KILL_SIGNAL`: Set the signal ID to be delivered to child processes on timeout.
- Unless you implement your own targets or instrumentation, you likely don't have to set it.
- By default, on timeout and on exit, `SIGKILL` (`AFL_KILL_SIGNAL=9`) will be delivered to the child.
+ - `AFL_KILL_SIGNAL`: Set the signal ID to be delivered to child processes on
+ timeout. Unless you implement your own targets or instrumentation, you
+ likely don't have to set it. By default, on timeout and on exit, `SIGKILL`
+ (`AFL_KILL_SIGNAL=9`) will be delivered to the child.
- `AFL_MAP_SIZE` sets the size of the shared map that afl-fuzz, afl-showmap,
- afl-tmin and afl-analyze create to gather instrumentation data from
- the target. This must be equal or larger than the size the target was
- compiled with.
+ afl-tmin and afl-analyze create to gather instrumentation data from the
+ target. This must be equal or larger than the size the target was compiled
+ with.
- - Setting `AFL_MAX_DET_EXRAS` will change the threshold at what number of elements in the `-x` dictionary and LTO autodict (combined) the probabilistic mode will kick off.
- In probabilistic mode, not all dictionary entries will be used all of the time for fuzzing mutations to not slow down fuzzing.
- The default count is `200` elements.
- So for the 200 + 1st element, there is a 1 in 201 chance, that one of the dictionary entries will not be used directly.
+ - Setting `AFL_MAX_DET_EXRAS` will change the threshold at what number of
+ elements in the `-x` dictionary and LTO autodict (combined) the
+ probabilistic mode will kick off. In probabilistic mode, not all dictionary
+ entries will be used all of the time for fuzzing mutations to not slow down
+ fuzzing. The default count is `200` elements. So for the 200 + 1st element,
+ there is a 1 in 201 chance, that one of the dictionary entries will not be
+ used directly.
- Setting `AFL_NO_AFFINITY` disables attempts to bind to a specific CPU core
- on Linux systems. This slows things down, but lets you run more instances
- of afl-fuzz than would be prudent (if you really want to).
+ on Linux systems. This slows things down, but lets you run more instances of
+ afl-fuzz than would be prudent (if you really want to).
- `AFL_NO_ARITH` causes AFL++ to skip most of the deterministic arithmetics.
This can be useful to speed up the fuzzing of text-based file formats.
@@ -379,85 +417,100 @@ checks or alter some of the more exotic semantics of the tool:
- The CPU widget shown at the bottom of the screen is fairly simplistic and
may complain of high load prematurely, especially on systems with low core
- counts.
- To avoid the alarming red color for very high cpu usages, you can set `AFL_NO_CPU_RED`.
+ counts. To avoid the alarming red color for very high cpu usages, you can
+ set `AFL_NO_CPU_RED`.
- Setting `AFL_NO_COLOR` or `AFL_NO_COLOUR` will omit control sequences for
- coloring console output when configured with USE_COLOR and not ALWAYS_COLORED.
+ coloring console output when configured with USE_COLOR and not
+ ALWAYS_COLORED.
- Setting `AFL_NO_FORKSRV` disables the forkserver optimization, reverting to
- fork + execve() call for every tested input.
- This is useful mostly when working with unruly libraries that create threads or do other crazy things when initializing (before the instrumentation has a chance to run).
+ fork + execve() call for every tested input. This is useful mostly when
+ working with unruly libraries that create threads or do other crazy things
+ when initializing (before the instrumentation has a chance to run).
Note that this setting inhibits some of the user-friendly diagnostics
normally done when starting up the forkserver and causes a pretty
significant performance drop.
- - `AFL_NO_SNAPSHOT` will advice afl-fuzz not to use the snapshot feature
- if the snapshot lkm is loaded.
+ - `AFL_NO_SNAPSHOT` will advice afl-fuzz not to use the snapshot feature if
+ the snapshot lkm is loaded.
- Setting `AFL_NO_UI` inhibits the UI altogether, and just periodically prints
- some basic stats.
- This behavior is also automatically triggered when the output from afl-fuzz is redirected to a file or to a pipe.
+ some basic stats. This behavior is also automatically triggered when the
+ output from afl-fuzz is redirected to a file or to a pipe.
- - In QEMU mode (-Q) and Frida mode (-O), `AFL_PATH` will be searched for afl-qemu-trace and afl-frida-trace.so.
+ - In QEMU mode (-Q) and Frida mode (-O), `AFL_PATH` will be searched for
+ afl-qemu-trace and afl-frida-trace.so.
- - 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 with a value of how many previous fuzz cases to keep prio a crash.
- If set to e.g. 10, then the 9 previous inputs are written to out/default/crashes as RECORD:000000,cnt:000000 to RECORD:000000,cnt:000008 and RECORD:000000,cnt:000009 being the crash case.
- NOTE: This option needs to be enabled in config.h first!
+ - 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
+ with a value of how many previous fuzz cases to keep prio a crash. If set to
+ e.g. 10, then the 9 previous inputs are written to out/default/crashes as
+ RECORD:000000,cnt:000000 to RECORD:000000,cnt:000008 and
+ RECORD:000000,cnt:000009 being the crash case. NOTE: This option needs to be
+ enabled in config.h first!
- Note that `AFL_POST_LIBRARY` is deprecated, use `AFL_CUSTOM_MUTATOR_LIBRARY`
instead (see below).
- Setting `AFL_PRELOAD` causes AFL++ to set `LD_PRELOAD` for the target binary
- without disrupting the afl-fuzz process itself.
- This is useful, among other things, for bootstrapping libdislocator.so.
+ without disrupting the afl-fuzz process itself. This is useful, among other
+ things, for bootstrapping libdislocator.so.
- In QEMU mode (-Q), setting `AFL_QEMU_CUSTOM_BIN` will cause afl-fuzz to skip
- prepending `afl-qemu-trace` to your command line.
- Use this if you wish to use a custom afl-qemu-trace or if you need to modify the afl-qemu-trace arguments.
+ prepending `afl-qemu-trace` to your command line. Use this if you wish to
+ use a custom afl-qemu-trace or if you need to modify the afl-qemu-trace
+ arguments.
- - `AFL_SHUFFLE_QUEUE` randomly reorders the input queue on startup.
- Requested by some users for unorthodox parallelized fuzzing setups, but not
- advisable otherwise.
+ - `AFL_SHUFFLE_QUEUE` randomly reorders the input queue on startup. Requested
+ by some users for unorthodox parallelized fuzzing setups, but not advisable
+ otherwise.
- When developing custom instrumentation on top of afl-fuzz, you can use
- `AFL_SKIP_BIN_CHECK` to inhibit the checks for non-instrumented binaries
- and shell scripts; and `AFL_DUMB_FORKSRV` in conjunction with the `-n`
- setting to instruct afl-fuzz to still follow the fork server protocol
- without expecting any instrumentation data in return.
- Note that this also turns off auto map size detection.
+ `AFL_SKIP_BIN_CHECK` to inhibit the checks for non-instrumented binaries and
+ shell scripts; and `AFL_DUMB_FORKSRV` in conjunction with the `-n` setting
+ to instruct afl-fuzz to still follow the fork server protocol without
+ expecting any instrumentation data in return. Note that this also turns off
+ auto map size detection.
- Setting `AFL_SKIP_CPUFREQ` skips the check for CPU scaling policy. This is
- useful if you can't change the defaults (e.g., no root access to the
- system) and are OK with some performance loss.
+ useful if you can't change the defaults (e.g., no root access to the system)
+ and are OK with some performance loss.
- - Setting `AFL_STATSD` enables StatsD metrics collection.
- By default, AFL++ will send these metrics over UDP to 127.0.0.1:8125.
- The host and port are configurable with `AFL_STATSD_HOST` and `AFL_STATSD_PORT` respectively.
- To enable tags (banner and afl_version), you should provide `AFL_STATSD_TAGS_FLAVOR` that matches your StatsD server (see `AFL_STATSD_TAGS_FLAVOR`).
+ - Setting `AFL_STATSD` enables StatsD metrics collection. By default, AFL++
+ will send these metrics over UDP to 127.0.0.1:8125. The host and port are
+ configurable with `AFL_STATSD_HOST` and `AFL_STATSD_PORT` respectively. To
+ enable tags (banner and afl_version), you should provide
+ `AFL_STATSD_TAGS_FLAVOR` that matches your StatsD server (see
+ `AFL_STATSD_TAGS_FLAVOR`).
- - Setting `AFL_STATSD_TAGS_FLAVOR` to one of `dogstatsd`, `librato`, `signalfx` or `influxdb` allows you to add tags to your fuzzing instances.
- This is especially useful when running multiple instances (`-M/-S` for example).
- Applied tags are `banner` and `afl_version`.
- `banner` corresponds to the name of the fuzzer provided through `-M/-S`.
- `afl_version` corresponds to the currently running AFL version (e.g. `++3.0c`).
- Default (empty/non present) will add no tags to the metrics.
- For more information, see [rpc_statsd.md](rpc_statsd.md).
+ - Setting `AFL_STATSD_TAGS_FLAVOR` to one of `dogstatsd`, `librato`,
+ `signalfx` or `influxdb` allows you to add tags to your fuzzing instances.
+ This is especially useful when running multiple instances (`-M/-S` for
+ example). Applied tags are `banner` and `afl_version`. `banner` corresponds
+ to the name of the fuzzer provided through `-M/-S`. `afl_version`
+ corresponds to the currently running AFL version (e.g. `++3.0c`). Default
+ (empty/non present) will add no tags to the metrics. For more information,
+ see [rpc_statsd.md](rpc_statsd.md).
- - Setting `AFL_TARGET_ENV` causes AFL++ to set extra environment variables
- for the target binary. Example: `AFL_TARGET_ENV="VAR1=1 VAR2='a b c'" afl-fuzz ... `.
- This exists mostly for things like `LD_LIBRARY_PATH` but it would theoretically allow fuzzing of AFL++ itself (with 'target' AFL++ using some AFL_ vars that would disrupt work of 'fuzzer' AFL++).
+ - Setting `AFL_TARGET_ENV` causes AFL++ to set extra environment variables for
+ the target binary. Example: `AFL_TARGET_ENV="VAR1=1 VAR2='a b c'" afl-fuzz
+ ... `. This exists mostly for things like `LD_LIBRARY_PATH` but it would
+ theoretically allow fuzzing of AFL++ itself (with 'target' AFL++ using some
+ AFL_ vars that would disrupt work of 'fuzzer' AFL++).
- - `AFL_TESTCACHE_SIZE` allows you to override the size of `#define TESTCASE_CACHE`
- in config.h. Recommended values are 50-250MB - or more if your fuzzing
- finds a huge amount of paths for large inputs.
+ - `AFL_TESTCACHE_SIZE` allows you to override the size of `#define
+ TESTCASE_CACHE` in config.h. Recommended values are 50-250MB - or more if
+ your fuzzing finds a huge amount of paths for large inputs.
- - `AFL_TMPDIR` is used to write the `.cur_input` file to if exists, and in
- the normal output directory otherwise.
- You would use this to point to a ramdisk/tmpfs.
- This increases the speed by a small value but also reduces the stress on SSDs.
+ - `AFL_TMPDIR` is used to write the `.cur_input` file to if exists, and in the
+ normal output directory otherwise. You would use this to point to a
+ ramdisk/tmpfs. This increases the speed by a small value but also reduces
+ the stress on SSDs.
- Setting `AFL_TRY_AFFINITY` tries to attempt binding to a specific CPU core
on Linux systems, but will not terminate if that fails.
@@ -472,21 +525,20 @@ The QEMU wrapper used to instrument binary-only code supports several settings:
- Setting `AFL_COMPCOV_LEVEL` enables the CompareCoverage tracing of all cmp
and sub in x86 and x86_64 and memory comparions functions (e.g. strcmp,
- memcmp, ...) when libcompcov is preloaded using `AFL_PRELOAD`.
- More info at qemu_mode/libcompcov/README.md.
- There are two levels at the moment, `AFL_COMPCOV_LEVEL=1` that instruments
- only comparisons with immediate values / read-only memory and
- `AFL_COMPCOV_LEVEL=2` that instruments all the comparions. Level 2 is more
- accurate but may need a larger shared memory.
+ memcmp, ...) when libcompcov is preloaded using `AFL_PRELOAD`. More info at
+ qemu_mode/libcompcov/README.md. There are two levels at the moment,
+ `AFL_COMPCOV_LEVEL=1` that instruments only comparisons with immediate
+ values / read-only memory and `AFL_COMPCOV_LEVEL=2` that instruments all the
+ comparions. Level 2 is more accurate but may need a larger shared memory.
- - `AFL_DEBUG` will print the found entrypoint for the binary to stderr.
- Use this if you are unsure if the entrypoint might be wrong - but
- use it directly, e.g. `afl-qemu-trace ./program`.
+ - `AFL_DEBUG` will print the found entrypoint for the binary to stderr. Use
+ this if you are unsure if the entrypoint might be wrong - but use it
+ directly, e.g. `afl-qemu-trace ./program`.
- - `AFL_ENTRYPOINT` allows you to specify a specific entrypoint into the
- binary (this can be very good for the performance!).
- The entrypoint is specified as hex address, e.g. `0x4004110`
- Note that the address must be the address of a basic block.
+ - `AFL_ENTRYPOINT` allows you to specify a specific entrypoint into the binary
+ (this can be very good for the performance!). The entrypoint is specified as
+ hex address, e.g. `0x4004110` Note that the address must be the address of a
+ basic block.
- Setting `AFL_INST_LIBS` causes the translator to also instrument the code
inside any dynamically linked libraries (notably including glibc).
@@ -495,10 +547,9 @@ The QEMU wrapper used to instrument binary-only code supports several settings:
of the basic blocks, which can be useful when dealing with very complex
binaries.
- - Setting `AFL_QEMU_COMPCOV` enables the CompareCoverage tracing of all
- cmp and sub in x86 and x86_64.
- This is an alias of `AFL_COMPCOV_LEVEL=1` when `AFL_COMPCOV_LEVEL` is
- not specified.
+ - Setting `AFL_QEMU_COMPCOV` enables the CompareCoverage tracing of all cmp
+ and sub in x86 and x86_64. This is an alias of `AFL_COMPCOV_LEVEL=1` when
+ `AFL_COMPCOV_LEVEL` is not specified.
- With `AFL_QEMU_FORCE_DFL` you force QEMU to ignore the registered signal
handlers of the target.
@@ -511,11 +562,13 @@ The QEMU wrapper used to instrument binary-only code supports several settings:
purpose registers and restore them in each persistent cycle.
- Another modality to execute the persistent loop is to specify also the
- `AFL_QEMU_PERSISTENT_RET=end addr` env variable.
- With this variable assigned, instead of patching the return address, the
- specified instruction is transformed to a jump towards `start addr`.
+ `AFL_QEMU_PERSISTENT_RET=end addr` env variable. With this variable
+ assigned, instead of patching the return address, the specified instruction
+ is transformed to a jump towards `start addr`.
- - With `AFL_QEMU_PERSISTENT_RETADDR_OFFSET` you can specify the offset from the stack pointer in which QEMU can find the return address when `start addr` is hit.
+ - With `AFL_QEMU_PERSISTENT_RETADDR_OFFSET` you can specify the offset from
+ the stack pointer in which QEMU can find the return address when `start
+ addr` is hit.
- With `AFL_USE_QASAN` you can enable QEMU AddressSanitizer for dynamically
linked binaries.
@@ -528,28 +581,31 @@ The QEMU wrapper used to instrument binary-only code supports several settings:
The corpus minimization script offers very little customization:
- - `AFL_ALLOW_TMP` permits this and some other scripts to run in /tmp.
- This is a modest security risk on multi-user systems with rogue users, but should be safe on dedicated fuzzing boxes.
+ - `AFL_ALLOW_TMP` permits this and some other scripts to run in /tmp. This is
+ a modest security risk on multi-user systems with rogue users, but should be
+ safe on dedicated fuzzing boxes.
- `AFL_KEEP_TRACES` makes the tool keep traces and other metadata used for
- minimization and normally deleted at exit.
- The files can be found in the `/.traces/` directory.
+ minimization and normally deleted at exit. The files can be found in the
+ `/.traces/` directory.
- - Setting `AFL_PATH` offers a way to specify the location of afl-showmap
- and afl-qemu-trace (the latter only in `-Q` mode).
+ - Setting `AFL_PATH` offers a way to specify the location of afl-showmap and
+ afl-qemu-trace (the latter only in `-Q` mode).
- `AFL_PRINT_FILENAMES` prints each filename to stdout, as it gets processed.
- This can help when embedding `afl-cmin` or `afl-showmap` in other scripts scripting.
+ This can help when embedding `afl-cmin` or `afl-showmap` in other scripts
+ scripting.
## 7) Settings for afl-tmin
-Virtually nothing to play with.
-Well, in QEMU mode (`-Q`), `AFL_PATH` will be searched for afl-qemu-trace.
-In addition to this, `TMPDIR` may be used if a temporary file can't be created in the current working directory.
+Virtually nothing to play with. Well, in QEMU mode (`-Q`), `AFL_PATH` will be
+searched for afl-qemu-trace. In addition to this, `TMPDIR` may be used if a
+temporary file can't be created in the current working directory.
-You can specify `AFL_TMIN_EXACT` if you want afl-tmin to require execution paths to match when minimizing crashes.
-This will make minimization less useful, but may prevent the tool from "jumping" from one crashing condition to another in very buggy software.
-You probably want to combine it with the `-e` flag.
+You can specify `AFL_TMIN_EXACT` if you want afl-tmin to require execution paths
+to match when minimizing crashes. This will make minimization less useful, but
+may prevent the tool from "jumping" from one crashing condition to another in
+very buggy software. You probably want to combine it with the `-e` flag.
## 8) Settings for afl-analyze
@@ -571,12 +627,12 @@ The library honors these environmental variables:
library, in megabytes. The default value is 1 GB. Once this is exceeded,
allocations will return NULL.
- - `AFL_LD_NO_CALLOC_OVER` inhibits `abort()` on `calloc()` overflows. Most
- of the common allocators check for that internally and return NULL, so
- it's a security risk only in more exotic setups.
+ - `AFL_LD_NO_CALLOC_OVER` inhibits `abort()` on `calloc()` overflows. Most of
+ the common allocators check for that internally and return NULL, so it's a
+ security risk only in more exotic setups.
- - `AFL_LD_VERBOSE` causes the library to output some diagnostic messages
- that may be useful for pinpointing the cause of any observed issues.
+ - `AFL_LD_VERBOSE` causes the library to output some diagnostic messages that
+ may be useful for pinpointing the cause of any observed issues.
## 10) Settings for libtokencap
@@ -588,10 +644,9 @@ discovered tokens should be written.
Several variables are not directly interpreted by afl-fuzz, but are set to
optimal values if not already present in the environment:
- - By default, `LD_BIND_NOW` is set to speed up fuzzing by forcing the
- linker to do all the work before the fork server kicks in. You can
- override this by setting `LD_BIND_LAZY` beforehand, but it is almost
- certainly pointless.
+ - By default, `LD_BIND_NOW` is set to speed up fuzzing by forcing the linker
+ to do all the work before the fork server kicks in. You can override this by
+ setting `LD_BIND_LAZY` beforehand, but it is almost certainly pointless.
- By default, `ASAN_OPTIONS` are set to (among others):
@@ -604,8 +659,8 @@ optimal values if not already present in the environment:
```
If you want to set your own options, be sure to include `abort_on_error=1` -
- otherwise, the fuzzer will not be able to detect crashes in the tested
- app. Similarly, include `symbolize=0`, since without it, AFL++ may have
+ otherwise, the fuzzer will not be able to detect crashes in the tested app.
+ Similarly, include `symbolize=0`, since without it, AFL++ may have
difficulty telling crashes and hangs apart.
- Similarly, the default `LSAN_OPTIONS` are set to:
@@ -617,7 +672,9 @@ optimal values if not already present in the environment:
print_suppressions=0
```
- Be sure to include the first ones for LSAN and MSAN when customizing anything, since some MSAN and LSAN versions don't call `abort()` on error, and we need a way to detect faults.
+ Be sure to include the first ones for LSAN and MSAN when customizing
+ anything, since some MSAN and LSAN versions don't call `abort()` on error,
+ and we need a way to detect faults.
- In the same vein, by default, `MSAN_OPTIONS` are set to:
From 36d8f979724de64ad986acd3b9fe8933e99950c4 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 28 Oct 2021 15:38:50 +0200
Subject: [PATCH 117/305] gcc instrumentation opt
---
src/afl-cc.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 77407a98..ed6390ce 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -423,6 +423,8 @@ static void edit_params(u32 argc, char **argv, char **envp) {
char *fplugin_arg = alloc_printf("-fplugin=%s/afl-gcc-pass.so", obj_path);
cc_params[cc_par_cnt++] = fplugin_arg;
+ cc_params[cc_par_cnt++] = "-fno-if-conversion";
+ cc_params[cc_par_cnt++] = "-fno-if-conversion2";
}
From c64735df9e87f2ee15ea32208be85e481c78814b Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 31 Oct 2021 11:55:36 +0100
Subject: [PATCH 118/305] help gcc
---
src/afl-cc.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/afl-cc.c b/src/afl-cc.c
index ed6390ce..e7f08aac 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -737,6 +737,14 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
+ if ((compiler_mode == GCC || compiler_mode == GCC_PLUGIN) &&
+ !strncmp(cur, "-stdlib=", 8)) {
+
+ if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
+ continue;
+
+ }
+
if ((!strncmp(cur, "-fsanitize=fuzzer-", strlen("-fsanitize=fuzzer-")) ||
!strncmp(cur, "-fsanitize-coverage", strlen("-fsanitize-coverage"))) &&
(strncmp(cur, "sanitize-coverage-allow",
From 639d108512027bda6e7baf4a96f9d4e058e3c1d3 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 31 Oct 2021 12:29:45 +0100
Subject: [PATCH 119/305] add cmplog compatability check
---
include/types.h | 2 +
instrumentation/afl-compiler-rt.o.c | 9 +-
src/afl-forkserver.c | 11 +++
src/afl-fuzz-redqueen.c | 144 +---------------------------
4 files changed, 22 insertions(+), 144 deletions(-)
diff --git a/include/types.h b/include/types.h
index 7b94fb83..063e6bbd 100644
--- a/include/types.h
+++ b/include/types.h
@@ -46,6 +46,7 @@ typedef uint128_t u128;
#define FS_ERROR_SHM_OPEN 4
#define FS_ERROR_SHMAT 8
#define FS_ERROR_MMAP 16
+#define FS_ERROR_OLD_CMPLOG 32
/* Reporting options */
#define FS_OPT_ENABLED 0x80000001
@@ -53,6 +54,7 @@ typedef uint128_t u128;
#define FS_OPT_SNAPSHOT 0x20000000
#define FS_OPT_AUTODICT 0x10000000
#define FS_OPT_SHDMEM_FUZZ 0x01000000
+#define FS_OPT_NEWCMPLOG 0x02000000
#define FS_OPT_OLD_AFLPP_WORKAROUND 0x0f000000
// FS_OPT_MAX_MAPSIZE is 8388608 = 0x800000 = 2^23 = 1 << 22
#define FS_OPT_MAX_MAPSIZE ((0x00fffffeU >> 1) + 1)
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 17724e74..6ee86add 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -679,7 +679,7 @@ static void __afl_start_snapshots(void) {
/* Phone home and tell the parent that we're OK. If parent isn't there,
assume we're not running in forkserver mode and just execute program. */
- status |= (FS_OPT_ENABLED | FS_OPT_SNAPSHOT);
+ status |= (FS_OPT_ENABLED | FS_OPT_SNAPSHOT | FS_OPT_NEWCMPLOG);
if (__afl_sharedmem_fuzzing != 0) status |= FS_OPT_SHDMEM_FUZZ;
if (__afl_map_size <= FS_OPT_MAX_MAPSIZE)
status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE);
@@ -945,7 +945,12 @@ static void __afl_start_forkserver(void) {
}
if (__afl_sharedmem_fuzzing != 0) { status_for_fsrv |= FS_OPT_SHDMEM_FUZZ; }
- if (status_for_fsrv) { status_for_fsrv |= (FS_OPT_ENABLED); }
+ if (status_for_fsrv) {
+
+ status_for_fsrv |= (FS_OPT_ENABLED | FS_OPT_NEWCMPLOG);
+
+ }
+
memcpy(tmp, &status_for_fsrv, 4);
/* Phone home and tell the parent that we're OK. If parent isn't there,
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 54f510c4..da036d2f 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -342,6 +342,11 @@ static void report_error_and_exit(int error) {
"the fuzzing target reports that the mmap() call to the shared "
"memory failed.");
break;
+ case FS_ERROR_OLD_CMPLOG:
+ FATAL(
+ "the -c cmplog target was instrumented with an too old afl++ "
+ "version, you need to recompile it.");
+ break;
default:
FATAL("unknown error code %d from fuzzing target!", error);
@@ -651,6 +656,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if ((status & FS_OPT_OLD_AFLPP_WORKAROUND) == FS_OPT_OLD_AFLPP_WORKAROUND)
status = (status & 0xf0ffffff);
+ if ((status & FS_OPT_NEWCMPLOG) == 0 && fsrv->cmplog_binary) {
+
+ report_error_and_exit(FS_ERROR_OLD_CMPLOG);
+
+ }
+
if ((status & FS_OPT_SNAPSHOT) == FS_OPT_SNAPSHOT) {
fsrv->snapshot = 1;
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index b5dc23c2..c97080c7 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -28,8 +28,6 @@
#include "afl-fuzz.h"
#include "cmplog.h"
-#define VARIANT 6
-
//#define _DEBUG
//#define CMPLOG_INTROSPECTION
@@ -1855,10 +1853,9 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
// we only learn 16 bit +
if (hshape > 1) {
-#if VARIANT == 6
if (!found_one || afl->queue_cur->is_ascii) {
- #ifdef WORD_SIZE_64
+#ifdef WORD_SIZE_64
if (unlikely(is_n)) {
if (!found_one ||
@@ -1872,7 +1869,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
} else
- #endif
+#endif
{
if (!memcmp((u8 *)&o->v0, (u8 *)&orig_o->v0, SHAPE_BYTES(h->shape)) &&
@@ -1890,75 +1887,6 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
-#else
-
- u8 same0 = 0, same1 = 0, same2 = 0, same3 = 0,
- result = 1 + (found_one << 2);
- if (o->v0 != orig_o->v0) { same0 = 8; }
- if (o->v1 != orig_o->v1) { same1 = 8; }
- if (o->v0 != o->v1) { same2 = 8; }
- if (orig_o->v0 != orig_o->v1) { same3 = 8; }
- if (check_if_text_buf((u8 *)&o->v0, hshape) < hshape) same0 += 2;
- if (check_if_text_buf((u8 *)&o->v1, hshape) < hshape) same1 += 2;
-
- if (!same2 && !same3) {
-
- #ifdef WORD_SIZE_64
- if (unlikely(is_n)) {
-
- if (
- #if VARIANT == 1
- !(!same0 && same1) &&
- #endif
- DICT_ADD_STRATEGY >= same0 + result) {
-
- try_to_add_to_dictN(afl, s128_v0, hshape);
-
- }
-
- if (
- #if VARIANT == 1
- !(same0 && !same1) &&
- #endif
- DICT_ADD_STRATEGY >= same1 + result) {
-
- try_to_add_to_dictN(afl, s128_v1, hshape);
-
- }
-
- } else
-
- #endif
- {
-
- if (
- #if VARIANT == 1
- !(!same0 && same1) &&
- #endif
- DICT_ADD_STRATEGY >= same0 + result) {
-
- // fprintf(stderr, "add v0 0x%llx\n", o->v0);
- try_to_add_to_dict(afl, o->v0, hshape);
-
- }
-
- if (
- #if VARIANT == 1
- !(same0 && !same1) &&
- #endif
- DICT_ADD_STRATEGY >= same1 + result) {
-
- // fprintf(stderr, "add v1 0x%llx\n", o->v1);
- try_to_add_to_dict(afl, o->v1, hshape);
-
- }
-
- }
-
- }
-
-#endif
-
}
cmp_fuzz_next_iter:
@@ -2606,7 +2534,6 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
// if (unlikely(!afl->pass_stats[key].total)) {
-#if VARIANT == 6
if ((!found_one && (lvl & LVL1)) || afl->queue_cur->is_ascii) {
// if (unlikely(!afl->pass_stats[key].total)) {
@@ -2643,73 +2570,6 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
-#else
- if (lvl & LVL1) {
-
- u8 is_txt = 0, l0 = o->v0_len, ol0 = orig_o->v0_len, l1 = o->v1_len,
- ol1 = orig_o->v1_len;
- if (l0 >= 0x80 || ol0 >= 0x80) {
-
- is_txt = 1;
- l0 -= 0x80;
- l1 -= 0x80;
- ol0 -= 0x80;
- ol1 -= 0x80;
-
- }
-
- if (l0 == 0 || l1 == 0 || ol0 == 0 || ol1 == 0 || l0 > 31 || l1 > 31 ||
- ol0 > 31 || ol1 > 31) {
-
- l0 = l1 = ol0 = ol1 = hshape;
-
- }
-
- u8 same0 = 0, same1 = 0, same2 = 0, same3 = 0,
- result = 1 + (found_one << 2);
- if (l0 != ol0 || memcmp(o->v0, orig_o->v0, l0) != 0) { same0 = 8; }
- if (l1 != ol1 || memcmp(o->v1, orig_o->v1, l1) != 0) { same1 = 8; }
- if (l0 != l1 || memcmp(o->v0, o->v1, l0) != 0) { same2 = 8; }
- if (ol0 != ol1 || memcmp(orig_o->v0, orig_o->v1, l0) != 0) { same3 = 8; }
- if (!is_txt && check_if_text_buf((u8 *)&o->v0, l0) < l0) { same0 += 2; }
- if (!is_txt && check_if_text_buf((u8 *)&o->v1, l1) < l1) { same1 += 2; }
-
- if (
- #if VARIANT < 3
- !(same0 && !same1) &&
- #endif
- #if VARIANT == 4
- (!same2 && same3)
- #else
- (DICT_ADD_STRATEGY >= same0 + result)
- #endif
- ) {
-
- // fprintf(stderr, "add v0 [%u]\"%s\"\n", l0, o->v0);
- maybe_add_auto(afl, o->v0, l0);
-
- }
-
- if (
- #if VARIANT < 3
- !(!same0 && same1) &&
- #endif
- #if VARIANT == 4
- (same2 && !same3)
- #else
- (DICT_ADD_STRATEGY >= same1 + result)
- #endif
- ) {
-
- // fprintf(stderr, "add v1 [%u]\"%s\"\n", l1, o->v1);
- maybe_add_auto(afl, o->v1, l1);
-
- }
-
- }
-
-#endif
-
rtn_fuzz_next_iter:
afl->stage_cur++;
From 01d266f2b4870fbdfd8daba7498ec422fed84c91 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 31 Oct 2021 12:40:32 +0100
Subject: [PATCH 120/305] wipe overflow data
---
include/cmplog.h | 3 ++-
instrumentation/afl-compiler-rt.o.c | 28 ++++++++++++++++++++--------
2 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/include/cmplog.h b/include/cmplog.h
index b95a8e43..76082121 100644
--- a/include/cmplog.h
+++ b/include/cmplog.h
@@ -48,7 +48,8 @@ struct cmp_header {
unsigned shape : 5;
unsigned type : 2;
unsigned attribute : 4;
- unsigned reserved : 5;
+ unsigned overflow : 1;
+ unsigned reserved : 4;
} __attribute__((packed));
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 6ee86add..ff3998e6 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -1935,9 +1935,12 @@ void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u64 len) {
struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
hits &= CMP_MAP_RTN_H - 1;
- if (unlikely(reset && !hits)) {
- __builtin_memset(cmpfn, 0, sizeof(struct cmpfn_operands));
+ if (unlikely(reset && !hits)) { __afl_cmp_map->headers[k].overflow = 1; }
+
+ if (unlikely(__afl_cmp_map->headers[k].overflow)) {
+
+ __builtin_memset((char *)&cmpfn[hits], 0, sizeof(struct cmpfn_operands));
}
@@ -1988,9 +1991,12 @@ void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u64 len) {
struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
hits &= CMP_MAP_RTN_H - 1;
- if (unlikely(reset && !hits)) {
- __builtin_memset(cmpfn, 0, sizeof(struct cmpfn_operands));
+ if (unlikely(reset && !hits)) { __afl_cmp_map->headers[k].overflow = 1; }
+
+ if (unlikely(__afl_cmp_map->headers[k].overflow)) {
+
+ __builtin_memset((char *)&cmpfn[hits], 0, sizeof(struct cmpfn_operands));
}
@@ -2043,9 +2049,12 @@ void __cmplog_rtn_hook_str(u8 *ptr1, u8 *ptr2) {
struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
hits &= CMP_MAP_RTN_H - 1;
- if (unlikely(reset && !hits)) {
- __builtin_memset(cmpfn, 0, sizeof(struct cmpfn_operands));
+ if (unlikely(reset && !hits)) { __afl_cmp_map->headers[k].overflow = 1; }
+
+ if (unlikely(__afl_cmp_map->headers[k].overflow)) {
+
+ __builtin_memset((char *)&cmpfn[hits], 0, sizeof(struct cmpfn_operands));
}
@@ -2106,9 +2115,12 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
hits &= CMP_MAP_RTN_H - 1;
- if (unlikely(reset && !hits)) {
- __builtin_memset(cmpfn, 0, sizeof(struct cmpfn_operands));
+ if (unlikely(reset && !hits)) { __afl_cmp_map->headers[k].overflow = 1; }
+
+ if (unlikely(__afl_cmp_map->headers[k].overflow)) {
+
+ __builtin_memset((char *)&cmpfn[hits], 0, sizeof(struct cmpfn_operands));
}
From d918a9e85b3b73127bbf7e0e14e63104537ab1d6 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 31 Oct 2021 13:25:27 +0100
Subject: [PATCH 121/305] insert select instrumentation
---
.../SanitizerCoveragePCGUARD.so.cc | 67 ++++++++++++++++++-
1 file changed, 64 insertions(+), 3 deletions(-)
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 013492f9..d6098897 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -203,7 +203,7 @@ class ModuleSanitizerCoverage {
SanitizerCoverageOptions Options;
- uint32_t instr = 0;
+ uint32_t instr = 0, selects = 0;
GlobalVariable *AFLMapPtr = NULL;
ConstantInt * One = NULL;
ConstantInt * Zero = NULL;
@@ -553,8 +553,9 @@ bool ModuleSanitizerCoverage::instrumentModule(
getenv("AFL_USE_MSAN") ? ", MSAN" : "",
getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
- OKF("Instrumented %u locations with no collisions (%s mode).", instr,
- modeline);
+ OKF("Instrumented %u locations with no collisions (%s mode) and %u "
+ "selects.",
+ instr, modeline, selects);
}
@@ -836,6 +837,8 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
if (AllBlocks.empty()) return false;
uint32_t special = 0;
+ uint32_t skip_next = 0;
+
for (auto &BB : F) {
for (auto &IN : BB) {
@@ -856,6 +859,64 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
}
+ SelectInst *selectInst = nullptr;
+
+ if (!skip_next && (selectInst = dyn_cast(&IN))) {
+
+ selects++;
+ uint32_t id1 = 1 + instr + (uint32_t)AllBlocks.size() + special++;
+ uint32_t id2 = 1 + instr + (uint32_t)AllBlocks.size() + special++;
+ Value * val1 = ConstantInt::get(Int32Ty, id1);
+ Value * val2 = ConstantInt::get(Int32Ty, id2);
+ auto cond = selectInst->getCondition();
+ IRBuilder<> IRB(selectInst->getNextNode());
+ auto result = IRB.CreateSelect(cond, val1, val2);
+
+ /* Get CurLoc */
+
+ /* Load SHM pointer */
+
+ LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
+
+ /* Load counter for CurLoc */
+
+ Value *MapPtrIdx = IRB.CreateGEP(MapPtr, result);
+
+ if (use_threadsafe_counters) {
+
+ IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One,
+#if LLVM_VERSION_MAJOR >= 13
+ llvm::MaybeAlign(1),
+#endif
+ llvm::AtomicOrdering::Monotonic);
+
+ } else {
+
+ LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
+ /* Update bitmap */
+
+ Value *Incr = IRB.CreateAdd(Counter, One);
+
+ if (skip_nozero == NULL) {
+
+ auto cf = IRB.CreateICmpEQ(Incr, Zero);
+ auto carry = IRB.CreateZExt(cf, Int8Ty);
+ Incr = IRB.CreateAdd(Incr, carry);
+
+ }
+
+ IRB.CreateStore(Incr, MapPtrIdx);
+
+ }
+
+ skip_next = 1;
+
+ } else {
+
+ skip_next = 0;
+
+ }
+
}
}
From 0cbb406451a77b7b293cd317ad116531a9cb46bf Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 1 Nov 2021 00:30:56 +0100
Subject: [PATCH 122/305] fix
---
.../SanitizerCoveragePCGUARD.so.cc | 90 +++++++++++++++----
1 file changed, 71 insertions(+), 19 deletions(-)
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index d6098897..cfb777ce 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -834,10 +834,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
ArrayRef AllBlocks,
bool IsLeafFunc) {
- if (AllBlocks.empty()) return false;
-
- uint32_t special = 0;
- uint32_t skip_next = 0;
+ uint32_t cnt_cov = 0, cnt_sel = 0;
for (auto &BB : F) {
@@ -853,9 +850,46 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
StringRef FuncName = Callee->getName();
if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue;
- uint32_t id = 1 + instr + (uint32_t)AllBlocks.size() + special++;
- Value * val = ConstantInt::get(Int32Ty, id);
- callInst->setOperand(1, val);
+ cnt_cov++;
+
+ }
+
+ SelectInst *selectInst = nullptr;
+
+ if ((selectInst = dyn_cast(&IN))) { cnt_sel++; }
+
+ }
+
+ }
+
+ /* Create PCGUARD array */
+ CreateFunctionLocalArrays(F, AllBlocks, cnt_cov + cnt_sel * 2);
+ selects += cnt_sel;
+
+ uint32_t special = 0, local_selects = 0, skip_next = 0;
+
+ for (auto &BB : F) {
+
+ for (auto &IN : BB) {
+
+ CallInst *callInst = nullptr;
+
+ if ((callInst = dyn_cast(&IN))) {
+
+ Function *Callee = callInst->getCalledFunction();
+ if (!Callee) continue;
+ if (callInst->getCallingConv() != llvm::CallingConv::C) continue;
+ StringRef FuncName = Callee->getName();
+ if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue;
+
+ IRBuilder<> IRB(callInst);
+ Value * GuardPtr = IRB.CreateIntToPtr(
+ IRB.CreateAdd(
+ IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
+ ConstantInt::get(IntptrTy, (++special + AllBlocks.size()) * 4)),
+ Int32PtrTy);
+
+ callInst->setOperand(1, GuardPtr);
}
@@ -863,24 +897,40 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
if (!skip_next && (selectInst = dyn_cast(&IN))) {
- selects++;
- uint32_t id1 = 1 + instr + (uint32_t)AllBlocks.size() + special++;
- uint32_t id2 = 1 + instr + (uint32_t)AllBlocks.size() + special++;
- Value * val1 = ConstantInt::get(Int32Ty, id1);
- Value * val2 = ConstantInt::get(Int32Ty, id2);
- auto cond = selectInst->getCondition();
IRBuilder<> IRB(selectInst->getNextNode());
- auto result = IRB.CreateSelect(cond, val1, val2);
+
+ Value *GuardPtr1 = IRB.CreateIntToPtr(
+ IRB.CreateAdd(
+ IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
+ ConstantInt::get(
+ IntptrTy,
+ (cnt_cov + local_selects * 2 + 1 + AllBlocks.size()) * 4)),
+ Int32PtrTy);
+
+ Value *GuardPtr2 = IRB.CreateIntToPtr(
+ IRB.CreateAdd(
+ IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
+ ConstantInt::get(
+ IntptrTy,
+ (cnt_cov + local_selects * 2 + 2 + AllBlocks.size()) * 4)),
+ Int32PtrTy);
+
+ local_selects++;
+
+ auto cond = selectInst->getCondition();
+ auto result = IRB.CreateSelect(cond, GuardPtr1, GuardPtr2);
/* Get CurLoc */
+ LoadInst *CurLoc = IRB.CreateLoad(result);
+
/* Load SHM pointer */
LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
/* Load counter for CurLoc */
- Value *MapPtrIdx = IRB.CreateGEP(MapPtr, result);
+ Value *MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc);
if (use_threadsafe_counters) {
@@ -893,6 +943,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
} else {
LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
+
/* Update bitmap */
Value *Incr = IRB.CreateAdd(Counter, One);
@@ -910,6 +961,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
}
skip_next = 1;
+ instr += 2;
} else {
@@ -921,11 +973,11 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
}
- CreateFunctionLocalArrays(F, AllBlocks, special);
- for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
- InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc);
+ if (AllBlocks.empty() && !special && !local_selects) return false;
- instr += special;
+ if (!AllBlocks.empty())
+ for (size_t i = 0, N = AllBlocks.size(); i < N; i++)
+ InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc);
return true;
From 7e813ca4925c26253dcba34daa29cd5140b7b8ba Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 1 Nov 2021 09:23:05 +0100
Subject: [PATCH 123/305] fix
---
.../SanitizerCoveragePCGUARD.so.cc | 108 ++++++++++--------
1 file changed, 63 insertions(+), 45 deletions(-)
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index cfb777ce..4bd62bc7 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -203,7 +203,7 @@ class ModuleSanitizerCoverage {
SanitizerCoverageOptions Options;
- uint32_t instr = 0, selects = 0;
+ uint32_t instr = 0, selects = 0, unhandled = 0;
GlobalVariable *AFLMapPtr = NULL;
ConstantInt * One = NULL;
ConstantInt * Zero = NULL;
@@ -553,9 +553,9 @@ bool ModuleSanitizerCoverage::instrumentModule(
getenv("AFL_USE_MSAN") ? ", MSAN" : "",
getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
- OKF("Instrumented %u locations with no collisions (%s mode) and %u "
- "selects.",
- instr, modeline, selects);
+ OKF("Instrumented %u locations with no collisions (%s mode) of which are "
+ "%u handled and %u unhandled selects.",
+ instr, modeline, selects, unhandled);
}
@@ -856,12 +856,20 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
SelectInst *selectInst = nullptr;
- if ((selectInst = dyn_cast(&IN))) { cnt_sel++; }
+ if ((selectInst = dyn_cast(&IN))) {
+
+ Value *c = selectInst->getCondition();
+ auto t = c->getType();
+ if (t->getTypeID() == llvm::Type::IntegerTyID) cnt_sel++;
+
+ }
}
}
+ fprintf(stderr, "%u selects in %s!\n", cnt_sel, F.getName().str().c_str());
+
/* Create PCGUARD array */
CreateFunctionLocalArrays(F, AllBlocks, cnt_cov + cnt_sel * 2);
selects += cnt_sel;
@@ -897,72 +905,82 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
if (!skip_next && (selectInst = dyn_cast(&IN))) {
- IRBuilder<> IRB(selectInst->getNextNode());
+ Value *c = selectInst->getCondition();
+ auto t = c->getType();
+ if (t->getTypeID() == llvm::Type::IntegerTyID) {
- Value *GuardPtr1 = IRB.CreateIntToPtr(
- IRB.CreateAdd(
- IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
- ConstantInt::get(
- IntptrTy,
- (cnt_cov + local_selects * 2 + 1 + AllBlocks.size()) * 4)),
- Int32PtrTy);
+ IRBuilder<> IRB(selectInst->getNextNode());
- Value *GuardPtr2 = IRB.CreateIntToPtr(
- IRB.CreateAdd(
- IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
- ConstantInt::get(
- IntptrTy,
- (cnt_cov + local_selects * 2 + 2 + AllBlocks.size()) * 4)),
- Int32PtrTy);
+ Value *GuardPtr1 = IRB.CreateIntToPtr(
+ IRB.CreateAdd(
+ IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
+ ConstantInt::get(IntptrTy, (cnt_cov + local_selects * 2 + 1 +
+ AllBlocks.size()) *
+ 4)),
+ Int32PtrTy);
- local_selects++;
+ Value *GuardPtr2 = IRB.CreateIntToPtr(
+ IRB.CreateAdd(
+ IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
+ ConstantInt::get(IntptrTy, (cnt_cov + local_selects * 2 + 2 +
+ AllBlocks.size()) *
+ 4)),
+ Int32PtrTy);
- auto cond = selectInst->getCondition();
- auto result = IRB.CreateSelect(cond, GuardPtr1, GuardPtr2);
+ local_selects++;
- /* Get CurLoc */
+ auto cond = selectInst->getCondition();
+ auto result = IRB.CreateSelect(cond, GuardPtr1, GuardPtr2);
- LoadInst *CurLoc = IRB.CreateLoad(result);
+ /* Get CurLoc */
- /* Load SHM pointer */
+ LoadInst *CurLoc = IRB.CreateLoad(result);
- LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
+ /* Load SHM pointer */
- /* Load counter for CurLoc */
+ LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
- Value *MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc);
+ /* Load counter for CurLoc */
- if (use_threadsafe_counters) {
+ Value *MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc);
- IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One,
+ if (use_threadsafe_counters) {
+
+ IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One,
#if LLVM_VERSION_MAJOR >= 13
- llvm::MaybeAlign(1),
+ llvm::MaybeAlign(1),
#endif
- llvm::AtomicOrdering::Monotonic);
+ llvm::AtomicOrdering::Monotonic);
- } else {
+ } else {
- LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
+ LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
- /* Update bitmap */
+ /* Update bitmap */
- Value *Incr = IRB.CreateAdd(Counter, One);
+ Value *Incr = IRB.CreateAdd(Counter, One);
- if (skip_nozero == NULL) {
+ if (skip_nozero == NULL) {
- auto cf = IRB.CreateICmpEQ(Incr, Zero);
- auto carry = IRB.CreateZExt(cf, Int8Ty);
- Incr = IRB.CreateAdd(Incr, carry);
+ auto cf = IRB.CreateICmpEQ(Incr, Zero);
+ auto carry = IRB.CreateZExt(cf, Int8Ty);
+ Incr = IRB.CreateAdd(Incr, carry);
+
+ }
+
+ IRB.CreateStore(Incr, MapPtrIdx);
}
- IRB.CreateStore(Incr, MapPtrIdx);
+ skip_next = 1;
+ instr += 2;
+
+ } else {
+
+ unhandled++;
}
- skip_next = 1;
- instr += 2;
-
} else {
skip_next = 0;
From f97c5dba2af3c1428ee26e0936c931e58e5d67e7 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 1 Nov 2021 09:25:11 +0100
Subject: [PATCH 124/305] remove debug
---
instrumentation/SanitizerCoveragePCGUARD.so.cc | 2 --
1 file changed, 2 deletions(-)
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 4bd62bc7..da1db3ff 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -868,8 +868,6 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
}
- fprintf(stderr, "%u selects in %s!\n", cnt_sel, F.getName().str().c_str());
-
/* Create PCGUARD array */
CreateFunctionLocalArrays(F, AllBlocks, cnt_cov + cnt_sel * 2);
selects += cnt_sel;
From cd9f596ce04cdf5bb18d73be7052a7f4aa8f7c94 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 1 Nov 2021 17:33:18 +0100
Subject: [PATCH 125/305] remove debug
---
instrumentation/SanitizerCoveragePCGUARD.so.cc | 1 +
1 file changed, 1 insertion(+)
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index da1db3ff..6b6a00d1 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -905,6 +905,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
Value *c = selectInst->getCondition();
auto t = c->getType();
+
if (t->getTypeID() == llvm::Type::IntegerTyID) {
IRBuilder<> IRB(selectInst->getNextNode());
From fb3a71bd253e446de0b71b73c1d4a69c478f1ecd Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 2 Nov 2021 17:47:17 +0100
Subject: [PATCH 126/305] support select with vectors
---
.../SanitizerCoveragePCGUARD.so.cc | 181 +++++++++++++++---
1 file changed, 150 insertions(+), 31 deletions(-)
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 6b6a00d1..e8239483 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -834,7 +834,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
ArrayRef AllBlocks,
bool IsLeafFunc) {
- uint32_t cnt_cov = 0, cnt_sel = 0;
+ uint32_t cnt_cov = 0, cnt_sel = 0, cnt_sel_inc = 0;
for (auto &BB : F) {
@@ -860,7 +860,22 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
Value *c = selectInst->getCondition();
auto t = c->getType();
- if (t->getTypeID() == llvm::Type::IntegerTyID) cnt_sel++;
+ if (t->getTypeID() == llvm::Type::IntegerTyID) {
+
+ cnt_sel++;
+ cnt_sel_inc += 2;
+
+ } else if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
+
+ FixedVectorType *tt = dyn_cast(t);
+ if (tt) {
+
+ cnt_sel++;
+ cnt_sel_inc += tt->getElementCount().getFixedValue();
+
+ }
+
+ }
}
@@ -869,7 +884,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
}
/* Create PCGUARD array */
- CreateFunctionLocalArrays(F, AllBlocks, cnt_cov + cnt_sel * 2);
+ CreateFunctionLocalArrays(F, AllBlocks, cnt_cov + cnt_sel_inc);
selects += cnt_sel;
uint32_t special = 0, local_selects = 0, skip_next = 0;
@@ -889,13 +904,16 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue;
IRBuilder<> IRB(callInst);
- Value * GuardPtr = IRB.CreateIntToPtr(
+
+ Value *GuardPtr = IRB.CreateIntToPtr(
IRB.CreateAdd(
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
ConstantInt::get(IntptrTy, (++special + AllBlocks.size()) * 4)),
Int32PtrTy);
- callInst->setOperand(1, GuardPtr);
+ LoadInst *Idx = IRB.CreateLoad(GuardPtr);
+
+ callInst->setOperand(1, Idx);
}
@@ -903,45 +921,139 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
if (!skip_next && (selectInst = dyn_cast(&IN))) {
- Value *c = selectInst->getCondition();
- auto t = c->getType();
+ uint32_t vector_cnt = 0;
+ Value * condition = selectInst->getCondition();
+ Value * result;
+ auto t = condition->getType();
+ IRBuilder<> IRB(selectInst->getNextNode());
if (t->getTypeID() == llvm::Type::IntegerTyID) {
- IRBuilder<> IRB(selectInst->getNextNode());
-
- Value *GuardPtr1 = IRB.CreateIntToPtr(
+ auto GuardPtr1 = IRB.CreateIntToPtr(
IRB.CreateAdd(
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
- ConstantInt::get(IntptrTy, (cnt_cov + local_selects * 2 + 1 +
- AllBlocks.size()) *
- 4)),
+ ConstantInt::get(
+ IntptrTy,
+ (cnt_cov + ++local_selects + AllBlocks.size()) * 4)),
Int32PtrTy);
- Value *GuardPtr2 = IRB.CreateIntToPtr(
+ auto GuardPtr2 = IRB.CreateIntToPtr(
IRB.CreateAdd(
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
- ConstantInt::get(IntptrTy, (cnt_cov + local_selects * 2 + 2 +
- AllBlocks.size()) *
- 4)),
+ ConstantInt::get(
+ IntptrTy,
+ (cnt_cov + ++local_selects + AllBlocks.size()) * 4)),
Int32PtrTy);
- local_selects++;
+ result = IRB.CreateSelect(condition, GuardPtr1, GuardPtr2);
- auto cond = selectInst->getCondition();
- auto result = IRB.CreateSelect(cond, GuardPtr1, GuardPtr2);
+ } else if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
+
+ FixedVectorType *tt = dyn_cast(t);
+ if (tt) {
+
+ uint32_t elements = tt->getElementCount().getFixedValue();
+ vector_cnt = elements;
+ if (elements) {
+
+ FixedVectorType *GuardPtr1 =
+ FixedVectorType::get(Int32PtrTy, elements);
+ FixedVectorType *GuardPtr2 =
+ FixedVectorType::get(Int32PtrTy, elements);
+ Value *x, *y;
+
+ Value *val1 = IRB.CreateIntToPtr(
+ IRB.CreateAdd(
+ IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
+ ConstantInt::get(
+ IntptrTy,
+ (cnt_cov + ++local_selects + AllBlocks.size()) * 4)),
+ Int32PtrTy);
+ x = IRB.CreateInsertElement(GuardPtr1, val1, (uint64_t)0);
+
+ Value *val2 = IRB.CreateIntToPtr(
+ IRB.CreateAdd(
+ IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
+ ConstantInt::get(
+ IntptrTy,
+ (cnt_cov + ++local_selects + AllBlocks.size()) * 4)),
+ Int32PtrTy);
+ y = IRB.CreateInsertElement(GuardPtr2, val2, (uint64_t)0);
+
+ for (uint64_t i = 1; i < elements; i++) {
+
+ val1 = IRB.CreateIntToPtr(
+ IRB.CreateAdd(
+ IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
+ ConstantInt::get(IntptrTy, (cnt_cov + ++local_selects +
+ AllBlocks.size()) *
+ 4)),
+ Int32PtrTy);
+ x = IRB.CreateInsertElement(x, val1, i);
+
+ val2 = IRB.CreateIntToPtr(
+ IRB.CreateAdd(
+ IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
+ ConstantInt::get(IntptrTy, (cnt_cov + ++local_selects +
+ AllBlocks.size()) *
+ 4)),
+ Int32PtrTy);
+ y = IRB.CreateInsertElement(y, val2, i);
+
+ }
+
+ /*
+ std::string errMsg;
+ raw_string_ostream os(errMsg);
+ x->print(os);
+ fprintf(stderr, "X: %s\n", os.str().c_str());
+ */
+ result = IRB.CreateSelect(condition, x, y);
+
+ }
+
+ }
+
+ } else {
+
+ unhandled++;
+
+ }
+
+ local_selects++;
+ uint32_t vector_cur = 0;
+
+ /* Load SHM pointer */
+
+ LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
+
+ /*
+ std::string errMsg;
+ raw_string_ostream os(errMsg);
+ result->print(os);
+ fprintf(stderr, "X: %s\n", os.str().c_str());
+ */
+
+ while (1) {
/* Get CurLoc */
-
- LoadInst *CurLoc = IRB.CreateLoad(result);
-
- /* Load SHM pointer */
-
- LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
+ LoadInst *CurLoc = nullptr;
+ Value * MapPtrIdx = nullptr;
/* Load counter for CurLoc */
+ if (!vector_cnt) {
- Value *MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc);
+ CurLoc = IRB.CreateLoad(result);
+ MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc);
+
+ } else {
+
+ auto element = IRB.CreateExtractElement(result, vector_cur++);
+ auto elementptr = IRB.CreateIntToPtr(element, Int32PtrTy);
+ auto elementld = IRB.CreateLoad(elementptr);
+ MapPtrIdx = IRB.CreateGEP(MapPtr, elementld);
+
+ }
if (use_threadsafe_counters) {
@@ -971,15 +1083,22 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
}
- skip_next = 1;
- instr += 2;
+ if (!vector_cnt) {
- } else {
+ vector_cnt = 2;
+ break;
- unhandled++;
+ } else if (vector_cnt == vector_cur) {
+
+ break;
+
+ }
}
+ skip_next = 1;
+ instr += vector_cnt;
+
} else {
skip_next = 0;
From 682e1d835cac4c33f93d3709c98e5e8489f0ec7e Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 2 Nov 2021 19:20:18 +0100
Subject: [PATCH 127/305] select support for LTO
---
instrumentation/SanitizerCoverageLTO.so.cc | 140 ++++++++++++++++++++-
1 file changed, 137 insertions(+), 3 deletions(-)
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index 7a3d8c4d..bc4df34e 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -235,6 +235,8 @@ class ModuleSanitizerCoverage {
uint32_t autodictionary = 1;
uint32_t inst = 0;
uint32_t afl_global_id = 0;
+ uint32_t unhandled = 0;
+ uint32_t select_cnt = 0;
uint64_t map_addr = 0;
const char * skip_nozero = NULL;
const char * use_threadsafe_counters = nullptr;
@@ -1150,9 +1152,9 @@ bool ModuleSanitizerCoverage::instrumentModule(
getenv("AFL_USE_MSAN") ? ", MSAN" : "",
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/vanilla AFL) (%s mode).",
- inst, calculateCollisions(inst), modeline);
+ OKF("Instrumented %u locations (%u selects) without collisions (%llu "
+ "collisions have been avoided) (%s mode).",
+ inst, select_cnt, calculateCollisions(inst), modeline);
}
@@ -1274,6 +1276,7 @@ void ModuleSanitizerCoverage::instrumentFunction(
const DominatorTree * DT = DTCallback(F);
const PostDominatorTree *PDT = PDTCallback(F);
bool IsLeafFunc = true;
+ uint32_t skip_next = 0, local_selects = 0;
for (auto &BB : F) {
@@ -1291,6 +1294,137 @@ void ModuleSanitizerCoverage::instrumentFunction(
Value *val = ConstantInt::get(Int32Ty, ++afl_global_id);
callInst->setOperand(1, val);
+ ++inst;
+
+ }
+
+ SelectInst *selectInst = nullptr;
+
+ if (!skip_next && (selectInst = dyn_cast(&IN))) {
+
+ uint32_t vector_cnt = 0;
+ Value * condition = selectInst->getCondition();
+ Value * result;
+ auto t = condition->getType();
+ IRBuilder<> IRB(selectInst->getNextNode());
+
+ ++select_cnt;
+
+ if (t->getTypeID() == llvm::Type::IntegerTyID) {
+
+ Value *val1 = ConstantInt::get(Int32Ty, ++afl_global_id);
+ Value *val2 = ConstantInt::get(Int32Ty, ++afl_global_id);
+ result = IRB.CreateSelect(condition, val1, val2);
+ inst += 2;
+
+ } else if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
+
+ FixedVectorType *tt = dyn_cast(t);
+ if (tt) {
+
+ uint32_t elements = tt->getElementCount().getFixedValue();
+ vector_cnt = elements;
+ inst += vector_cnt * 2;
+ if (elements) {
+
+ FixedVectorType *GuardPtr1 =
+ FixedVectorType::get(Int32Ty, elements);
+ FixedVectorType *GuardPtr2 =
+ FixedVectorType::get(Int32Ty, elements);
+ Value *x, *y;
+
+ Value *val1 = ConstantInt::get(Int32Ty, ++afl_global_id);
+ Value *val2 = ConstantInt::get(Int32Ty, ++afl_global_id);
+ x = IRB.CreateInsertElement(GuardPtr1, val1, (uint64_t)0);
+ y = IRB.CreateInsertElement(GuardPtr2, val2, (uint64_t)0);
+
+ for (uint64_t i = 1; i < elements; i++) {
+
+ val1 = ConstantInt::get(Int32Ty, ++afl_global_id);
+ val2 = ConstantInt::get(Int32Ty, ++afl_global_id);
+ x = IRB.CreateInsertElement(GuardPtr1, val1, i);
+ y = IRB.CreateInsertElement(GuardPtr2, val2, i);
+
+ }
+
+ /*
+ std::string errMsg;
+ raw_string_ostream os(errMsg);
+ x->print(os);
+ fprintf(stderr, "X: %s\n", os.str().c_str());
+ */
+ result = IRB.CreateSelect(condition, x, y);
+
+ }
+
+ }
+
+ } else {
+
+ unhandled++;
+ continue;
+
+ }
+
+ local_selects++;
+ uint32_t vector_cur = 0;
+ /* Load SHM pointer */
+ LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
+
+ while (1) {
+
+ /* Get CurLoc */
+ Value *MapPtrIdx = nullptr;
+
+ /* Load counter for CurLoc */
+ if (!vector_cnt) {
+
+ MapPtrIdx = IRB.CreateGEP(MapPtr, result);
+
+ } else {
+
+ auto element = IRB.CreateExtractElement(result, vector_cur++);
+ MapPtrIdx = IRB.CreateGEP(MapPtr, element);
+
+ }
+
+ if (use_threadsafe_counters) {
+
+ IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One,
+#if LLVM_VERSION_MAJOR >= 13
+ llvm::MaybeAlign(1),
+#endif
+ llvm::AtomicOrdering::Monotonic);
+
+ } else {
+
+ LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
+
+ /* Update bitmap */
+
+ Value *Incr = IRB.CreateAdd(Counter, One);
+
+ if (skip_nozero == NULL) {
+
+ auto cf = IRB.CreateICmpEQ(Incr, Zero);
+ auto carry = IRB.CreateZExt(cf, Int8Ty);
+ Incr = IRB.CreateAdd(Incr, carry);
+
+ }
+
+ IRB.CreateStore(Incr, MapPtrIdx);
+
+ }
+
+ if (!vector_cnt || vector_cnt == vector_cur) { break; }
+
+ }
+
+ skip_next = 1;
+
+ } else {
+
+ skip_next = 0;
}
From ce41f881a0109ada6b550d96766d52e692a0e0f4 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 2 Nov 2021 19:53:15 +0100
Subject: [PATCH 128/305] nosan
---
instrumentation/SanitizerCoverageLTO.so.cc | 27 +++++++++----------
.../SanitizerCoveragePCGUARD.so.cc | 15 +++++++++--
2 files changed, 25 insertions(+), 17 deletions(-)
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index bc4df34e..b3a6ba45 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -1042,8 +1042,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
M, Int64Tyi, true, GlobalValue::ExternalLinkage, 0, "__afl_map_addr");
ConstantInt *MapAddr = ConstantInt::get(Int64Tyi, map_addr);
StoreInst * StoreMapAddr = IRB.CreateStore(MapAddr, AFLMapAddrFixed);
- StoreMapAddr->setMetadata(M.getMDKindID("nosanitize"),
- MDNode::get(Ctx, None));
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreMapAddr);
}
@@ -1058,8 +1057,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
"__afl_final_loc");
ConstantInt *const_loc = ConstantInt::get(Int32Tyi, write_loc);
StoreInst * StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc);
- StoreFinalLoc->setMetadata(M.getMDKindID("nosanitize"),
- MDNode::get(Ctx, None));
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreFinalLoc);
}
@@ -1107,8 +1105,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
0, "__afl_dictionary_len");
ConstantInt *const_len = ConstantInt::get(Int32Tyi, offset);
StoreInst *StoreDictLen = IRB.CreateStore(const_len, AFLDictionaryLen);
- StoreDictLen->setMetadata(M.getMDKindID("nosanitize"),
- MDNode::get(Ctx, None));
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreDictLen);
ArrayType *ArrayTy = ArrayType::get(IntegerType::get(Ctx, 8), offset);
GlobalVariable *AFLInternalDictionary = new GlobalVariable(
@@ -1128,8 +1125,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
Value *AFLDictPtr =
IRB.CreatePointerCast(AFLDictOff, PointerType::get(Int8Tyi, 0));
StoreInst *StoreDict = IRB.CreateStore(AFLDictPtr, AFLDictionary);
- StoreDict->setMetadata(M.getMDKindID("nosanitize"),
- MDNode::get(Ctx, None));
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreDict);
}
@@ -1370,6 +1366,7 @@ void ModuleSanitizerCoverage::instrumentFunction(
uint32_t vector_cur = 0;
/* Load SHM pointer */
LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr);
while (1) {
@@ -1399,6 +1396,7 @@ void ModuleSanitizerCoverage::instrumentFunction(
} else {
LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter);
/* Update bitmap */
@@ -1412,7 +1410,8 @@ void ModuleSanitizerCoverage::instrumentFunction(
}
- IRB.CreateStore(Incr, MapPtrIdx);
+ auto nosan = IRB.CreateStore(Incr, MapPtrIdx);
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(nosan);
}
@@ -1655,8 +1654,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
} else {
LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
- MapPtr->setMetadata(Mo->getMDKindID("nosanitize"),
- MDNode::get(*Ct, None));
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr);
MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc);
}
@@ -1673,8 +1671,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
} else {
LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
- Counter->setMetadata(Mo->getMDKindID("nosanitize"),
- MDNode::get(*Ct, None));
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter);
Value *Incr = IRB.CreateAdd(Counter, One);
@@ -1686,8 +1683,8 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
}
- IRB.CreateStore(Incr, MapPtrIdx)
- ->setMetadata(Mo->getMDKindID("nosanitize"), MDNode::get(*Ct, None));
+ auto nosan = IRB.CreateStore(Incr, MapPtrIdx);
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(nosan);
}
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index e8239483..70af2ee2 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -912,6 +912,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
Int32PtrTy);
LoadInst *Idx = IRB.CreateLoad(GuardPtr);
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(Idx);
callInst->setOperand(1, Idx);
@@ -1026,6 +1027,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
/* Load SHM pointer */
LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr);
/*
std::string errMsg;
@@ -1044,6 +1046,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
if (!vector_cnt) {
CurLoc = IRB.CreateLoad(result);
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(CurLoc);
MapPtrIdx = IRB.CreateGEP(MapPtr, CurLoc);
} else {
@@ -1051,6 +1054,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
auto element = IRB.CreateExtractElement(result, vector_cur++);
auto elementptr = IRB.CreateIntToPtr(element, Int32PtrTy);
auto elementld = IRB.CreateLoad(elementptr);
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(elementld);
MapPtrIdx = IRB.CreateGEP(MapPtr, elementld);
}
@@ -1066,6 +1070,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
} else {
LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter);
/* Update bitmap */
@@ -1079,7 +1084,8 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
}
- IRB.CreateStore(Incr, MapPtrIdx);
+ StoreInst *StoreCtx = IRB.CreateStore(Incr, MapPtrIdx);
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreCtx);
}
@@ -1309,10 +1315,12 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
Int32PtrTy);
LoadInst *CurLoc = IRB.CreateLoad(GuardPtr);
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(CurLoc);
/* Load SHM pointer */
LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr);
/* Load counter for CurLoc */
@@ -1329,6 +1337,8 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
} else {
LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter);
+
/* Update bitmap */
Value *Incr = IRB.CreateAdd(Counter, One);
@@ -1341,7 +1351,8 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
}
- IRB.CreateStore(Incr, MapPtrIdx);
+ StoreInst *StoreCtx = IRB.CreateStore(Incr, MapPtrIdx);
+ ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreCtx);
}
From f35e71ca11babe72cf0a5c7aa99c9a42aceef5fa Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 2 Nov 2021 19:58:02 +0100
Subject: [PATCH 129/305] fix
---
instrumentation/afl-compiler-rt.o.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index ff3998e6..694d61c1 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -2086,7 +2086,7 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
if ((l1 = area_is_valid(ptr1, 32)) <= 0 ||
(l2 = area_is_valid(ptr2, 32)) <= 0)
return;
- int len = MIN(l1, l2);
+ int len = MIN(31, MIN(l1, l2));
// fprintf(stderr, "RTN2 %u\n", len);
uintptr_t k = (uintptr_t)__builtin_return_address(0);
@@ -2124,6 +2124,8 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
}
+ cmpfn[hits].v0_len = len;
+ cmpfn[hits].v1_len = len;
__builtin_memcpy(cmpfn[hits].v0, ptr1, len);
__builtin_memcpy(cmpfn[hits].v1, ptr2, len);
// fprintf(stderr, "RTN3\n");
From 5bcb7a8fed18247e827452b127c6e4a6240bb93b Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 2 Nov 2021 20:21:43 +0100
Subject: [PATCH 130/305] modify frida for new cmplog
---
frida_mode/src/cmplog/cmplog_arm64.c | 51 +++++++++++++++++++++------
frida_mode/src/cmplog/cmplog_x64.c | 52 +++++++++++++++++++++-------
frida_mode/src/cmplog/cmplog_x86.c | 51 ++++++++++++++++++++-------
3 files changed, 118 insertions(+), 36 deletions(-)
diff --git a/frida_mode/src/cmplog/cmplog_arm64.c b/frida_mode/src/cmplog/cmplog_arm64.c
index dd97f38d..ccc8e89e 100644
--- a/frida_mode/src/cmplog/cmplog_arm64.c
+++ b/frida_mode/src/cmplog/cmplog_arm64.c
@@ -104,9 +104,9 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
gsize x0 = ctx_read_reg(context, ARM64_REG_X0);
gsize x1 = ctx_read_reg(context, ARM64_REG_X1);
- if (((G_MAXULONG - x0) < 32) || ((G_MAXULONG - x1) < 32)) return;
+ if (((G_MAXULONG - x0) < 31) || ((G_MAXULONG - x1) < 31)) return;
- if (!cmplog_is_readable(x0, 32) || !cmplog_is_readable(x1, 32)) return;
+ if (!cmplog_is_readable(x0, 31) || !cmplog_is_readable(x1, 31)) return;
void *ptr1 = GSIZE_TO_POINTER(x0);
void *ptr2 = GSIZE_TO_POINTER(x1);
@@ -116,18 +116,36 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
- __afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
+ if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
+
+ __afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
+ __afl_cmp_map->headers[k].hits = 0;
+
+ }
+
+ u32 hits = 0;
+
+ if (__afl_cmp_map->headers[k].hits == 0) {
+
+ __afl_cmp_map->headers[k].shape = 30;
+
+ } else {
+
+ hits = __afl_cmp_map->headers[k].hits;
+
+ }
- u32 hits = __afl_cmp_map->headers[k].hits;
__afl_cmp_map->headers[k].hits = hits + 1;
- __afl_cmp_map->headers[k].shape = 31;
+ __afl_cmp_map->headers[k].shape = 30;
hits &= CMP_MAP_RTN_H - 1;
+ ((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0_len = 31;
+ ((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1_len = 31;
gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0, ptr1,
- 32);
+ 31);
gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1, ptr2,
- 32);
+ 31);
}
@@ -193,13 +211,24 @@ static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1,
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
- __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+ if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS)
+ __afl_cmp_map->headers[k].hits = 0;
+
+ u32 hits = 0;
+
+ if (__afl_cmp_map->headers[k].hits == 0) {
+
+ __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+ __afl_cmp_map->headers[k].shape = (size - 1);
+
+ } else {
+
+ hits = __afl_cmp_map->headers[k].hits;
+
+ }
- u32 hits = __afl_cmp_map->headers[k].hits;
__afl_cmp_map->headers[k].hits = hits + 1;
- __afl_cmp_map->headers[k].shape = (size - 1);
-
hits &= CMP_MAP_H - 1;
__afl_cmp_map->log[k][hits].v0 = operand1;
__afl_cmp_map->log[k][hits].v1 = operand2;
diff --git a/frida_mode/src/cmplog/cmplog_x64.c b/frida_mode/src/cmplog/cmplog_x64.c
index 0d18767a..5319f727 100644
--- a/frida_mode/src/cmplog/cmplog_x64.c
+++ b/frida_mode/src/cmplog/cmplog_x64.c
@@ -99,9 +99,9 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
gsize rdi = ctx_read_reg(context, X86_REG_RDI);
gsize rsi = ctx_read_reg(context, X86_REG_RSI);
- if (((G_MAXULONG - rdi) < 32) || ((G_MAXULONG - rsi) < 32)) return;
+ if (((G_MAXULONG - rdi) < 31) || ((G_MAXULONG - rsi) < 31)) return;
- if (!cmplog_is_readable(rdi, 32) || !cmplog_is_readable(rsi, 32)) return;
+ if (!cmplog_is_readable(rdi, 31) || !cmplog_is_readable(rsi, 31)) return;
void *ptr1 = GSIZE_TO_POINTER(rdi);
void *ptr2 = GSIZE_TO_POINTER(rsi);
@@ -111,18 +111,34 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
- __afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
+ if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
+
+ __afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
+ __afl_cmp_map->headers[k].hits = 0;
+
+ }
+
+ u32 hits = 0;
+
+ if (__afl_cmp_map->headers[k].hits == 0) {
+
+ __afl_cmp_map->headers[k].shape = 30;
+
+ } else {
+
+ hits = __afl_cmp_map->headers[k].hits;
+
+ }
- u32 hits = __afl_cmp_map->headers[k].hits;
__afl_cmp_map->headers[k].hits = hits + 1;
- __afl_cmp_map->headers[k].shape = 31;
-
hits &= CMP_MAP_RTN_H - 1;
+ ((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0_len = 31;
+ ((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1_len = 31;
gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0, ptr1,
- 32);
+ 31);
gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1, ptr2,
- 32);
+ 31);
}
@@ -179,13 +195,23 @@ static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1,
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 7;
- __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+ if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS)
+ __afl_cmp_map->headers[k].hits = 0;
+
+ u32 hits = 0;
+
+ if (__afl_cmp_map->headers[k].hits == 0) {
+
+ __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+ __afl_cmp_map->headers[k].shape = (size - 1);
+
+ } else {
+
+ hits = __afl_cmp_map->headers[k].hits;
+
+ }
- u32 hits = __afl_cmp_map->headers[k].hits;
__afl_cmp_map->headers[k].hits = hits + 1;
-
- __afl_cmp_map->headers[k].shape = (size - 1);
-
hits &= CMP_MAP_H - 1;
__afl_cmp_map->log[k][hits].v0 = operand1;
__afl_cmp_map->log[k][hits].v1 = operand2;
diff --git a/frida_mode/src/cmplog/cmplog_x86.c b/frida_mode/src/cmplog/cmplog_x86.c
index dd666c34..27d06720 100644
--- a/frida_mode/src/cmplog/cmplog_x86.c
+++ b/frida_mode/src/cmplog/cmplog_x86.c
@@ -104,9 +104,9 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
gsize arg1 = esp[0];
gsize arg2 = esp[1];
- if (((G_MAXULONG - arg1) < 32) || ((G_MAXULONG - arg2) < 32)) return;
+ if (((G_MAXULONG - arg1) < 31) || ((G_MAXULONG - arg2) < 31)) return;
- if (!cmplog_is_readable(arg1, 32) || !cmplog_is_readable(arg2, 32)) return;
+ if (!cmplog_is_readable(arg1, 31) || !cmplog_is_readable(arg2, 31)) return;
void *ptr1 = GSIZE_TO_POINTER(arg1);
void *ptr2 = GSIZE_TO_POINTER(arg2);
@@ -116,18 +116,34 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
- __afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
+ if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
+
+ __afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
+ __afl_cmp_map->headers[k].hits = 0;
+
+ }
+
+ u32 hits = 0;
+
+ if (__afl_cmp_map->headers[k].hits == 0) {
+
+ __afl_cmp_map->headers[k].shape = 30;
+
+ } else {
+
+ hits = __afl_cmp_map->headers[k].hits;
+
+ }
- u32 hits = __afl_cmp_map->headers[k].hits;
__afl_cmp_map->headers[k].hits = hits + 1;
- __afl_cmp_map->headers[k].shape = 31;
-
hits &= CMP_MAP_RTN_H - 1;
+ ((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0_len = 31;
+ ((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1_len = 31;
gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0, ptr1,
- 32);
+ 31);
gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1, ptr2,
- 32);
+ 31);
}
@@ -184,13 +200,24 @@ static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1,
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
- __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+ if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS)
+ __afl_cmp_map->headers[k].hits = 0;
+
+ u32 hits = 0;
+
+ if (__afl_cmp_map->headers[k].hits == 0) {
+
+ __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+ __afl_cmp_map->headers[k].shape = (size - 1);
+
+ } else {
+
+ hits = __afl_cmp_map->headers[k].hits;
+
+ }
- u32 hits = __afl_cmp_map->headers[k].hits;
__afl_cmp_map->headers[k].hits = hits + 1;
- __afl_cmp_map->headers[k].shape = (size - 1);
-
hits &= CMP_MAP_H - 1;
__afl_cmp_map->log[k][hits].v0 = operand1;
__afl_cmp_map->log[k][hits].v1 = operand2;
From caf68e5bf25a8a73bcc21b870499b640e7702d85 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 3 Nov 2021 12:34:26 +0100
Subject: [PATCH 131/305] support vectorized cmps
---
instrumentation/cmplog-instructions-pass.cc | 219 ++++++++++++++------
1 file changed, 155 insertions(+), 64 deletions(-)
diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc
index 0562c5b2..86e206f1 100644
--- a/instrumentation/cmplog-instructions-pass.cc
+++ b/instrumentation/cmplog-instructions-pass.cc
@@ -274,14 +274,15 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
Value *op0 = selectcmpInst->getOperand(0);
Value *op1 = selectcmpInst->getOperand(1);
+ Value *op0_saved = op0, *op1_saved = op1;
+ auto ty0 = op0->getType();
+ auto ty1 = op1->getType();
- IntegerType * intTyOp0 = NULL;
- IntegerType * intTyOp1 = NULL;
- unsigned max_size = 0, cast_size = 0;
- unsigned char attr = 0;
- std::vector args;
-
- CmpInst *cmpInst = dyn_cast(selectcmpInst);
+ IntegerType *intTyOp0 = NULL;
+ IntegerType *intTyOp1 = NULL;
+ unsigned max_size = 0, cast_size = 0;
+ unsigned attr = 0, vector_cnt = 0;
+ CmpInst * cmpInst = dyn_cast(selectcmpInst);
if (!cmpInst) { continue; }
@@ -327,7 +328,21 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
if (selectcmpInst->getOpcode() == Instruction::FCmp) {
- auto ty0 = op0->getType();
+ if (ty0->isVectorTy()) {
+
+ VectorType *tt = dyn_cast(ty0);
+ if (!tt) {
+
+ fprintf(stderr, "Warning: cmplog cmp vector is not a vector!\n");
+ continue;
+
+ }
+
+ vector_cnt = tt->getElementCount().getFixedValue();
+ ty0 = tt->getElementType();
+
+ }
+
if (ty0->isHalfTy()
#if LLVM_VERSION_MAJOR >= 11
|| ty0->isBFloatTy()
@@ -342,13 +357,32 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
max_size = 80;
else if (ty0->isFP128Ty() || ty0->isPPC_FP128Ty())
max_size = 128;
+ else if (ty0->getTypeID() != llvm::Type::PointerTyID && !be_quiet)
+ fprintf(stderr, "Warning: unsupported cmp type for cmplog: %u!\n",
+ ty0->getTypeID());
attr += 8;
} else {
- intTyOp0 = dyn_cast(op0->getType());
- intTyOp1 = dyn_cast(op1->getType());
+ if (ty0->isVectorTy()) {
+
+ VectorType *tt = dyn_cast(ty0);
+ if (!tt) {
+
+ fprintf(stderr, "Warning: cmplog cmp vector is not a vector!\n");
+ continue;
+
+ }
+
+ vector_cnt = tt->getElementCount().getFixedValue();
+ ty1 = ty0 = tt->getElementType();
+ fprintf(stderr, "vec %u\n", vector_cnt);
+
+ }
+
+ intTyOp0 = dyn_cast(ty0);
+ intTyOp1 = dyn_cast(ty1);
if (intTyOp0 && intTyOp1) {
@@ -356,11 +390,25 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
? intTyOp0->getBitWidth()
: intTyOp1->getBitWidth();
+ } else {
+
+ if (ty0->getTypeID() != llvm::Type::PointerTyID && !be_quiet) {
+
+ fprintf(stderr, "Warning: unsupported cmp type for cmplog: %u!\n",
+ ty0->getTypeID());
+
+ }
+
}
}
- if (!max_size || max_size < 16) { continue; }
+ if (!max_size || max_size < 16) {
+
+ // fprintf(stderr, "too small\n");
+ continue;
+
+ }
if (max_size % 8) { max_size = (((max_size / 8) + 1) * 8); }
@@ -393,67 +441,110 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
}
- // errs() << "[CMPLOG] cmp " << *cmpInst << "(in function " <<
- // cmpInst->getFunction()->getName() << ")\n";
+ uint64_t cur = 0, last_val0 = 0, last_val1 = 0, cur_val;
- // first bitcast to integer type of the same bitsize as the original
- // type (this is a nop, if already integer)
- Value *op0_i = IRB.CreateBitCast(
- op0, IntegerType::get(C, op0->getType()->getPrimitiveSizeInBits()));
- // then create a int cast, which does zext, trunc or bitcast. In our case
- // usually zext to the next larger supported type (this is a nop if
- // already the right type)
- Value *V0 =
- IRB.CreateIntCast(op0_i, IntegerType::get(C, cast_size), false);
- args.push_back(V0);
- Value *op1_i = IRB.CreateBitCast(
- op1, IntegerType::get(C, op1->getType()->getPrimitiveSizeInBits()));
- Value *V1 =
- IRB.CreateIntCast(op1_i, IntegerType::get(C, cast_size), false);
- args.push_back(V1);
+ while (1) {
- // errs() << "[CMPLOG] casted parameters:\n0: " << *V0 << "\n1: " << *V1
- // << "\n";
+ std::vector args;
+ uint32_t skip = 0;
- ConstantInt *attribute = ConstantInt::get(Int8Ty, attr);
- args.push_back(attribute);
+ if (vector_cnt) {
- if (cast_size != max_size) {
+ op0 = IRB.CreateExtractElement(op0_saved, cur);
+ op1 = IRB.CreateExtractElement(op1_saved, cur);
+ ConstantInt *i0 = dyn_cast(op0);
+ ConstantInt *i1 = dyn_cast(op1);
+ if (i0 && i0->uge(0xffffffffffffffff) == false) {
- ConstantInt *bitsize = ConstantInt::get(Int8Ty, (max_size / 8) - 1);
- args.push_back(bitsize);
-
- }
-
- // fprintf(stderr, "_ExtInt(%u) castTo %u with attr %u didcast %u\n",
- // max_size, cast_size, attr);
-
- switch (cast_size) {
-
- case 8:
- IRB.CreateCall(cmplogHookIns1, args);
- break;
- case 16:
- IRB.CreateCall(cmplogHookIns2, args);
- break;
- case 32:
- IRB.CreateCall(cmplogHookIns4, args);
- break;
- case 64:
- IRB.CreateCall(cmplogHookIns8, args);
- break;
- case 128:
- if (max_size == 128) {
-
- IRB.CreateCall(cmplogHookIns16, args);
-
- } else {
-
- IRB.CreateCall(cmplogHookInsN, args);
+ cur_val = i0->getZExtValue();
+ if (last_val0 && last_val0 == cur_val) { skip = 1; }
+ last_val0 = cur_val;
}
- break;
+ if (i1 && i1->uge(0xffffffffffffffff) == false) {
+
+ cur_val = i1->getZExtValue();
+ if (last_val1 && last_val1 == cur_val) { skip = 1; }
+ last_val1 = cur_val;
+
+ }
+
+ }
+
+ if (!skip) {
+
+ // errs() << "[CMPLOG] cmp " << *cmpInst << "(in function " <<
+ // cmpInst->getFunction()->getName() << ")\n";
+
+ // first bitcast to integer type of the same bitsize as the original
+ // type (this is a nop, if already integer)
+ Value *op0_i = IRB.CreateBitCast(
+ op0, IntegerType::get(C, ty0->getPrimitiveSizeInBits()));
+ // then create a int cast, which does zext, trunc or bitcast. In our
+ // case usually zext to the next larger supported type (this is a nop
+ // if already the right type)
+ Value *V0 =
+ IRB.CreateIntCast(op0_i, IntegerType::get(C, cast_size), false);
+ args.push_back(V0);
+ Value *op1_i = IRB.CreateBitCast(
+ op1, IntegerType::get(C, ty1->getPrimitiveSizeInBits()));
+ Value *V1 =
+ IRB.CreateIntCast(op1_i, IntegerType::get(C, cast_size), false);
+ args.push_back(V1);
+
+ // errs() << "[CMPLOG] casted parameters:\n0: " << *V0 << "\n1: " <<
+ // *V1
+ // << "\n";
+
+ ConstantInt *attribute = ConstantInt::get(Int8Ty, attr);
+ args.push_back(attribute);
+
+ if (cast_size != max_size) {
+
+ ConstantInt *bitsize = ConstantInt::get(Int8Ty, (max_size / 8) - 1);
+ args.push_back(bitsize);
+
+ }
+
+ // fprintf(stderr, "_ExtInt(%u) castTo %u with attr %u didcast %u\n",
+ // max_size, cast_size, attr);
+
+ switch (cast_size) {
+
+ case 8:
+ IRB.CreateCall(cmplogHookIns1, args);
+ break;
+ case 16:
+ IRB.CreateCall(cmplogHookIns2, args);
+ break;
+ case 32:
+ IRB.CreateCall(cmplogHookIns4, args);
+ break;
+ case 64:
+ IRB.CreateCall(cmplogHookIns8, args);
+ break;
+ case 128:
+ if (max_size == 128) {
+
+ IRB.CreateCall(cmplogHookIns16, args);
+
+ } else {
+
+ IRB.CreateCall(cmplogHookInsN, args);
+
+ }
+
+ break;
+
+ }
+
+ }
+
+ /* else fprintf(stderr, "skipped\n"); */
+
+ ++cur;
+ if (cur >= vector_cnt) { break; }
}
From ccded9fc5cfead1b88104484c4acde12e81e0afe Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 3 Nov 2021 12:49:54 +0100
Subject: [PATCH 132/305] vectorized coverage only possible for llvm 14 :(
---
instrumentation/SanitizerCoverageLTO.so.cc | 10 ++++++++--
instrumentation/SanitizerCoveragePCGUARD.so.cc | 17 +++++++++++++++--
instrumentation/cmplog-instructions-pass.cc | 1 -
3 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index b3a6ba45..fbbe24a2 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -1313,7 +1313,10 @@ void ModuleSanitizerCoverage::instrumentFunction(
result = IRB.CreateSelect(condition, val1, val2);
inst += 2;
- } else if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
+ }
+
+#if LLVM_VERSION_MAJOR > 13
+ else if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
FixedVectorType *tt = dyn_cast(t);
if (tt) {
@@ -1355,7 +1358,10 @@ void ModuleSanitizerCoverage::instrumentFunction(
}
- } else {
+ } else
+
+#endif
+ {
unhandled++;
continue;
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 70af2ee2..10c9430e 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -895,6 +895,12 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
CallInst *callInst = nullptr;
+ /*
+ std::string errMsg;
+ raw_string_ostream os(errMsg);
+ IN.print(os);
+ fprintf(stderr, "X: %s\n", os.str().c_str());
+ */
if ((callInst = dyn_cast(&IN))) {
Function *Callee = callInst->getCalledFunction();
@@ -948,7 +954,10 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
result = IRB.CreateSelect(condition, GuardPtr1, GuardPtr2);
- } else if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
+ } else
+
+#if LLVM_VERSION_MAJOR > 13
+ if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
FixedVectorType *tt = dyn_cast(t);
if (tt) {
@@ -1015,9 +1024,13 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
}
- } else {
+ } else
+
+#endif
+ {
unhandled++;
+ continue;
}
diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc
index 86e206f1..cb149e9a 100644
--- a/instrumentation/cmplog-instructions-pass.cc
+++ b/instrumentation/cmplog-instructions-pass.cc
@@ -377,7 +377,6 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
vector_cnt = tt->getElementCount().getFixedValue();
ty1 = ty0 = tt->getElementType();
- fprintf(stderr, "vec %u\n", vector_cnt);
}
From 7a7630ae91c87e000b40f63c592fad9e09ad45d3 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 3 Nov 2021 13:18:02 +0100
Subject: [PATCH 133/305] support llvm >= 11
---
instrumentation/SanitizerCoverageLTO.so.cc | 18 ++++++++++--------
instrumentation/SanitizerCoveragePCGUARD.so.cc | 7 ++++++-
instrumentation/cmplog-instructions-pass.cc | 11 ++++++++++-
3 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index fbbe24a2..ee8c317e 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -1296,6 +1296,12 @@ void ModuleSanitizerCoverage::instrumentFunction(
SelectInst *selectInst = nullptr;
+ /*
+ std::string errMsg;
+ raw_string_ostream os(errMsg);
+ IN.print(os);
+ fprintf(stderr, "X(%u): %s\n", skip_next, os.str().c_str());
+ */
if (!skip_next && (selectInst = dyn_cast(&IN))) {
uint32_t vector_cnt = 0;
@@ -1311,12 +1317,13 @@ void ModuleSanitizerCoverage::instrumentFunction(
Value *val1 = ConstantInt::get(Int32Ty, ++afl_global_id);
Value *val2 = ConstantInt::get(Int32Ty, ++afl_global_id);
result = IRB.CreateSelect(condition, val1, val2);
+ skip_next = 1;
inst += 2;
- }
+ } else
#if LLVM_VERSION_MAJOR > 13
- else if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
+ if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
FixedVectorType *tt = dyn_cast(t);
if (tt) {
@@ -1346,13 +1353,8 @@ void ModuleSanitizerCoverage::instrumentFunction(
}
- /*
- std::string errMsg;
- raw_string_ostream os(errMsg);
- x->print(os);
- fprintf(stderr, "X: %s\n", os.str().c_str());
- */
result = IRB.CreateSelect(condition, x, y);
+ skip_next = 1;
}
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 10c9430e..be3f4f49 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -865,7 +865,10 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
cnt_sel++;
cnt_sel_inc += 2;
- } else if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
+ }
+
+#if LLVM__MAJOR > 11
+ else if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
FixedVectorType *tt = dyn_cast(t);
if (tt) {
@@ -877,6 +880,8 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F,
}
+#endif
+
}
}
diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc
index cb149e9a..01a8a637 100644
--- a/instrumentation/cmplog-instructions-pass.cc
+++ b/instrumentation/cmplog-instructions-pass.cc
@@ -338,8 +338,10 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
}
+#if LLVM_MAJOR > 11
vector_cnt = tt->getElementCount().getFixedValue();
ty0 = tt->getElementType();
+#endif
}
@@ -357,9 +359,11 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
max_size = 80;
else if (ty0->isFP128Ty() || ty0->isPPC_FP128Ty())
max_size = 128;
+#if LLVM_MAJOR > 11
else if (ty0->getTypeID() != llvm::Type::PointerTyID && !be_quiet)
fprintf(stderr, "Warning: unsupported cmp type for cmplog: %u!\n",
ty0->getTypeID());
+#endif
attr += 8;
@@ -367,6 +371,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
if (ty0->isVectorTy()) {
+#if LLVM_MAJOR > 11
VectorType *tt = dyn_cast(ty0);
if (!tt) {
@@ -377,6 +382,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
vector_cnt = tt->getElementCount().getFixedValue();
ty1 = ty0 = tt->getElementType();
+#endif
}
@@ -391,13 +397,16 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
} else {
+#if LLVM_MAJOR > 11
if (ty0->getTypeID() != llvm::Type::PointerTyID && !be_quiet) {
- fprintf(stderr, "Warning: unsupported cmp type for cmplog: %u!\n",
+ fprintf(stderr, "Warning: unsupported cmp type for cmplog: %u\n",
ty0->getTypeID());
}
+#endif
+
}
}
From 701997a2a5226c731c15f8d3f512cd8c91df1612 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 3 Nov 2021 13:33:59 +0100
Subject: [PATCH 134/305] fix
---
src/afl-fuzz-redqueen.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index c97080c7..a9c5625f 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -1383,7 +1383,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
- hshape = 7; // recover shape
+ hshape = 8; // recover shape
}
From 45399b7a56f77652f09f6825a7bdf2ae1708ff3a Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 3 Nov 2021 13:35:52 +0100
Subject: [PATCH 135/305] afl4 qemu
---
qemu_mode/QEMUAFL_VERSION | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index 7bdedf7b..40bae8f5 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-71ed0d206f
+4eb8c66a6077157e96f8660c0e64a69f001dc06f
From 3670412d2e6841f2cee26e3624a02c08a24671c8 Mon Sep 17 00:00:00 2001
From: yuan
Date: Wed, 3 Nov 2021 23:44:37 +0800
Subject: [PATCH 136/305] Fix request size & remove redundant code (#1139)
* fix request size
* fix null terminator index
* remove redundant code
---
src/afl-common.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/afl-common.c b/src/afl-common.c
index db19f0a7..26a0d54b 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -217,11 +217,10 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
}
- char **new_argv = ck_alloc(sizeof(char *) * (argc + 4));
+ char **new_argv = ck_alloc(sizeof(char *) * (argc + 3));
if (unlikely(!new_argv)) { FATAL("Illegal amount of arguments specified"); }
memcpy(&new_argv[3], &argv[1], (int)(sizeof(char *)) * (argc - 1));
- new_argv[argc + 3] = NULL;
new_argv[2] = *target_path_p;
new_argv[1] = "--";
@@ -237,11 +236,10 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
- char **new_argv = ck_alloc(sizeof(char *) * (argc + 3));
+ char **new_argv = ck_alloc(sizeof(char *) * (argc + 2));
if (unlikely(!new_argv)) { FATAL("Illegal amount of arguments specified"); }
memcpy(&new_argv[2], &argv[1], (int)(sizeof(char *)) * (argc - 1));
- new_argv[argc + 2] = NULL;
new_argv[1] = *target_path_p;
From 651133ea00ae803377f941b95a9d396bf92eb407 Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Wed, 3 Nov 2021 21:11:11 +0100
Subject: [PATCH 137/305] Clean up references to power_schedules.md
---
docs/parallel_fuzzing.md | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/docs/parallel_fuzzing.md b/docs/parallel_fuzzing.md
index e37276a5..d24f2837 100644
--- a/docs/parallel_fuzzing.md
+++ b/docs/parallel_fuzzing.md
@@ -27,9 +27,8 @@ will not be able to use that input to guide their work.
To help with this problem, afl-fuzz offers a simple way to synchronize test
cases on the fly.
-Note that AFL++ has AFLfast's power schedules implemented.
-It is therefore a good idea to use different power schedules if you run
-several instances in parallel. See [power_schedules.md](power_schedules.md)
+It is a good idea to use different power schedules if you run several instances
+in parallel (`-p` option).
Alternatively running other AFL spinoffs in parallel can be of value,
e.g. Angora (https://github.com/AngoraFuzzer/Angora/)
@@ -39,7 +38,7 @@ e.g. Angora (https://github.com/AngoraFuzzer/Angora/)
If you wish to parallelize a single job across multiple cores on a local
system, simply create a new, empty output directory ("sync dir") that will be
shared by all the instances of afl-fuzz; and then come up with a naming scheme
-for every instance - say, "fuzzer01", "fuzzer02", etc.
+for every instance - say, "fuzzer01", "fuzzer02", etc.
Run the first one ("main node", -M) like this:
@@ -93,7 +92,7 @@ file name.
There is support for parallelizing the deterministic checks.
This is only needed where
-
+
1. many new paths are found fast over a long time and it looks unlikely that
main node will ever catch up, and
2. deterministic fuzzing is actively helping path discovery (you can see this
@@ -195,7 +194,7 @@ to keep in mind:
- You do not want a "main" instance of afl-fuzz on every system; you should
run them all with -S, and just designate a single process somewhere within
the fleet to run with -M.
-
+
- Syncing is only necessary for the main nodes on a system. It is possible
to run main-less with only secondaries. However then you need to find out
which secondary took over the temporary role to be the main node. Look for
From afc84438c60f7a70464ddc353216e0d9fb0c0b49 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 3 Nov 2021 21:23:03 +0100
Subject: [PATCH 138/305] move bitmap and saveauto
---
src/afl-fuzz.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 6ec033b2..e06060ab 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -2226,13 +2226,12 @@ int main(int argc, char **argv_orig, char **envp) {
}
- write_bitmap(afl);
- save_auto(afl);
-
stop_fuzzing:
afl->force_ui_update = 1; // ensure the screen is reprinted
show_stats(afl); // print the screen one last time
+ write_bitmap(afl);
+ save_auto(afl);
SAYF(CURSOR_SHOW cLRD "\n\n+++ Testing aborted %s +++\n" cRST,
afl->stop_soon == 2 ? "programmatically" : "by user");
From 02a5d96846c222ab91b6c1edff9eeb9b75a6aefc Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 3 Nov 2021 21:27:19 +0100
Subject: [PATCH 139/305] remove overflow wiping
---
instrumentation/afl-compiler-rt.o.c | 32 -----------------------------
1 file changed, 32 deletions(-)
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 694d61c1..112893ee 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -1936,14 +1936,6 @@ void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u64 len) {
struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
hits &= CMP_MAP_RTN_H - 1;
- if (unlikely(reset && !hits)) { __afl_cmp_map->headers[k].overflow = 1; }
-
- if (unlikely(__afl_cmp_map->headers[k].overflow)) {
-
- __builtin_memset((char *)&cmpfn[hits], 0, sizeof(struct cmpfn_operands));
-
- }
-
cmpfn[hits].v0_len = l;
cmpfn[hits].v1_len = l;
__builtin_memcpy(cmpfn[hits].v0, ptr1, l);
@@ -1992,14 +1984,6 @@ void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u64 len) {
struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
hits &= CMP_MAP_RTN_H - 1;
- if (unlikely(reset && !hits)) { __afl_cmp_map->headers[k].overflow = 1; }
-
- if (unlikely(__afl_cmp_map->headers[k].overflow)) {
-
- __builtin_memset((char *)&cmpfn[hits], 0, sizeof(struct cmpfn_operands));
-
- }
-
cmpfn[hits].v0_len = 0x80 + l;
cmpfn[hits].v1_len = 0x80 + l;
__builtin_memcpy(cmpfn[hits].v0, ptr1, l);
@@ -2050,14 +2034,6 @@ void __cmplog_rtn_hook_str(u8 *ptr1, u8 *ptr2) {
struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
hits &= CMP_MAP_RTN_H - 1;
- if (unlikely(reset && !hits)) { __afl_cmp_map->headers[k].overflow = 1; }
-
- if (unlikely(__afl_cmp_map->headers[k].overflow)) {
-
- __builtin_memset((char *)&cmpfn[hits], 0, sizeof(struct cmpfn_operands));
-
- }
-
cmpfn[hits].v0_len = 0x80 + len1;
cmpfn[hits].v1_len = 0x80 + len2;
__builtin_memcpy(cmpfn[hits].v0, ptr1, len1);
@@ -2116,14 +2092,6 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
hits &= CMP_MAP_RTN_H - 1;
- if (unlikely(reset && !hits)) { __afl_cmp_map->headers[k].overflow = 1; }
-
- if (unlikely(__afl_cmp_map->headers[k].overflow)) {
-
- __builtin_memset((char *)&cmpfn[hits], 0, sizeof(struct cmpfn_operands));
-
- }
-
cmpfn[hits].v0_len = len;
cmpfn[hits].v1_len = len;
__builtin_memcpy(cmpfn[hits].v0, ptr1, len);
From 25c947cd5ae93cb865081f9259255b4fdb3ca3ba Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 3 Nov 2021 21:36:10 +0100
Subject: [PATCH 140/305] fix unneeded ifdef
---
instrumentation/afl-compiler-rt.o.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 112893ee..fcd8caaf 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -158,11 +158,7 @@ static void at_exit(int signal) {
}
-#ifdef WORD_SIZE_64
- #define default_hash(a, b) XXH64(a, b, HASH_CONST)
-#else
- #define default_hash(a, b) XXH64(a, b, HASH_CONST)
-#endif
+#define default_hash(a, b) XXH64(a, b, HASH_CONST)
/* Uninspired gcc plugin instrumentation */
From 809f4922b9e26dc0a83de6d68eb55df4744daf41 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 3 Nov 2021 22:16:22 +0100
Subject: [PATCH 141/305] remove old var
---
instrumentation/afl-compiler-rt.o.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index fcd8caaf..65bc16bc 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -1908,14 +1908,14 @@ void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u64 len) {
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
- u32 hits, reset = 1;
+ u32 hits;
if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
__afl_cmp_map->headers[k].hits = 1;
__afl_cmp_map->headers[k].shape = l - 1;
- reset = hits = 0;
+ hits = 0;
} else {
@@ -1956,14 +1956,14 @@ void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u64 len) {
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
- u32 hits, reset = 1;
+ u32 hits;
if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
__afl_cmp_map->headers[k].hits = 1;
__afl_cmp_map->headers[k].shape = l - 1;
- reset = hits = 0;
+ hits = 0;
} else {
@@ -2006,14 +2006,14 @@ void __cmplog_rtn_hook_str(u8 *ptr1, u8 *ptr2) {
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
- u32 hits, reset = 1;
+ u32 hits;
if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
__afl_cmp_map->headers[k].hits = 1;
__afl_cmp_map->headers[k].shape = l - 1;
- reset = hits = 0;
+ hits = 0;
} else {
@@ -2064,14 +2064,14 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
- u32 hits, reset = 1;
+ u32 hits;
if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
__afl_cmp_map->headers[k].hits = 1;
__afl_cmp_map->headers[k].shape = len - 1;
- reset = hits = 0;
+ hits = 0;
} else {
From 5e0e385e6290e44eebef32e8b1a2438ebde572e5 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 4 Nov 2021 13:06:13 +0100
Subject: [PATCH 142/305] update todo
---
TODO.md | 24 +++++++++---------------
1 file changed, 9 insertions(+), 15 deletions(-)
diff --git a/TODO.md b/TODO.md
index 1c616b4a..1d4270b4 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,30 +1,26 @@
# TODO list for AFL++
-## Roadmap 3.00+
+## TODO
- - Update afl->pending_not_fuzzed for MOpt
- - put fuzz target in top line of UI
- - afl-plot to support multiple plot_data
- - afl_custom_fuzz_splice_optin()
- - afl_custom_splice()
+ - screen update during input2stage
- better autodetection of shifting runtime timeout values
- - cmplog: use colorization input for havoc?
+ - Update afl->pending_not_fuzzed for MOpt
+ - afl-plot to support multiple plot_data
- parallel builds for source-only targets
+## Perhaps
+
+ - afl_custom_fuzz_splice_optin()
+ - afl_custom_splice()
## Further down the road
-afl-fuzz:
- - setting min_len/max_len/start_offset/end_offset limits for mutation output
-
-qemu_mode:
+qemu_mode/frida_mode:
- non colliding instrumentation
- rename qemu specific envs to AFL_QEMU (AFL_ENTRYPOINT, AFL_CODE_START/END,
AFL_COMPCOV_LEVEL?)
- add AFL_QEMU_EXITPOINT (maybe multiple?), maybe pointless as we have
persistent mode
- - add/implement AFL_QEMU_INST_LIBLIST and AFL_QEMU_NOINST_PROGRAM
- - add/implement AFL_QEMU_INST_REGIONS as a list of _START/_END addresses
## Ideas
@@ -34,5 +30,3 @@ qemu_mode:
up edge numbers that both following cmp paths have been found and then
disable working on this edge id -> cmplog_intelligence branch
- use cmplog colorization taint result for havoc locations?
- - new instrumentation option for a thread-safe variant of feedback to shared mem.
- The user decides, if this is needed (eg the target is multithreaded).
From 6ce3d7fede6b32b522b6cc4403f7c0101cf4a4bc Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 4 Nov 2021 15:53:17 +0100
Subject: [PATCH 143/305] add AFL_USE_TSAN
---
TODO.md | 1 +
docs/Changelog.md | 2 +
docs/fuzzing_expert.md | 2 +
frida_mode/src/instrument/instrument.c | 4 +-
frida_mode/src/instrument/instrument_arm32.c | 2 +
frida_mode/src/instrument/instrument_arm64.c | 1 +
frida_mode/src/instrument/instrument_x64.c | 54 ++++++++++---------
frida_mode/src/instrument/instrument_x86.c | 1 +
frida_mode/src/main.c | 7 +--
frida_mode/src/prefetch.c | 6 +--
frida_mode/src/seccomp/seccomp_callback.c | 32 +++++------
frida_mode/src/seccomp/seccomp_filter.c | 6 +--
include/envs.h | 1 +
instrumentation/SanitizerCoverageLTO.so.cc | 3 +-
.../SanitizerCoveragePCGUARD.so.cc | 3 +-
instrumentation/afl-llvm-pass.so.cc | 3 +-
qemu_mode/libcompcov/libcompcov.so.c | 25 +++++++--
src/afl-as.c | 1 +
src/afl-cc.c | 9 ++++
utils/aflpp_driver/aflpp_qemu_driver.c | 2 +-
20 files changed, 106 insertions(+), 59 deletions(-)
diff --git a/TODO.md b/TODO.md
index 1d4270b4..30676312 100644
--- a/TODO.md
+++ b/TODO.md
@@ -2,6 +2,7 @@
## TODO
+ - AFL_USE_TSAN to docs/env_variables.md after work over
- screen update during input2stage
- better autodetection of shifting runtime timeout values
- Update afl->pending_not_fuzzed for MOpt
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 04b2fb2e..cfeb8cc1 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -26,7 +26,9 @@ sending a mail to