about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--frida_mode/DEBUGGING.md160
-rw-r--r--frida_mode/README.md3
-rw-r--r--frida_mode/src/cmplog/cmplog.c4
-rw-r--r--frida_mode/src/entry.c2
-rw-r--r--frida_mode/src/instrument/instrument.c4
5 files changed, 169 insertions, 4 deletions
diff --git a/frida_mode/DEBUGGING.md b/frida_mode/DEBUGGING.md
new file mode 100644
index 00000000..f8d91f2f
--- /dev/null
+++ b/frida_mode/DEBUGGING.md
@@ -0,0 +1,160 @@
+If you are using FRIDA mode and have hit some problems, then this guide may help
+you to diagnose any problems you are encountering. This assumes you have
+followed the [osx-lib](#test/osx-lib) example to start fuzzing your target.
+
+It should be noted that attempting to debug code using gdb which has been
+instrumented in FRIDA is unlikely to be successful since the debugger will be
+inserting breakpoints by patching the code in memory. FRIDA works by reading
+this code and generating an instrumented copy to execute. In any case, unless
+you are very familiar with the implementation of Stalker, the instrumented code
+generated by FRIDA is likely to be very difficult to follow. For this reason,
+the following debugging strategies are outlined below.
+
+Byte convention below all files should be provided with their path (they are
+omitted for readability) and all items in `<braces>` are placeholders and should
+be replaced accordingly.
+
+# Select your version
+Test with both the `dev` and `stable` branches of AFL++. The `dev` branch should
+have the very latest version containing any fixes for identified issues. The
+`stable` branch is updated less frequently, but equally might avoid a problem if
+a regression has been introduced into the `dev` branch.
+
+# Enable Diagnostic Information
+- Run your target specifying the `AFL_DEBUG_CHILD=1` environment variable. This
+  will print a lot more diagnostic information to the screen when the target
+  starts up. If you have a simple configuration issue then you will likely see a
+  warning or error message in the output.
+
+# Check your Test Harness
+If any of the following steps fail, then there is a problem with your test
+harness, or your target library. Since this is running without FRIDA mode or
+`afl-fuzz` that greatly reduces the search area for your defect. This is why it
+is *VERY* important to carry out these basic steps first before taking on the
+additional complexity of debugging with FRIDA mode or `afl-fuzz`.
+
+- Run your harness outside of the fuzzer, passing it a representative seed as
+  it's input `./harness <input>`.
+- Pass you harness multiple seeds to check that it is stable when running
+  multiple tests as it will when running in fork server mode `./harness <input1>
+  <intput2>`.
+- Build your test harness with `CFLAGS=-fsanitize=address` and
+  `LDFLAGS=-fsanitize=address`. Then run it again with multiple inputs to check
+  for errors (note that when fuzzing your harness should not be built with any
+  sanitizer options).
+
+# Check the Samples
+FRIDA mode contains a number of different sample targets in the `test` folder.
+Have a look throught these and find one which is similar to your real target.
+Check whether you have any issues running the sample target and make sure you
+compare the command line used to launch the sample with that you are using to
+launch your real target very carefully to check for any differences. If possible
+start with one of these samples and gradually make changes one at a time
+re-testing as you go until you have migrated it to run your own target.
+
+# FRIDA Mode
+## Basic
+First just try running your target with `LD_PRELOAD=afl-frida-trace.so ./harness
+ <input>`. An error here means that your defect occurs when running with just
+ FRIDA mode and isn't related to `afl-fuzz`.
+
+Now you can try commenting out the implementation of `LLVMFuzzerTestOneInput` so
+that the harness doesn't actually run your target library. This may also aid in
+narrowing down the problem.
+```c
+int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size){
+    // fpn_crashme(data, size);
+    return 0;
+}
+
+```
+
+## Persistent Mode
+If your target is ok running in basic mode, you can try running it in persistent
+mode (if that is the configuration you are having issues with) as follows (again
+outside of afl-fuzz). This time you will want to run it inside a debugger so
+that you can use the debugger to send the `SIGCONT` signals (by continuing)
+usually sent by `afl-fuzz` on each iteration.
+
+```bash
+gdb \
+  --ex 'set environment __AFL_PERSISTENT=1' \
+  --ex 'set environment AFL_FRIDA_PERSISTENT_CNT=3' \
+  --ex 'set environment LD_PRELOAD=afl-frida-trace.so' \
+  --ex 'set environment AFL_FRIDA_PERSISTENT_ADDR=<entry_address>' \
+  --args ./harness <input>
+```
+Note we have to manually set the `__AFL_PERSISTENT` environment variable which
+is usually passed by `afl-fuzz`.
+
+Note that setting breakpoints etc is likely to interfere with FRIDA and cause
+spurious errors.
+
+If this is successful, you can try additionally loading the hook library:
+```bash
+gdb \
+  --ex 'set environment __AFL_PERSISTENT=1' \
+  --ex 'set environment AFL_FRIDA_PERSISTENT_CNT=3' \
+  --ex 'set environment LD_PRELOAD=afl-frida-trace.so' \
+  --ex 'set environment AFL_FRIDA_PERSISTENT_ADDR=<entry_address>' \
+  --ex 'set environment AFL_FRIDA_PERSISTENT_HOOK=frida_hook.so'
+  --args ./harness <input>
+```
+Note that the format of the hook used for FRIDA mode is subtly different to that
+used when running in QEMU mode as shown below. Thus the DSO used for the hook is
+not interchangeable.
+
+```c
+void afl_persistent_hook(GumCpuContext *regs, uint8_t *input_buf,
+                         uint32_t input_buf_len);
+
+void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base,
+                         uint8_t *input_buf, uint32_t input_buf_len);
+```
+
+## ASAN
+It is also possible to enalbe ASAN (if that is the configuration you are having
+issues with) without having to use `afl-fuzz` this can be done as follows (note
+that the name of the asan DSO may need to be changed depending on your
+platform). Note that the asan DSO must appear first in the `LD_PRELOAD`
+environment variable:
+
+```bash
+LD_PRELOAD=libclang_rt.asan-x86_64.so:afl-frida-trace.so \
+ASAN_OPTIONS=detect_leaks=false,halt_on_error=0 \
+AFL_USE_FASAN=1 \
+  ./harness <input>
+```
+
+Note that care should be taken to ensure that if you set `AFL_INST_LIBS=1`, you
+use `AFL_FRIDA_INST_RANGES` or `AFL_FRIDA_EXCLUDE_RANGES` to exclude the ASAN
+DSO from coverage. Failure to do so will result in ASAN attempting to sanitize
+itself and as a result detecting failures when it attempts to update the shadow
+maps.
+
+# Printf
+If you have an idea of where things are going wrong for you, then don't be
+scared to add `printf` statements to either AFL++ or FRIDA mode itself to show
+more diagnostic information. Just be sure to set `AFL_DEBUG=1` and
+`AFL_DEBUG_CHILD=1` when you are testing it.
+
+# Core Dumps
+Lastly, if your defect only occurs when using `afl-fuzz` (e.g. when using
+`CMPLOG` which cannot be tested outside of `afl-fuzz` due to it's need for a
+shared memory mapping being created for it to record its data), it is possible
+to enable the creation of a core dump for post-mortem analysis.
+
+Firstly check your `/proc/sys/kernel/core_pattern` configuration is simply set
+to a filename (AFL++ encourages you to set it to the value 'core' in any case
+since it doesn't want any handler applications getting in the way). Next set
+`ulimit -c unlimited` to remove any size limitations for core files. Lastly,
+when you `afl-fuzz` set the environment variable `AFL_DEBUG=1` to enable the
+creation of the `core` file. The file should be created in the working directory
+of the target application. If there is an existing `core` file aleady there,
+then it may not be overwritten.
+
+# Reach out
+Get in touch on discord and ask for help. The groups are pretty active so
+someone may well be able to offer some advice. Better still, if you are able to
+create a minimal reproducer for your problem it will make it easier to diagnose
+the issue.
diff --git a/frida_mode/README.md b/frida_mode/README.md
index 63959af6..83612210 100644
--- a/frida_mode/README.md
+++ b/frida_mode/README.md
@@ -311,6 +311,9 @@ of `main`, since this is the point that FRIDA mode is initialized. Otherwise, it
 will not be possible to configure coverage for the test library using
 `AFL_FRIDA_INST_RANGES` or similar.
 
+# Debugging
+Please refer to the [debugging](#debugging) guide for assistant should you
+encounter problems with FRIDA mode.
 
 ## TODO
 
diff --git a/frida_mode/src/cmplog/cmplog.c b/frida_mode/src/cmplog/cmplog.c
index a2609c8e..ae3116eb 100644
--- a/frida_mode/src/cmplog/cmplog.c
+++ b/frida_mode/src/cmplog/cmplog.c
@@ -56,7 +56,9 @@ void cmplog_config(void) {
 
 void cmplog_init(void) {
 
-  if (__afl_cmp_map != NULL) { OKF("CMPLOG mode enabled"); }
+  OKF("CMPLOG - Enabled [%c]", __afl_cmp_map == NULL ? ' ' : 'X');
+
+  if (__afl_cmp_map == NULL) { return; }
 
   cmplog_get_ranges();
 
diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c
index a0ffd028..0b5f61ec 100644
--- a/frida_mode/src/entry.c
+++ b/frida_mode/src/entry.c
@@ -21,6 +21,7 @@ static void entry_launch(void) {
   __afl_manual_init();
 
   /* Child here */
+  entry_reached = TRUE;
   instrument_on_fork();
   stats_on_fork();
 
@@ -59,7 +60,6 @@ void entry_prologue(GumStalkerIterator *iterator, GumStalkerOutput *output) {
 
   if (persistent_start == 0) {
 
-    entry_reached = TRUE;
     ranges_exclude();
     stalker_trust();
 
diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c
index 67aafa5a..fddff19a 100644
--- a/frida_mode/src/instrument/instrument.c
+++ b/frida_mode/src/instrument/instrument.c
@@ -116,8 +116,8 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context,
 
   }
 
-  instrument_previous_pc =
-      ((current_pc & (MAP_SIZE - 1) >> 1)) | ((current_pc & 0x1) << 15);
+  instrument_previous_pc = ((current_pc & (MAP_SIZE - 1) >> 1)) |
+                           ((current_pc & 0x1) << (MAP_SIZE_POW2 - 1));
 
 }