From c1415b816aac3e55c46028c9f032bc8550b652b0 Mon Sep 17 00:00:00 2001
From: Damiano Melotti
Date: Sat, 15 Jan 2022 19:28:18 +0100
Subject: Adjustments to unicorn docs and speedtest sample
---
unicorn_mode/README.md | 24 ++++++++++++------------
unicorn_mode/samples/speedtest/README.md | 8 ++++----
unicorn_mode/samples/speedtest/c/harness.c | 4 ++--
3 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/unicorn_mode/README.md b/unicorn_mode/README.md
index 0f28cf96..392a3254 100644
--- a/unicorn_mode/README.md
+++ b/unicorn_mode/README.md
@@ -9,7 +9,7 @@ The CompareCoverage and NeverZero counters features are by Andrea Fioraldi /unicorn_mode/samples/simple/
+ $ cd /unicorn_mode/samples/speedtest/c
$ make
- $ ../../../afl-fuzz -m none -i sample_inputs -o out -- ./harness @@
+ $ ../../../../afl-fuzz -i ../sample_inputs -o out -U -- ./harness @@
*/
// This is not your everyday Unicorn.
--
cgit 1.4.1
From 751e09f47b0449d57105e533087e49ce34bce0b4 Mon Sep 17 00:00:00 2001
From: Damiano Melotti
Date: Sat, 15 Jan 2022 20:02:57 +0100
Subject: Fixed Rust harness name to be consistent with the others
---
unicorn_mode/samples/speedtest/rust/Cargo.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/unicorn_mode/samples/speedtest/rust/Cargo.toml b/unicorn_mode/samples/speedtest/rust/Cargo.toml
index 9b81be0b..e2c3d7c4 100644
--- a/unicorn_mode/samples/speedtest/rust/Cargo.toml
+++ b/unicorn_mode/samples/speedtest/rust/Cargo.toml
@@ -1,5 +1,5 @@
[package]
-name = "unicornafl_harness"
+name = "unicornafl"
version = "0.1.0"
authors = ["Dominik Maier "]
edition = "2018"
--
cgit 1.4.1
From a45cdb240c20e019a98ab9b143bb928d91e7f959 Mon Sep 17 00:00:00 2001
From: Damiano Melotti
Date: Mon, 17 Jan 2022 14:32:06 +0100
Subject: fixup! Fixed Rust harness name to be consistent with the others
---
unicorn_mode/samples/speedtest/rust/Cargo.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/unicorn_mode/samples/speedtest/rust/Cargo.toml b/unicorn_mode/samples/speedtest/rust/Cargo.toml
index e2c3d7c4..766b2f27 100644
--- a/unicorn_mode/samples/speedtest/rust/Cargo.toml
+++ b/unicorn_mode/samples/speedtest/rust/Cargo.toml
@@ -1,5 +1,5 @@
[package]
-name = "unicornafl"
+name = "harness"
version = "0.1.0"
authors = ["Dominik Maier "]
edition = "2018"
--
cgit 1.4.1
From 34caf7d7816382575bb8045f809c03526ca534a2 Mon Sep 17 00:00:00 2001
From: Damiano Melotti
Date: Mon, 17 Jan 2022 17:38:46 +0100
Subject: Cleaned unicorn speedtest sample README
---
unicorn_mode/samples/speedtest/README.md | 40 ++++----------------------------
1 file changed, 4 insertions(+), 36 deletions(-)
diff --git a/unicorn_mode/samples/speedtest/README.md b/unicorn_mode/samples/speedtest/README.md
index 9305417c..f46a5772 100644
--- a/unicorn_mode/samples/speedtest/README.md
+++ b/unicorn_mode/samples/speedtest/README.md
@@ -6,6 +6,10 @@ to show the raw speed of C, Rust, and Python harnesses.
## Compiling...
Make sure you built unicornafl first (`../../build_unicorn_support.sh`).
+Build the target using the provided Makefile.
+This will also run the [./get_offsets.py](./get_offsets.py) script,
+which finds some relevant addresses in the target binary using `objdump`,
+and dumps them to different files.
Then, follow these individual steps:
### Rust
@@ -34,39 +38,3 @@ cd python
## Results
TODO: add results here.
-
-## Compiling speedtest_target.c
-
-You shouldn't need to compile simple_target.c since a X86_64 binary version is
-pre-built and shipped in this sample folder. This file documents how the binary
-was built in case you want to rebuild it or recompile it for any reason.
-
-The pre-built binary (simple_target_x86_64.bin) was built using -g -O0 in gcc.
-
-Then load the binary and execute the main function directly.
-
-## Addresses for the harness
-
-To find the address (in hex) of main, run:
-
-```bash
-objdump -M intel -D target | grep ':' | cut -d" " -f1
-```
-
-To find all call sites to magicfn, run:
-
-```bash
-objdump -M intel -D target | grep '$' | cut -d":" -f1
-```
-
-For malloc callsites:
-
-```bash
-objdump -M intel -D target | grep '$' | cut -d":" -f1
-```
-
-And free callsites:
-
-```bash
-objdump -M intel -D target | grep '$' | cut -d":" -f1
-```
\ No newline at end of file
--
cgit 1.4.1
From 4721d869ad70241953cd74bcc391f794bed72eb7 Mon Sep 17 00:00:00 2001
From: Andrea Fioraldi
Date: Thu, 20 Jan 2022 17:33:17 +0100
Subject: Poison with ASan the remaining unused input buffer in aflpp_driver.c
---
utils/aflpp_driver/aflpp_driver.c | 57 +++++++++++++++++++++++++++++++++++++--
1 file changed, 55 insertions(+), 2 deletions(-)
diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c
index ff42f3b9..65b8de06 100644
--- a/utils/aflpp_driver/aflpp_driver.c
+++ b/utils/aflpp_driver/aflpp_driver.c
@@ -62,6 +62,25 @@ extern unsigned char *__afl_fuzz_ptr;
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv);
+// Default nop ASan hooks for manual posisoning when not linking the ASan
+// runtime
+// https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning
+__attribute__((weak)) void __asan_poison_memory_region(
+ void const volatile *addr, size_t size) {
+
+ (void)addr;
+ (void)size;
+
+}
+
+__attribute__((weak)) void __asan_unpoison_memory_region(
+ void const volatile *addr, size_t size) {
+
+ (void)addr;
+ (void)size;
+
+}
+
// Notify AFL about persistent mode.
static volatile char AFL_PERSISTENT[] = "##SIG_AFL_PERSISTENT##";
int __afl_persistent_loop(unsigned int);
@@ -175,6 +194,9 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) {
unsigned char *buf = (unsigned char *)malloc(MAX_FILE);
+ __asan_poison_memory_region(buf, MAX_FILE);
+ ssize_t prev_length = 0;
+
for (int i = 1; i < argc; i++) {
int fd = 0;
@@ -187,6 +209,18 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) {
if (length > 0) {
+ if (length < prev_length) {
+
+ __asan_poison_memory_region(buf + length, prev_length - length);
+
+ } else {
+
+ __asan_unpoison_memory_region(buf + prev_length, length - prev_length);
+
+ }
+
+ prev_length = length;
+
printf("Reading %zu bytes from %s\n", length, argv[i]);
LLVMFuzzerTestOneInput(buf, length);
printf("Execution successful.\n");
@@ -284,9 +318,14 @@ int main(int argc, char **argv) {
// on the first execution of LLVMFuzzerTestOneInput is ignored.
LLVMFuzzerTestOneInput(dummy_input, 1);
+ __asan_poison_memory_region(__afl_fuzz_ptr, MAX_FILE);
+ size_t prev_length = 0;
+
int num_runs = 0;
while (__afl_persistent_loop(N)) {
+ size_t length = *__afl_fuzz_len;
+
#ifdef _DEBUG
fprintf(stderr, "CLIENT crc: %016llx len: %u\n",
hash64(__afl_fuzz_ptr, *__afl_fuzz_len, 0xa5b35705),
@@ -297,10 +336,24 @@ int main(int argc, char **argv) {
fprintf(stderr, "\n");
#endif
- if (*__afl_fuzz_len) {
+ if (length) {
+
+ if (length < prev_length) {
+
+ __asan_poison_memory_region(__afl_fuzz_ptr + length,
+ prev_length - length);
+
+ } else {
+
+ __asan_unpoison_memory_region(__afl_fuzz_ptr + prev_length,
+ length - prev_length);
+
+ }
+
+ prev_length = length;
num_runs++;
- LLVMFuzzerTestOneInput(__afl_fuzz_ptr, *__afl_fuzz_len);
+ LLVMFuzzerTestOneInput(__afl_fuzz_ptr, length);
}
--
cgit 1.4.1
From a9d549ca073ca3fc37b63c1fa454c575bba174b9 Mon Sep 17 00:00:00 2001
From: Andrea Fioraldi
Date: Thu, 20 Jan 2022 17:41:38 +0100
Subject: Raw read syscall in aflpp_driver.c to bypass ASan checks
---
utils/aflpp_driver/aflpp_driver.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c
index 65b8de06..547b78fb 100644
--- a/utils/aflpp_driver/aflpp_driver.c
+++ b/utils/aflpp_driver/aflpp_driver.c
@@ -45,6 +45,9 @@ $AFL_HOME/afl-fuzz -i IN -o OUT ./a.out
#include
#include
#include
+#ifndef __HAIKU__
+ #include
+#endif
#include "config.h"
#include "types.h"
@@ -205,7 +208,11 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) {
if (fd == -1) { continue; }
- ssize_t length = read(fd, buf, MAX_FILE);
+#ifndef __HAIKU__
+ ssize_t length = syscall(SYS_read, fd, buf, MAX_FILE);
+#else
+ ssize_t length = _kern_read(fd, buf, MAX_FILE);
+#endif // HAIKU
if (length > 0) {
--
cgit 1.4.1
From 492418ebd60db51ad45f37eadb8859ec70361e2d Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Thu, 20 Jan 2022 20:22:00 +0100
Subject: Fix punctuation and line length
---
README.md | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index 5c2262cf..24164262 100644
--- a/README.md
+++ b/README.md
@@ -11,10 +11,10 @@ Repository:
AFL++ is maintained by:
-* Marc "van Hauser" Heuse ,
-* Heiko "hexcoder-" Eißfeldt ,
-* Andrea Fioraldi and
-* Dominik Maier .
+* Marc "van Hauser" Heuse
+* Heiko "hexcoder-" Eißfeldt
+* Andrea Fioraldi
+* Dominik Maier
* Documentation: Jana Aydinbas
Originally developed by Michał "lcamtuf" Zalewski.
@@ -29,13 +29,13 @@ terms of the Apache-2.0 License. See the [LICENSE](LICENSE) for details.
Here is some information to get you started:
-* For an overview of the AFL++ documentation and a very helpful graphical
- guide please visit [docs/README.md](docs/README.md)
+* For an overview of the AFL++ documentation and a very helpful graphical guide,
+ please visit [docs/README.md](docs/README.md).
* To get you started with tutorials, go to
[docs/tutorials.md](docs/tutorials.md).
* For releases, see the
[Releases tab](https://github.com/AFLplusplus/AFLplusplus/releases) and
- [branches](#branches). The best branches to use are however `stable` or
+ [branches](#branches). The best branches to use are, however, `stable` or
`dev` - depending on your risk appetite. Also take a look at the list of
[important changes in AFL++](docs/important_changes.md) and the list of
[features](docs/features.md).
@@ -133,7 +133,7 @@ Questions? Concerns? Bug reports?
question missing, submit it via
[https://github.com/AFLplusplus/AFLplusplus/discussions](https://github.com/AFLplusplus/AFLplusplus/discussions).
* Best: join the [Awesome Fuzzing](https://discord.gg/gCraWct) Discord server.
-* There is a (not really used) mailing list for the AFL/AFL++ project
+* There is a (not really used) 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 , but note that this is not
--
cgit 1.4.1
From 88905c65af7fac8234631ee29a36413845a0bbed Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Thu, 20 Jan 2022 20:27:02 +0100
Subject: Add missing tags, fix punctuation
---
docs/FAQ.md | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 73328d6e..1822e46b 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -188,8 +188,9 @@ If you find an interesting or important question missing, submit it via
A power schedule measures how "interesting" a value is, and depending on
the calculated value spends more or less time mutating it.
- AFL++ comes with several power schedules, initially ported from [AFLFast](https://github.com/mboehme/aflfast)
- however modified to be more effective and several more modes added.
+ AFL++ comes with several power schedules, initially ported from
+ [AFLFast](https://github.com/mboehme/aflfast), however, modified to be more
+ effective and several more modes added.
The most effective modes are `-p fast` (default) and `-p explore`.
@@ -200,6 +201,7 @@ If you find an interesting or important question missing, submit it via
It does not make sense to explain the details of the calculation and
reasoning behind all of the schedules. If you are interested, read the source
code and the AFLFast paper.
+
## Troubleshooting
@@ -215,16 +217,18 @@ If you find an interesting or important question missing, submit it via
To ignore this set AFL_IGNORE_PROBLEMS=1.
```
- As the error describes, a dlopen() call is happening in the target that is loading an instrumented library after the forkserver is already in place,
- This is a problem for afl-fuzz because when the forkserver is started we must know the map size already and it can't be changed later.
+ As the error describes, a dlopen() call is happening in the target that is
+ loading an instrumented library after the forkserver is already in place. This
+ is a problem for afl-fuzz because when the forkserver is started, we must know
+ the map size already and it can't be changed later.
- The best solution is to simply set `AFL_PRELOAD=foo.so` the libraries that
- are dlopen'ed (e.g. use `strace` to see which), or to set a manual forkserver
+ The best solution is to simply set `AFL_PRELOAD=foo.so` to the libraries that
+ are dlopen'ed (e.g., use `strace` to see which), or to set a manual forkserver
after the final dlopen().
- If this is not a viable option you can set `AFL_IGNORE_PROBLEMS=1` but then
+ If this is not a viable option, you can set `AFL_IGNORE_PROBLEMS=1` but then
the existing map will be used also for the newly loaded libraries, which
- allows it to work, however the efficiency of the fuzzing will be partially
+ allows it to work, however, the efficiency of the fuzzing will be partially
degraded.
--
cgit 1.4.1
From 029bfc386f3a164482a29d51bcd2e646c5d06d5c Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Thu, 20 Jan 2022 20:33:23 +0100
Subject: Fix formatting
---
docs/important_changes.md | 35 ++++++++++++++++++-----------------
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/docs/important_changes.md b/docs/important_changes.md
index 39fe56b9..e847f360 100644
--- a/docs/important_changes.md
+++ b/docs/important_changes.md
@@ -7,23 +7,23 @@ changes.
With AFL++ 4.00, we introduced the following changes from previous behaviors:
* the complete documentation was overhauled and restructured thanks to @llzmb!
- * a new CMPLOG target format requires recompiling CMPLOG targets for use
- with afl++ 4.0 onwards
+ * a new CMPLOG target format requires recompiling CMPLOG targets for use with
+ AFL++ 4.0 onwards
* better naming for several fields in the UI
With AFL++ 3.15, we introduced the following changes from previous behaviors:
- * afl-cmin and afl-showmap -Ci now descend into subdirectories like afl-fuzz
- -i does (but note that afl-cmin.bash does not)
+ * afl-cmin and afl-showmap `-Ci` now descend into subdirectories like afl-fuzz
+ `-i` does (but note that afl-cmin.bash does not)
With AFL++ 3.14, we introduced the following changes from previous behaviors:
- * afl-fuzz: deterministic fuzzing is not a default for -M main anymore
+ * afl-fuzz: deterministic fuzzing is not a default for `-M main` anymore
* afl-cmin/afl-showmap -i now descends into subdirectories (afl-cmin.bash,
however, does not)
With AFL++ 3.10, we introduced the following changes from previous behaviors:
- * The '+' feature of the '-t' option now means to auto-calculate the timeout
+ * The '+' feature of the `-t` option now means to auto-calculate the timeout
with the value given being the maximum timeout. The original meaning of
- "skipping timeouts instead of abort" is now inherent to the -t option.
+ "skipping timeouts instead of abort" is now inherent to the `-t` option.
With AFL++ 3.00, we introduced changes that break some previous AFL and AFL++
behaviors and defaults:
@@ -41,19 +41,20 @@ behaviors and defaults:
if any were given. This allows to fuzz targets build regularly like those
for debug or release versions.
* afl-fuzz:
- * if neither -M or -S is specified, `-S default` is assumed, so more fuzzers
- can easily be added later
+ * if neither `-M` or `-S` is specified, `-S default` is assumed, so more
+ fuzzers can easily be added later
* `-i` input directory option now descends into subdirectories. It also does
not fail on crashes and too large files, instead it skips them and uses
them for splicing mutations
- * -m none is now the default, set memory limits (in MB) with, e.g., -m 250
- * deterministic fuzzing is now disabled by default (unless using -M) and can
- be enabled with -D
+ * `-m` none is now the default, set memory limits (in MB) with, e.g., `-m
+ 250`
+ * deterministic fuzzing is now disabled by default (unless using `-M`) and
+ can be enabled with `-D`
* a caching of test cases can now be performed and can be modified by
- editing config.h for TESTCASE_CACHE or by specifying the environment
+ editing config.h for `TESTCASE_CACHE` or by specifying the environment
variable `AFL_TESTCACHE_SIZE` (in MB). Good values are between 50-500
(default: 50).
- * -M mains do not perform trimming
- * examples/ got renamed to utils/
- * libtokencap/ libdislocator/ and qdbi_mode/ were moved to utils/
- * afl-cmin/afl-cmin.bash now search first in PATH and last in AFL_PATH
+ * `-M` mains do not perform trimming
+ * `examples/` got renamed to `utils/`
+ * `libtokencap/`, `libdislocator/`, and `qdbi_mode/` were moved to `utils/`
+ * afl-cmin/afl-cmin.bash now search first in `PATH` and last in `AFL_PATH`
--
cgit 1.4.1
From 29f8040f09fd08ebcc24e2551a321c78e8f7311a Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Thu, 20 Jan 2022 20:35:19 +0100
Subject: Fix formatting and line length
---
docs/fuzzing_binary-only_targets.md | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/docs/fuzzing_binary-only_targets.md b/docs/fuzzing_binary-only_targets.md
index 32e6c6c2..1a2b27c7 100644
--- a/docs/fuzzing_binary-only_targets.md
+++ b/docs/fuzzing_binary-only_targets.md
@@ -14,6 +14,7 @@ fuzzed with AFL++.
FRIDA mode and QEMU mode in persistent mode are the fastest - if persistent mode
is possible and the stability is high enough.
+
Otherwise, try Zafl, RetroWrite, Dyninst, and if these fail, too, then try
standard FRIDA/QEMU mode with `AFL_ENTRYPOINT` to where you need it.
@@ -127,13 +128,13 @@ Working examples already exist :-)
### Nyx mode
-Nyx is a full system emulation fuzzing environment with snapshot support that
-is built upon KVM and QEMU.
-It is only available on Linux and currently restricted to x86_x64.
+Nyx is a full system emulation fuzzing environment with snapshot support that is
+built upon KVM and QEMU. It is only available on Linux and currently restricted
+to x86_x64.
For binary-only fuzzing a special 5.10 kernel is required.
-See [nyx_mode/README.md](../nyx_mode/README.md)
+See [nyx_mode/README.md](../nyx_mode/README.md).
### Unicorn
@@ -198,15 +199,15 @@ afl-clang-fast's.
### RetroWrite
-RetroWrite is a static binary rewriter that can be combined with AFL++.
-If you have an x86_64 binary that still has its symbols (i.e., not stripped binary),
-is compiled with position independent code (PIC/PIE), and does not contain C++ exceptions,
-then the RetroWrite solution might be for you. It decompiles to ASM files which
-can then be instrumented with afl-gcc.
+RetroWrite is a static binary rewriter that can be combined with AFL++. If you
+have an x86_64 binary that still has its symbols (i.e., not stripped binary), is
+compiled with position independent code (PIC/PIE), and does not contain C++
+exceptions, then the RetroWrite solution might be for you. It decompiles to ASM
+files which can then be instrumented with afl-gcc.
Binaries that are statically instrumented for fuzzing using RetroWrite are close
-in performance to compiler-instrumented binaries and outperform
-the QEMU-based instrumentation.
+in performance to compiler-instrumented binaries and outperform the QEMU-based
+instrumentation.
[https://github.com/HexHive/retrowrite](https://github.com/HexHive/retrowrite)
--
cgit 1.4.1
From 1529bd070ea208dfd1196bdb18aebbf9c9661437 Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Thu, 20 Jan 2022 20:41:49 +0100
Subject: Fix punctuation, formatting, and line length
---
docs/fuzzing_in_depth.md | 142 ++++++++++++++++++++++++-----------------------
1 file changed, 74 insertions(+), 68 deletions(-)
diff --git a/docs/fuzzing_in_depth.md b/docs/fuzzing_in_depth.md
index 446c4466..ac72c757 100644
--- a/docs/fuzzing_in_depth.md
+++ b/docs/fuzzing_in_depth.md
@@ -141,37 +141,39 @@ options are available:
[instrumentation/README.cmplog.md](../instrumentation/README.cmplog.md).
If you use LTO, LLVM, or GCC_PLUGIN mode
-(afl-clang-fast/afl-clang-lto/afl-gcc-fast), you have the option to
-selectively instrument _parts_ of the target that you are interested in.
-For afl-clang-fast you have to use an llvm version newer than 10.0.0 or a mode
-other than DEFAULT/PCGUARD.
+(afl-clang-fast/afl-clang-lto/afl-gcc-fast), you have the option to selectively
+instrument _parts_ of the target that you are interested in. For afl-clang-fast,
+you have to use an llvm version newer than 10.0.0 or a mode other than
+DEFAULT/PCGUARD.
-This step can be done either by explicitly including parts to be instrumented
-or by explicitly excluding parts from instrumentation.
+This step can be done either by explicitly including parts to be instrumented or
+by explicitly excluding parts from instrumentation.
-* To instrument _only specified parts_
- create a file (eg `allowlist.txt`) with all the filenames and/or functions of
- the source code that should be instrumented and then:
+* To instrument _only specified parts_, create a file (e.g., `allowlist.txt`)
+ with all the filenames and/or functions of the source code that should be
+ instrumented and then:
- 1. just put one filename or function (prefixing with `fun: `) per line (no
- directory information necessary for filenames) in the file `allowlist.txt`.
- Example:
-```
-foo.cpp # will match foo/foo.cpp, bar/foo.cpp, barfoo.cpp etc.
-fun: foo_func # will match the function foo_func
-```
+ 1. Just put one filename or function (prefixing with `fun: `) per line (no
+ directory information necessary for filenames) in the file `allowlist.txt`.
- 2. set `export AFL_LLVM_ALLOWLIST=allowlist.txt` to enable selective positive
+ Example:
+
+ ```
+ foo.cpp # will match foo/foo.cpp, bar/foo.cpp, barfoo.cpp etc.
+ fun: foo_func # will match the function foo_func
+ ```
+
+ 2. Set `export AFL_LLVM_ALLOWLIST=allowlist.txt` to enable selective positive
instrumentation.
-* Similarly to _exclude_ specified parts from instrumentation
- create a file (eg `denylist.txt`) with all the filenames of the source code
- that should be skipped during instrumentation and then
+* Similarly to _exclude_ specified parts from instrumentation, create a file
+ (e.g., `denylist.txt`) with all the filenames of the source code that should
+ be skipped during instrumentation and then:
- 1. same as above just put one filename or function per line in the file
- `denylist.txt`
+ 1. Same as above. Just put one filename or function per line in the file
+ `denylist.txt`.
- 2. set `export AFL_LLVM_DENYLIST=denylist.txt` to enable selective negative
+ 2. Set `export AFL_LLVM_DENYLIST=denylist.txt` to enable selective negative
instrumentation.
**NOTE:** During optimization functions might be
@@ -195,8 +197,8 @@ allows you to find bugs that would not necessarily result in a crash.
Note that sanitizers have a huge impact on CPU (= less executions per second)
and RAM usage. Also, you should only run one afl-fuzz instance per sanitizer
-type. This is enough because e.g. a use-after-free bug will be picked up by
-ASAN (address sanitizer) anyway after syncing test cases from other fuzzing
+type. This is enough because e.g. a use-after-free bug will be picked up by ASAN
+(address sanitizer) anyway after syncing test cases from other fuzzing
instances, so running more than one address sanitized target would be a waste.
The following sanitizers have built-in support in AFL++:
@@ -208,9 +210,9 @@ The following sanitizers have built-in support in AFL++:
local variable that is defined and read before it is even set. Enabled with
`export AFL_USE_MSAN=1` before compiling.
* UBSAN = Undefined Behavior SANitizer, finds instances where - by the C and C++
- standards - undefined behavior happens, e.g., adding two signed integers
- where the result is larger than what a signed integer can hold. Enabled
- with `export AFL_USE_UBSAN=1` before compiling.
+ standards - undefined behavior happens, e.g., adding two signed integers where
+ the result is larger than what a signed integer can hold. Enabled with `export
+ AFL_USE_UBSAN=1` before compiling.
* CFISAN = Control Flow Integrity SANitizer, finds instances where the control
flow is found to be illegal. Originally this was rather to prevent return
oriented programming (ROP) exploit chains from functioning. In fuzzing, this
@@ -224,7 +226,7 @@ The following sanitizers have built-in support in AFL++:
the other sanitizers above this needs `__AFL_LEAK_CHECK();` added to all areas
of the target source code where you find a leak check necessary! Enabled with
`export AFL_USE_LSAN=1` before compiling. To ignore the memory-leaking check
- for certain allocations, `__AFL_LSAN_OFF();` can be used before memory is
+ for certain allocations, `__AFL_LSAN_OFF();` can be used before memory is
allocated, and `__AFL_LSAN_ON();` afterwards. Memory allocated between these
two macros will not be checked for memory leaks.
@@ -286,8 +288,8 @@ Then build the target. (Usually with `make`.)
3. In case the configure/build system complains about AFL++'s compiler and
aborts, then set `export AFL_NOOPT=1` which will then just behave like the
- real compiler and run the configure step separately.
- For building the target afterwards this option has to be unset again!
+ real compiler and run the configure step separately. For building the target
+ afterwards this option has to be unset again!
#### configure
@@ -397,11 +399,12 @@ You can find many good examples of starting files in the
Use the AFL++ tool `afl-cmin` to remove inputs from the corpus that do not
produce a new path/coverage in the target:
-1. Put all files from [step a](#a-collecting-inputs) into one directory, e.g., INPUTS.
+1. Put all files from [step a](#a-collecting-inputs) into one directory, e.g.,
+ `INPUTS`.
2. Run afl-cmin:
- * If the target program is to be called by fuzzing as `bin/target
- INPUTFILE`, replace the INPUTFILE argument that the target program would read
- from with `@@`:
+ * If the target program is to be called by fuzzing as `bin/target INPUTFILE`,
+ replace the INPUTFILE argument that the target program would read from with
+ `@@`:
```
afl-cmin -i INPUTS -o INPUTS_UNIQUE -- bin/target -someopt @@
@@ -448,8 +451,8 @@ In this final step, fuzz the target. There are not that many important options
to run the target - unless you want to use many CPU cores/threads for the
fuzzing, which will make the fuzzing much more useful.
-If you just use one instance for fuzzing, then you are fuzzing just for fun and not
-seriously :-)
+If you just use one instance for fuzzing, then you are fuzzing just for fun and
+not seriously :-)
### a) Running afl-fuzz
@@ -482,14 +485,14 @@ afl-fuzz -i input -o output -- bin/target -someopt @@
Note that the directory specified with `-o` will be created if it does not
exist.
-It can be valuable to run afl-fuzz in a `screen` or `tmux` shell so you can log off,
-or afl-fuzz is not aborted if you are running it in a remote ssh session where
-the connection fails in between. Only do that though once you have verified that
-your fuzzing setup works! Run it like `screen -dmS afl-main -- afl-fuzz -M
-main-$HOSTNAME -i ...` and it will start away in a screen session. To enter this
-session, type `screen -r afl-main`. You see - it makes sense to name the screen
-session same as the afl-fuzz -M/-S naming :-) For more information on screen or
-tmux, check their documentation.
+It can be valuable to run afl-fuzz in a `screen` or `tmux` shell so you can log
+off, or afl-fuzz is not aborted if you are running it in a remote ssh session
+where the connection fails in between. Only do that though once you have
+verified that your fuzzing setup works! Run it like `screen -dmS afl-main --
+afl-fuzz -M main-$HOSTNAME -i ...` and it will start away in a screen session.
+To enter this session, type `screen -r afl-main`. You see - it makes sense to
+name the screen session same as the afl-fuzz `-M`/`-S` naming :-) For more
+information on screen or tmux, check their documentation.
If you need to stop and re-start the fuzzing, use the same command line options
(or even change them by selecting a different power schedule or another mutation
@@ -499,18 +502,21 @@ mode!) and switch the input directory with a dash (`-`):
afl-fuzz -i - -o output -- bin/target -someopt @@
```
-Adding a dictionary is helpful. See the directory
-[dictionaries/](../dictionaries/) if something is already included for your data
-format, and tell afl-fuzz to load that dictionary by adding `-x
+Adding a dictionary is helpful. You have to following options:
+
+* See the directory
+[dictionaries/](../dictionaries/), if something is already included for your
+data format, and tell afl-fuzz to load that dictionary by adding `-x
dictionaries/FORMAT.dict`.
-With `afl-clang-lto`, you have an autodictionary generation for which you need
-to do nothing except to use afl-clang-lto as the compiler.
-With `afl-clang-fast` you can set
-`AFL_LLVM_DICT2FILE=/full/path/to/new/file.dic` to automatically generate a
-dictionary during target compilation.
-You also have the option to generate a dictionary yourself during an independant
-run of the target, see [utils/libtokencap/README.md](../utils/libtokencap/README.md).
-Finally you can also write a dictionary file manually, of course.
+* With `afl-clang-lto`, you have an autodictionary generation for which you need
+ to do nothing except to use afl-clang-lto as the compiler.
+* With `afl-clang-fast`, you can set
+ `AFL_LLVM_DICT2FILE=/full/path/to/new/file.dic` to automatically generate a
+ dictionary during target compilation.
+* You also have the option to generate a dictionary yourself during an
+ independent run of the target, see
+ [utils/libtokencap/README.md](../utils/libtokencap/README.md).
+* Finally, you can also write a dictionary file manually, of course.
afl-fuzz has a variety of options that help to workaround target quirks like
very specific locations for the input file (`-f`), performing deterministic
@@ -572,8 +578,8 @@ can set the cache size (in MB) by setting the environment variable
There should be one main fuzzer (`-M main-$HOSTNAME` option) and as many
secondary fuzzers (e.g., `-S variant1`) as you have cores that you use. Every
--M/-S entry needs a unique name (that can be whatever), however, the same -o
-output directory location has to be used for all instances.
+`-M`/`-S` entry needs a unique name (that can be whatever), however, the same
+`-o` output directory location has to be used for all instances.
For every secondary fuzzer there should be a variation, e.g.:
* one should fuzz the target that was compiled differently: with sanitizers
@@ -588,10 +594,10 @@ For every secondary fuzzer there should be a variation, e.g.:
All other secondaries should be used like this:
* a quarter to a third with the MOpt mutator enabled: `-L 0`
-* run with a different power schedule, recommended are:
- `fast (default), explore, coe, lin, quad, exploit and rare` which you can set
- with the `-p` option, e.g., `-p explore`. See the [FAQ](FAQ.md#what-are-power-schedules)
- for details.
+* run with a different power schedule, recommended are: `fast` (default),
+ `explore`, `coe`, `lin`, `quad`, `exploit`, and `rare` which you can set with
+ the `-p` option, e.g., `-p explore`. See the
+ [FAQ](FAQ.md#what-are-power-schedules) for details.
* a few instances should use the old queue cycling with `-Z`
Also, it is recommended to set `export AFL_IMPORT_FIRST=1` to load test cases
@@ -615,7 +621,7 @@ A long list can be found at
[https://github.com/Microsvuln/Awesome-AFL](https://github.com/Microsvuln/Awesome-AFL).
However, you can also sync AFL++ with honggfuzz, libfuzzer with `-entropic=1`,
-etc. Just show the main fuzzer (-M) with the `-F` option where the queue/work
+etc. Just show the main fuzzer (`-M`) with the `-F` option where the queue/work
directory of a different fuzzer is, e.g., `-F /src/target/honggfuzz`. Using
honggfuzz (with `-n 1` or `-n 2`) and libfuzzer in parallel is highly
recommended!
@@ -877,9 +883,9 @@ normal fuzzing campaigns as these are much shorter runnings.
1. Always:
* LTO has a much longer compile time which is diametrical to short fuzzing -
hence use afl-clang-fast instead.
- * If you compile with CMPLOG, then you can save compilation time and reuse that
- compiled target with the `-c` option and as the main fuzz target. This
- will impact the speed by ~15% though.
+ * If you compile with CMPLOG, then you can save compilation time and reuse
+ that compiled target with the `-c` option and as the main fuzz target.
+ This will impact the speed by ~15% though.
* `AFL_FAST_CAL` - enables fast calibration, this halves the time the
saturated corpus needs to be loaded.
* `AFL_CMPLOG_ONLY_NEW` - only perform cmplog on new finds, not the initial
@@ -909,8 +915,8 @@ and
## The End
-Check out the [FAQ](FAQ.md). Maybe it answers your question (that you might
-not even have known you had ;-) ).
+Check out the [FAQ](FAQ.md). Maybe it answers your question (that you might not
+even have known you had ;-) ).
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
--
cgit 1.4.1
From 686a595df36a52f43ab43572b28683f8db09ac11 Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Thu, 20 Jan 2022 20:48:09 +0100
Subject: Fix typo
---
src/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/README.md b/src/README.md
index 35af6ab9..3f332280 100644
--- a/src/README.md
+++ b/src/README.md
@@ -18,7 +18,7 @@ Quick explanation about the files here:
- `afl-fuzz-performance.c` - hash64 and rand functions
- `afl-fuzz-python.c` - afl-fuzz the python mutator extension
- `afl-fuzz-queue.c` - afl-fuzz handling the queue
-- `afl-fuzz-redqueen.c` - afl-fuzz redqueen implemention
+- `afl-fuzz-redqueen.c` - afl-fuzz redqueen implementation
- `afl-fuzz-run.c` - afl-fuzz running the target
- `afl-fuzz-state.c` - afl-fuzz state and globals
- `afl-fuzz-stats.c` - afl-fuzz writing the statistics file
--
cgit 1.4.1
From 237a475d9b363930640a009f80ab1fceed4f202e Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Thu, 20 Jan 2022 20:54:38 +0100
Subject: Fix structure and formatting
---
docs/features.md | 98 ++++++++++++++++++++++++++++++++++----------------------
1 file changed, 59 insertions(+), 39 deletions(-)
diff --git a/docs/features.md b/docs/features.md
index 628f9383..25e1a9a3 100644
--- a/docs/features.md
+++ b/docs/features.md
@@ -4,67 +4,85 @@ AFL++ supports llvm from 3.8 up to version 12, very fast binary fuzzing with
QEMU 5.1 with laf-intel and redqueen, FRIDA mode, unicorn mode, gcc plugin, full
*BSD, Mac OS, Solaris and Android support and much, much, much more.
-| Feature/Instrumentation | afl-gcc | llvm | gcc_plugin | FRIDA mode(9) | QEMU mode(10) |unicorn_mode(10) |nyx_mode(12)|coresight_mode(11)|
-| ------------------------------|:-------:|:---------:|:----------:|:----------------:|:----------------:|:----------------:|:----------:|:----------------:|
-| Threadsafe counters [A] | | x(3) | | | | | x | |
-| NeverZero [B] | x86[_64]| x(1) | x | x | x | x | | |
-| Persistent Mode [C] | | x | x | x86[_64]/arm64 | x86[_64]/arm[64] | x | | |
-| LAF-Intel / CompCov [D] | | x | | | x86[_64]/arm[64] | x86[_64]/arm[64] | x86[_64] | |
-| CmpLog [E] | | x | | x86[_64]/arm64 | x86[_64]/arm[64] | | | |
-| Selective Instrumentation [F] | | x | x | x | x | | | |
-| Non-Colliding Coverage [G] | | x(4) | | | (x)(5) | | | |
-| Ngram prev_loc Coverage [H] | | x(6) | | | | | | |
-| Context Coverage [I] | | x(6) | | | | | | |
-| Auto Dictionary [J] | | x(7) | | | | | | |
-| Snapshot Support (K) | | (x)(8) | (x)(8) | | (x)(5) | | x | |
-| Shared Memory Test cases [L] | | x | x | x86[_64]/arm64 | x | x | x | |
+## Features and instrumentation
+
+| Feature/Instrumentation | afl-gcc | llvm | gcc_plugin | FRIDA mode(9) | QEMU mode(10) | unicorn_mode(10) | nyx_mode(12) | coresight_mode(11) |
+| ------------------------------|:--------:|:---------:|:----------:|:--------------:|:----------------:|:----------------:|:------------:|:------------------:|
+| Threadsafe counters [A] | | x(3) | | | | | x | |
+| NeverZero [B] | x86[_64] | x(1) | x | x | x | x | | |
+| Persistent Mode [C] | | x | x | x86[_64]/arm64 | x86[_64]/arm[64] | x | | |
+| LAF-Intel / CompCov [D] | | x | | | x86[_64]/arm[64] | x86[_64]/arm[64] | x86[_64] | |
+| CmpLog [E] | | x | | x86[_64]/arm64 | x86[_64]/arm[64] | | | |
+| Selective Instrumentation [F] | | x | x | x | x | | | |
+| Non-Colliding Coverage [G] | | x(4) | | | (x)(5) | | | |
+| Ngram prev_loc Coverage [H] | | x(6) | | | | | | |
+| Context Coverage [I] | | x(6) | | | | | | |
+| Auto Dictionary [J] | | x(7) | | | | | | |
+| Snapshot Support [K] | | (x)(8) | (x)(8) | | (x)(5) | | x | |
+| Shared Memory Test cases [L] | | x | x | x86[_64]/arm64 | x | x | x | |
+
+## More information about features
A. Default is not thread-safe coverage counter updates for better performance,
see [instrumentation/README.llvm.md](../instrumentation/README.llvm.md)
-B. On wrapping coverage counters (255 + 1) skip the 0 value and jump to 1
- instead. This has shown to give better coverage data and is the default;
- see [instrumentation/README.llvm.md](../instrumentation/README.llvm.md)
+
+B. On wrapping coverage counters (255 + 1), skip the 0 value and jump to 1
+ instead. This has shown to give better coverage data and is the default; see
+ [instrumentation/README.llvm.md](../instrumentation/README.llvm.md).
+
C. Instead of forking, reiterate the fuzz target function in a loop (like
- `LLVMFuzzerTestOneInput`. Great speed increase but only work with target
- functions that does not keep state, leak memory or exit;
- see [instrumentation/README.persistent_mode.md](../instrumentation/README.persistent_mode.md)
-D. Split any non-8-bit comparison to 8 bit comparison;
- see [instrumentation/README.laf-intel.md](../instrumentation/README.laf-intel.md)
-E. CmpLog is our enhanced [Redqueen](https://www.ndss-symposium.org/ndss-paper/redqueen-fuzzing-with-input-to-state-correspondence/)
- implementation, see see [instrumentation/README.cmplog.md](../instrumentation/README.cmplog.md)
+ `LLVMFuzzerTestOneInput`. Great speed increase but only works with target
+ functions that do not keep state, leak memory, or exit; see
+ [instrumentation/README.persistent_mode.md](../instrumentation/README.persistent_mode.md)
+
+D. Split any non-8-bit comparison to 8-bit comparison; see
+ [instrumentation/README.laf-intel.md](../instrumentation/README.laf-intel.md)
+
+E. CmpLog is our enhanced
+ [Redqueen](https://www.ndss-symposium.org/ndss-paper/redqueen-fuzzing-with-input-to-state-correspondence/)
+ implementation, see
+ [instrumentation/README.cmplog.md](../instrumentation/README.cmplog.md)
+
F. Similar and compatible to clang 13+ sancov sanitize-coverage-allow/deny but
for all llvm versions and all our compile modes, only instrument what should
- be instrumented, for more speed, directed fuzzing and less instability;
- see [instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md)
+ be instrumented, for more speed, directed fuzzing and less instability; see
+ [instrumentation/README.instrument_list.md](../instrumentation/README.instrument_list.md)
+
G. Vanilla AFL uses coverage where edges could collide to the same coverage
bytes the larger the target is. Our default instrumentation in LTO and
afl-clang-fast (PCGUARD) uses non-colliding coverage that also makes it
- faster. Vanilla AFL style is available with `AFL_LLVM_INSTRUMENT=AFL`;
- see [instrumentation/README.llvm.md](../instrumentation/README.llvm.md)
+ faster. Vanilla AFL style is available with `AFL_LLVM_INSTRUMENT=AFL`; see
+ [instrumentation/README.llvm.md](../instrumentation/README.llvm.md).
+
H.+I. Alternative coverage based on previous edges (NGRAM) or depending on the
- caller (CTX), based on
+ caller (CTX), based on
[https://www.usenix.org/system/files/raid2019-wang-jinghan.pdf](https://www.usenix.org/system/files/raid2019-wang-jinghan.pdf);
- see [instrumentation/README.llvm.md](../instrumentation/README.llvm.md)
+ see [instrumentation/README.llvm.md](../instrumentation/README.llvm.md).
+
J. An LTO feature that creates a fuzzing dictionary based on comparisons found
- during compilation/instrumentation. Automatic feature :)
- See [instrumentation/README.lto.md](../instrumentation/README.lto.md)
+ during compilation/instrumentation. Automatic feature :) See
+ [instrumentation/README.lto.md](../instrumentation/README.lto.md)
+
K. The snapshot feature requires a kernel module that was a lot of work to get
right and maintained so it is no longer supported. We have
[nyx_mode](../nyx_mode/README.md) instead.
+
L. Faster fuzzing and less kernel syscall overhead by in-memory fuzz testcase
delivery, see
[instrumentation/README.persistent_mode.md](../instrumentation/README.persistent_mode.md)
-1. default for LLVM >= 9.0, environment variable for older version due an
+## More information about instrumentation
+
+1. Default for LLVM >= 9.0, environment variable for older version due an
efficiency bug in previous llvm versions
2. GCC creates non-performant code, hence it is disabled in gcc_plugin
-3. with `AFL_LLVM_THREADSAFE_INST`, disables NeverZero
-4. with pcguard mode and LTO mode for LLVM 11 and newer
-5. upcoming, development in the branch
-6. not compatible with LTO instrumentation and needs at least LLVM v4.1
-7. automatic in LTO mode with LLVM 11 and newer, an extra pass for all LLVM
+3. With `AFL_LLVM_THREADSAFE_INST`, disables NeverZero
+4. With pcguard mode and LTO mode for LLVM 11 and newer
+5. Upcoming, development in the branch
+6. Not compatible with LTO instrumentation and needs at least LLVM v4.1
+7. Automatic in LTO mode with LLVM 11 and newer, an extra pass for all LLVM
versions that write to a file to use with afl-fuzz' `-x`
-8. the snapshot LKM is currently unmaintained due to too many kernel changes
+8. The snapshot LKM is currently unmaintained due to too many kernel changes
coming too fast :-(
9. FRIDA mode is supported on Linux and MacOS for Intel and ARM
10. QEMU/Unicorn is only supported on Linux
@@ -72,6 +90,8 @@ L. Faster fuzzing and less kernel syscall overhead by in-memory fuzz testcase
extension
12. Nyx mode is only supported on Linux and currently restricted to x86_x64
+## Integrated features and patches
+
Among others, the following features and patches have been integrated:
* NeverZero patch for afl-gcc, instrumentation, QEMU mode and unicorn_mode which
--
cgit 1.4.1
From 4902bb91d259e128afff3cb135830e486740ddb3 Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Thu, 20 Jan 2022 20:59:36 +0100
Subject: Fix links and spelling of Redqueen
---
docs/features.md | 4 ++--
instrumentation/README.cmplog.md | 5 ++---
qemu_mode/README.md | 2 +-
3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/docs/features.md b/docs/features.md
index 25e1a9a3..dd3d2bcb 100644
--- a/docs/features.md
+++ b/docs/features.md
@@ -1,7 +1,7 @@
# Important features of AFL++
AFL++ supports llvm from 3.8 up to version 12, very fast binary fuzzing with
-QEMU 5.1 with laf-intel and redqueen, FRIDA mode, unicorn mode, gcc plugin, full
+QEMU 5.1 with laf-intel and Redqueen, FRIDA mode, unicorn mode, gcc plugin, full
*BSD, Mac OS, Solaris and Android support and much, much, much more.
## Features and instrumentation
@@ -100,7 +100,7 @@ Among others, the following features and patches have been integrated:
* Unicorn mode which allows fuzzing of binaries from completely different
platforms (integration provided by domenukk)
* The new CmpLog instrumentation for LLVM and QEMU inspired by
- [Redqueen](https://www.syssec.ruhr-uni-bochum.de/media/emma/veroeffentlichungen/2018/12/17/NDSS19-Redqueen.pdf)
+ [Redqueen](https://github.com/RUB-SysSec/redqueen)
* Win32 PE binary-only fuzzing with QEMU and Wine
* AFLfast's power schedules by Marcel Böhme:
[https://github.com/mboehme/aflfast](https://github.com/mboehme/aflfast)
diff --git a/instrumentation/README.cmplog.md b/instrumentation/README.cmplog.md
index a2caca4f..8a9fd372 100644
--- a/instrumentation/README.cmplog.md
+++ b/instrumentation/README.cmplog.md
@@ -4,9 +4,8 @@ The CmpLog instrumentation enables logging of comparison operands in a shared
memory.
These values can be used by various mutators built on top of it. At the moment,
-we support the RedQueen mutator (input-2-state instructions only), for details
-see
-[the RedQueen paper](https://www.syssec.ruhr-uni-bochum.de/media/emma/veroeffentlichungen/2018/12/17/NDSS19-Redqueen.pdf).
+we support the Redqueen mutator (input-2-state instructions only), for details
+see [the Redqueen paper](https://github.com/RUB-SysSec/redqueen).
## Build
diff --git a/qemu_mode/README.md b/qemu_mode/README.md
index a045ef4f..3ebfc54c 100644
--- a/qemu_mode/README.md
+++ b/qemu_mode/README.md
@@ -135,7 +135,7 @@ Recommended, but not as good as CMPLOG mode (see below).
## 8) CMPLOG mode
-Another new feature is CMPLOG, which is based on the redqueen project. Here all
+Another new feature is CMPLOG, which is based on the Redqueen project. Here all
immediates in CMP instructions are learned and put into a dynamic dictionary and
applied to all locations in the input that reached that CMP, trying to solve and
pass it. This is a very effective feature and it is available for x86, x86_64,
--
cgit 1.4.1
From c74686e20d5bd096ac5eb586f96fa11ea3d0cd83 Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Thu, 20 Jan 2022 21:23:28 +0100
Subject: Fix structure
---
docs/tutorials.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/tutorials.md b/docs/tutorials.md
index 9d4f50eb..64d2b376 100644
--- a/docs/tutorials.md
+++ b/docs/tutorials.md
@@ -28,7 +28,7 @@ structure is), these links have you covered:
* Superion for AFL++:
[https://github.com/adrian-rt/superion-mutator](https://github.com/adrian-rt/superion-mutator)
-# Video Tutorials
+## Video Tutorials
* [Install AFL++ Ubuntu](https://www.youtube.com/watch?v=5dCvhkbi3RA)
* [[Fuzzing with AFLplusplus] Installing AFLPlusplus and fuzzing a simple C program](https://www.youtube.com/watch?v=9wRVo0kYSlc)
* [[Fuzzing with AFLplusplus] How to fuzz a binary with no source code on Linux in persistent mode](https://www.youtube.com/watch?v=LGPJdEO02p4)
--
cgit 1.4.1
From ec7b14a3d637038ea0d67adb838d1fc35b0e0cc5 Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Thu, 20 Jan 2022 21:25:06 +0100
Subject: Fix line length
---
docs/INSTALL.md | 18 +++++++++---------
docs/env_variables.md | 16 ++++++++--------
2 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index 3c96a4fd..2847ca2a 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -33,10 +33,10 @@ sudo make install
It is recommended to install the newest available gcc, clang and llvm-dev
possible in your distribution!
-Note that `make distrib` also builds FRIDA mode, QEMU mode, unicorn_mode
-and more. If you just want plain AFL++, then do `make all`. If you want
-some assisting tooling compiled but are not interested in binary-only targets
-then instead choose:
+Note that `make distrib` also builds FRIDA mode, QEMU mode, unicorn_mode, and
+more. If you just want plain AFL++, then do `make all`. If you want some
+assisting tooling compiled but are not interested in binary-only targets, then
+instead choose:
```shell
make source-only
@@ -46,7 +46,8 @@ These build targets exist:
* all: the main afl++ binaries and llvm/gcc instrumentation
* binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode,
- qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator, libtokencap
+ qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator,
+ libtokencap
* source-only: everything for source code fuzzing: nyx_mode, libdislocator,
libtokencap
* distrib: everything (for both binary-only and source code fuzzing)
@@ -116,10 +117,9 @@ sudo gmake install
```
`afl-gcc` will fail unless you have GCC installed, but that is using outdated
-instrumentation anyway. `afl-clang` might fail too depending on your PATH
-setup. But you don't want neither, you want `afl-clang-fast` anyway :)
-Note that `afl-clang-lto`, `afl-gcc-fast` and `qemu_mode` are not working on
-MacOS.
+instrumentation anyway. `afl-clang` might fail too depending on your PATH setup.
+But you don't want neither, you want `afl-clang-fast` anyway :) Note that
+`afl-clang-lto`, `afl-gcc-fast` and `qemu_mode` are not working on MacOS.
The crash reporting daemon that comes by default with MacOS X will cause
problems with fuzzing. You need to turn it off:
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 76a64bd2..2a8fbcb7 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -285,12 +285,12 @@ mode.
```
- GCC_PLUGIN mode only: Setting `AFL_GCC_INSTRUMENT_FILE` or
- `AFL_GCC_ALLOWLIST` with a filename will only instrument those files
- that match the names listed in this file (one filename per line).
-
- Setting `AFL_GCC_DENYLIST` or `AFL_GCC_BLOCKLIST`
- with a file name and/or function will only skip those files that match
- the names listed in the specified file. See
+ `AFL_GCC_ALLOWLIST` with a filename will only instrument those files that
+ match the names listed in this file (one filename per line).
+
+ Setting `AFL_GCC_DENYLIST` or `AFL_GCC_BLOCKLIST` with a file name and/or
+ function will only 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.
@@ -298,8 +298,8 @@ mode.
code with calls to an injected subroutine instead of the much more efficient
inline instrumentation.
- Setting `AFL_GCC_SKIP_NEVERZERO=1` will not implement the skip zero test.
- If the target performs only a few loops, then this will give a small
+ Setting `AFL_GCC_SKIP_NEVERZERO=1` will not implement the skip zero test. If
+ the target performs only a few loops, then this will give a small
performance boost.
## 4) Settings for afl-fuzz
--
cgit 1.4.1
From ecf8db0014b12d01958ec3256338a452e892ca29 Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Thu, 20 Jan 2022 21:26:13 +0100
Subject: Fix punctuation
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 24164262..966e8036 100644
--- a/README.md
+++ b/README.md
@@ -127,7 +127,7 @@ Step-by-step quick start:
Questions? Concerns? Bug reports?
-* The contributors can be reached via (e.g. by creating an issue):
+* The contributors can be reached via (e.g., by creating an issue):
[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
--
cgit 1.4.1
From b4c2fc94166b22a77c521884a07fdfee2098147a Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Thu, 20 Jan 2022 21:40:28 +0100
Subject: Fix formatting and line length
---
nyx_mode/README.md | 208 ++++++++++++++++++++++++++++++++---------------------
1 file changed, 127 insertions(+), 81 deletions(-)
diff --git a/nyx_mode/README.md b/nyx_mode/README.md
index f975c764..f5350164 100644
--- a/nyx_mode/README.md
+++ b/nyx_mode/README.md
@@ -1,7 +1,7 @@
-# Nyx Mode
+# Nyx mode
-Nyx is a full system emulation fuzzing mode that supports snapshotting and
-can be used for both source code based instrumentation and binary-only targets.
+Nyx is a full system emulation fuzzing mode that supports snapshotting and can
+be used for both source code based instrumentation and binary-only targets.
It is recommended to be used if the target cannot be fuzzed in persistent mode
(so default fork mode fuzzing is used).
@@ -10,36 +10,36 @@ It is only available on Linux and is currently restricted to x86_x64 however
aarch64 support is in the works (but the host must then run on aarch64 too).
Underneath it is built upon KVM and QEMU and requires a modern Linux kernel
-(5.11+) for fuzzing source code based instrumented targets (e.g.
-`afl-clang-fast`). To fuzz binary-only targets, this is done via Intel PT
-and requires an Intel processor (6th generation onwards) and a special
-5.10 kernel (see [KVM-Nyx](https://github.com/nyx-fuzz/KVM-Nyx)).
+(5.11+) for fuzzing source code based instrumented targets (e.g.,
+`afl-clang-fast`). To fuzz binary-only targets, this is done via Intel PT and
+requires an Intel processor (6th generation onwards) and a special 5.10 kernel
+(see [KVM-Nyx](https://github.com/nyx-fuzz/KVM-Nyx)).
## Building Nyx mode
1. Install all the packages from [docs/INSTALL.md](../docs/INSTALL.md).
-2. Additionally install the following packages:
+2. Additionally, install the following packages:
-```shell
-apt-get install -y libgtk-3-dev pax-utils python3-msgpack python3-jinja2
-```
+ ```shell
+ apt-get install -y libgtk-3-dev pax-utils python3-msgpack python3-jinja2
+ ```
-3. As Nyx is written in Rust, install the newest rust compiler (rust packages
- in the Linux distribution are usually too old to be able to build Nyx):
+3. As Nyx is written in Rust, install the newest rust compiler (rust packages in
+ the Linux distribution are usually too old to be able to build Nyx):
-```shell
-curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-```
+ ```shell
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+ ```
4. Finally build Nyx mode:
-```shell
-./build_nyx_support.sh
-```
+ ```shell
+ ./build_nyx_support.sh
+ ```
5. Optionally, for binary-only fuzzing: set up the required 5.10 kernel, see
- [KVM-Nyx](https://github.com/nyx-fuzz/KVM-Nyx).
+ [KVM-Nyx](https://github.com/nyx-fuzz/KVM-Nyx).
## Preparing to fuzz a target with Nyx mode
@@ -55,35 +55,37 @@ option `instrumentation` below with `process_trace`):
```shell
python3 nyx_mode/packer/packer/nyx_packer.py \
- /PATH/TO/TARGET \
- PACKAGE-DIRECTORY \
- afl \
- instrumentation \
- --fast_reload_mode \
- --purge
+ /PATH/TO/TARGET \
+ PACKAGE-DIRECTORY \
+ afl \
+ instrumentation \
+ --fast_reload_mode \
+ --purge
```
This will create a directory with all necessary files and the Nyx configuration.
-The name of the directory will be whatever you choose for PACKAGE-DIRECTORY
+The name of the directory will be whatever you choose for `PACKAGE-DIRECTORY`
above.
In the final step for the packaging we generate the Nyx configuration:
+
```shell
python3 nyx_mode/packer/packer/nyx_config_gen.py PACKAGE-DIRECTORY Kernel
```
## Fuzzing with Nyx mode
-All the hard parts are done, fuzzing with Nyx mode is easy - just supply
-the PACKAGE-DIRECTORY as fuzzing target and specify the `-X` option to afl-fuzz:
+All the hard parts are done, fuzzing with Nyx mode is easy - just supply the
+`PACKAGE-DIRECTORY` as fuzzing target and specify the `-X` option to afl-fuzz:
```shell
afl-fuzz -i in -o out -X -- ./PACKAGE-DIRECTORY
```
Most likely your first run will fail because the Linux modules have to be
-specially set up, but afl-fuzz will tell you this on startup and how to
-rectify the situation:
+specially set up, but afl-fuzz will tell you this on startup and how to rectify
+the situation:
+
```
sudo modprobe -r kvm-intel # or kvm-amd for AMD processors
sudo modprobe -r kvm
@@ -94,10 +96,10 @@ sudo modprobe kvm-intel # or kvm-amd for AMD processors
If you want to fuzz in parallel (and you should!), then this has to be done in a
special way:
- * Instead of `-X` (standalone mode) you specify `-Y` (multi processor mode).
- * First a Main afl-fuzz instance has to be started with `-M 0`
- * Only afterwards can you start Secondary afl-fuzz instances, which must have
- an increasing number value, starting at 1, e.g. `-S 1`
+* Instead of `-X` (standalone mode), you specify `-Y` (multi processor mode).
+* First, a Main afl-fuzz instance has to be started with `-M 0`.
+* Only afterwards you can start Secondary afl-fuzz instances, which must have an
+ increasing number value, starting at 1, e.g., `-S 1`.
```shell
afl-fuzz -i in -o out -Y -M 0 -- ./PACKAGE-DIRECTORY
@@ -115,11 +117,13 @@ afl-fuzz -i in -o out -Y -S 2 -- ./PACKAGE-DIRECTORY
### Fuzzing libxml2 with AFL++ in Nyx-mode
-This tutorial is based on the [Fuzzing libxml2 with AFL++](https://aflplus.plus/docs/tutorials/libxml2_tutorial/) tutorial.
+This tutorial is based on the
+[Fuzzing libxml2 with AFL++](https://aflplus.plus/docs/tutorials/libxml2_tutorial/)
+tutorial.
-### Preparing libxml2
+### Preparing libxml2
-First, get the latest libxml2 source files by using `git`:
+First, get the latest libxml2 source files by using `git`:
```
git clone https://gitlab.gnome.org/GNOME/libxml2
@@ -128,7 +132,7 @@ cd libxml2
Remember that currently only classic AFL instrumentation is supported!
-```
+```
export AFL_LLVM_INSTRUMENT=AFL
./autogen.sh
./configure --enable-shared=no
@@ -139,43 +143,65 @@ make CC=afl-clang-fast CXX=afl-clang-fast++ LD=afl-clang-fast
Nyx expects that the target is provided in a certain format. More specifically, the target is passed as a so-called „share directory“ to a Nyx-frontend implementation. The share directory contains the target as well as a folder containing all dependencies and other files that are copied over to the guest. But more importantly, this share directory also contains a bootstrap script (`fuzz.sh`if you are using `KVM-Nyx`otherwise `fuzz_no_pt.sh`) that is also executed right after launching the fuzzer. Both bootstrap scripts use several tools to communicate with the "outer world":
-- `hcat` - this tool copies a given string to the host
-- `hget` - this program requests a file from the host's share directory
-- `hget_bulk` - an improved version of `hget`. It is quite useful if you want to transfer huge files. But please keep in mind that this version of `hget` has a much larger startup overhead and won't improve your transfer rates on small files (typically files smaller than 100MB).
-- `habort` - this tool basically sends an abort signal to the host (useful if something went wrong during bootstrap)
-- `hpush` - a tool to transfer a given file to the host (the transfered file will be put in the `dump/` folder of your Nyx workdir)
-
-Those tools are all using hypercalls which are defined in `packer/nyx.h`. We will give some more examples later on how to use these hypercalls directly to implement custom fuzzing harnesses.
+- `hcat` - this tool copies a given string to the host
+- `hget` - this program requests a file from the host's share directory
+- `hget_bulk` - an improved version of `hget`. It is quite useful if you want to
+ transfer huge files. But please keep in mind that this version of `hget` has a
+ much larger startup overhead and won't improve your transfer rates on small
+ files (typically files smaller than 100 MB).
+- `habort` - this tool basically sends an abort signal to the host (useful if
+ something went wrong during bootstrap)
+- `hpush` - a tool to transfer a given file to the host (the transferred file
+ will be put in the `dump/` folder of your Nyx workdir)
+
+Those tools are all using hypercalls which are defined in `packer/nyx.h`. We
+will give some more examples later on how to use these hypercalls directly to
+implement custom fuzzing harnesses.
### Pack libxml2 into Nyx sharedir format
-To turn a given linux target into the Nyx format, you can simply use `nyx_packer.py`. To do so, move to the following directory:
+To turn a given linux target into the Nyx format, you can simply use
+`nyx_packer.py`. To do so, move to the following directory:
```
cd nyx_mode/packer/packer
```
- And run the tool with the following options to pack `libxml2`:
+And run the tool with the following options to pack `libxml2`:
-```.
-python3 ./nyx_packer.py \
- ~/libxml2/xmllint \
- /tmp/nyx_libxml2 \
- afl \
- instrumentation \
- -args "/tmp/input" \
- -file "/tmp/input" \
- --fast_reload_mode \
- --purge
```
-
-In this example, the packer will take `xmllint`, recursively get all dependencies and put both into the specified share directory (`/tmp/nyx_libxml2` in this case). Because we have selected the `afl` option, an `ld_preload`-based agent is also automatically built and put into the sharedir. Another option would be `spec`. Without going into too much detail here, the `spec`mode is only used by Nyx's [spec-fuzzer](https://github.com/nyx-fuzz/spec-fuzzer) implementation. Next, since our target is built with compile-time instrumentations, we must select the `instrumentation` option, otherwise we could also use `processor-trace` option to enable Intel-PT fuzzing on targets without instrumentation.
-
-To specify that the input generated by the fuzzer is passed as a seperate file to the target, we need to set the `-file` option. Otherwise, the input will be passed over to the target via `stdin`. To specify any required `argv` options you can use the `-args`parameter.
-
-In case you want to fuzz the target only with fast snapshots enabled, you can also set the `--fast_reload_mode` option to improve performance.
-
-Finally, we need to generate a Nyx configuration file. Simply run the following command and you're good to proceed:
+python3 ./nyx_packer.py \
+ ~/libxml2/xmllint \
+ /tmp/nyx_libxml2 \
+ afl \
+ instrumentation \
+ -args "/tmp/input" \
+ -file "/tmp/input" \
+ --fast_reload_mode \
+ --purge
+```
+
+In this example, the packer will take `xmllint`, recursively get all
+dependencies and put both into the specified share directory (`/tmp/nyx_libxml2`
+in this case). Because we have selected the `afl` option, an `ld_preload`-based
+agent is also automatically built and put into the sharedir. Another option
+would be `spec`. Without going into too much detail here, the `spec` mode is
+only used by Nyx's [spec-fuzzer](https://github.com/nyx-fuzz/spec-fuzzer)
+implementation. Next, since our target is built with compile-time
+instrumentations, we must select the `instrumentation` option, otherwise we
+could also use `processor-trace` option to enable Intel-PT fuzzing on targets
+without instrumentation.
+
+To specify that the input generated by the fuzzer is passed as a separate file
+to the target, we need to set the `-file` option. Otherwise, the input will be
+passed over to the target via `stdin`. To specify any required `argv` options,
+you can use the `-args` parameter.
+
+In case you want to fuzz the target only with fast snapshots enabled, you can
+also set the `--fast_reload_mode` option to improve performance.
+
+Finally, we need to generate a Nyx configuration file. Simply run the following
+command and you're good to proceed:
```
python3 ./nyx_config_gen.py /tmp/nyx_libxml2/ Kernel
@@ -183,15 +209,17 @@ python3 ./nyx_config_gen.py /tmp/nyx_libxml2/ Kernel
### Run Nyx mode
-From here on, we are almost done. Move to the AFL++ top directory and start the fuzzer with the following arguments:
+From here on, we are almost done. Move to the AFL++ top directory and start the
+fuzzer with the following arguments:
```shell
-mkdir /tmp/in/ # create an input folder
-echo "AAAA" >> /tmp/in/A # create a dummy input file
+mkdir /tmp/in/ # create an input folder
+echo "AAAA" >> /tmp/in/A # create a dummy input file
./afl-fuzz -i /tmp/in/ -o /tmp/out -X /tmp/nyx_libxml2/
```
-If everything has been successfully set up to this point, you will now be welcomed by the following AFL++ screen:
+If everything has been successfully set up to this point, you will now be
+welcomed by the following AFL++ screen:
```
american fuzzy lop ++3.15a {default} (/tmp/nyx_libxml2/) [fast] - NYX
@@ -220,46 +248,64 @@ If everything has been successfully set up to this point, you will now be welcom
└────────────────────────────────────────────────────┘
```
-If you want to run the fuzzer in distributed mode, which might be especially useful if you want to keep your memory footprint low, we got you covered. To start an initiating `parent` process, which will also create the snapshot which is later shared across all other `child`s, simply run AFL++Nyx with the following arguments:
+If you want to run the fuzzer in distributed mode, which might be especially
+useful if you want to keep your memory footprint low, we got you covered. To
+start an initiating `parent` process, which will also create the snapshot which
+is later shared across all other `child`s, simply run AFL++Nyx with the
+following arguments:
```
./afl-fuzz -i /tmp/in/ -o /tmp/out -d -Y -M 0 /tmp/nyx_libxml2/
```
-To attach other child processes adjust the `-S ` and run the following command:
+To attach other child processes adjust the `-S ` and run the following
+command:
```
./afl-fuzz -i /tmp/in/ -o /tmp/out -d -Y -S 1 /tmp/nyx_libxml2/
```
-If you want to disable fast snapshots (except for crashes), you can simply set the `NYX_DISABLE_SNAPSHOT_MODE` environment variable.
+If you want to disable fast snapshots (except for crashes), you can simply set
+the `NYX_DISABLE_SNAPSHOT_MODE` environment variable.
### Run AFL++Nyx with a custom agent
-Most of the common use-cases for linux userland targets are already handled by our general purpose [agent](https://github.com/nyx-fuzz/packer/blob/main/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c) implementation. But in case you want to build your own agent, or write a custom harness for a specific target or you just want to implement all the hypercall and shared memory communication on your own, you can use our custom harness example as a starting point for that. You can find the code [here](custom_harness/)
+Most of the common use-cases for linux userland targets are already handled by
+our general purpose
+[agent](https://github.com/nyx-fuzz/packer/blob/main/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c)
+implementation. But in case you want to build your own agent, or write a custom
+harness for a specific target or you just want to implement all the hypercall
+and shared memory communication on your own, you can use our custom harness
+example as a starting point for that. You can find the code in
+[custom_harness/](./custom_harness/).
-This custom harness can be statically compiled with by gcc or clang. There is no need to use an AFL compiler, because this agent implements its own very basic coverage tracking by simply setting specific bytes in the "coverage" bitmap after specific branches have been covered.
+This custom harness can be statically compiled with by gcc or clang. There is no
+need to use an AFL compiler, because this agent implements its own very basic
+coverage tracking by simply setting specific bytes in the "coverage" bitmap
+after specific branches have been covered.
-To prepare this target, we must first create a new folder that will later become the sharedir.
+To prepare this target, we must first create a new folder that will later become
+the sharedir.
````
mkdir /tmp/nyx_custom_agent/
````
- To compile this example, run the following command (remove the `-DNO_PT_NYX` option if you are using KVM-Nyx ):
+To compile this example, run the following command (remove the `-DNO_PT_NYX`
+option if you are using KVM-Nyx):
-```
+```
gcc example.c -DNO_PT_NYX -static -I ./packer/ -o /tmp/nyx_custom_agent/target
```
-Copy both bootstrap scripts into the sharedir:
+Copy both bootstrap scripts into the sharedir:
```
cp fuzz.sh /tmp/nyx_custom_agent
cp fuzz_no_pt.sh /tmp/nyx_custom_agent
```
-Copy all `htools` executables into the sharedir:
+Copy all `htools` executables into the sharedir:
```
cd ~/AFLplusplus/packer/packer/linux_x86_64-userspace/
@@ -267,7 +313,7 @@ sh compile_64.sh
cp bin64/h* /tmp/nyx_custom_agent/
```
-And finally, generate a Nyx configuration:
+And finally, generate a Nyx configuration:
```
cd ~/AFLplusplus/packer/packer
--
cgit 1.4.1
From 9d87f408dd6537ee4dbcf390496a0518f0c817ef Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Fri, 21 Jan 2022 06:50:26 +0100
Subject: update nyx_mode git submodules
---
nyx_mode/LIBNYX_VERSION | 2 +-
nyx_mode/PACKER_VERSION | 2 +-
nyx_mode/QEMU-Nyx | 2 +-
nyx_mode/QEMU_NXY_VERSION | 2 +-
nyx_mode/libnyx | 2 +-
nyx_mode/packer | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/nyx_mode/LIBNYX_VERSION b/nyx_mode/LIBNYX_VERSION
index 1ac5611b..109c3c6f 100644
--- a/nyx_mode/LIBNYX_VERSION
+++ b/nyx_mode/LIBNYX_VERSION
@@ -1 +1 @@
-ecbcb2d
+a5ae4c1
diff --git a/nyx_mode/PACKER_VERSION b/nyx_mode/PACKER_VERSION
index 2596e40f..0c9db1e3 100644
--- a/nyx_mode/PACKER_VERSION
+++ b/nyx_mode/PACKER_VERSION
@@ -1 +1 @@
-f91742c
+8842549
diff --git a/nyx_mode/QEMU-Nyx b/nyx_mode/QEMU-Nyx
index d5a7011a..902306be 160000
--- a/nyx_mode/QEMU-Nyx
+++ b/nyx_mode/QEMU-Nyx
@@ -1 +1 @@
-Subproject commit d5a7011ad20ba5ba91f1371f9d40154035d5d768
+Subproject commit 902306beb01d858dcbcbaf0e1be26ce9dd0f293f
diff --git a/nyx_mode/QEMU_NXY_VERSION b/nyx_mode/QEMU_NXY_VERSION
index d2f0328b..96133165 100644
--- a/nyx_mode/QEMU_NXY_VERSION
+++ b/nyx_mode/QEMU_NXY_VERSION
@@ -1 +1 @@
-acc90e462b
+902306beb0
diff --git a/nyx_mode/libnyx b/nyx_mode/libnyx
index ecbcb2d7..a5ae4c13 160000
--- a/nyx_mode/libnyx
+++ b/nyx_mode/libnyx
@@ -1 +1 @@
-Subproject commit ecbcb2d7234fef0b5e1db8ca6019e6137ee0582d
+Subproject commit a5ae4c13e11de776779444eb69932802e102d7c4
diff --git a/nyx_mode/packer b/nyx_mode/packer
index f91742ce..8842549b 160000
--- a/nyx_mode/packer
+++ b/nyx_mode/packer
@@ -1 +1 @@
-Subproject commit f91742ce6c51eee133b5675edd68f39202785db1
+Subproject commit 8842549b5612a890258dcef812276cfdb62b76c7
--
cgit 1.4.1
From a59418231469b1dd54abec57fe6e399905b8b58a Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Fri, 21 Jan 2022 07:13:35 +0100
Subject: update nyx_mode build script
---
nyx_mode/build_nyx_support.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nyx_mode/build_nyx_support.sh b/nyx_mode/build_nyx_support.sh
index 8626342d..b6c1d54e 100755
--- a/nyx_mode/build_nyx_support.sh
+++ b/nyx_mode/build_nyx_support.sh
@@ -53,7 +53,7 @@ fi
echo "[*] Checking QEMU-Nyx ..."
if [ ! -f "QEMU-Nyx/x86_64-softmmu/qemu-system-x86_64" ]; then
cd QEMU-Nyx/
- ./compile_qemu_nyx.sh || exit 1
+ ./compile_qemu_nyx.sh static || exit 1
cd ..
fi
--
cgit 1.4.1
From 1a15e98fff74db21eb7d54cf89fba6f40fe4eedd Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Fri, 21 Jan 2022 07:14:38 +0100
Subject: fix typo (QEMU_NXY_VERSION -> QEMU_NYX_VERSION)
---
nyx_mode/QEMU_NXY_VERSION | 1 -
nyx_mode/QEMU_NYX_VERSION | 1 +
nyx_mode/update_ref.sh | 2 +-
3 files changed, 2 insertions(+), 2 deletions(-)
delete mode 100644 nyx_mode/QEMU_NXY_VERSION
create mode 100644 nyx_mode/QEMU_NYX_VERSION
diff --git a/nyx_mode/QEMU_NXY_VERSION b/nyx_mode/QEMU_NXY_VERSION
deleted file mode 100644
index 96133165..00000000
--- a/nyx_mode/QEMU_NXY_VERSION
+++ /dev/null
@@ -1 +0,0 @@
-902306beb0
diff --git a/nyx_mode/QEMU_NYX_VERSION b/nyx_mode/QEMU_NYX_VERSION
new file mode 100644
index 00000000..96133165
--- /dev/null
+++ b/nyx_mode/QEMU_NYX_VERSION
@@ -0,0 +1 @@
+902306beb0
diff --git a/nyx_mode/update_ref.sh b/nyx_mode/update_ref.sh
index 3e94a42b..898a803f 100755
--- a/nyx_mode/update_ref.sh
+++ b/nyx_mode/update_ref.sh
@@ -71,7 +71,7 @@ echo "$NEW_VERSION" > "$UC_VERSION_FILE"
echo "Done. New XXX version is $NEW_VERSION."
-UC_VERSION_FILE='./QEMU_NXY_VERSION'
+UC_VERSION_FILE='./QEMU_NYX_VERSION'
NEW_VERSION=""
cd ./QEMU-Nyx || exit 1
--
cgit 1.4.1
From 9d3e6a869e9474c1a3927a319b6ec2142130f5d3 Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Fri, 21 Jan 2022 07:21:43 +0100
Subject: add LTO support in nyx_mode
---
include/forkserver.h | 8 +++++++-
src/afl-forkserver.c | 21 ++++++++++++---------
src/afl-fuzz.c | 9 ++++++++-
3 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/include/forkserver.h b/include/forkserver.h
index 48db2e26..4a05b17e 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -54,7 +54,13 @@ typedef enum NyxReturnValue {
typedef struct {
void *(*nyx_new)(const char *sharedir, const char *workdir,
- uint32_t worker_id, uint32_t cpu_id, bool create_snapshot);
+ uint32_t cpu_id, uint32_t input_buffer_size,
+ bool input_buffer_write_protection);
+ void *(*nyx_new_parent)(const char *sharedir, const char *workdir,
+ uint32_t cpu_id, uint32_t input_buffer_size,
+ bool input_buffer_write_protection);
+ void *(*nyx_new_child)(const char *sharedir, const char *workdir,
+ uint32_t cpu_id, uint32_t worker_id);
void (*nyx_shutdown)(void *qemu_process);
void (*nyx_option_set_reload_mode)(void *qemu_process, bool enable);
void (*nyx_option_set_timeout)(void *qemu_process, uint8_t timeout_sec,
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index eebbb7c8..1f03cfd3 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -405,24 +405,27 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
- if (fsrv->nyx_parent) {
-
+ if (fsrv->nyx_standalone){
fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(
- fsrv->target_path, x, fsrv->nyx_id, fsrv->nyx_bind_cpu_id,
- !fsrv->nyx_standalone);
-
- } else {
+ fsrv->target_path, x, fsrv->nyx_bind_cpu_id, 0x10000, true);
+ }
+ else{
+ if (fsrv->nyx_parent) {
+ fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new_parent(
+ fsrv->target_path, x, fsrv->nyx_bind_cpu_id, MAX_FILE, true);
- fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(
- fsrv->target_path, x, fsrv->nyx_id, fsrv->nyx_bind_cpu_id, true);
+ } else {
+ fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new_child(
+ fsrv->target_path, x, fsrv->nyx_bind_cpu_id, fsrv->nyx_id);
+ }
}
if (fsrv->nyx_runner == NULL) { FATAL("Something went wrong ..."); }
u32 tmp_map_size =
fsrv->nyx_handlers->nyx_get_bitmap_buffer_size(fsrv->nyx_runner);
- fsrv->real_map_size = fsrv->map_size;
+ fsrv->real_map_size = tmp_map_size;
fsrv->map_size = (((tmp_map_size + 63) >> 6) << 6);
if (!be_quiet) { ACTF("Target map size: %u", fsrv->real_map_size); }
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 1edf82f4..50874f47 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -404,6 +404,12 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) {
plugin->nyx_new = dlsym(handle, "nyx_new");
if (plugin->nyx_new == NULL) { goto fail; }
+ plugin->nyx_new_parent = dlsym(handle, "nyx_new_parent");
+ if (plugin->nyx_new_parent == NULL) { goto fail; }
+
+ plugin->nyx_new_child = dlsym(handle, "nyx_new_child");
+ if (plugin->nyx_new_child == NULL) { goto fail; }
+
plugin->nyx_shutdown = dlsym(handle, "nyx_shutdown");
if (plugin->nyx_shutdown == NULL) { goto fail; }
@@ -1340,7 +1346,8 @@ int main(int argc, char **argv_orig, char **envp) {
"0)");
}
-
+
+ afl->fsrv.nyx_parent = true;
afl->fsrv.nyx_id = 0;
}
--
cgit 1.4.1
From 74d9da7203ca40dac7c6c1c7b163844f0d050b28 Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Fri, 21 Jan 2022 08:05:30 +0100
Subject: update nyx_mode README
---
nyx_mode/README.md | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/nyx_mode/README.md b/nyx_mode/README.md
index f975c764..9c7a1d1f 100644
--- a/nyx_mode/README.md
+++ b/nyx_mode/README.md
@@ -46,12 +46,9 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Nyx uses full system emulation hence your fuzzing targets have to be especially
packaged.
-**For source code based instrumentation with `afl-clang-fast` for the time
-being these must be instrumented to `AFL_LLVM_INSTRUMENT=AFL` to work!**
-
With your target ready at hand execute the following command
(note that for binary-only fuzzing with the special 5.10 kernel switch the
-option `instrumentation` below with `process_trace`):
+option `instrumentation` below with `processor_trace`):
```shell
python3 nyx_mode/packer/packer/nyx_packer.py \
@@ -126,10 +123,9 @@ git clone https://gitlab.gnome.org/GNOME/libxml2
cd libxml2
```
-Remember that currently only classic AFL instrumentation is supported!
+Next, compile libxml2:
```
-export AFL_LLVM_INSTRUMENT=AFL
./autogen.sh
./configure --enable-shared=no
make CC=afl-clang-fast CXX=afl-clang-fast++ LD=afl-clang-fast
@@ -249,7 +245,7 @@ mkdir /tmp/nyx_custom_agent/
To compile this example, run the following command (remove the `-DNO_PT_NYX` option if you are using KVM-Nyx ):
```
-gcc example.c -DNO_PT_NYX -static -I ./packer/ -o /tmp/nyx_custom_agent/target
+gcc example.c -DNO_PT_NYX -static -I ../packer/ -o /tmp/nyx_custom_agent/target
```
Copy both bootstrap scripts into the sharedir:
--
cgit 1.4.1
From 830dcacc07f2740178af666c6e63935885a24d34 Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Fri, 21 Jan 2022 08:06:31 +0100
Subject: update nyx custom_harness example
---
nyx_mode/custom_harness/example.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/nyx_mode/custom_harness/example.c b/nyx_mode/custom_harness/example.c
index 0b12e60b..7cfecc24 100644
--- a/nyx_mode/custom_harness/example.c
+++ b/nyx_mode/custom_harness/example.c
@@ -4,8 +4,7 @@
#include
#include "nyx.h"
-/* this is our "bitmap" that is later shared with the fuzzer (you can also pass the pointer of the bitmap used by compile-time instrumentations in your target) */
-uint8_t* trace_buffer[64*1024] = {0};
+#define TRACE_BUFFER_SIZE (1024*64)
int main(int argc, char** argv){
/* if you want to debug code running in Nyx, hprintf() is the way to go.
@@ -20,21 +19,27 @@ int main(int argc, char** argv){
hprintf("[capablities] host_config.ijon_bitmap_size: 0x%"PRIx64"\n", host_config.ijon_bitmap_size);
hprintf("[capablities] host_config.payload_buffer_size: 0x%"PRIx64"x\n", host_config.payload_buffer_size);
+ /* this is our "bitmap" that is later shared with the fuzzer (you can also pass the pointer of the bitmap used by compile-time instrumentations in your target) */
+ uint8_t* trace_buffer = mmap(NULL, TRACE_BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ memset(trace_buffer, 0, TRACE_BUFFER_SIZE); // makes sure that the bitmap buffer is already mapped into the guest's memory (alternatively you can use mlock) */
+
/* Submit agent configuration */
- memset(trace_buffer, 0, 64*1024); // makes sure that the bitmap buffer is already mapped into the guest's memory (alternatively you can use mlock) */
agent_config_t agent_config = {0};
+ agent_config.agent_magic = NYX_AGENT_MAGIC;
+ agent_config.agent_version = NYX_AGENT_VERSION;
agent_config.agent_timeout_detection = 0; /* timeout detection is implemented by the agent (currently not used) */
agent_config.agent_tracing = 1; /* set this flag to propagade that instrumentation-based fuzzing is availabe */
agent_config.agent_ijon_tracing = 0; /* set this flag to propagade that IJON extension is implmented agent-wise */
agent_config.trace_buffer_vaddr = (uintptr_t)trace_buffer; /* trace "bitmap" pointer - required for instrumentation-only fuzzing */
agent_config.ijon_trace_buffer_vaddr = (uintptr_t)NULL; /* "IJON" buffer pointer */
agent_config.agent_non_reload_mode = 1; /* non-reload mode is supported (usually because the agent implements a fork-server; currently not used) */
+ agent_config.coverage_bitmap_size = TRACE_BUFFER_SIZE;
kAFL_hypercall(HYPERCALL_KAFL_SET_AGENT_CONFIG, (uintptr_t)&agent_config);
/* Tell hypervisor the virtual address of the payload (input) buffer (call mlock to ensure that this buffer stays in the guest's memory)*/
- kAFL_payload* payload_buffer = mmap((void*)0x4000000ULL, PAYLOAD_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
- mlock(payload_buffer, (size_t)PAYLOAD_SIZE);
- memset(payload_buffer, 0, PAYLOAD_SIZE);
+ kAFL_payload* payload_buffer = mmap(NULL, host_config.payload_buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ mlock(payload_buffer, (size_t)host_config.payload_buffer_size);
+ memset(payload_buffer, 0, host_config.payload_buffer_size);
kAFL_hypercall(HYPERCALL_KAFL_GET_PAYLOAD, (uintptr_t)payload_buffer);
hprintf("[init] payload buffer is mapped at %p\n", payload_buffer);
--
cgit 1.4.1
From 6ce736aa913363647760d088ef0cb3610a765ff4 Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Fri, 21 Jan 2022 08:13:33 +0100
Subject: use MAX_FILE as maximum size in Nyx mode
---
src/afl-forkserver.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 1f03cfd3..ffcb30c3 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -407,7 +407,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if (fsrv->nyx_standalone){
fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(
- fsrv->target_path, x, fsrv->nyx_bind_cpu_id, 0x10000, true);
+ fsrv->target_path, x, fsrv->nyx_bind_cpu_id, MAX_FILE, true);
}
else{
if (fsrv->nyx_parent) {
--
cgit 1.4.1
From 22da04f077d2a5b16ffb48acbd668f29d21e6b64 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 21 Jan 2022 10:13:37 +0100
Subject: fix
---
nyx_mode/QEMU-Nyx | 2 +-
nyx_mode/libnyx | 2 +-
nyx_mode/packer | 2 +-
src/afl-cc.c | 8 +++----
utils/aflpp_driver/aflpp_driver.c | 48 ++++++++++++++++++++-------------------
5 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/nyx_mode/QEMU-Nyx b/nyx_mode/QEMU-Nyx
index 902306be..d5a7011a 160000
--- a/nyx_mode/QEMU-Nyx
+++ b/nyx_mode/QEMU-Nyx
@@ -1 +1 @@
-Subproject commit 902306beb01d858dcbcbaf0e1be26ce9dd0f293f
+Subproject commit d5a7011ad20ba5ba91f1371f9d40154035d5d768
diff --git a/nyx_mode/libnyx b/nyx_mode/libnyx
index a5ae4c13..ecbcb2d7 160000
--- a/nyx_mode/libnyx
+++ b/nyx_mode/libnyx
@@ -1 +1 @@
-Subproject commit a5ae4c13e11de776779444eb69932802e102d7c4
+Subproject commit ecbcb2d7234fef0b5e1db8ca6019e6137ee0582d
diff --git a/nyx_mode/packer b/nyx_mode/packer
index 8842549b..f91742ce 160000
--- a/nyx_mode/packer
+++ b/nyx_mode/packer
@@ -1 +1 @@
-Subproject commit 8842549b5612a890258dcef812276cfdb62b76c7
+Subproject commit f91742ce6c51eee133b5675edd68f39202785db1
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 974b1d2a..9197c74b 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -767,15 +767,13 @@ static void edit_params(u32 argc, char **argv, char **envp) {
u8 *afllib = find_object("libAFLDriver.a", argv[0]);
if (!be_quiet)
- WARNF(
- "Found erroneous '-fsanitize=fuzzer', trying to replace with "
- "libAFLDriver.a");
+ OKF("Found '-fsanitize=fuzzer', replacing with libAFLDriver.a");
if (!afllib) {
WARNF(
- "Cannot find 'libAFLDriver.a' to replace a wrong "
- "'-fsanitize=fuzzer' in the flags - this will fail!");
+ "Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in "
+ "the flags - this will fail!");
} else {
diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c
index 547b78fb..c648674a 100644
--- a/utils/aflpp_driver/aflpp_driver.c
+++ b/utils/aflpp_driver/aflpp_driver.c
@@ -84,6 +84,8 @@ __attribute__((weak)) void __asan_unpoison_memory_region(
}
+__attribute__((weak)) void *__asan_region_is_poisoned(void *beg, size_t size);
+
// Notify AFL about persistent mode.
static volatile char AFL_PERSISTENT[] = "##SIG_AFL_PERSISTENT##";
int __afl_persistent_loop(unsigned int);
@@ -328,45 +330,45 @@ int main(int argc, char **argv) {
__asan_poison_memory_region(__afl_fuzz_ptr, MAX_FILE);
size_t prev_length = 0;
- int num_runs = 0;
- while (__afl_persistent_loop(N)) {
+ // for speed only insert asan functions if the target is linked with asan
+ if (__asan_region_is_poisoned) {
- size_t length = *__afl_fuzz_len;
+ while (__afl_persistent_loop(N)) {
-#ifdef _DEBUG
- fprintf(stderr, "CLIENT crc: %016llx len: %u\n",
- hash64(__afl_fuzz_ptr, *__afl_fuzz_len, 0xa5b35705),
- *__afl_fuzz_len);
- fprintf(stderr, "RECV:");
- for (int i = 0; i < *__afl_fuzz_len; i++)
- fprintf(stderr, "%02x", __afl_fuzz_ptr[i]);
- fprintf(stderr, "\n");
-#endif
+ size_t length = *__afl_fuzz_len;
- if (length) {
+ if (likely(length)) {
- if (length < prev_length) {
+ if (length < prev_length) {
- __asan_poison_memory_region(__afl_fuzz_ptr + length,
- prev_length - length);
+ __asan_poison_memory_region(__afl_fuzz_ptr + length,
+ prev_length - length);
- } else {
+ } else if (length > prev_length) {
+
+ __asan_unpoison_memory_region(__afl_fuzz_ptr + prev_length,
+ length - prev_length);
- __asan_unpoison_memory_region(__afl_fuzz_ptr + prev_length,
- length - prev_length);
+ }
+
+ prev_length = length;
+ LLVMFuzzerTestOneInput(__afl_fuzz_ptr, length);
}
- prev_length = length;
+ }
- num_runs++;
- LLVMFuzzerTestOneInput(__afl_fuzz_ptr, length);
+ } else {
+
+ while (__afl_persistent_loop(N)) {
+
+ LLVMFuzzerTestOneInput(__afl_fuzz_ptr, *__afl_fuzz_len);
}
}
- printf("%s: successfully executed %d input(s)\n", argv[0], num_runs);
+ return 0;
}
--
cgit 1.4.1
From 2a0f082723c02fa19a5077985a0c56f2b4dcff2f Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 21 Jan 2022 10:14:20 +0100
Subject: code-format
---
nyx_mode/custom_harness/example.c | 211 +++++++++++++++++++++++---------------
1 file changed, 126 insertions(+), 85 deletions(-)
diff --git a/nyx_mode/custom_harness/example.c b/nyx_mode/custom_harness/example.c
index 7cfecc24..00b516a2 100644
--- a/nyx_mode/custom_harness/example.c
+++ b/nyx_mode/custom_harness/example.c
@@ -4,93 +4,134 @@
#include
#include "nyx.h"
-#define TRACE_BUFFER_SIZE (1024*64)
-
-int main(int argc, char** argv){
- /* if you want to debug code running in Nyx, hprintf() is the way to go.
- * Long story short -- it's just a guest-to-hypervisor printf. Hence the name "hprintf"
- */
- hprintf("Agent test\n");
-
- /* Request information on available (host) capabilites (optional) */
- host_config_t host_config;
- kAFL_hypercall(HYPERCALL_KAFL_GET_HOST_CONFIG, (uintptr_t)&host_config);
- hprintf("[capablities] host_config.bitmap_size: 0x%"PRIx64"\n", host_config.bitmap_size);
- hprintf("[capablities] host_config.ijon_bitmap_size: 0x%"PRIx64"\n", host_config.ijon_bitmap_size);
- hprintf("[capablities] host_config.payload_buffer_size: 0x%"PRIx64"x\n", host_config.payload_buffer_size);
-
- /* this is our "bitmap" that is later shared with the fuzzer (you can also pass the pointer of the bitmap used by compile-time instrumentations in your target) */
- uint8_t* trace_buffer = mmap(NULL, TRACE_BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
- memset(trace_buffer, 0, TRACE_BUFFER_SIZE); // makes sure that the bitmap buffer is already mapped into the guest's memory (alternatively you can use mlock) */
-
- /* Submit agent configuration */
- agent_config_t agent_config = {0};
- agent_config.agent_magic = NYX_AGENT_MAGIC;
- agent_config.agent_version = NYX_AGENT_VERSION;
- agent_config.agent_timeout_detection = 0; /* timeout detection is implemented by the agent (currently not used) */
- agent_config.agent_tracing = 1; /* set this flag to propagade that instrumentation-based fuzzing is availabe */
- agent_config.agent_ijon_tracing = 0; /* set this flag to propagade that IJON extension is implmented agent-wise */
- agent_config.trace_buffer_vaddr = (uintptr_t)trace_buffer; /* trace "bitmap" pointer - required for instrumentation-only fuzzing */
- agent_config.ijon_trace_buffer_vaddr = (uintptr_t)NULL; /* "IJON" buffer pointer */
- agent_config.agent_non_reload_mode = 1; /* non-reload mode is supported (usually because the agent implements a fork-server; currently not used) */
- agent_config.coverage_bitmap_size = TRACE_BUFFER_SIZE;
- kAFL_hypercall(HYPERCALL_KAFL_SET_AGENT_CONFIG, (uintptr_t)&agent_config);
-
- /* Tell hypervisor the virtual address of the payload (input) buffer (call mlock to ensure that this buffer stays in the guest's memory)*/
- kAFL_payload* payload_buffer = mmap(NULL, host_config.payload_buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
- mlock(payload_buffer, (size_t)host_config.payload_buffer_size);
- memset(payload_buffer, 0, host_config.payload_buffer_size);
- kAFL_hypercall(HYPERCALL_KAFL_GET_PAYLOAD, (uintptr_t)payload_buffer);
- hprintf("[init] payload buffer is mapped at %p\n", payload_buffer);
-
- /* the main fuzzing loop */
- while(1){
-
- /* Creates a root snapshot on first execution. Also we requested the next input with this hypercall */
- kAFL_hypercall(HYPERCALL_KAFL_USER_FAST_ACQUIRE, 0); // root snapshot <--
+#define TRACE_BUFFER_SIZE (1024 * 64)
+
+int main(int argc, char **argv) {
+
+ /* if you want to debug code running in Nyx, hprintf() is the way to go.
+ * Long story short -- it's just a guest-to-hypervisor printf. Hence the name
+ * "hprintf"
+ */
+ hprintf("Agent test\n");
+
+ /* Request information on available (host) capabilites (optional) */
+ host_config_t host_config;
+ kAFL_hypercall(HYPERCALL_KAFL_GET_HOST_CONFIG, (uintptr_t)&host_config);
+ hprintf("[capablities] host_config.bitmap_size: 0x%" PRIx64 "\n",
+ host_config.bitmap_size);
+ hprintf("[capablities] host_config.ijon_bitmap_size: 0x%" PRIx64 "\n",
+ host_config.ijon_bitmap_size);
+ hprintf("[capablities] host_config.payload_buffer_size: 0x%" PRIx64 "x\n",
+ host_config.payload_buffer_size);
+
+ /* this is our "bitmap" that is later shared with the fuzzer (you can also
+ * pass the pointer of the bitmap used by compile-time instrumentations in
+ * your target) */
+ uint8_t *trace_buffer = mmap(NULL, TRACE_BUFFER_SIZE, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ memset(trace_buffer, 0,
+ TRACE_BUFFER_SIZE); // makes sure that the bitmap buffer is already
+ // mapped into the guest's memory (alternatively
+ // you can use mlock) */
+
+ /* Submit agent configuration */
+ agent_config_t agent_config = {0};
+ agent_config.agent_magic = NYX_AGENT_MAGIC;
+ agent_config.agent_version = NYX_AGENT_VERSION;
+ agent_config.agent_timeout_detection =
+ 0; /* timeout detection is implemented by the agent (currently not used)
+ */
+ agent_config.agent_tracing =
+ 1; /* set this flag to propagade that instrumentation-based fuzzing is
+ availabe */
+ agent_config.agent_ijon_tracing = 0; /* set this flag to propagade that IJON
+ extension is implmented agent-wise */
+ agent_config.trace_buffer_vaddr =
+ (uintptr_t)trace_buffer; /* trace "bitmap" pointer - required for
+ instrumentation-only fuzzing */
+ agent_config.ijon_trace_buffer_vaddr =
+ (uintptr_t)NULL; /* "IJON" buffer pointer */
+ agent_config.agent_non_reload_mode =
+ 1; /* non-reload mode is supported (usually because the agent implements a
+ fork-server; currently not used) */
+ agent_config.coverage_bitmap_size = TRACE_BUFFER_SIZE;
+ kAFL_hypercall(HYPERCALL_KAFL_SET_AGENT_CONFIG, (uintptr_t)&agent_config);
+
+ /* Tell hypervisor the virtual address of the payload (input) buffer (call
+ * mlock to ensure that this buffer stays in the guest's memory)*/
+ kAFL_payload *payload_buffer =
+ mmap(NULL, host_config.payload_buffer_size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ mlock(payload_buffer, (size_t)host_config.payload_buffer_size);
+ memset(payload_buffer, 0, host_config.payload_buffer_size);
+ kAFL_hypercall(HYPERCALL_KAFL_GET_PAYLOAD, (uintptr_t)payload_buffer);
+ hprintf("[init] payload buffer is mapped at %p\n", payload_buffer);
+
+ /* the main fuzzing loop */
+ while (1) {
+
+ /* Creates a root snapshot on first execution. Also we requested the next
+ * input with this hypercall */
+ kAFL_hypercall(HYPERCALL_KAFL_USER_FAST_ACQUIRE, 0); // root snapshot <--
#ifdef DEBUG
- hprintf("Size: %ld Data: %x %x %x %x\n", payload_buffer->size,
- payload_buffer->data[4],
- payload_buffer->data[5],
- payload_buffer->data[6],
- payload_buffer->data[7]
- );
+ hprintf("Size: %ld Data: %x %x %x %x\n", payload_buffer->size,
+ payload_buffer->data[4], payload_buffer->data[5],
+ payload_buffer->data[6], payload_buffer->data[7]);
#endif
- uint32_t len = payload_buffer->size;
-
- /* set a byte to make AFL++ happy (otherwise the fuzzer might refuse to start fuzzing at all) */
- ((uint8_t*)trace_buffer)[0] = 0x1;
-
- if (len >= 4){
- /* set a byte in the bitmap to guide your fuzzer */
- ((uint8_t*)trace_buffer)[0] = 0x1;
- if (payload_buffer->data[0] == '!'){
- ((uint8_t*)trace_buffer)[1] = 0x1;
- if (payload_buffer->data[1] == 'N'){
- ((uint8_t*)trace_buffer)[2] = 0x1;
- if (payload_buffer->data[2] == 'Y'){
- ((uint8_t*)trace_buffer)[3] = 0x1;
- if (payload_buffer->data[3] == 'X'){
- ((uint8_t*)trace_buffer)[4] = 0x1;
- /* Notifiy the hypervisor and the fuzzer that a "crash" has occured. Also a string is passed by this hypercall (this is currently not supported by AFL++-Nyx) */
- kAFL_hypercall(HYPERCALL_KAFL_PANIC_EXTENDED, (uintptr_t)"Something went wrong\n");
- }
- }
- }
- }
- }
- /* this hypercall is used to notify the hypervisor and the fuzzer that a single fuzzing "execution" has finished.
- * If the reload-mode is enabled, we will jump back to our root snapshot.
- * Otherwise, the hypervisor passes control back to the guest once the bitmap buffer has been "processed" by the fuzzer.
- */
- kAFL_hypercall(HYPERCALL_KAFL_RELEASE, 0);
-
- /* This shouldn't happen if you have enabled the reload mode */
- hprintf("This should never happen :)\n");
- }
-
-
- return 0;
+ uint32_t len = payload_buffer->size;
+
+ /* set a byte to make AFL++ happy (otherwise the fuzzer might refuse to
+ * start fuzzing at all) */
+ ((uint8_t *)trace_buffer)[0] = 0x1;
+
+ if (len >= 4) {
+
+ /* set a byte in the bitmap to guide your fuzzer */
+ ((uint8_t *)trace_buffer)[0] = 0x1;
+ if (payload_buffer->data[0] == '!') {
+
+ ((uint8_t *)trace_buffer)[1] = 0x1;
+ if (payload_buffer->data[1] == 'N') {
+
+ ((uint8_t *)trace_buffer)[2] = 0x1;
+ if (payload_buffer->data[2] == 'Y') {
+
+ ((uint8_t *)trace_buffer)[3] = 0x1;
+ if (payload_buffer->data[3] == 'X') {
+
+ ((uint8_t *)trace_buffer)[4] = 0x1;
+ /* Notifiy the hypervisor and the fuzzer that a "crash" has
+ * occured. Also a string is passed by this hypercall (this is
+ * currently not supported by AFL++-Nyx) */
+ kAFL_hypercall(HYPERCALL_KAFL_PANIC_EXTENDED,
+ (uintptr_t) "Something went wrong\n");
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ /* this hypercall is used to notify the hypervisor and the fuzzer that a
+ * single fuzzing "execution" has finished. If the reload-mode is enabled,
+ * we will jump back to our root snapshot. Otherwise, the hypervisor passes
+ * control back to the guest once the bitmap buffer has been "processed" by
+ * the fuzzer.
+ */
+ kAFL_hypercall(HYPERCALL_KAFL_RELEASE, 0);
+
+ /* This shouldn't happen if you have enabled the reload mode */
+ hprintf("This should never happen :)\n");
+
+ }
+
+ return 0;
+
}
+
--
cgit 1.4.1
From 26a3d1b53b0a3ae690735c550c2985f079f3c672 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 21 Jan 2022 10:36:41 +0100
Subject: add nyx_mode to make clean target
---
GNUmakefile | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/GNUmakefile b/GNUmakefile
index 527cdcfc..9efb22c2 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -578,10 +578,12 @@ clean:
$(MAKE) -C qemu_mode/libcompcov clean
$(MAKE) -C qemu_mode/libqasan clean
-$(MAKE) -C frida_mode clean
+ rm -rf nyx_mode/packer/linux_initramfs/init.cpio.gz nyx_mode/libnyx/libnyx/target/release/* nyx_mode/QEMU-Nyx/x86_64-softmmu/qemu-system-x86_64
ifeq "$(IN_REPO)" "1"
-test -e coresight_mode/coresight-trace/Makefile && $(MAKE) -C coresight_mode/coresight-trace clean || true
-test -e qemu_mode/qemuafl/Makefile && $(MAKE) -C qemu_mode/qemuafl clean || true
- test -e unicorn_mode/unicornafl/Makefile && $(MAKE) -C unicorn_mode/unicornafl clean || true
+ -test -e unicorn_mode/unicornafl/Makefile && $(MAKE) -C unicorn_mode/unicornafl clean || true
+ -test -e nyx_mode/QEMU-Nyx/Makefile && $(MAKE) -C nyx_mode/QEMU-Nyx clean || true
else
rm -rf coresight_mode/coresight_trace
rm -rf qemu_mode/qemuafl
@@ -593,11 +595,14 @@ deepclean: clean
rm -rf coresight_mode/coresight-trace
rm -rf unicorn_mode/unicornafl
rm -rf qemu_mode/qemuafl
+ rm -rf nyx_mode/libnyx nyx_mode/packer nyx_mode/QEMU-Nyx
ifeq "$(IN_REPO)" "1"
-# NEVER EVER ACTIVATE THAT!!!!! git reset --hard >/dev/null 2>&1 || true
git checkout coresight_mode/coresight-trace
git checkout unicorn_mode/unicornafl
git checkout qemu_mode/qemuafl
+ git checkout nyx_mode/libnyx
+ git checkout nyx_mode/packer
+ git checkout nyx_mode/QEMU-Nyx
endif
.PHONY: distrib
--
cgit 1.4.1
From fce512db4067e527a4b360c8fcbc929f5a2d7bfe Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 21 Jan 2022 13:20:12 +0100
Subject: update grammar mutator
---
custom_mutators/grammar_mutator/GRAMMAR_VERSION | 2 +-
custom_mutators/grammar_mutator/grammar_mutator | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/custom_mutators/grammar_mutator/GRAMMAR_VERSION b/custom_mutators/grammar_mutator/GRAMMAR_VERSION
index 4743e7c2..93f9321c 100644
--- a/custom_mutators/grammar_mutator/GRAMMAR_VERSION
+++ b/custom_mutators/grammar_mutator/GRAMMAR_VERSION
@@ -1 +1 @@
-6ca490c
+cbe5e32
diff --git a/custom_mutators/grammar_mutator/grammar_mutator b/custom_mutators/grammar_mutator/grammar_mutator
index 6ca490c6..cbe5e327 160000
--- a/custom_mutators/grammar_mutator/grammar_mutator
+++ b/custom_mutators/grammar_mutator/grammar_mutator
@@ -1 +1 @@
-Subproject commit 6ca490c66b949db20d8c861ebc8fb2e6ca725ead
+Subproject commit cbe5e32752773945e0142fac9f1b7a0ccb5dcdff
--
cgit 1.4.1
From f7a5ea667b3a2d686a97cfec2a6e267c305d9d8b Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 21 Jan 2022 13:23:11 +0100
Subject: update changelog
---
docs/Changelog.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index bdd6c405..687232a0 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -54,6 +54,7 @@ sending a mail to .
- Prevent accidentaly killing non-afl/fuzz services when aborting
afl-showmap and other tools.
- afl-cc:
+ - detect overflow reads on initial input buffer for asan
- new cmplog mode (incompatible with older afl++ versions)
- support llvm IR select instrumentation for default PCGUARD and LTO
- fix for shared linking on MacOS
--
cgit 1.4.1
From 29235a793596b46bb014a41e3e0d90672179e52d Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Fri, 21 Jan 2022 16:18:25 +0100
Subject: Fix punctuation, formatting, and line length
---
unicorn_mode/README.md | 172 ++++++++++++++++++++++++++++---------------------
1 file changed, 97 insertions(+), 75 deletions(-)
diff --git a/unicorn_mode/README.md b/unicorn_mode/README.md
index 392a3254..559f70bc 100644
--- a/unicorn_mode/README.md
+++ b/unicorn_mode/README.md
@@ -1,74 +1,81 @@
# Unicorn-based binary-only instrumentation for afl-fuzz
-The idea and much of the original implementation comes from Nathan Voss .
+The idea and much of the original implementation comes from Nathan Voss
+.
The port to AFL++ is by Dominik Maier .
-The CompareCoverage and NeverZero counters features are by Andrea Fioraldi .
+The CompareCoverage and NeverZero counters features are by Andrea Fioraldi
+.
## 1) Introduction
-The code in ./unicorn_mode allows you to build the
+The code in [unicorn_mode/](./) allows you to build the
[Unicorn Engine](https://github.com/unicorn-engine/unicorn) with AFL++ support.
-This means, you can run anything that can be emulated in unicorn and obtain instrumentation
-output for black-box, closed-source binary code snippets. This mechanism
-can be then used by afl-fuzz to stress-test targets that couldn't be built
-with afl-cc or used in QEMU mode.
+This means, you can run anything that can be emulated in unicorn and obtain
+instrumentation output for black-box, closed-source binary code snippets. This
+mechanism can be then used by afl-fuzz to stress-test targets that couldn't be
+built with afl-cc or used in QEMU mode.
-There is a significant performance penalty compared to native AFL,
-but at least we're able to use AFL++ on these binaries, right?
+There is a significant performance penalty compared to native AFL, but at least
+we're able to use AFL++ on these binaries, right?
## 2) How to use
-First, you will need a working harness for your target in unicorn, using Python, C, or Rust.
-For some pointers for more advanced emulation, take a look at [BaseSAFE](https://github.com/fgsect/BaseSAFE) and [Qiling](https://github.com/qilingframework/qiling).
+First, you will need a working harness for your target in unicorn, using Python,
+C, or Rust.
-### Building AFL++'s Unicorn Mode
+For some pointers for more advanced emulation, take a look at
+[BaseSAFE](https://github.com/fgsect/BaseSAFE) and
+[Qiling](https://github.com/qilingframework/qiling).
-First, make AFL++ as usual.
-Once that completes successfully you need to build and add in the Unicorn Mode
-features:
+### Building AFL++'s Unicorn mode
+
+First, make AFL++ as usual. Once that completes successfully, you need to build
+and add in the Unicorn mode features:
```
cd unicorn_mode
./build_unicorn_support.sh
```
-NOTE: This script checks out a Unicorn Engine fork as submodule that has been tested
-and is stable-ish, based on the unicorn engine `next` branch.
-
-Building Unicorn will take a little bit (~5-10 minutes). Once it completes
-it automatically compiles a sample application and verifies that it works.
-
-### Fuzzing with Unicorn Mode
-
-To use unicorn-mode effectively you need to prepare the following:
-
- * Relevant binary code to be fuzzed
- * Knowledge of the memory map and good starting state
- * Folder containing sample inputs to start fuzzing with
- + Same ideas as any other AFL++ inputs
- + Quality/speed of results will depend greatly on the quality of starting
- samples
- + See AFL's guidance on how to create a sample corpus
- * Unicornafl-based test harness in Rust, C, or Python, which:
- + Adds memory map regions
- + Loads binary code into memory
- + Calls uc.afl_fuzz() / uc.afl_start_forkserver
- + Loads and verifies data to fuzz from a command-line specified file
- + AFL++ will provide mutated inputs by changing the file passed to
- the test harness
- + Presumably the data to be fuzzed is at a fixed buffer address
- + If input constraints (size, invalid bytes, etc.) are known they
- should be checked in the place_input handler. If a constraint
- fails, just return false from the handler. AFL++ will treat the input as 'uninteresting' and move on.
- + Sets up registers and memory state to start testing
- + Emulates the interesting code from beginning to end
- + If a crash is detected, the test harness must 'crash' by
- throwing a signal (SIGSEGV, SIGKILL, SIGABORT, etc.), or indicate a crash in the crash validation callback.
-
-Once you have all those things ready to go you just need to run afl-fuzz in
-'unicorn-mode' by passing in the '-U' flag:
+NOTE: This script checks out a Unicorn Engine fork as submodule that has been
+tested and is stable-ish, based on the unicorn engine `next` branch.
+
+Building Unicorn will take a little bit (~5-10 minutes). Once it completes, it
+automatically compiles a sample application and verifies that it works.
+
+### Fuzzing with Unicorn mode
+
+To use unicorn-mode effectively, you need to prepare the following:
+
+* Relevant binary code to be fuzzed
+* Knowledge of the memory map and good starting state
+* Folder containing sample inputs to start fuzzing with
+ * Same ideas as any other AFL++ inputs
+ * Quality/speed of results will depend greatly on the quality of starting
+ samples
+ * See AFL's guidance on how to create a sample corpus
+* Unicornafl-based test harness in Rust, C, or Python, which:
+ * Adds memory map regions
+ * Loads binary code into memory
+ * Calls uc.afl_fuzz() / uc.afl_start_forkserver
+ * Loads and verifies data to fuzz from a command-line specified file
+ * AFL++ will provide mutated inputs by changing the file passed to the
+ test harness
+ * Presumably the data to be fuzzed is at a fixed buffer address
+ * If input constraints (size, invalid bytes, etc.) are known, they
+ should be checked in the place_input handler. If a constraint fails,
+ just return false from the handler. AFL++ will treat the input as
+ 'uninteresting' and move on.
+ * Sets up registers and memory state to start testing
+ * Emulates the interesting code from beginning to end
+ * If a crash is detected, the test harness must 'crash' by throwing a signal
+ (SIGSEGV, SIGKILL, SIGABORT, etc.), or indicate a crash in the crash
+ validation callback.
+
+Once you have all those things ready to go, you just need to run afl-fuzz in
+`unicorn-mode` by passing in the `-U` flag:
```
afl-fuzz -U -m none -i /path/to/inputs -o /path/to/results -- ./test_harness @@
@@ -78,39 +85,44 @@ The normal afl-fuzz command line format applies to everything here. Refer to
AFL's main documentation for more info about how to use afl-fuzz effectively.
For a much clearer vision of what all of this looks like, refer to the sample
-provided in the 'unicorn_mode/samples' directory. There is also a blog post that
-uses slightly older concepts, but describes the general ideas, at:
+provided in the [samples/](./samples/) directory. There is also a
+blog post that uses slightly older concepts, but describes the general ideas,
+at:
[https://medium.com/@njvoss299/afl-unicorn-fuzzing-arbitrary-binary-code-563ca28936bf](https://medium.com/@njvoss299/afl-unicorn-fuzzing-arbitrary-binary-code-563ca28936bf)
-The ['helper_scripts'](./helper_scripts) directory also contains several helper scripts that allow you
-to dump context from a running process, load it, and hook heap allocations. For details
-on how to use this check out the follow-up blog post to the one linked above.
+The [helper_scripts/](./helper_scripts/) directory also contains several helper
+scripts that allow you to dump context from a running process, load it, and hook
+heap allocations. For details on how to use this, check out the follow-up blog
+post to the one linked above.
A example use of AFL-Unicorn mode is discussed in the paper Unicorefuzz:
[https://www.usenix.org/conference/woot19/presentation/maier](https://www.usenix.org/conference/woot19/presentation/maier)
## 3) Options
-As for the QEMU-based instrumentation, unicornafl comes with a sub-instruction based instrumentation similar in purpose to laf-intel.
+As for the QEMU-based instrumentation, unicornafl comes with a sub-instruction
+based instrumentation similar in purpose to laf-intel.
-The options that enable Unicorn CompareCoverage are the same used for QEMU.
-This will split up each multi-byte compare to give feedback for each correct byte.
-`AFL_COMPCOV_LEVEL=1` is to instrument comparisons with only immediate values.
+The options that enable Unicorn CompareCoverage are the same used for QEMU. This
+will split up each multi-byte compare to give feedback for each correct byte:
-`AFL_COMPCOV_LEVEL=2` instruments all comparison instructions.
+* `AFL_COMPCOV_LEVEL=1` to instrument comparisons with only immediate values.
+* `AFL_COMPCOV_LEVEL=2` to instrument all comparison instructions.
-Comparison instructions are currently instrumented only for the x86, x86_64 and ARM targets.
+Comparison instructions are currently instrumented only for the x86, x86_64, and
+ARM targets.
## 4) Gotchas, feedback, bugs
Running the build script builds unicornafl and its Python bindings and installs
-them on your system.
-This installation will leave any existing Unicorn installations untouched.
-If you want to use unicornafl instead of unicorn in a script,
-replace all `unicorn` imports with `unicornafl` inputs, everything else should "just work".
-If you use 3rd party code depending on unicorn, you can use unicornafl monkeypatching:
-Before importing anything that depends on unicorn, do:
+them on your system. This installation will leave any existing Unicorn
+installations untouched.
+
+If you want to use unicornafl instead of unicorn in a script, replace all
+`unicorn` imports with `unicornafl` inputs, everything else should "just work".
+If you use 3rd party code depending on unicorn, you can use unicornafl
+monkeypatching. Before importing anything that depends on unicorn, do:
```python
import unicornafl
@@ -121,18 +133,28 @@ This will replace all unicorn imports with unicornafl inputs.
## 5) Examples
-Apart from reading the documentation in `afl.c` and the Python bindings of unicornafl, the best documentation are the [samples/](./samples).
+Apart from reading the documentation in `afl.c` and the Python bindings of
+unicornafl, the best documentation are the [samples/](./samples).
+
The following examples exist at the time of writing:
- c: A simple example on how to use the C bindings
-- compcov_x64: A Python example that uses compcov to traverse hard-to-reach blocks
-- persistent: A C example using persistent mode for maximum speed, and resetting the target state between each iteration
+- compcov_x64: A Python example that uses compcov to traverse hard-to-reach
+ blocks
+- persistent: A C example using persistent mode for maximum speed, and resetting
+ the target state between each iteration
- simple: A simple Python example
-- speedtest/c: The C harness for an example target, used to compare C, Python, and Rust bindings and fix speed issues
+- speedtest/c: The C harness for an example target, used to compare C, Python,
+ and Rust bindings and fix speed issues
- speedtest/python: Fuzzing the same target in Python
- speedtest/rust: Fuzzing the same target using a Rust harness
-Usually, the place to look at is the `harness` in each folder. The source code in each harness is pretty well documented.
-Most harnesses also have the `afl-fuzz` commandline, or even offer a `make fuzz` Makefile target.
-Targets in these folders, if x86, can usually be made using `make target` in each folder or get shipped pre-built (plus their source).
-Especially take a look at the [speedtest documentation](./samples/speedtest/README.md) to see how the languages compare.
\ No newline at end of file
+Usually, the place to look at is the `harness` in each folder. The source code
+in each harness is pretty well documented. Most harnesses also have the
+`afl-fuzz` commandline, or even offer a `make fuzz` Makefile target. Targets in
+these folders, if x86, can usually be made using `make target` in each folder or
+get shipped pre-built (plus their source).
+
+Especially take a look at the
+[speedtest documentation](./samples/speedtest/README.md) to see how the
+languages compare.
\ No newline at end of file
--
cgit 1.4.1
From f63d2b0f55f09cbd90be2532ff5f2da71c7a0260 Mon Sep 17 00:00:00 2001
From: llzmb <46303940+llzmb@users.noreply.github.com>
Date: Fri, 21 Jan 2022 16:27:17 +0100
Subject: Fix typo, add link
---
unicorn_mode/README.md | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/unicorn_mode/README.md b/unicorn_mode/README.md
index 559f70bc..ce87a2e9 100644
--- a/unicorn_mode/README.md
+++ b/unicorn_mode/README.md
@@ -85,18 +85,19 @@ The normal afl-fuzz command line format applies to everything here. Refer to
AFL's main documentation for more info about how to use afl-fuzz effectively.
For a much clearer vision of what all of this looks like, refer to the sample
-provided in the [samples/](./samples/) directory. There is also a
-blog post that uses slightly older concepts, but describes the general ideas,
-at:
+provided in the [samples/](./samples/) directory. There is also a blog post that
+uses slightly older concepts, but describes the general ideas, at:
[https://medium.com/@njvoss299/afl-unicorn-fuzzing-arbitrary-binary-code-563ca28936bf](https://medium.com/@njvoss299/afl-unicorn-fuzzing-arbitrary-binary-code-563ca28936bf)
The [helper_scripts/](./helper_scripts/) directory also contains several helper
scripts that allow you to dump context from a running process, load it, and hook
heap allocations. For details on how to use this, check out the follow-up blog
-post to the one linked above.
+post to the one linked above:
-A example use of AFL-Unicorn mode is discussed in the paper Unicorefuzz:
+[https://hackernoon.com/afl-unicorn-part-2-fuzzing-the-unfuzzable-bea8de3540a5](https://hackernoon.com/afl-unicorn-part-2-fuzzing-the-unfuzzable-bea8de3540a5)
+
+An example use of AFL-Unicorn mode is discussed in the paper Unicorefuzz:
[https://www.usenix.org/conference/woot19/presentation/maier](https://www.usenix.org/conference/woot19/presentation/maier)
## 3) Options
--
cgit 1.4.1
From 0090b3a3f01cad64a0d27c064d00eb87aa68ffef Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Fri, 21 Jan 2022 21:03:07 +0100
Subject: update Nyx submodules
---
nyx_mode/LIBNYX_VERSION | 2 +-
nyx_mode/QEMU-Nyx | 2 +-
nyx_mode/QEMU_NYX_VERSION | 2 +-
nyx_mode/libnyx | 2 +-
nyx_mode/packer | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/nyx_mode/LIBNYX_VERSION b/nyx_mode/LIBNYX_VERSION
index 109c3c6f..b45b4e90 100644
--- a/nyx_mode/LIBNYX_VERSION
+++ b/nyx_mode/LIBNYX_VERSION
@@ -1 +1 @@
-a5ae4c1
+2e45754
diff --git a/nyx_mode/QEMU-Nyx b/nyx_mode/QEMU-Nyx
index d5a7011a..c2c69cfc 160000
--- a/nyx_mode/QEMU-Nyx
+++ b/nyx_mode/QEMU-Nyx
@@ -1 +1 @@
-Subproject commit d5a7011ad20ba5ba91f1371f9d40154035d5d768
+Subproject commit c2c69cfc528398d9db9363b92f8c50db4008c98f
diff --git a/nyx_mode/QEMU_NYX_VERSION b/nyx_mode/QEMU_NYX_VERSION
index 96133165..be13a784 100644
--- a/nyx_mode/QEMU_NYX_VERSION
+++ b/nyx_mode/QEMU_NYX_VERSION
@@ -1 +1 @@
-902306beb0
+c2c69cfc52
diff --git a/nyx_mode/libnyx b/nyx_mode/libnyx
index ecbcb2d7..2e45754e 160000
--- a/nyx_mode/libnyx
+++ b/nyx_mode/libnyx
@@ -1 +1 @@
-Subproject commit ecbcb2d7234fef0b5e1db8ca6019e6137ee0582d
+Subproject commit 2e45754e271463f446c31a6f467231d8657910e8
diff --git a/nyx_mode/packer b/nyx_mode/packer
index f91742ce..8842549b 160000
--- a/nyx_mode/packer
+++ b/nyx_mode/packer
@@ -1 +1 @@
-Subproject commit f91742ce6c51eee133b5675edd68f39202785db1
+Subproject commit 8842549b5612a890258dcef812276cfdb62b76c7
--
cgit 1.4.1
From 06ee6b1986dc83c65e67d827a4fdecc70942f4d1 Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Fri, 21 Jan 2022 21:07:28 +0100
Subject: update Nyx custom harness: use a coverage bitmap that is smaller than
64k
---
nyx_mode/custom_harness/example.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/nyx_mode/custom_harness/example.c b/nyx_mode/custom_harness/example.c
index 00b516a2..dd268534 100644
--- a/nyx_mode/custom_harness/example.c
+++ b/nyx_mode/custom_harness/example.c
@@ -4,7 +4,10 @@
#include
#include "nyx.h"
-#define TRACE_BUFFER_SIZE (1024 * 64)
+#define TRACE_BUFFER_SIZE (64)
+
+#define PAGE_SIZE 0x1000
+#define MMAP_SIZE(x) ((x & ~(PAGE_SIZE-1)) + PAGE_SIZE)
int main(int argc, char **argv) {
@@ -27,8 +30,8 @@ int main(int argc, char **argv) {
/* this is our "bitmap" that is later shared with the fuzzer (you can also
* pass the pointer of the bitmap used by compile-time instrumentations in
* your target) */
- uint8_t *trace_buffer = mmap(NULL, TRACE_BUFFER_SIZE, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ uint8_t *trace_buffer = mmap(NULL, MMAP_SIZE(TRACE_BUFFER_SIZE), PROT_READ |
+ PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
memset(trace_buffer, 0,
TRACE_BUFFER_SIZE); // makes sure that the bitmap buffer is already
// mapped into the guest's memory (alternatively
--
cgit 1.4.1
From 3609912f41ec5d639719bfdd2770e09cf3932bf9 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sat, 22 Jan 2022 10:31:50 +0100
Subject: new logo
---
README.md | 2 +-
nyx_mode/QEMU-Nyx | 2 +-
nyx_mode/libnyx | 2 +-
nyx_mode/packer | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 966e8036..ccef6e30 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# American Fuzzy Lop plus plus (AFL++)
-
+
Release version: [3.14c](https://github.com/AFLplusplus/AFLplusplus/releases)
diff --git a/nyx_mode/QEMU-Nyx b/nyx_mode/QEMU-Nyx
index c2c69cfc..d5a7011a 160000
--- a/nyx_mode/QEMU-Nyx
+++ b/nyx_mode/QEMU-Nyx
@@ -1 +1 @@
-Subproject commit c2c69cfc528398d9db9363b92f8c50db4008c98f
+Subproject commit d5a7011ad20ba5ba91f1371f9d40154035d5d768
diff --git a/nyx_mode/libnyx b/nyx_mode/libnyx
index 2e45754e..ecbcb2d7 160000
--- a/nyx_mode/libnyx
+++ b/nyx_mode/libnyx
@@ -1 +1 @@
-Subproject commit 2e45754e271463f446c31a6f467231d8657910e8
+Subproject commit ecbcb2d7234fef0b5e1db8ca6019e6137ee0582d
diff --git a/nyx_mode/packer b/nyx_mode/packer
index 8842549b..f91742ce 160000
--- a/nyx_mode/packer
+++ b/nyx_mode/packer
@@ -1 +1 @@
-Subproject commit 8842549b5612a890258dcef812276cfdb62b76c7
+Subproject commit f91742ce6c51eee133b5675edd68f39202785db1
--
cgit 1.4.1
From ac169c30874251e3dcd74f9ce4b43a7d26435cdd Mon Sep 17 00:00:00 2001
From: Dominik Maier
Date: Sat, 22 Jan 2022 17:22:00 +0100
Subject: fix makefiles for uc2 c examples
---
custom_mutators/grammar_mutator/grammar_mutator | 2 +-
unicorn_mode/samples/c/Makefile | 39 ++--
unicorn_mode/samples/c/harness.c | 5 +-
unicorn_mode/samples/persistent/Makefile | 38 ++--
unicorn_mode/samples/persistent/harness.c | 1 +
unicorn_mode/samples/python_simple/COMPILE.md | 40 ++++
.../python_simple/sample_inputs/sample1.bin | 1 +
.../python_simple/sample_inputs/sample2.bin | Bin 0 -> 1 bytes
.../python_simple/sample_inputs/sample3.bin | 1 +
.../python_simple/sample_inputs/sample4.bin | 1 +
.../python_simple/sample_inputs/sample5.bin | 1 +
.../samples/python_simple/simple_target.bin | Bin 0 -> 256 bytes
unicorn_mode/samples/python_simple/simple_target.c | 31 +++
.../samples/python_simple/simple_test_harness.py | 163 +++++++++++++++
.../python_simple/simple_test_harness_alt.py | 223 +++++++++++++++++++++
unicorn_mode/samples/simple/COMPILE.md | 40 ----
.../samples/simple/sample_inputs/sample1.bin | 1 -
.../samples/simple/sample_inputs/sample2.bin | Bin 1 -> 0 bytes
.../samples/simple/sample_inputs/sample3.bin | 1 -
.../samples/simple/sample_inputs/sample4.bin | 1 -
.../samples/simple/sample_inputs/sample5.bin | 1 -
unicorn_mode/samples/simple/simple_target.bin | Bin 256 -> 0 bytes
unicorn_mode/samples/simple/simple_target.c | 31 ---
unicorn_mode/samples/simple/simple_test_harness.py | 163 ---------------
.../samples/simple/simple_test_harness_alt.py | 223 ---------------------
unicorn_mode/samples/speedtest/c/Makefile | 36 ++--
unicorn_mode/samples/speedtest/c/harness.c | 5 +-
27 files changed, 530 insertions(+), 518 deletions(-)
create mode 100644 unicorn_mode/samples/python_simple/COMPILE.md
create mode 100644 unicorn_mode/samples/python_simple/sample_inputs/sample1.bin
create mode 100644 unicorn_mode/samples/python_simple/sample_inputs/sample2.bin
create mode 100644 unicorn_mode/samples/python_simple/sample_inputs/sample3.bin
create mode 100644 unicorn_mode/samples/python_simple/sample_inputs/sample4.bin
create mode 100644 unicorn_mode/samples/python_simple/sample_inputs/sample5.bin
create mode 100644 unicorn_mode/samples/python_simple/simple_target.bin
create mode 100644 unicorn_mode/samples/python_simple/simple_target.c
create mode 100644 unicorn_mode/samples/python_simple/simple_test_harness.py
create mode 100644 unicorn_mode/samples/python_simple/simple_test_harness_alt.py
delete mode 100644 unicorn_mode/samples/simple/COMPILE.md
delete mode 100644 unicorn_mode/samples/simple/sample_inputs/sample1.bin
delete mode 100644 unicorn_mode/samples/simple/sample_inputs/sample2.bin
delete mode 100644 unicorn_mode/samples/simple/sample_inputs/sample3.bin
delete mode 100644 unicorn_mode/samples/simple/sample_inputs/sample4.bin
delete mode 100644 unicorn_mode/samples/simple/sample_inputs/sample5.bin
delete mode 100644 unicorn_mode/samples/simple/simple_target.bin
delete mode 100644 unicorn_mode/samples/simple/simple_target.c
delete mode 100644 unicorn_mode/samples/simple/simple_test_harness.py
delete mode 100644 unicorn_mode/samples/simple/simple_test_harness_alt.py
diff --git a/custom_mutators/grammar_mutator/grammar_mutator b/custom_mutators/grammar_mutator/grammar_mutator
index cbe5e327..6ca490c6 160000
--- a/custom_mutators/grammar_mutator/grammar_mutator
+++ b/custom_mutators/grammar_mutator/grammar_mutator
@@ -1 +1 @@
-Subproject commit cbe5e32752773945e0142fac9f1b7a0ccb5dcdff
+Subproject commit 6ca490c66b949db20d8c861ebc8fb2e6ca725ead
diff --git a/unicorn_mode/samples/c/Makefile b/unicorn_mode/samples/c/Makefile
index cb491e10..fd6dbe77 100644
--- a/unicorn_mode/samples/c/Makefile
+++ b/unicorn_mode/samples/c/Makefile
@@ -4,29 +4,28 @@
.POSIX:
UNAME_S =$(shell uname -s)# GNU make
UNAME_S:sh=uname -s # BSD make
-_UNIQ=_QINU_
-LIBDIR = ../../unicornafl
+UNICORNAFL_LIB = ../../unicornafl/build
+UNICORN_LIB = ../../unicornafl/unicorn/build
BIN_EXT =
AR_EXT = a
# Verbose output?
V ?= 0
-CFLAGS += -Wall -Werror -I../../unicornafl/include
+CFLAGS += -Wall -Werror -I../../unicornafl/unicorn/include -I../../unicornafl/include
-LDFLAGS += -L$(LIBDIR) -lpthread -lm
+LDFLAGS += -L$(UNICORNAFL_LIB) -L$(UNICORN_LIB) -lpthread -lm -lunicornafl -lunicorn -lc++
-_LRT = $(_UNIQ)$(UNAME_S:Linux=)
-__LRT = $(_LRT:$(_UNIQ)=-lrt)
-LRT = $(__LRT:$(_UNIQ)=)
+ifeq ($(UNAME), Linux)
+# do something Linux-y
+LRT = -lrt
+else
+LRT =
+endif
LDFLAGS += $(LRT)
-_CC = $(_UNIQ)$(CROSS)
-__CC = $(_CC:$(_UNIQ)=$(CC))
-MYCC = $(__CC:$(_UNIQ)$(CROSS)=$(CROSS)gcc)
-
.PHONY: all clean
all: harness
@@ -34,14 +33,20 @@ all: harness
clean:
rm -rf *.o harness harness-debug
-harness.o: harness.c ../../unicornafl/include/unicorn/*.h
- ${MYCC} ${CFLAGS} -O3 -c harness.c
+harness.o: harness.c ../../unicornafl/unicorn/include/unicorn/*.h
+ ${CC} ${CFLAGS} -O3 -c harness.c
+
+harness-debug.o: harness.c ../../unicornafl/unicorn/include/unicorn/*.h
+ ${CC} ${CFLAGS} -g -c harness.c -o $@
-harness-debug.o: harness.c ../../unicornafl/include/unicorn/*.h
- ${MYCC} ${CFLAGS} -g -c harness.c -o $@
+../../unicornafl/build/libunicornafl.a:
+ cd ../.. && ./build_unicorn_support.sh
harness: harness.o
- ${MYCC} -L${LIBDIR} harness.o ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@
+ ${CC} harness.o ../../unicornafl/build/libunicornafl.a $(LDFLAGS) -o $@
debug: harness-debug.o
- ${MYCC} -L${LIBDIR} harness.o ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug
+ ${CC} harness.o ../../unicornafl/build/libunicornafl.a $(LDFLAGS) -o harness-debug
+
+fuzz: harness
+ DYLD_FALLBACK_LIBRARY_PATH="../../unicornafl/unicorn/build" LD_LIBRARY_PATH="../../unicornafl/unicorn/build" ../../../afl-fuzz -m none -i sample_inputs -o out -- ./harness @@
diff --git a/unicorn_mode/samples/c/harness.c b/unicorn_mode/samples/c/harness.c
index 4bda6e2d..3a93aeaa 100644
--- a/unicorn_mode/samples/c/harness.c
+++ b/unicorn_mode/samples/c/harness.c
@@ -26,6 +26,7 @@
#include
#include
+#include
// Path to the file containing the binary to emulate
#define BINARY_FILE ("persistent_target_x86_64")
@@ -141,7 +142,7 @@ static void mem_map_checked(uc_engine *uc, uint64_t addr, size_t size, uint32_t
//printf("SIZE %llx, align: %llx\n", size, ALIGNMENT);
uc_err err = uc_mem_map(uc, addr, size, mode);
if (err != UC_ERR_OK) {
- printf("Error mapping %ld bytes at 0x%lx: %s (mode: %d)\n", size, addr, uc_strerror(err), mode);
+ printf("Error mapping %ld bytes at 0x%llx: %s (mode: %d)\n", size, (unsigned long long) addr, uc_strerror(err), (int) mode);
exit(1);
}
}
@@ -184,7 +185,7 @@ int main(int argc, char **argv, char **envp) {
// Map memory.
mem_map_checked(uc, BASE_ADDRESS, len, UC_PROT_ALL);
- printf("Len: %lx\n", len);
+ printf("Len: %lx\n", (unsigned long) len);
fflush(stdout);
// write machine code to be emulated to memory
diff --git a/unicorn_mode/samples/persistent/Makefile b/unicorn_mode/samples/persistent/Makefile
index 80a47550..35584416 100644
--- a/unicorn_mode/samples/persistent/Makefile
+++ b/unicorn_mode/samples/persistent/Makefile
@@ -4,29 +4,28 @@
.POSIX:
UNAME_S =$(shell uname -s)# GNU make
UNAME_S:sh=uname -s # BSD make
-_UNIQ=_QINU_
-LIBDIR = ../../unicornafl
+UNICORNAFL_LIB = ../../unicornafl/build
+UNICORN_LIB = ../../unicornafl/unicorn/build
BIN_EXT =
AR_EXT = a
# Verbose output?
V ?= 0
-CFLAGS += -Wall -Werror -I../../unicornafl/include
+CFLAGS += -Wall -Werror -I../../unicornafl/unicorn/include -I../../unicornafl/include
-LDFLAGS += -L$(LIBDIR) -lpthread -lm
+LDFLAGS += -L$(UNICORNAFL_LIB) -L$(UNICORN_LIB) -lpthread -lm -lunicornafl -lunicorn -lc++
-_LRT = $(_UNIQ)$(UNAME_S)
-__LRT = $(_LRT:$(_UNIQ)Linux=-lrt)
-LRT = $(__LRT:$(_UNIQ)$(UNAME_S)=)
+ifeq ($(UNAME), Linux)
+# do something Linux-y
+LRT = -lrt
+else
+LRT =
+endif
LDFLAGS += $(LRT)
-_CC = $(_UNIQ)$(CROSS)
-__CC = $(_CC:$(_UNIQ)=$(CC))
-MYCC = $(__CC:$(_UNIQ)$(CROSS)=$(CROSS)gcc)
-
.PHONY: all clean
all: harness
@@ -34,20 +33,23 @@ all: harness
clean:
rm -rf *.o harness harness-debug
-harness.o: harness.c ../../unicornafl/include/unicorn/*.h
- ${MYCC} ${CFLAGS} -O3 -c harness.c
+harness.o: harness.c ../../unicornafl/unicorn/include/unicorn/*.h
+ ${CC} ${CFLAGS} -O3 -c harness.c
-harness-debug.o: harness.c ../../unicornafl/include/unicorn/*.h
- ${MYCC} ${CFLAGS} -DAFL_DEBUG=1 -g -c harness.c -o $@
+harness-debug.o: harness.c ../../unicornafl/unicorn/include/unicorn/*.h
+ ${CC} ${CFLAGS} -DAFL_DEBUG=1 -g -c harness.c -o $@
harness: harness.o
- ${MYCC} -L${LIBDIR} harness.o ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@
+ ${CC} harness.o ../../unicornafl/build/libunicornafl.a $(LDFLAGS) -o $@
debug: harness-debug.o
- ${MYCC} -L${LIBDIR} harness-debug.o ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug
+ ${CC} harness-debug.o ../../unicornafl/build/libunicornafl.a $(LDFLAGS) -o harness-debug
+
+../../unicornafl/build/libunicornafl.a:
+ cd ../.. && ./build_unicorn_support.sh
fuzz: harness
- ../../../afl-fuzz -m none -i sample_inputs -o out -- ./harness @@
+ DYLD_FALLBACK_LIBRARY_PATH="../../unicornafl/unicorn/build" LD_LIBRARY_PATH="../../unicornafl/unicorn/build" ../../../afl-fuzz -m none -i sample_inputs -o out -- ./harness @@
debugmake:
@echo UNAME_S=$(UNAME_S), _LRT=$(_LRT), __LRT=$(__LRT), LRT=$(LRT)
diff --git a/unicorn_mode/samples/persistent/harness.c b/unicorn_mode/samples/persistent/harness.c
index eae3f1fc..37b652e0 100644
--- a/unicorn_mode/samples/persistent/harness.c
+++ b/unicorn_mode/samples/persistent/harness.c
@@ -30,6 +30,7 @@
#include
#include
+#include
// Path to the file containing the binary to emulate
#define BINARY_FILE ("persistent_target_x86_64")
diff --git a/unicorn_mode/samples/python_simple/COMPILE.md b/unicorn_mode/samples/python_simple/COMPILE.md
new file mode 100644
index 00000000..f7bf5b50
--- /dev/null
+++ b/unicorn_mode/samples/python_simple/COMPILE.md
@@ -0,0 +1,40 @@
+# Compiling simple_target.c
+
+You shouldn't need to compile simple_target.c since a MIPS binary version is
+pre-built and shipped with afl-unicorn. This file documents how the binary
+was built in case you want to rebuild it or recompile it for any reason.
+
+The pre-built binary (simple_target.bin) was built by cross-compiling
+simple_target.c for MIPS using the mips-linux-gnu-gcc package on an Ubuntu
+16.04 LTS system. This cross compiler (and associated binutils) was installed
+from apt-get packages:
+
+```
+sudo apt-get install gcc-mips-linux-gnu
+```
+
+simple_target.c was compiled without optimization, position-independent,
+and without standard libraries using the following command line:
+
+```
+mips-linux-gnu-gcc -o simple_target.elf simple_target.c -fPIC -O0 -nostdlib
+```
+
+The .text section from the resulting ELF binary was then extracted to create
+the raw binary blob that is loaded and emulated by simple_test_harness.py:
+
+```
+mips-linux-gnu-objcopy -O binary --only-section=.text simple_target.elf simple_target.bin
+```
+
+In summary, to recreate simple_taget.bin execute the following:
+
+```
+mips-linux-gnu-gcc -o simple_target.elf simple_target.c -fPIC -O0 -nostdlib
+ && mips-linux-gnu-objcopy -O binary --only-section=.text simple_target.elf simple_target.bin
+ && rm simple_target.elf
+```
+
+Note that the output of this is padded with nulls for 16-byte alignment. This is
+important when emulating it, as NOPs will be added after the return of main()
+as necessary.
diff --git a/unicorn_mode/samples/python_simple/sample_inputs/sample1.bin b/unicorn_mode/samples/python_simple/sample_inputs/sample1.bin
new file mode 100644
index 00000000..85df5078
--- /dev/null
+++ b/unicorn_mode/samples/python_simple/sample_inputs/sample1.bin
@@ -0,0 +1 @@
+abcd
\ No newline at end of file
diff --git a/unicorn_mode/samples/python_simple/sample_inputs/sample2.bin b/unicorn_mode/samples/python_simple/sample_inputs/sample2.bin
new file mode 100644
index 00000000..f76dd238
Binary files /dev/null and b/unicorn_mode/samples/python_simple/sample_inputs/sample2.bin differ
diff --git a/unicorn_mode/samples/python_simple/sample_inputs/sample3.bin b/unicorn_mode/samples/python_simple/sample_inputs/sample3.bin
new file mode 100644
index 00000000..6b2aaa76
--- /dev/null
+++ b/unicorn_mode/samples/python_simple/sample_inputs/sample3.bin
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/unicorn_mode/samples/python_simple/sample_inputs/sample4.bin b/unicorn_mode/samples/python_simple/sample_inputs/sample4.bin
new file mode 100644
index 00000000..71bd63e6
--- /dev/null
+++ b/unicorn_mode/samples/python_simple/sample_inputs/sample4.bin
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/unicorn_mode/samples/python_simple/sample_inputs/sample5.bin b/unicorn_mode/samples/python_simple/sample_inputs/sample5.bin
new file mode 100644
index 00000000..aed2973e
--- /dev/null
+++ b/unicorn_mode/samples/python_simple/sample_inputs/sample5.bin
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/unicorn_mode/samples/python_simple/simple_target.bin b/unicorn_mode/samples/python_simple/simple_target.bin
new file mode 100644
index 00000000..0095eb6c
Binary files /dev/null and b/unicorn_mode/samples/python_simple/simple_target.bin differ
diff --git a/unicorn_mode/samples/python_simple/simple_target.c b/unicorn_mode/samples/python_simple/simple_target.c
new file mode 100644
index 00000000..49e1b4d8
--- /dev/null
+++ b/unicorn_mode/samples/python_simple/simple_target.c
@@ -0,0 +1,31 @@
+/*
+ * Sample target file to test afl-unicorn fuzzing capabilities.
+ * This is a very trivial example that will crash pretty easily
+ * in several different exciting ways.
+ *
+ * Input is assumed to come from a buffer located at DATA_ADDRESS
+ * (0x00300000), so make sure that your Unicorn emulation of this
+ * puts user data there.
+ *
+ * Written by Nathan Voss
+ */
+
+// Magic address where mutated data will be placed
+#define DATA_ADDRESS 0x00300000
+
+int main(void) {
+ unsigned char *data_buf = (unsigned char *) DATA_ADDRESS;
+
+ if (data_buf[20] != 0) {
+ // Cause an 'invalid read' crash if data[0..3] == '\x01\x02\x03\x04'
+ unsigned char invalid_read = *(unsigned char *) 0x00000000;
+ } else if (data_buf[0] > 0x10 && data_buf[0] < 0x20 && data_buf[1] > data_buf[2]) {
+ // Cause an 'invalid read' crash if (0x10 < data[0] < 0x20) and data[1] > data[2]
+ unsigned char invalid_read = *(unsigned char *) 0x00000000;
+ } else if (data_buf[9] == 0x00 && data_buf[10] != 0x00 && data_buf[11] == 0x00) {
+ // Cause a crash if data[10] is not zero, but [9] and [11] are zero
+ unsigned char invalid_read = *(unsigned char *) 0x00000000;
+ }
+
+ return 0;
+}
diff --git a/unicorn_mode/samples/python_simple/simple_test_harness.py b/unicorn_mode/samples/python_simple/simple_test_harness.py
new file mode 100644
index 00000000..cd04ad3a
--- /dev/null
+++ b/unicorn_mode/samples/python_simple/simple_test_harness.py
@@ -0,0 +1,163 @@
+#!/usr/bin/env python3
+"""
+ Simple test harness for AFL's Unicorn Mode.
+
+ This loads the simple_target.bin binary (precompiled as MIPS code) into
+ Unicorn's memory map for emulation, places the specified input into
+ simple_target's buffer (hardcoded to be at 0x300000), and executes 'main()'.
+ If any crashes occur during emulation, unicornafl will
+ tell AFL that a crash occurred.
+
+ Run under AFL as follows:
+
+ $ cd /unicorn_mode/samples/simple/
+ $ ../../../afl-fuzz -U -m none -i ./sample_inputs -o ./output -- python simple_test_harness.py @@
+"""
+
+import argparse
+import os
+import signal
+
+from unicornafl import *
+from unicornafl.mips_const import *
+
+# Path to the file containing the binary to emulate
+BINARY_FILE = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)), "simple_target.bin"
+)
+
+# Memory map for the code to be tested
+CODE_ADDRESS = 0x00100000 # Arbitrary address where code to test will be loaded
+CODE_SIZE_MAX = 0x00010000 # Max size for the code (64kb)
+STACK_ADDRESS = 0x00200000 # Address of the stack (arbitrarily chosen)
+STACK_SIZE = 0x00010000 # Size of the stack (arbitrarily chosen)
+DATA_ADDRESS = 0x00300000 # Address where mutated data will be placed
+DATA_SIZE_MAX = 0x00010000 # Maximum allowable size of mutated data
+
+try:
+ # If Capstone is installed then we'll dump disassembly, otherwise just dump the binary.
+ from capstone import *
+
+ cs = Cs(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN)
+
+ def unicorn_debug_instruction(uc, address, size, user_data):
+ mem = uc.mem_read(address, size)
+ for (cs_address, cs_size, cs_mnemonic, cs_opstr) in cs.disasm_lite(
+ bytes(mem), size
+ ):
+ print(" Instr: {:#016x}:\t{}\t{}".format(address, cs_mnemonic, cs_opstr))
+
+
+except ImportError:
+
+ def unicorn_debug_instruction(uc, address, size, user_data):
+ print(" Instr: addr=0x{0:016x}, size=0x{1:016x}".format(address, size))
+
+
+def unicorn_debug_block(uc, address, size, user_data):
+ print("Basic Block: addr=0x{0:016x}, size=0x{1:016x}".format(address, size))
+
+
+def unicorn_debug_mem_access(uc, access, address, size, value, user_data):
+ if access == UC_MEM_WRITE:
+ print(
+ " >>> Write: addr=0x{0:016x} size={1} data=0x{2:016x}".format(
+ address, size, value
+ )
+ )
+ else:
+ print(" >>> Read: addr=0x{0:016x} size={1}".format(address, size))
+
+
+def unicorn_debug_mem_invalid_access(uc, access, address, size, value, user_data):
+ if access == UC_MEM_WRITE_UNMAPPED:
+ print(
+ " >>> INVALID Write: addr=0x{0:016x} size={1} data=0x{2:016x}".format(
+ address, size, value
+ )
+ )
+ else:
+ print(
+ " >>> INVALID Read: addr=0x{0:016x} size={1}".format(address, size)
+ )
+
+
+def main():
+
+ parser = argparse.ArgumentParser(description="Test harness for simple_target.bin")
+ parser.add_argument(
+ "input_file",
+ type=str,
+ help="Path to the file containing the mutated input to load",
+ )
+ parser.add_argument(
+ "-t",
+ "--trace",
+ default=False,
+ action="store_true",
+ help="Enables debug tracing",
+ )
+ args = parser.parse_args()
+
+ # Instantiate a MIPS32 big endian Unicorn Engine instance
+ uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN)
+
+ if args.trace:
+ uc.hook_add(UC_HOOK_BLOCK, unicorn_debug_block)
+ uc.hook_add(UC_HOOK_CODE, unicorn_debug_instruction)
+ uc.hook_add(UC_HOOK_MEM_WRITE | UC_HOOK_MEM_READ, unicorn_debug_mem_access)
+ uc.hook_add(
+ UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_READ_INVALID,
+ unicorn_debug_mem_invalid_access,
+ )
+
+ # ---------------------------------------------------
+ # Load the binary to emulate and map it into memory
+
+ print("Loading data input from {}".format(args.input_file))
+ binary_file = open(BINARY_FILE, "rb")
+ binary_code = binary_file.read()
+ binary_file.close()
+
+ # Apply constraints to the mutated input
+ if len(binary_code) > CODE_SIZE_MAX:
+ print("Binary code is too large (> {} bytes)".format(CODE_SIZE_MAX))
+ return
+
+ # Write the mutated command into the data buffer
+ uc.mem_map(CODE_ADDRESS, CODE_SIZE_MAX)
+ uc.mem_write(CODE_ADDRESS, binary_code)
+
+ # Set the program counter to the start of the code
+ start_address = CODE_ADDRESS # Address of entry point of main()
+ end_address = CODE_ADDRESS + 0xF4 # Address of last instruction in main()
+ uc.reg_write(UC_MIPS_REG_PC, start_address)
+
+ # -----------------
+ # Setup the stack
+
+ uc.mem_map(STACK_ADDRESS, STACK_SIZE)
+ uc.reg_write(UC_MIPS_REG_SP, STACK_ADDRESS + STACK_SIZE)
+
+ # reserve some space for data
+ uc.mem_map(DATA_ADDRESS, DATA_SIZE_MAX)
+
+ # -----------------------------------------------------
+ # Set up a callback to place input data (do little work here, it's called for every single iteration)
+ # We did not pass in any data and don't use persistent mode, so we can ignore these params.
+ # Be sure to check out the docstrings for the uc.afl_* functions.
+ def place_input_callback(uc, input, persistent_round, data):
+ # Apply constraints to the mutated input
+ if len(input) > DATA_SIZE_MAX:
+ # print("Test input is too long (> {} bytes)")
+ return False
+
+ # Write the mutated command into the data buffer
+ uc.mem_write(DATA_ADDRESS, input)
+
+ # Start the fuzzer.
+ uc.afl_fuzz(args.input_file, place_input_callback, [end_address])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/unicorn_mode/samples/python_simple/simple_test_harness_alt.py b/unicorn_mode/samples/python_simple/simple_test_harness_alt.py
new file mode 100644
index 00000000..3249b13d
--- /dev/null
+++ b/unicorn_mode/samples/python_simple/simple_test_harness_alt.py
@@ -0,0 +1,223 @@
+#!/usr/bin/env python
+"""
+ Alternative simple test harness for Unicornafl.
+ It is slower but compatible with anything that uses unicorn.
+
+ Have a look at `unicornafl.monkeypatch()` for an easy way to fuzz unicorn projects.
+
+ This loads the simple_target.bin binary (precompiled as MIPS code) into
+ Unicorn's memory map for emulation, places the specified input into
+ simple_target's buffer (hardcoded to be at 0x300000), and executes 'main()'.
+ If any crashes occur during emulation, this script throws a matching signal
+ to tell AFL that a crash occurred.
+
+ Run under AFL as follows:
+
+ $ cd /unicorn_mode/samples/simple/
+ $ ../../../afl-fuzz -U -m none -i ./sample_inputs -o ./output -- python simple_test_harness_alt.py @@
+"""
+
+import argparse
+import os
+import signal
+
+from unicornafl import *
+from unicornafl.mips_const import *
+
+# Path to the file containing the binary to emulate
+BINARY_FILE = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)), "simple_target.bin"
+)
+
+# Memory map for the code to be tested
+CODE_ADDRESS = 0x00100000 # Arbitrary address where code to test will be loaded
+CODE_SIZE_MAX = 0x00010000 # Max size for the code (64kb)
+STACK_ADDRESS = 0x00200000 # Address of the stack (arbitrarily chosen)
+STACK_SIZE = 0x00010000 # Size of the stack (arbitrarily chosen)
+DATA_ADDRESS = 0x00300000 # Address where mutated data will be placed
+DATA_SIZE_MAX = 0x00010000 # Maximum allowable size of mutated data
+
+try:
+ # If Capstone is installed then we'll dump disassembly, otherwise just dump the binary.
+ from capstone import *
+
+ cs = Cs(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN)
+
+ def unicorn_debug_instruction(uc, address, size, user_data):
+ mem = uc.mem_read(address, size)
+ for (cs_address, cs_size, cs_mnemonic, cs_opstr) in cs.disasm_lite(
+ bytes(mem), size
+ ):
+ print(" Instr: {:#016x}:\t{}\t{}".format(address, cs_mnemonic, cs_opstr))
+
+
+except ImportError:
+
+ def unicorn_debug_instruction(uc, address, size, user_data):
+ print(" Instr: addr=0x{0:016x}, size=0x{1:016x}".format(address, size))
+
+
+def unicorn_debug_block(uc, address, size, user_data):
+ print("Basic Block: addr=0x{0:016x}, size=0x{1:016x}".format(address, size))
+
+
+def unicorn_debug_mem_access(uc, access, address, size, value, user_data):
+ if access == UC_MEM_WRITE:
+ print(
+ " >>> Write: addr=0x{0:016x} size={1} data=0x{2:016x}".format(
+ address, size, value
+ )
+ )
+ else:
+ print(" >>> Read: addr=0x{0:016x} size={1}".format(address, size))
+
+
+def unicorn_debug_mem_invalid_access(uc, access, address, size, value, user_data):
+ if access == UC_MEM_WRITE_UNMAPPED:
+ print(
+ " >>> INVALID Write: addr=0x{0:016x} size={1} data=0x{2:016x}".format(
+ address, size, value
+ )
+ )
+ else:
+ print(
+ " >>> INVALID Read: addr=0x{0:016x} size={1}".format(address, size)
+ )
+
+
+def force_crash(uc_error):
+ # This function should be called to indicate to AFL that a crash occurred during emulation.
+ # Pass in the exception received from Uc.emu_start()
+ mem_errors = [
+ UC_ERR_READ_UNMAPPED,
+ UC_ERR_READ_PROT,
+ UC_ERR_READ_UNALIGNED,
+ UC_ERR_WRITE_UNMAPPED,
+ UC_ERR_WRITE_PROT,
+ UC_ERR_WRITE_UNALIGNED,
+ UC_ERR_FETCH_UNMAPPED,
+ UC_ERR_FETCH_PROT,
+ UC_ERR_FETCH_UNALIGNED,
+ ]
+ if uc_error.errno in mem_errors:
+ # Memory error - throw SIGSEGV
+ os.kill(os.getpid(), signal.SIGSEGV)
+ elif uc_error.errno == UC_ERR_INSN_INVALID:
+ # Invalid instruction - throw SIGILL
+ os.kill(os.getpid(), signal.SIGILL)
+ else:
+ # Not sure what happened - throw SIGABRT
+ os.kill(os.getpid(), signal.SIGABRT)
+
+
+def main():
+
+ parser = argparse.ArgumentParser(description="Test harness for simple_target.bin")
+ parser.add_argument(
+ "input_file",
+ type=str,
+ help="Path to the file containing the mutated input to load",
+ )
+ parser.add_argument(
+ "-d",
+ "--debug",
+ default=False,
+ action="store_true",
+ help="Enables debug tracing",
+ )
+ args = parser.parse_args()
+
+ # Instantiate a MIPS32 big endian Unicorn Engine instance
+ uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN)
+
+ if args.debug:
+ uc.hook_add(UC_HOOK_BLOCK, unicorn_debug_block)
+ uc.hook_add(UC_HOOK_CODE, unicorn_debug_instruction)
+ uc.hook_add(UC_HOOK_MEM_WRITE | UC_HOOK_MEM_READ, unicorn_debug_mem_access)
+ uc.hook_add(
+ UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_READ_INVALID,
+ unicorn_debug_mem_invalid_access,
+ )
+
+ # ---------------------------------------------------
+ # Load the binary to emulate and map it into memory
+
+ print("Loading data input from {}".format(args.input_file))
+ binary_file = open(BINARY_FILE, "rb")
+ binary_code = binary_file.read()
+ binary_file.close()
+
+ # Apply constraints to the mutated input
+ if len(binary_code) > CODE_SIZE_MAX:
+ print("Binary code is too large (> {} bytes)".format(CODE_SIZE_MAX))
+ return
+
+ # Write the mutated command into the data buffer
+ uc.mem_map(CODE_ADDRESS, CODE_SIZE_MAX)
+ uc.mem_write(CODE_ADDRESS, binary_code)
+
+ # Set the program counter to the start of the code
+ start_address = CODE_ADDRESS # Address of entry point of main()
+ end_address = CODE_ADDRESS + 0xF4 # Address of last instruction in main()
+ uc.reg_write(UC_MIPS_REG_PC, start_address)
+
+ # -----------------
+ # Setup the stack
+
+ uc.mem_map(STACK_ADDRESS, STACK_SIZE)
+ uc.reg_write(UC_MIPS_REG_SP, STACK_ADDRESS + STACK_SIZE)
+
+ # reserve some space for data
+ uc.mem_map(DATA_ADDRESS, DATA_SIZE_MAX)
+
+ # -----------------------------------------------------
+ # Kick off AFL's fork server
+ # THIS MUST BE DONE BEFORE LOADING USER DATA!
+ # If this isn't done every single run, the AFL fork server
+ # will not be started appropriately and you'll get erratic results!
+
+ print("Starting the AFL forkserver")
+
+ afl_mode = uc.afl_forkserver_start([end_address])
+ if afl_mode != UC_AFL_RET_NO_AFL:
+ # Disable prints for speed
+ out = lambda x, y: None
+ else:
+ out = lambda x, y: print(x.format(y))
+
+ # -----------------------------------------------
+ # Load the mutated input and map it into memory
+
+ # Load the mutated input from disk
+ out("Loading data input from {}", args.input_file)
+ input_file = open(args.input_file, "rb")
+ input = input_file.read()
+ input_file.close()
+
+ # Apply constraints to the mutated input
+ if len(input) > DATA_SIZE_MAX:
+ out("Test input is too long (> {} bytes)", DATA_SIZE_MAX)
+ return
+
+ # Write the mutated command into the data buffer
+ uc.mem_write(DATA_ADDRESS, input)
+
+ # ------------------------------------------------------------
+ # Emulate the code, allowing it to process the mutated input
+
+ out("Executing until a crash or execution reaches 0x{0:016x}", end_address)
+ try:
+ uc.emu_start(uc.reg_read(UC_MIPS_REG_PC), end_address, timeout=0, count=0)
+ except UcError as e:
+ out("Execution failed with error: {}", e)
+ force_crash(e)
+
+ # UC_AFL_RET_ERROR = 0
+ # UC_AFL_RET_CHILD = 1
+ # UC_AFL_RET_NO_AFL = 2
+ # UC_AFL_RET_FINISHED = 3
+ out("Done. AFL Mode is {}", afl_mode)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/unicorn_mode/samples/simple/COMPILE.md b/unicorn_mode/samples/simple/COMPILE.md
deleted file mode 100644
index f7bf5b50..00000000
--- a/unicorn_mode/samples/simple/COMPILE.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Compiling simple_target.c
-
-You shouldn't need to compile simple_target.c since a MIPS binary version is
-pre-built and shipped with afl-unicorn. This file documents how the binary
-was built in case you want to rebuild it or recompile it for any reason.
-
-The pre-built binary (simple_target.bin) was built by cross-compiling
-simple_target.c for MIPS using the mips-linux-gnu-gcc package on an Ubuntu
-16.04 LTS system. This cross compiler (and associated binutils) was installed
-from apt-get packages:
-
-```
-sudo apt-get install gcc-mips-linux-gnu
-```
-
-simple_target.c was compiled without optimization, position-independent,
-and without standard libraries using the following command line:
-
-```
-mips-linux-gnu-gcc -o simple_target.elf simple_target.c -fPIC -O0 -nostdlib
-```
-
-The .text section from the resulting ELF binary was then extracted to create
-the raw binary blob that is loaded and emulated by simple_test_harness.py:
-
-```
-mips-linux-gnu-objcopy -O binary --only-section=.text simple_target.elf simple_target.bin
-```
-
-In summary, to recreate simple_taget.bin execute the following:
-
-```
-mips-linux-gnu-gcc -o simple_target.elf simple_target.c -fPIC -O0 -nostdlib
- && mips-linux-gnu-objcopy -O binary --only-section=.text simple_target.elf simple_target.bin
- && rm simple_target.elf
-```
-
-Note that the output of this is padded with nulls for 16-byte alignment. This is
-important when emulating it, as NOPs will be added after the return of main()
-as necessary.
diff --git a/unicorn_mode/samples/simple/sample_inputs/sample1.bin b/unicorn_mode/samples/simple/sample_inputs/sample1.bin
deleted file mode 100644
index 85df5078..00000000
--- a/unicorn_mode/samples/simple/sample_inputs/sample1.bin
+++ /dev/null
@@ -1 +0,0 @@
-abcd
\ No newline at end of file
diff --git a/unicorn_mode/samples/simple/sample_inputs/sample2.bin b/unicorn_mode/samples/simple/sample_inputs/sample2.bin
deleted file mode 100644
index f76dd238..00000000
Binary files a/unicorn_mode/samples/simple/sample_inputs/sample2.bin and /dev/null differ
diff --git a/unicorn_mode/samples/simple/sample_inputs/sample3.bin b/unicorn_mode/samples/simple/sample_inputs/sample3.bin
deleted file mode 100644
index 6b2aaa76..00000000
--- a/unicorn_mode/samples/simple/sample_inputs/sample3.bin
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/unicorn_mode/samples/simple/sample_inputs/sample4.bin b/unicorn_mode/samples/simple/sample_inputs/sample4.bin
deleted file mode 100644
index 71bd63e6..00000000
--- a/unicorn_mode/samples/simple/sample_inputs/sample4.bin
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/unicorn_mode/samples/simple/sample_inputs/sample5.bin b/unicorn_mode/samples/simple/sample_inputs/sample5.bin
deleted file mode 100644
index aed2973e..00000000
--- a/unicorn_mode/samples/simple/sample_inputs/sample5.bin
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/unicorn_mode/samples/simple/simple_target.bin b/unicorn_mode/samples/simple/simple_target.bin
deleted file mode 100644
index 0095eb6c..00000000
Binary files a/unicorn_mode/samples/simple/simple_target.bin and /dev/null differ
diff --git a/unicorn_mode/samples/simple/simple_target.c b/unicorn_mode/samples/simple/simple_target.c
deleted file mode 100644
index 49e1b4d8..00000000
--- a/unicorn_mode/samples/simple/simple_target.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Sample target file to test afl-unicorn fuzzing capabilities.
- * This is a very trivial example that will crash pretty easily
- * in several different exciting ways.
- *
- * Input is assumed to come from a buffer located at DATA_ADDRESS
- * (0x00300000), so make sure that your Unicorn emulation of this
- * puts user data there.
- *
- * Written by Nathan Voss
- */
-
-// Magic address where mutated data will be placed
-#define DATA_ADDRESS 0x00300000
-
-int main(void) {
- unsigned char *data_buf = (unsigned char *) DATA_ADDRESS;
-
- if (data_buf[20] != 0) {
- // Cause an 'invalid read' crash if data[0..3] == '\x01\x02\x03\x04'
- unsigned char invalid_read = *(unsigned char *) 0x00000000;
- } else if (data_buf[0] > 0x10 && data_buf[0] < 0x20 && data_buf[1] > data_buf[2]) {
- // Cause an 'invalid read' crash if (0x10 < data[0] < 0x20) and data[1] > data[2]
- unsigned char invalid_read = *(unsigned char *) 0x00000000;
- } else if (data_buf[9] == 0x00 && data_buf[10] != 0x00 && data_buf[11] == 0x00) {
- // Cause a crash if data[10] is not zero, but [9] and [11] are zero
- unsigned char invalid_read = *(unsigned char *) 0x00000000;
- }
-
- return 0;
-}
diff --git a/unicorn_mode/samples/simple/simple_test_harness.py b/unicorn_mode/samples/simple/simple_test_harness.py
deleted file mode 100644
index cd04ad3a..00000000
--- a/unicorn_mode/samples/simple/simple_test_harness.py
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/env python3
-"""
- Simple test harness for AFL's Unicorn Mode.
-
- This loads the simple_target.bin binary (precompiled as MIPS code) into
- Unicorn's memory map for emulation, places the specified input into
- simple_target's buffer (hardcoded to be at 0x300000), and executes 'main()'.
- If any crashes occur during emulation, unicornafl will
- tell AFL that a crash occurred.
-
- Run under AFL as follows:
-
- $ cd /unicorn_mode/samples/simple/
- $ ../../../afl-fuzz -U -m none -i ./sample_inputs -o ./output -- python simple_test_harness.py @@
-"""
-
-import argparse
-import os
-import signal
-
-from unicornafl import *
-from unicornafl.mips_const import *
-
-# Path to the file containing the binary to emulate
-BINARY_FILE = os.path.join(
- os.path.dirname(os.path.abspath(__file__)), "simple_target.bin"
-)
-
-# Memory map for the code to be tested
-CODE_ADDRESS = 0x00100000 # Arbitrary address where code to test will be loaded
-CODE_SIZE_MAX = 0x00010000 # Max size for the code (64kb)
-STACK_ADDRESS = 0x00200000 # Address of the stack (arbitrarily chosen)
-STACK_SIZE = 0x00010000 # Size of the stack (arbitrarily chosen)
-DATA_ADDRESS = 0x00300000 # Address where mutated data will be placed
-DATA_SIZE_MAX = 0x00010000 # Maximum allowable size of mutated data
-
-try:
- # If Capstone is installed then we'll dump disassembly, otherwise just dump the binary.
- from capstone import *
-
- cs = Cs(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN)
-
- def unicorn_debug_instruction(uc, address, size, user_data):
- mem = uc.mem_read(address, size)
- for (cs_address, cs_size, cs_mnemonic, cs_opstr) in cs.disasm_lite(
- bytes(mem), size
- ):
- print(" Instr: {:#016x}:\t{}\t{}".format(address, cs_mnemonic, cs_opstr))
-
-
-except ImportError:
-
- def unicorn_debug_instruction(uc, address, size, user_data):
- print(" Instr: addr=0x{0:016x}, size=0x{1:016x}".format(address, size))
-
-
-def unicorn_debug_block(uc, address, size, user_data):
- print("Basic Block: addr=0x{0:016x}, size=0x{1:016x}".format(address, size))
-
-
-def unicorn_debug_mem_access(uc, access, address, size, value, user_data):
- if access == UC_MEM_WRITE:
- print(
- " >>> Write: addr=0x{0:016x} size={1} data=0x{2:016x}".format(
- address, size, value
- )
- )
- else:
- print(" >>> Read: addr=0x{0:016x} size={1}".format(address, size))
-
-
-def unicorn_debug_mem_invalid_access(uc, access, address, size, value, user_data):
- if access == UC_MEM_WRITE_UNMAPPED:
- print(
- " >>> INVALID Write: addr=0x{0:016x} size={1} data=0x{2:016x}".format(
- address, size, value
- )
- )
- else:
- print(
- " >>> INVALID Read: addr=0x{0:016x} size={1}".format(address, size)
- )
-
-
-def main():
-
- parser = argparse.ArgumentParser(description="Test harness for simple_target.bin")
- parser.add_argument(
- "input_file",
- type=str,
- help="Path to the file containing the mutated input to load",
- )
- parser.add_argument(
- "-t",
- "--trace",
- default=False,
- action="store_true",
- help="Enables debug tracing",
- )
- args = parser.parse_args()
-
- # Instantiate a MIPS32 big endian Unicorn Engine instance
- uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN)
-
- if args.trace:
- uc.hook_add(UC_HOOK_BLOCK, unicorn_debug_block)
- uc.hook_add(UC_HOOK_CODE, unicorn_debug_instruction)
- uc.hook_add(UC_HOOK_MEM_WRITE | UC_HOOK_MEM_READ, unicorn_debug_mem_access)
- uc.hook_add(
- UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_READ_INVALID,
- unicorn_debug_mem_invalid_access,
- )
-
- # ---------------------------------------------------
- # Load the binary to emulate and map it into memory
-
- print("Loading data input from {}".format(args.input_file))
- binary_file = open(BINARY_FILE, "rb")
- binary_code = binary_file.read()
- binary_file.close()
-
- # Apply constraints to the mutated input
- if len(binary_code) > CODE_SIZE_MAX:
- print("Binary code is too large (> {} bytes)".format(CODE_SIZE_MAX))
- return
-
- # Write the mutated command into the data buffer
- uc.mem_map(CODE_ADDRESS, CODE_SIZE_MAX)
- uc.mem_write(CODE_ADDRESS, binary_code)
-
- # Set the program counter to the start of the code
- start_address = CODE_ADDRESS # Address of entry point of main()
- end_address = CODE_ADDRESS + 0xF4 # Address of last instruction in main()
- uc.reg_write(UC_MIPS_REG_PC, start_address)
-
- # -----------------
- # Setup the stack
-
- uc.mem_map(STACK_ADDRESS, STACK_SIZE)
- uc.reg_write(UC_MIPS_REG_SP, STACK_ADDRESS + STACK_SIZE)
-
- # reserve some space for data
- uc.mem_map(DATA_ADDRESS, DATA_SIZE_MAX)
-
- # -----------------------------------------------------
- # Set up a callback to place input data (do little work here, it's called for every single iteration)
- # We did not pass in any data and don't use persistent mode, so we can ignore these params.
- # Be sure to check out the docstrings for the uc.afl_* functions.
- def place_input_callback(uc, input, persistent_round, data):
- # Apply constraints to the mutated input
- if len(input) > DATA_SIZE_MAX:
- # print("Test input is too long (> {} bytes)")
- return False
-
- # Write the mutated command into the data buffer
- uc.mem_write(DATA_ADDRESS, input)
-
- # Start the fuzzer.
- uc.afl_fuzz(args.input_file, place_input_callback, [end_address])
-
-
-if __name__ == "__main__":
- main()
diff --git a/unicorn_mode/samples/simple/simple_test_harness_alt.py b/unicorn_mode/samples/simple/simple_test_harness_alt.py
deleted file mode 100644
index 3249b13d..00000000
--- a/unicorn_mode/samples/simple/simple_test_harness_alt.py
+++ /dev/null
@@ -1,223 +0,0 @@
-#!/usr/bin/env python
-"""
- Alternative simple test harness for Unicornafl.
- It is slower but compatible with anything that uses unicorn.
-
- Have a look at `unicornafl.monkeypatch()` for an easy way to fuzz unicorn projects.
-
- This loads the simple_target.bin binary (precompiled as MIPS code) into
- Unicorn's memory map for emulation, places the specified input into
- simple_target's buffer (hardcoded to be at 0x300000), and executes 'main()'.
- If any crashes occur during emulation, this script throws a matching signal
- to tell AFL that a crash occurred.
-
- Run under AFL as follows:
-
- $ cd /unicorn_mode/samples/simple/
- $ ../../../afl-fuzz -U -m none -i ./sample_inputs -o ./output -- python simple_test_harness_alt.py @@
-"""
-
-import argparse
-import os
-import signal
-
-from unicornafl import *
-from unicornafl.mips_const import *
-
-# Path to the file containing the binary to emulate
-BINARY_FILE = os.path.join(
- os.path.dirname(os.path.abspath(__file__)), "simple_target.bin"
-)
-
-# Memory map for the code to be tested
-CODE_ADDRESS = 0x00100000 # Arbitrary address where code to test will be loaded
-CODE_SIZE_MAX = 0x00010000 # Max size for the code (64kb)
-STACK_ADDRESS = 0x00200000 # Address of the stack (arbitrarily chosen)
-STACK_SIZE = 0x00010000 # Size of the stack (arbitrarily chosen)
-DATA_ADDRESS = 0x00300000 # Address where mutated data will be placed
-DATA_SIZE_MAX = 0x00010000 # Maximum allowable size of mutated data
-
-try:
- # If Capstone is installed then we'll dump disassembly, otherwise just dump the binary.
- from capstone import *
-
- cs = Cs(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN)
-
- def unicorn_debug_instruction(uc, address, size, user_data):
- mem = uc.mem_read(address, size)
- for (cs_address, cs_size, cs_mnemonic, cs_opstr) in cs.disasm_lite(
- bytes(mem), size
- ):
- print(" Instr: {:#016x}:\t{}\t{}".format(address, cs_mnemonic, cs_opstr))
-
-
-except ImportError:
-
- def unicorn_debug_instruction(uc, address, size, user_data):
- print(" Instr: addr=0x{0:016x}, size=0x{1:016x}".format(address, size))
-
-
-def unicorn_debug_block(uc, address, size, user_data):
- print("Basic Block: addr=0x{0:016x}, size=0x{1:016x}".format(address, size))
-
-
-def unicorn_debug_mem_access(uc, access, address, size, value, user_data):
- if access == UC_MEM_WRITE:
- print(
- " >>> Write: addr=0x{0:016x} size={1} data=0x{2:016x}".format(
- address, size, value
- )
- )
- else:
- print(" >>> Read: addr=0x{0:016x} size={1}".format(address, size))
-
-
-def unicorn_debug_mem_invalid_access(uc, access, address, size, value, user_data):
- if access == UC_MEM_WRITE_UNMAPPED:
- print(
- " >>> INVALID Write: addr=0x{0:016x} size={1} data=0x{2:016x}".format(
- address, size, value
- )
- )
- else:
- print(
- " >>> INVALID Read: addr=0x{0:016x} size={1}".format(address, size)
- )
-
-
-def force_crash(uc_error):
- # This function should be called to indicate to AFL that a crash occurred during emulation.
- # Pass in the exception received from Uc.emu_start()
- mem_errors = [
- UC_ERR_READ_UNMAPPED,
- UC_ERR_READ_PROT,
- UC_ERR_READ_UNALIGNED,
- UC_ERR_WRITE_UNMAPPED,
- UC_ERR_WRITE_PROT,
- UC_ERR_WRITE_UNALIGNED,
- UC_ERR_FETCH_UNMAPPED,
- UC_ERR_FETCH_PROT,
- UC_ERR_FETCH_UNALIGNED,
- ]
- if uc_error.errno in mem_errors:
- # Memory error - throw SIGSEGV
- os.kill(os.getpid(), signal.SIGSEGV)
- elif uc_error.errno == UC_ERR_INSN_INVALID:
- # Invalid instruction - throw SIGILL
- os.kill(os.getpid(), signal.SIGILL)
- else:
- # Not sure what happened - throw SIGABRT
- os.kill(os.getpid(), signal.SIGABRT)
-
-
-def main():
-
- parser = argparse.ArgumentParser(description="Test harness for simple_target.bin")
- parser.add_argument(
- "input_file",
- type=str,
- help="Path to the file containing the mutated input to load",
- )
- parser.add_argument(
- "-d",
- "--debug",
- default=False,
- action="store_true",
- help="Enables debug tracing",
- )
- args = parser.parse_args()
-
- # Instantiate a MIPS32 big endian Unicorn Engine instance
- uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN)
-
- if args.debug:
- uc.hook_add(UC_HOOK_BLOCK, unicorn_debug_block)
- uc.hook_add(UC_HOOK_CODE, unicorn_debug_instruction)
- uc.hook_add(UC_HOOK_MEM_WRITE | UC_HOOK_MEM_READ, unicorn_debug_mem_access)
- uc.hook_add(
- UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_READ_INVALID,
- unicorn_debug_mem_invalid_access,
- )
-
- # ---------------------------------------------------
- # Load the binary to emulate and map it into memory
-
- print("Loading data input from {}".format(args.input_file))
- binary_file = open(BINARY_FILE, "rb")
- binary_code = binary_file.read()
- binary_file.close()
-
- # Apply constraints to the mutated input
- if len(binary_code) > CODE_SIZE_MAX:
- print("Binary code is too large (> {} bytes)".format(CODE_SIZE_MAX))
- return
-
- # Write the mutated command into the data buffer
- uc.mem_map(CODE_ADDRESS, CODE_SIZE_MAX)
- uc.mem_write(CODE_ADDRESS, binary_code)
-
- # Set the program counter to the start of the code
- start_address = CODE_ADDRESS # Address of entry point of main()
- end_address = CODE_ADDRESS + 0xF4 # Address of last instruction in main()
- uc.reg_write(UC_MIPS_REG_PC, start_address)
-
- # -----------------
- # Setup the stack
-
- uc.mem_map(STACK_ADDRESS, STACK_SIZE)
- uc.reg_write(UC_MIPS_REG_SP, STACK_ADDRESS + STACK_SIZE)
-
- # reserve some space for data
- uc.mem_map(DATA_ADDRESS, DATA_SIZE_MAX)
-
- # -----------------------------------------------------
- # Kick off AFL's fork server
- # THIS MUST BE DONE BEFORE LOADING USER DATA!
- # If this isn't done every single run, the AFL fork server
- # will not be started appropriately and you'll get erratic results!
-
- print("Starting the AFL forkserver")
-
- afl_mode = uc.afl_forkserver_start([end_address])
- if afl_mode != UC_AFL_RET_NO_AFL:
- # Disable prints for speed
- out = lambda x, y: None
- else:
- out = lambda x, y: print(x.format(y))
-
- # -----------------------------------------------
- # Load the mutated input and map it into memory
-
- # Load the mutated input from disk
- out("Loading data input from {}", args.input_file)
- input_file = open(args.input_file, "rb")
- input = input_file.read()
- input_file.close()
-
- # Apply constraints to the mutated input
- if len(input) > DATA_SIZE_MAX:
- out("Test input is too long (> {} bytes)", DATA_SIZE_MAX)
- return
-
- # Write the mutated command into the data buffer
- uc.mem_write(DATA_ADDRESS, input)
-
- # ------------------------------------------------------------
- # Emulate the code, allowing it to process the mutated input
-
- out("Executing until a crash or execution reaches 0x{0:016x}", end_address)
- try:
- uc.emu_start(uc.reg_read(UC_MIPS_REG_PC), end_address, timeout=0, count=0)
- except UcError as e:
- out("Execution failed with error: {}", e)
- force_crash(e)
-
- # UC_AFL_RET_ERROR = 0
- # UC_AFL_RET_CHILD = 1
- # UC_AFL_RET_NO_AFL = 2
- # UC_AFL_RET_FINISHED = 3
- out("Done. AFL Mode is {}", afl_mode)
-
-
-if __name__ == "__main__":
- main()
diff --git a/unicorn_mode/samples/speedtest/c/Makefile b/unicorn_mode/samples/speedtest/c/Makefile
index 46789954..d34f49fa 100644
--- a/unicorn_mode/samples/speedtest/c/Makefile
+++ b/unicorn_mode/samples/speedtest/c/Makefile
@@ -4,29 +4,28 @@
.POSIX:
UNAME_S =$(shell uname -s)# GNU make
UNAME_S:sh=uname -s # BSD make
-_UNIQ=_QINU_
-LIBDIR = ../../../unicornafl
+UNICORNAFL_LIB = ../../../unicornafl/build
+UNICORN_LIB = ../../../unicornafl/unicorn/build
BIN_EXT =
AR_EXT = a
# Verbose output?
V ?= 0
-CFLAGS += -Wall -Werror -Wextra -Wno-unused-parameter -I../../../unicornafl/include
+CFLAGS += -Wall -I../../../unicornafl/unicorn/include -I../../../unicornafl/include
-LDFLAGS += -L$(LIBDIR) -lpthread -lm
+LDFLAGS += -L$(UNICORNAFL_LIB) -L$(UNICORN_LIB) -lpthread -lm -lunicornafl -lunicorn -lc++
-_LRT = $(_UNIQ)$(UNAME_S:Linux=)
-__LRT = $(_LRT:$(_UNIQ)=-lrt)
-LRT = $(__LRT:$(_UNIQ)=)
+ifeq ($(UNAME), Linux)
+# do something Linux-y
+LRT = -lrt
+else
+LRT =
+endif
LDFLAGS += $(LRT)
-_CC = $(_UNIQ)$(CROSS)
-__CC = $(_CC:$(_UNIQ)=$(CC))
-MYCC = $(__CC:$(_UNIQ)$(CROSS)=$(CROSS)gcc)
-
.PHONY: all clean
all: ../target harness
@@ -38,17 +37,20 @@ afl-fuzz: ../../../../afl-fuzz
clean:
rm -rf *.o harness harness-debug
-harness.o: harness.c ../../../unicornafl/include/unicorn/*.h
- ${MYCC} ${CFLAGS} -O3 -c harness.c -o $@
+../../../unicornafl/build/libunicornafl.a:
+ cd ../../.. && ./build_unicorn_support.sh
+
+harness.o: harness.c ../../../unicornafl/unicorn/include/unicorn/*.h
+ ${CC} ${CFLAGS} -O3 -c harness.c -o $@
-harness-debug.o: harness.c ../../../unicornafl/include/unicorn/*.h
- ${MYCC} ${CFLAGS} -fsanitize=address -g -Og -c harness.c -o $@
+harness-debug.o: harness.c ../../../unicornafl/unicorn/include/unicorn/*.h
+ ${CC} ${CFLAGS} -fsanitize=address -g -Og -c harness.c -o $@
harness: harness.o
- ${MYCC} -L${LIBDIR} harness.o ../../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@
+ ${CC} harness.o $(LDFLAGS) -o $@
harness-debug: harness-debug.o
- ${MYCC} -fsanitize=address -g -Og -L${LIBDIR} harness-debug.o ../../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug
+ ${CC} -fsanitize=address -g -Og harness-debug.o ../../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug
../target:
$(MAKE) -C ..
diff --git a/unicorn_mode/samples/speedtest/c/harness.c b/unicorn_mode/samples/speedtest/c/harness.c
index 9eb05257..184934b9 100644
--- a/unicorn_mode/samples/speedtest/c/harness.c
+++ b/unicorn_mode/samples/speedtest/c/harness.c
@@ -28,6 +28,7 @@
#include
#include
+#include
// Path to the file containing the binary to emulate
#define BINARY_FILE ("../target")
@@ -124,7 +125,7 @@ static void mem_map_checked(uc_engine *uc, uint64_t addr, size_t size, uint32_t
//printf("SIZE %llx, align: %llx\n", size, ALIGNMENT);
uc_err err = uc_mem_map(uc, addr, size, mode);
if (err != UC_ERR_OK) {
- printf("Error mapping %ld bytes at 0x%lx: %s (mode: %d)\n", size, addr, uc_strerror(err), mode);
+ printf("Error mapping %ld bytes at 0x%llx: %s (mode: %d)\n", (unsigned long) size, (unsigned long long) addr, uc_strerror(err), (int) mode);
exit(1);
}
}
@@ -306,7 +307,7 @@ int main(int argc, char **argv, char **envp) {
exit(-1);
}
uint64_t start_address;
- if(fscanf(f, "%lx", &start_address) == EOF) {
+ if(fscanf(f, "%llx", (unsigned long long) &start_address) == EOF) {
puts("Start address not found in target.offests.main");
exit(-1);
}
--
cgit 1.4.1
From 227b42b1d05b7dc74a11b54d185130ecdb91190e Mon Sep 17 00:00:00 2001
From: Dominik Maier
Date: Sat, 22 Jan 2022 19:44:07 +0100
Subject: unicorn fixes
---
unicorn_mode/UNICORNAFL_VERSION | 2 +-
unicorn_mode/build_unicorn_support.sh | 3 +--
unicorn_mode/unicornafl | 2 +-
3 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index 8b9c9fc0..ba9a4d9c 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-7b0c61f25042ebed910b88da2ca42778b858b852
+468798455a9f9790d2da369a18ed49fda3a64e8c
diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh
index 340ac77c..842ad020 100755
--- a/unicorn_mode/build_unicorn_support.sh
+++ b/unicorn_mode/build_unicorn_support.sh
@@ -180,8 +180,7 @@ sh -c 'git stash && git stash drop' 1>/dev/null 2>/dev/null
git checkout "$UNICORNAFL_VERSION" || exit 1
echo "[*] making sure afl++ header files match"
-cp "../../include/config.h" "." || exit 1
-cp "../../include/types.h" "." || exit 1
+cp "../../include/config.h" "./include" || exit 1
echo "[*] Configuring Unicorn build..."
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index 7b0c61f2..46879845 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit 7b0c61f25042ebed910b88da2ca42778b858b852
+Subproject commit 468798455a9f9790d2da369a18ed49fda3a64e8c
--
cgit 1.4.1
From 04e3b5a6d3ae33699f29d88bedb48432ed14f708 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 23 Jan 2022 18:38:04 +0100
Subject: update commit ids
---
custom_mutators/grammar_mutator/grammar_mutator | 2 +-
nyx_mode/QEMU-Nyx | 2 +-
nyx_mode/libnyx | 2 +-
nyx_mode/packer | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/custom_mutators/grammar_mutator/grammar_mutator b/custom_mutators/grammar_mutator/grammar_mutator
index 6ca490c6..cbe5e327 160000
--- a/custom_mutators/grammar_mutator/grammar_mutator
+++ b/custom_mutators/grammar_mutator/grammar_mutator
@@ -1 +1 @@
-Subproject commit 6ca490c66b949db20d8c861ebc8fb2e6ca725ead
+Subproject commit cbe5e32752773945e0142fac9f1b7a0ccb5dcdff
diff --git a/nyx_mode/QEMU-Nyx b/nyx_mode/QEMU-Nyx
index d5a7011a..c2c69cfc 160000
--- a/nyx_mode/QEMU-Nyx
+++ b/nyx_mode/QEMU-Nyx
@@ -1 +1 @@
-Subproject commit d5a7011ad20ba5ba91f1371f9d40154035d5d768
+Subproject commit c2c69cfc528398d9db9363b92f8c50db4008c98f
diff --git a/nyx_mode/libnyx b/nyx_mode/libnyx
index ecbcb2d7..a5ae4c13 160000
--- a/nyx_mode/libnyx
+++ b/nyx_mode/libnyx
@@ -1 +1 @@
-Subproject commit ecbcb2d7234fef0b5e1db8ca6019e6137ee0582d
+Subproject commit a5ae4c13e11de776779444eb69932802e102d7c4
diff --git a/nyx_mode/packer b/nyx_mode/packer
index f91742ce..8842549b 160000
--- a/nyx_mode/packer
+++ b/nyx_mode/packer
@@ -1 +1 @@
-Subproject commit f91742ce6c51eee133b5675edd68f39202785db1
+Subproject commit 8842549b5612a890258dcef812276cfdb62b76c7
--
cgit 1.4.1
From 9baa402344ca50e030b4c5cd443a955d9830d7b3 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 23 Jan 2022 18:39:55 +0100
Subject: update refs
---
nyx_mode/libnyx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nyx_mode/libnyx b/nyx_mode/libnyx
index a5ae4c13..2e45754e 160000
--- a/nyx_mode/libnyx
+++ b/nyx_mode/libnyx
@@ -1 +1 @@
-Subproject commit a5ae4c13e11de776779444eb69932802e102d7c4
+Subproject commit 2e45754e271463f446c31a6f467231d8657910e8
--
cgit 1.4.1
From 61d79f85c5f1f0d80bb7ab2d10d502fbd637ee83 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 23 Jan 2022 19:20:32 +0100
Subject: code format
---
docs/Changelog.md | 23 ++++++++++++-----------
include/forkserver.h | 12 ++++++------
src/afl-forkserver.c | 11 ++++++++---
src/afl-fuzz.c | 2 +-
4 files changed, 27 insertions(+), 21 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 687232a0..e25b43da 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -1,7 +1,7 @@
# Changelog
- This is the list of all noteworthy changes made in every public release of
- the tool. See README.md for the general instruction manual.
+ This is the list of all noteworthy changes made in every public
+ release of the tool. See README.md for the general instruction manual.
## Staying informed
@@ -9,7 +9,8 @@ Want to stay in the loop on major new features? Join our mailing list by
sending a mail to .
### Version ++3.15a (dev)
- - documentation restructuring, made possible by Google Season of Docs
+ - complete documentation restructuring, made possible by Google Season
+ of Docs :) thank you Jana!
- we renamed several UI and fuzzer_stat entries to be more precise,
e.g. "unique crashes" -> "saved crashes", "total paths" ->
"corpus count", "current path" -> "current item".
@@ -17,14 +18,14 @@ sending a mail to .
- Nyx mode (full system emulation with snapshot capability) has been
added - thanks to @schumilo and @eqv!
- unicorn_mode:
- - Moved to unicorn2! By Ziqiao Kong (@lazymio)
- - Faster, more accurate emulation (newer QEMU base), riscv support
+ - Moved to unicorn2! by Ziqiao Kong (@lazymio)
+ - Faster, more accurate emulation (newer QEMU base), risc-v support
- removed indirections in rust callbacks
- new binary-only fuzzing mode: coresight_mode for aarch64 CPUs :)
thanks to RICSecLab submitting!
- if instrumented libaries are dlopen()'ed after the forkserver you
- will now see crashes. before you would have colliding coverage.
- we changed this to force fixing a broken setup rather then allowing
+ will now see a crash. Before you would have colliding coverage.
+ We changed this to force fixing a broken setup rather then allowing
ineffective fuzzing.
See docs/best_practices.md how to fix such setups.
- afl-fuzz:
@@ -35,7 +36,7 @@ sending a mail to .
- added AFL_IGNORE_PROBLEMS, plus checks to identify and abort on
incorrect LTO usage setups and enhanced the READMEs for better
information on how to deal with instrumenting libraries
- - fix -n dumb mode (nobody should use this)
+ - fix -n dumb mode (nobody should use this mode though)
- fix stability issue with LTO and cmplog
- better banner
- more effective cmplog mode
@@ -63,7 +64,7 @@ sending a mail to .
- fixed a potential crash in targets for LAF string handling
- fixed a bad assert in LAF split switches
- added AFL_USE_TSAN thread sanitizer support
- - llvm and LTO mode modified to work with new llvm 14-dev (again. again.)
+ - llvm and LTO mode modified to work with new llvm 14-dev (again.)
- fix for AFL_REAL_LD
- more -z defs filtering
- make -v without options work
@@ -74,7 +75,7 @@ sending a mail to .
- added afl-persistent-config script to set perform permanent system
configuration settings for fuzzing, for Linux and Macos.
thanks to jhertz!
- - added xml, curl and exotic string functions to llvm dictionary features
+ - added xml, curl & exotic string functions to llvm dictionary feature
- 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!)
@@ -97,7 +98,7 @@ sending a mail to .
- Fix to instrument global namespace functions in c++
- Fix for llvm 13
- support partial linking
- - do honor AFL_LLVM_{ALLOW/DENY}LIST for LTO autodictionary and DICT2FILE
+ - do honor AFL_LLVM_{ALLOW/DENY}LIST for LTO autodictionary andDICT2FILE
- We do support llvm versions from 3.8 to 5.0 again
- frida_mode:
- several fixes for cmplog
diff --git a/include/forkserver.h b/include/forkserver.h
index 4a05b17e..01f45587 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -53,14 +53,14 @@ typedef enum NyxReturnValue {
typedef struct {
- void *(*nyx_new)(const char *sharedir, const char *workdir,
- uint32_t cpu_id, uint32_t input_buffer_size,
- bool input_buffer_write_protection);
+ void *(*nyx_new)(const char *sharedir, const char *workdir, uint32_t cpu_id,
+ uint32_t input_buffer_size,
+ bool input_buffer_write_protection);
void *(*nyx_new_parent)(const char *sharedir, const char *workdir,
- uint32_t cpu_id, uint32_t input_buffer_size,
- bool input_buffer_write_protection);
+ uint32_t cpu_id, uint32_t input_buffer_size,
+ bool input_buffer_write_protection);
void *(*nyx_new_child)(const char *sharedir, const char *workdir,
- uint32_t cpu_id, uint32_t worker_id);
+ uint32_t cpu_id, uint32_t worker_id);
void (*nyx_shutdown)(void *qemu_process);
void (*nyx_option_set_reload_mode)(void *qemu_process, bool enable);
void (*nyx_option_set_timeout)(void *qemu_process, uint8_t timeout_sec,
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index ffcb30c3..62110ad5 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -405,20 +405,25 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
- if (fsrv->nyx_standalone){
+ if (fsrv->nyx_standalone) {
+
fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(
fsrv->target_path, x, fsrv->nyx_bind_cpu_id, MAX_FILE, true);
- }
- else{
+
+ } else {
+
if (fsrv->nyx_parent) {
+
fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new_parent(
fsrv->target_path, x, fsrv->nyx_bind_cpu_id, MAX_FILE, true);
} else {
+
fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new_child(
fsrv->target_path, x, fsrv->nyx_bind_cpu_id, fsrv->nyx_id);
}
+
}
if (fsrv->nyx_runner == NULL) { FATAL("Something went wrong ..."); }
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 50874f47..e322ee57 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1346,7 +1346,7 @@ int main(int argc, char **argv_orig, char **envp) {
"0)");
}
-
+
afl->fsrv.nyx_parent = true;
afl->fsrv.nyx_id = 0;
--
cgit 1.4.1
From 7270cbe756113c4adf64a89dab364c32c6f6e55a Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 24 Jan 2022 10:28:48 +0100
Subject: try fix
---
qemu_mode/qemuafl | 2 +-
src/afl-fuzz.c | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
index ce65a734..8809a2b2 160000
--- a/qemu_mode/qemuafl
+++ b/qemu_mode/qemuafl
@@ -1 +1 @@
-Subproject commit ce65a7349e7156e052b37a660422cad8346764d0
+Subproject commit 8809a2b2ebf089d3427dd8f6a0044bcc2e13b389
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index e322ee57..06bff2be 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -50,14 +50,14 @@ static void at_exit() {
char *list[4] = {SHM_ENV_VAR, SHM_FUZZ_ENV_VAR, CMPLOG_SHM_ENV_VAR, NULL};
char *ptr;
- ptr = getenv(CPU_AFFINITY_ENV_VAR);
- if (ptr && *ptr) unlink(ptr);
+ ptr = getenv("__AFL_TARGET_PID2");
+ if (ptr && *ptr && (pid2 = atoi(ptr)) > 0) kill(pid2, SIGTERM);
ptr = getenv("__AFL_TARGET_PID1");
if (ptr && *ptr && (pid1 = atoi(ptr)) > 0) kill(pid1, SIGTERM);
- ptr = getenv("__AFL_TARGET_PID2");
- if (ptr && *ptr && (pid2 = atoi(ptr)) > 0) kill(pid2, SIGTERM);
+ ptr = getenv(CPU_AFFINITY_ENV_VAR);
+ if (ptr && *ptr) unlink(ptr);
i = 0;
while (list[i] != NULL) {
--
cgit 1.4.1
From 605b0e6465849ebb79714bef87041d7dacacec4b Mon Sep 17 00:00:00 2001
From: Andrea Fioraldi
Date: Mon, 24 Jan 2022 18:35:16 +0100
Subject: fix libqasan repeated line
---
qemu_mode/libqasan/libqasan.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/qemu_mode/libqasan/libqasan.c b/qemu_mode/libqasan/libqasan.c
index 13e48c75..f4d590bd 100644
--- a/qemu_mode/libqasan/libqasan.c
+++ b/qemu_mode/libqasan/libqasan.c
@@ -72,8 +72,6 @@ __attribute__((constructor)) void __libqasan_init() {
if (getenv("AFL_INST_LIBS") || getenv("QASAN_HOTPACH")) __libqasan_hotpatch();
- if (getenv("AFL_INST_LIBS") || getenv("QASAN_HOTPACH")) __libqasan_hotpatch();
-
#ifdef DEBUG
__qasan_debug = getenv("QASAN_DEBUG") != NULL;
#endif
--
cgit 1.4.1
From 3a78db2aded30302416039b694dbf0bd198e1fc0 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 25 Jan 2022 09:11:06 +0100
Subject: update sub gits
---
coresight_mode/coresight-trace | 2 +-
qemu_mode/qemuafl | 2 +-
unicorn_mode/UNICORNAFL_VERSION | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/coresight_mode/coresight-trace b/coresight_mode/coresight-trace
index ec0fd610..fe8b26ea 160000
--- a/coresight_mode/coresight-trace
+++ b/coresight_mode/coresight-trace
@@ -1 +1 @@
-Subproject commit ec0fd6104720ac0b59967616363dc18209adc02e
+Subproject commit fe8b26ea4b07fafa6f24e77c84dad0f3925d47d8
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
index 8809a2b2..ce65a734 160000
--- a/qemu_mode/qemuafl
+++ b/qemu_mode/qemuafl
@@ -1 +1 @@
-Subproject commit 8809a2b2ebf089d3427dd8f6a0044bcc2e13b389
+Subproject commit ce65a7349e7156e052b37a660422cad8346764d0
diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index ba9a4d9c..4697a492 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-468798455a9f9790d2da369a18ed49fda3a64e8c
+46879845
--
cgit 1.4.1
From 0b5ad8ee84b237923738a5db104e612b039113bb Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 25 Jan 2022 09:44:12 +0100
Subject: nits
---
GNUmakefile | 40 +++++++++++++++++++--------------------
utils/aflpp_driver/aflpp_driver.c | 10 +++++-----
2 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/GNUmakefile b/GNUmakefile
index 9efb22c2..68ca17d0 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -567,16 +567,16 @@ clean:
rm -rf $(PROGS) afl-fuzz-document afl-as as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 afl-cs-proxy afl-qemu-trace afl-gcc-fast afl-g++-fast ld *.so *.8 test/unittests/*.o test/unittests/unit_maybe_alloc test/unittests/preallocable .afl-* afl-gcc afl-g++ afl-clang afl-clang++ test/unittests/unit_hash test/unittests/unit_rand *.dSYM
-$(MAKE) -f GNUmakefile.llvm clean
-$(MAKE) -f GNUmakefile.gcc_plugin clean
- $(MAKE) -C utils/libdislocator clean
- $(MAKE) -C utils/libtokencap clean
+ -$(MAKE) -C utils/libdislocator clean
+ -$(MAKE) -C utils/libtokencap clean
$(MAKE) -C utils/aflpp_driver clean
- $(MAKE) -C utils/afl_network_proxy clean
- $(MAKE) -C utils/socket_fuzzing clean
- $(MAKE) -C utils/argv_fuzzing clean
+ -$(MAKE) -C utils/afl_network_proxy clean
+ -$(MAKE) -C utils/socket_fuzzing clean
+ -$(MAKE) -C utils/argv_fuzzing clean
-$(MAKE) -C utils/plot_ui clean
- $(MAKE) -C qemu_mode/unsigaction clean
- $(MAKE) -C qemu_mode/libcompcov clean
- $(MAKE) -C qemu_mode/libqasan clean
+ -$(MAKE) -C qemu_mode/unsigaction clean
+ -$(MAKE) -C qemu_mode/libcompcov clean
+ -$(MAKE) -C qemu_mode/libqasan clean
-$(MAKE) -C frida_mode clean
rm -rf nyx_mode/packer/linux_initramfs/init.cpio.gz nyx_mode/libnyx/libnyx/target/release/* nyx_mode/QEMU-Nyx/x86_64-softmmu/qemu-system-x86_64
ifeq "$(IN_REPO)" "1"
@@ -611,11 +611,11 @@ distrib: all
ifneq "$(SYS)" "Darwin"
-$(MAKE) -f GNUmakefile.gcc_plugin
endif
- $(MAKE) -C utils/libdislocator
- $(MAKE) -C utils/libtokencap
- $(MAKE) -C utils/afl_network_proxy
- $(MAKE) -C utils/socket_fuzzing
- $(MAKE) -C utils/argv_fuzzing
+ -$(MAKE) -C utils/libdislocator
+ -$(MAKE) -C utils/libtokencap
+ -$(MAKE) -C utils/afl_network_proxy
+ -$(MAKE) -C utils/socket_fuzzing
+ -$(MAKE) -C utils/argv_fuzzing
# -$(MAKE) -C utils/plot_ui
-$(MAKE) -C frida_mode
ifneq "$(SYS)" "Darwin"
@@ -631,11 +631,11 @@ endif
.PHONY: binary-only
binary-only: test_shm test_python ready $(PROGS)
- $(MAKE) -C utils/libdislocator
- $(MAKE) -C utils/libtokencap
- $(MAKE) -C utils/afl_network_proxy
- $(MAKE) -C utils/socket_fuzzing
- $(MAKE) -C utils/argv_fuzzing
+ -$(MAKE) -C utils/libdislocator
+ -$(MAKE) -C utils/libtokencap
+ -$(MAKE) -C utils/afl_network_proxy
+ -$(MAKE) -C utils/socket_fuzzing
+ -$(MAKE) -C utils/argv_fuzzing
# -$(MAKE) -C utils/plot_ui
-$(MAKE) -C frida_mode
ifneq "$(SYS)" "Darwin"
@@ -655,8 +655,8 @@ source-only: all
ifneq "$(SYS)" "Darwin"
-$(MAKE) -f GNUmakefile.gcc_plugin
endif
- $(MAKE) -C utils/libdislocator
- $(MAKE) -C utils/libtokencap
+ -$(MAKE) -C utils/libdislocator
+ -$(MAKE) -C utils/libtokencap
# -$(MAKE) -C utils/plot_ui
ifeq "$(SYS)" "Linux"
-cd nyx_mode && ./build_nyx_support.sh
diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c
index c648674a..7289c845 100644
--- a/utils/aflpp_driver/aflpp_driver.c
+++ b/utils/aflpp_driver/aflpp_driver.c
@@ -251,17 +251,17 @@ int main(int argc, char **argv) {
printf(
"============================== INFO ================================\n"
"This binary is built for afl++.\n"
- "To use with afl-cmin or afl-cmin.bash pass '-' as single command line "
- "option\n"
- "To run the target function on individual input(s) execute this:\n"
+ "To run the target function on individual input(s) execute:\n"
" %s INPUT_FILE1 [INPUT_FILE2 ... ]\n"
- "To fuzz with afl-fuzz execute this:\n"
+ "To fuzz with afl-fuzz execute:\n"
" afl-fuzz [afl-flags] -- %s [-N]\n"
"afl-fuzz will run N iterations before re-spawning the process "
"(default: "
"INT_MAX)\n"
"For stdin input processing, pass '-' as single command line option.\n"
"For file input processing, pass '@@' as single command line option.\n"
+ "To use with afl-cmin or afl-cmin.bash pass '-' as single command line "
+ "option\n"
"===================================================================\n",
argv[0], argv[0]);
@@ -325,7 +325,7 @@ int main(int argc, char **argv) {
// Call LLVMFuzzerTestOneInput here so that coverage caused by initialization
// on the first execution of LLVMFuzzerTestOneInput is ignored.
- LLVMFuzzerTestOneInput(dummy_input, 1);
+ LLVMFuzzerTestOneInput(dummy_input, 4);
__asan_poison_memory_region(__afl_fuzz_ptr, MAX_FILE);
size_t prev_length = 0;
--
cgit 1.4.1
From 28a176578172a572a03dfcbebf6479e3dcf69944 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 25 Jan 2022 12:41:22 +0100
Subject: fix atexit for rt
---
instrumentation/afl-compiler-rt.o.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index a84f31e3..af8c3218 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -155,6 +155,7 @@ static int __afl_dummy_fd[2] = {2, 2};
static void at_exit(int signal) {
if (child_pid > 0) { kill(child_pid, SIGKILL); }
+ _exit(0);
}
--
cgit 1.4.1
From 0fd6315dfb45dcc058dcf891efb8fb83eb1de225 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 25 Jan 2022 13:32:45 +0100
Subject: nit
---
instrumentation/afl-compiler-rt.o.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index af8c3218..59839750 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -154,7 +154,13 @@ static int __afl_dummy_fd[2] = {2, 2};
static void at_exit(int signal) {
- if (child_pid > 0) { kill(child_pid, SIGKILL); }
+ if (unlikely(child_pid > 0)) {
+
+ kill(child_pid, SIGKILL);
+ child_pid = -1;
+
+ }
+
_exit(0);
}
--
cgit 1.4.1
From d9ed7842987f221eee068c0b61cf890d5ed6aff7 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 25 Jan 2022 14:51:02 +0100
Subject: ensure all fuzz targets are killed on exit
---
docs/Changelog.md | 1 +
src/afl-fuzz.c | 57 ++++++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 47 insertions(+), 11 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index e25b43da..e89a0761 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -33,6 +33,7 @@ sending a mail to .
(it is better!)
- fix a regression introduced in 3.10 that resulted in less
coverage being detected. thanks to Collin May for reporting!
+ - ensure all spawned targets are killed on exit
- added AFL_IGNORE_PROBLEMS, plus checks to identify and abort on
incorrect LTO usage setups and enhanced the READMEs for better
information on how to deal with instrumenting libraries
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 06bff2be..d34cc6b4 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -46,15 +46,31 @@ extern u64 time_spent_working;
static void at_exit() {
- s32 i, pid1 = 0, pid2 = 0;
+ s32 i, pid1 = 0, pid2 = 0, pgrp = -1;
char *list[4] = {SHM_ENV_VAR, SHM_FUZZ_ENV_VAR, CMPLOG_SHM_ENV_VAR, NULL};
char *ptr;
ptr = getenv("__AFL_TARGET_PID2");
- if (ptr && *ptr && (pid2 = atoi(ptr)) > 0) kill(pid2, SIGTERM);
+ if (ptr && *ptr && (pid2 = atoi(ptr)) > 0) {
+
+#if defined(__linux__)
+ pgrp = getpgid(pid2);
+#endif
+ if (pgrp > 0) { killpg(pgrp, SIGTERM); }
+ kill(pid2, SIGTERM);
+
+ }
ptr = getenv("__AFL_TARGET_PID1");
- if (ptr && *ptr && (pid1 = atoi(ptr)) > 0) kill(pid1, SIGTERM);
+ if (ptr && *ptr && (pid1 = atoi(ptr)) > 0) {
+
+#if defined(__linux__)
+ pgrp = getpgid(pid1);
+#endif
+ if (pgrp > 0) { killpg(pgrp, SIGTERM); }
+ kill(pid1, SIGTERM);
+
+ }
ptr = getenv(CPU_AFFINITY_ENV_VAR);
if (ptr && *ptr) unlink(ptr);
@@ -85,8 +101,25 @@ static void at_exit() {
/* AFL_KILL_SIGNAL should already be a valid int at this point */
if ((ptr = getenv("AFL_KILL_SIGNAL"))) { kill_signal = atoi(ptr); }
- if (pid1 > 0) { kill(pid1, kill_signal); }
- if (pid2 > 0) { kill(pid2, kill_signal); }
+ if (pid1 > 0) {
+
+#if defined(__linux__)
+ pgrp = getpgid(pid1);
+#endif
+ if (pgrp > 0) { killpg(pgrp, kill_signal); }
+ kill(pid1, kill_signal);
+
+ }
+
+ if (pid2 > 0) {
+
+#if defined(__linux__)
+ pgrp = getpgid(pid1);
+#endif
+ if (pgrp > 0) { killpg(pgrp, kill_signal); }
+ kill(pid2, kill_signal);
+
+ }
}
@@ -121,8 +154,7 @@ static void usage(u8 *argv0, int more_help) {
#if defined(__linux__)
" -Q - use binary-only instrumentation (QEMU mode)\n"
" -U - use unicorn-based instrumentation (Unicorn mode)\n"
- " -W - use qemu-based instrumentation with Wine (Wine "
- "mode)\n"
+ " -W - use qemu-based instrumentation with Wine (Wine mode)\n"
#endif
#if defined(__linux__)
" -X - use VM fuzzing (NYX mode - standalone mode)\n"
@@ -173,8 +205,8 @@ static void usage(u8 *argv0, int more_help) {
" -T text - text banner to show on the screen\n"
" -I command - execute this command/script when a new crash is "
"found\n"
- //" -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap
- //" "file\n"
+ //" -B bitmap.txt - mutate a specific test case, use the
+ //out/default/fuzz_bitmap file\n"
" -C - crash exploration mode (the peruvian rabbit thing)\n"
" -b cpu_id - bind the fuzzing process to the specified CPU core "
"(0-...)\n"
@@ -744,6 +776,7 @@ int main(int argc, char **argv_orig, char **envp) {
case 'f': /* target file */
if (afl->fsrv.out_file) { FATAL("Multiple -f options not supported"); }
+
afl->fsrv.out_file = ck_strdup(optarg);
afl->fsrv.use_stdin = 0;
break;
@@ -923,6 +956,7 @@ int main(int argc, char **argv_orig, char **envp) {
case 'Y': /* NYX distributed mode */
if (afl->fsrv.nyx_mode) { FATAL("Multiple -Y options not supported"); }
+
afl->fsrv.nyx_mode = 1;
break;
@@ -966,6 +1000,7 @@ int main(int argc, char **argv_orig, char **envp) {
case 'Q': /* QEMU mode */
if (afl->fsrv.qemu_mode) { FATAL("Multiple -Q options not supported"); }
+
afl->fsrv.qemu_mode = 1;
if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_QEMU; }
@@ -1076,6 +1111,7 @@ int main(int argc, char **argv_orig, char **envp) {
case 'L': { /* MOpt mode */
if (afl->limit_time_sig) { FATAL("Multiple -L options not supported"); }
+
afl->havoc_max_mult = HAVOC_MAX_MULT_MOPT;
if (sscanf(optarg, "%d", &afl->limit_time_puppet) < 1) {
@@ -1276,8 +1312,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->fsrv.nyx_mode) {
OKF("afl++ Nyx mode is enabled (developed and mainted by Sergej Schumilo)");
- OKF("Nyx is open source, get it at "
- "https://github.com/Nyx-Fuzz");
+ OKF("Nyx is open source, get it at https://github.com/Nyx-Fuzz");
}
--
cgit 1.4.1
From 87f2789e98b2194dc3049a048d50e9c7cac6d82c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 25 Jan 2022 18:05:35 +0100
Subject: fix unicorn python test path
---
unicorn_mode/build_unicorn_support.sh | 2 +-
unicorn_mode/samples/c/harness.c | 2 +-
unicorn_mode/samples/compcov_x64/compcov_test_harness.py | 2 +-
unicorn_mode/samples/python_simple/simple_test_harness.py | 2 +-
unicorn_mode/samples/python_simple/simple_test_harness_alt.py | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh
index 842ad020..74f9e174 100755
--- a/unicorn_mode/build_unicorn_support.sh
+++ b/unicorn_mode/build_unicorn_support.sh
@@ -212,7 +212,7 @@ echo "[*] Unicornafl bindings installed successfully."
# Compile the sample, run it, verify that it works!
echo "[*] Testing unicornafl python functionality by running a sample test harness"
-cd ../samples/simple || echo "Cannot cd"
+cd ../samples/python_simple || echo "Cannot cd"
# Run afl-showmap on the sample application. If anything comes out then it must have worked!
unset AFL_INST_RATIO
diff --git a/unicorn_mode/samples/c/harness.c b/unicorn_mode/samples/c/harness.c
index 3a93aeaa..30972ce7 100644
--- a/unicorn_mode/samples/c/harness.c
+++ b/unicorn_mode/samples/c/harness.c
@@ -8,7 +8,7 @@
Run under AFL as follows:
- $ cd /unicorn_mode/samples/simple/
+ $ cd /unicorn_mode/samples/c
$ make
$ ../../../afl-fuzz -m none -i sample_inputs -o out -- ./harness @@
*/
diff --git a/unicorn_mode/samples/compcov_x64/compcov_test_harness.py b/unicorn_mode/samples/compcov_x64/compcov_test_harness.py
index f0749d1b..52f0a286 100644
--- a/unicorn_mode/samples/compcov_x64/compcov_test_harness.py
+++ b/unicorn_mode/samples/compcov_x64/compcov_test_harness.py
@@ -10,7 +10,7 @@
Run under AFL as follows:
- $ cd /unicorn_mode/samples/simple/
+ $ cd /unicorn_mode/samples/python_simple
$ AFL_COMPCOV_LEVEL=2 ../../../afl-fuzz -U -m none -i ./sample_inputs -o ./output -- python compcov_test_harness.py @@
"""
diff --git a/unicorn_mode/samples/python_simple/simple_test_harness.py b/unicorn_mode/samples/python_simple/simple_test_harness.py
index cd04ad3a..8c5239b6 100644
--- a/unicorn_mode/samples/python_simple/simple_test_harness.py
+++ b/unicorn_mode/samples/python_simple/simple_test_harness.py
@@ -10,7 +10,7 @@
Run under AFL as follows:
- $ cd /unicorn_mode/samples/simple/
+ $ cd /unicorn_mode/samples/python_simple
$ ../../../afl-fuzz -U -m none -i ./sample_inputs -o ./output -- python simple_test_harness.py @@
"""
diff --git a/unicorn_mode/samples/python_simple/simple_test_harness_alt.py b/unicorn_mode/samples/python_simple/simple_test_harness_alt.py
index 3249b13d..5fb3f82f 100644
--- a/unicorn_mode/samples/python_simple/simple_test_harness_alt.py
+++ b/unicorn_mode/samples/python_simple/simple_test_harness_alt.py
@@ -13,7 +13,7 @@
Run under AFL as follows:
- $ cd /unicorn_mode/samples/simple/
+ $ cd /unicorn_mode/samples/python_simple
$ ../../../afl-fuzz -U -m none -i ./sample_inputs -o ./output -- python simple_test_harness_alt.py @@
"""
--
cgit 1.4.1
From 026096ccf3b3e7e83cd332e95701e2269764e223 Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Tue, 25 Jan 2022 19:13:26 +0100
Subject: add AFL autodict capability to Nyx mode
---
nyx_mode/PACKER_VERSION | 2 +-
nyx_mode/packer | 2 +-
src/afl-forkserver.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/nyx_mode/PACKER_VERSION b/nyx_mode/PACKER_VERSION
index 0c9db1e3..43488114 100644
--- a/nyx_mode/PACKER_VERSION
+++ b/nyx_mode/PACKER_VERSION
@@ -1 +1 @@
-8842549
+76100c5
diff --git a/nyx_mode/packer b/nyx_mode/packer
index 8842549b..76100c52 160000
--- a/nyx_mode/packer
+++ b/nyx_mode/packer
@@ -1 +1 @@
-Subproject commit 8842549b5612a890258dcef812276cfdb62b76c7
+Subproject commit 76100c52db96429350693a6c7284c5c6cbcb6b08
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 62110ad5..031c8fd4 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -425,6 +425,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
}
+ ck_free(x);
if (fsrv->nyx_runner == NULL) { FATAL("Something went wrong ..."); }
@@ -464,6 +465,61 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
+ /* autodict in Nyx mode */
+ if (!ignore_autodict) {
+ x = alloc_printf("%s/workdir/dump/afl_autodict.txt", fsrv->out_dir_path);
+ int nyx_autodict_fd = open(x, O_RDONLY);
+ ck_free(x);
+
+ if (nyx_autodict_fd >= 0) {
+ struct stat st;
+ if (fstat(nyx_autodict_fd, &st) >= 0) {
+ u32 f_len = st.st_size;
+ u8 *dict = ck_alloc(f_len);
+ if (dict == NULL) {
+ FATAL("Could not allocate %u bytes of autodictionary memory", f_len);
+ }
+
+ u32 offset = 0, count = 0;
+ u32 len = f_len;
+
+ while (len != 0) {
+
+ rlen = read(nyx_autodict_fd, dict + offset, len);
+ if (rlen > 0) {
+
+ len -= rlen;
+ offset += rlen;
+
+ } else {
+
+ FATAL(
+ "Reading autodictionary fail at position %u with %u bytes "
+ "left.",
+ offset, len);
+ }
+
+ }
+ close(nyx_autodict_fd);
+
+ offset = 0;
+ while (offset < (u32)f_len &&
+ (u8)dict[offset] + offset < (u32)f_len) {
+
+ fsrv->add_extra_func(fsrv->afl_ptr, dict + offset + 1,
+ (u8)dict[offset]);
+ offset += (1 + dict[offset]);
+ count++;
+
+ }
+
+ if (!be_quiet) { ACTF("Loaded %u autodictionary entries", count); }
+ ck_free(dict);
+
+ }
+ }
+ }
+
return;
}
--
cgit 1.4.1
From 615a8ff986e2d456a4afa546f8b9418bf77c8792 Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Tue, 25 Jan 2022 19:33:47 +0100
Subject: close autodict file even if fstat fails (Nyx mode)
---
src/afl-forkserver.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 031c8fd4..6a1fe858 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -500,7 +500,6 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
}
- close(nyx_autodict_fd);
offset = 0;
while (offset < (u32)f_len &&
@@ -517,6 +516,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
ck_free(dict);
}
+ close(nyx_autodict_fd);
}
}
--
cgit 1.4.1
From 016bdc36bb7186e6c74e10aada9a5b73ff1ff5bc Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 25 Jan 2022 19:54:46 +0100
Subject: code-format
---
nyx_mode/README.md | 4 ++++
src/afl-forkserver.c | 25 ++++++++++++++++++-------
2 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/nyx_mode/README.md b/nyx_mode/README.md
index b75f1793..09421f27 100644
--- a/nyx_mode/README.md
+++ b/nyx_mode/README.md
@@ -43,6 +43,10 @@ requires an Intel processor (6th generation onwards) and a special 5.10 kernel
## Preparing to fuzz a target with Nyx mode
+For source instrumented fuzzing you can use any afl-cc mode, with LTO even
+auto-dictionary is supported.
+Note the CMPLOG is currently not supported (yet).
+
Nyx uses full system emulation hence your fuzzing targets have to be especially
packaged.
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 6a1fe858..ce554170 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -425,6 +425,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
}
+
ck_free(x);
if (fsrv->nyx_runner == NULL) { FATAL("Something went wrong ..."); }
@@ -467,17 +468,23 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
/* autodict in Nyx mode */
if (!ignore_autodict) {
+
x = alloc_printf("%s/workdir/dump/afl_autodict.txt", fsrv->out_dir_path);
int nyx_autodict_fd = open(x, O_RDONLY);
ck_free(x);
- if (nyx_autodict_fd >= 0) {
+ if (nyx_autodict_fd >= 0) {
+
struct stat st;
- if (fstat(nyx_autodict_fd, &st) >= 0) {
+ if (fstat(nyx_autodict_fd, &st) >= 0) {
+
u32 f_len = st.st_size;
u8 *dict = ck_alloc(f_len);
if (dict == NULL) {
- FATAL("Could not allocate %u bytes of autodictionary memory", f_len);
+
+ FATAL("Could not allocate %u bytes of autodictionary memory",
+ f_len);
+
}
u32 offset = 0, count = 0;
@@ -497,16 +504,17 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
"Reading autodictionary fail at position %u with %u bytes "
"left.",
offset, len);
+
}
}
-
+
offset = 0;
while (offset < (u32)f_len &&
- (u8)dict[offset] + offset < (u32)f_len) {
+ (u8)dict[offset] + offset < (u32)f_len) {
fsrv->add_extra_func(fsrv->afl_ptr, dict + offset + 1,
- (u8)dict[offset]);
+ (u8)dict[offset]);
offset += (1 + dict[offset]);
count++;
@@ -516,10 +524,13 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
ck_free(dict);
}
+
close(nyx_autodict_fd);
+
}
+
}
-
+
return;
}
--
cgit 1.4.1
From eebc2f4f1e8985af575d66a01e7d866ecdc10352 Mon Sep 17 00:00:00 2001
From: Dominik Maier
Date: Wed, 26 Jan 2022 01:33:58 +0100
Subject: adapt test harness to unicornafl for uc2
---
unicorn_mode/samples/python_simple/simple_test_harness.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/unicorn_mode/samples/python_simple/simple_test_harness.py b/unicorn_mode/samples/python_simple/simple_test_harness.py
index 8c5239b6..8758192e 100644
--- a/unicorn_mode/samples/python_simple/simple_test_harness.py
+++ b/unicorn_mode/samples/python_simple/simple_test_harness.py
@@ -19,7 +19,7 @@ import os
import signal
from unicornafl import *
-from unicornafl.mips_const import *
+from unicorn.mips_const import *
# Path to the file containing the binary to emulate
BINARY_FILE = os.path.join(
@@ -156,7 +156,7 @@ def main():
uc.mem_write(DATA_ADDRESS, input)
# Start the fuzzer.
- uc.afl_fuzz(args.input_file, place_input_callback, [end_address])
+ uc_afl_fuzz(uc=uc, input_file=args.input_file, place_input_callback=place_input_callback, exits=[end_address])
if __name__ == "__main__":
--
cgit 1.4.1
From 6bf52c14348b675953367eeadc62f4b73cedc397 Mon Sep 17 00:00:00 2001
From: Dominik Maier
Date: Wed, 26 Jan 2022 09:24:37 +0100
Subject: svg logo
---
README.md | 2 +-
coresight_mode/coresight-trace | 2 +-
custom_mutators/grammar_mutator/grammar_mutator | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index ccef6e30..47ed7a5c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# American Fuzzy Lop plus plus (AFL++)
-
+
Release version: [3.14c](https://github.com/AFLplusplus/AFLplusplus/releases)
diff --git a/coresight_mode/coresight-trace b/coresight_mode/coresight-trace
index fe8b26ea..ec0fd610 160000
--- a/coresight_mode/coresight-trace
+++ b/coresight_mode/coresight-trace
@@ -1 +1 @@
-Subproject commit fe8b26ea4b07fafa6f24e77c84dad0f3925d47d8
+Subproject commit ec0fd6104720ac0b59967616363dc18209adc02e
diff --git a/custom_mutators/grammar_mutator/grammar_mutator b/custom_mutators/grammar_mutator/grammar_mutator
index cbe5e327..6ca490c6 160000
--- a/custom_mutators/grammar_mutator/grammar_mutator
+++ b/custom_mutators/grammar_mutator/grammar_mutator
@@ -1 +1 @@
-Subproject commit cbe5e32752773945e0142fac9f1b7a0ccb5dcdff
+Subproject commit 6ca490c66b949db20d8c861ebc8fb2e6ca725ead
--
cgit 1.4.1
From 77c06408c35e889ac0091efe102ed57ce60c94a4 Mon Sep 17 00:00:00 2001
From: Dominik Maier
Date: Wed, 26 Jan 2022 09:26:03 +0100
Subject: resized logo
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 47ed7a5c..f050728c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# American Fuzzy Lop plus plus (AFL++)
-
+
Release version: [3.14c](https://github.com/AFLplusplus/AFLplusplus/releases)
--
cgit 1.4.1
From b0758ac8db0a2ec833b5ef7a60ab2d04cc7f6a9a Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 26 Jan 2022 09:55:12 +0100
Subject: 4.00c readiness
---
README.md | 4 ++--
coresight_mode/coresight-trace | 2 +-
custom_mutators/grammar_mutator/grammar_mutator | 2 +-
docs/Changelog.md | 2 +-
include/config.h | 2 +-
src/afl-fuzz.c | 2 +-
test/test-unicorn-mode.sh | 4 ++--
7 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/README.md b/README.md
index f050728c..049518f8 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
-Release version: [3.14c](https://github.com/AFLplusplus/AFLplusplus/releases)
+Release version: [4.00c](https://github.com/AFLplusplus/AFLplusplus/releases)
-GitHub version: 3.15a
+GitHub version: 4.00c
Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
diff --git a/coresight_mode/coresight-trace b/coresight_mode/coresight-trace
index ec0fd610..fe8b26ea 160000
--- a/coresight_mode/coresight-trace
+++ b/coresight_mode/coresight-trace
@@ -1 +1 @@
-Subproject commit ec0fd6104720ac0b59967616363dc18209adc02e
+Subproject commit fe8b26ea4b07fafa6f24e77c84dad0f3925d47d8
diff --git a/custom_mutators/grammar_mutator/grammar_mutator b/custom_mutators/grammar_mutator/grammar_mutator
index 6ca490c6..cbe5e327 160000
--- a/custom_mutators/grammar_mutator/grammar_mutator
+++ b/custom_mutators/grammar_mutator/grammar_mutator
@@ -1 +1 @@
-Subproject commit 6ca490c66b949db20d8c861ebc8fb2e6ca725ead
+Subproject commit cbe5e32752773945e0142fac9f1b7a0ccb5dcdff
diff --git a/docs/Changelog.md b/docs/Changelog.md
index e89a0761..7f539556 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -8,7 +8,7 @@
Want to stay in the loop on major new features? Join our mailing list by
sending a mail to .
-### Version ++3.15a (dev)
+### Version ++4.00c (release)
- complete documentation restructuring, made possible by Google Season
of Docs :) thank you Jana!
- we renamed several UI and fuzzer_stat entries to be more precise,
diff --git a/include/config.h b/include/config.h
index 99cacc40..66a646b1 100644
--- a/include/config.h
+++ b/include/config.h
@@ -26,7 +26,7 @@
/* Version string: */
// c = release, a = volatile github dev, e = experimental branch
-#define VERSION "++3.15a"
+#define VERSION "++4.00c"
/******************************************************
* *
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index d34cc6b4..a96dee97 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -315,7 +315,7 @@ static void usage(u8 *argv0, int more_help) {
SAYF("Compiled with %s module support, see docs/custom_mutator.md\n",
(char *)PYTHON_VERSION);
#else
- SAYF("Compiled without python module support.\n");
+ SAYF("Compiled without Python module support.\n");
#endif
#ifdef AFL_PERSISTENT_RECORD
diff --git a/test/test-unicorn-mode.sh b/test/test-unicorn-mode.sh
index e197e226..182958d6 100755
--- a/test/test-unicorn-mode.sh
+++ b/test/test-unicorn-mode.sh
@@ -4,7 +4,7 @@
$ECHO "$BLUE[*] Testing: unicorn_mode"
test -d ../unicorn_mode/unicornafl -a -e ../unicorn_mode/unicornafl/samples/shellcode && {
- test -e ../unicorn_mode/samples/simple/simple_target.bin -a -e ../unicorn_mode/samples/compcov_x64/compcov_target.bin && {
+ test -e ../unicorn_mode/samples/python_simple/simple_target.bin -a -e ../unicorn_mode/samples/compcov_x64/compcov_target.bin && {
{
# We want to see python errors etc. in logs, in case something doesn't work
export AFL_DEBUG_CHILD=1
@@ -61,7 +61,7 @@ test -d ../unicorn_mode/unicornafl -a -e ../unicorn_mode/unicornafl/samples/shel
{
$ECHO "$GREY[*] running afl-fuzz for unicorn_mode in python, this will take approx 25 seconds"
{
- ../afl-fuzz -m ${MEM_LIMIT} -V25 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/simple/simple_test_harness.py @@ >>errors 2>&1
+ ../afl-fuzz -m ${MEM_LIMIT} -V25 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/python_simple/simple_test_harness.py @@ >>errors 2>&1
} >>errors 2>&1
test -n "$( ls out/default/queue/id:000002* 2>/dev/null )" && {
$ECHO "$GREEN[+] afl-fuzz is working correctly with unicorn_mode"
--
cgit 1.4.1