* `AFL_FRIDA_INST_CACHE_SIZE` - Set the size of the instrumentation cache used as a look-up table to cache real to instrumented address block translations. Default is 256Mb. * `AFL_FRIDA_INST_INSN` - Generate instrumentation for conditional instructions (e.g. `CMOV` instructions on x64). * `AFL_FRIDA_INST_JIT` - Enable the instrumentation of Just-In-Time compiled code. Code is considered to be JIT if the executable segment is not backed by a file. * `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage instrumentation (the default where available). Required to use `AFL_FRIDA_INST_TRACE`. * `AFL_FRIDA_INST_NO_CACHE` - Don't use a look-up table to cache real to instrumented address block translations. * `AFL_FRIDA_INST_NO_PREFETCH` - Disable prefetching. By default, the child will report instrumented blocks back to the parent so that it can also instrument them and they be inherited by the next child on fork, implies `AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH`. * `AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH` - Disable prefetching of stalker backpatching information. By default, the child will report applied backpatches to the parent so that they can be applied and then be inherited by the next child on fork. * `AFL_FRIDA_INST_SEED` - Sets the initial seed for the hash function used to generate block (and hence edge) IDs. Setting this to a constant value may be useful for debugging purposes, e.g., investigating unstable edges. * `AFL_FRIDA_INST_TRACE` - Log to stdout the address of executed blocks, implies `AFL_FRIDA_INST_NO_OPTIMIZE`. * `AFL_FRIDA_INST_TRACE_UNIQUE` - As per `AFL_FRIDA_INST_TRACE`, but each edge is logged only once, requires `AFL_FRIDA_INST_NO_OPTIMIZE`. * `AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE` - File to write DynamoRIO format coverage information for unstable edges (e.g., to be loaded within IDA lighthouse). * `AFL_FRIDA_JS_SCRIPT` - Set the script to be loaded by the FRIDA scripting engine. See [Scipting.md](Scripting.md) for details. * `AFL_FRIDA_OUTPUT_STDOUT` - Redirect the standard output of the target application to the named file (supersedes the setting of `AFL_DEBUG_CHILD`). * `AFL_FRIDA_OUTPUT_STDERR` - Redirect the standard error of the target application to the named file (supersedes the setting of `AFL_DEBUG_CHILD`). * `AFL_FRIDA_PERSISTENT_DEBUG` - Insert a Breakpoint into the instrumented code at `AFL_FRIDA_PERSISTENT_HOOK` and `AFL_FRIDA_PERSISTENT_RET` to allow the user to detect issues in the persistent loop using a debugger.
gdb
--ex ‘set environment AFL_FRIDA_PERSISTENT_ADDR=XXXXXXXXXX’
--ex ‘set environment AFL_FRIDA_PERSISTENT_RET=XXXXXXXXXX’
--ex ‘set environment AFL_FRIDA_PERSISTENT_DEBUG=1’
--ex ‘set environment AFL_DEBUG_CHILD=1’
--ex ‘set environment LD_PRELOAD=afl-frida-trace.so’
--args [my arguments]
* `AFL_FRIDA_SECCOMP_FILE` - Write a log of any syscalls made by the target to the specified file. * `AFL_FRIDA_STALKER_ADJACENT_BLOCKS` - Configure the number of adjacent blocks to fetch when generating instrumented code. By fetching blocks in the same order they appear in the original program, rather than the order of execution should help reduce locality and adjacency. This includes allowing us to vector between adjacent blocks using a NOP slide rather than an immediate branch. * `AFL_FRIDA_STALKER_IC_ENTRIES` - Configure the number of inline cache entries stored along-side branch instructions which provide a cache to avoid having to call back into FRIDA to find the next block. Default is 32. * `AFL_FRIDA_STALKER_NO_BACKPATCH` - Disable backpatching. At the end of executing each block, control will return to FRIDA to identify the next block to execute. * `AFL_FRIDA_STATS_FILE` - Write statistics information about the code being instrumented to the given file name. The statistics are written only for the child process when new block is instrumented (when the `AFL_FRIDA_STATS_INTERVAL` has expired). Note that just because a new path is found does not mean a new block needs to be compiled. It could be that the existing blocks instrumented have been executed in a different order.
Time 2021-07-21 11:45:49 Elapsed 1 seconds
Transitions cumulative delta
total 753619 17645 call_imm 9193 ( 1.22%) 344 ( 1.95%) [ 344/s] call_reg 0 ( 0.00%) 0 ( 0.00%) [ 0/s] call_mem 0 ( 0.00%) 0 ( 0.00%) [ 0/s] ret_slow_path 67974 ( 9.02%) 2988 (16.93%) [ 2988/s] post_call_invoke 7996 ( 1.06%) 299 ( 1.69%) [ 299/s] excluded_call_imm 3804 ( 0.50%) 200 ( 1.13%) [ 200/s] jmp_imm 5445 ( 0.72%) 255 ( 1.45%) [ 255/s] jmp_reg 42081 ( 5.58%) 1021 ( 5.79%) [ 1021/s] jmp_mem 578092 (76.71%) 10956 (62.09%) [ 10956/s] jmp_cond_imm 38951 ( 5.17%) 1579 ( 8.95%) [ 1579/s] jmp_cond_mem 0 ( 0.00%) 0 ( 0.00%) [ 0/s] jmp_cond_reg 0 ( 0.00%) 0 ( 0.00%) [ 0/s] jmp_cond_jcxz 0 ( 0.00%) 0 ( 0.00%) [ 0/s] jmp_continuation 84 ( 0.01%) 3 ( 0.02%) [ 3/s]
Instructions 7907 Blocks 1764 Avg Instructions / Block 4
Total 1763 (22.30%) Call Immediates 358 ( 4.53%) Call Immediates Excluded 74 ( 0.94%) Call Register 0 ( 0.00%) Call Memory 0 ( 0.00%) Jump Immediates 176 ( 2.23%) Jump Register 8 ( 0.10%) Jump Memory 10 ( 0.13%) Conditional Jump Immediates 1051 (13.29%) Conditional Jump CX Immediate 0 ( 0.00%) Conditional Jump Register 0 ( 0.00%) Conditional Jump Memory 0 ( 0.00%) Returns 160 ( 2.02%)
Total 232 ( 2.93%) addsd 2 ( 0.86%) cmp 46 (19.83%) comisd 2 ( 0.86%) divsd 2 ( 0.86%) divss 2 ( 0.86%) lea 142 (61.21%) mov 32 (13.79%) movsd 2 ( 0.86%) ucomisd 2 ( 0.86%)
* `AFL_FRIDA_STATS_INTERVAL` - The maximum frequency to output statistics information. Stats will be written whenever they are updated if the given interval has elapsed since last time they were written. * `AFL_FRIDA_TRACEABLE` - Set the child process to be traceable by any process to aid debugging and overcome the restrictions imposed by YAMA. Supported on Linux only. Permits a non-root user to use `gcore` or similar to collect a core dump of the instrumented target. Note that in order to capture the core dump you must set a sufficient timeout (using `-t`) to avoid `afl-fuzz` killing the process whilst it is being dumped. * `AFL_FRIDA_VERBOSE` - Enable verbose output from FRIDA mode. ## FASAN - FRIDA Address Sanitizer mode FRIDA mode also supports FASAN. The design of this is actually quite simple and very similar to that used when instrumenting applications compiled from source. ### Address Sanitizer basics When Address Sanitizer is used to instrument programs built from source, the compiler first adds a dependency (`DT_NEEDED` entry) for the Address Sanitizer dynamic shared object (DSO). This shared object contains the main logic for Address Sanitizer, including setting and managing up the shadow memory. It also provides replacement implementations for a number of functions in standard libraries. These replacements include things like `malloc` and `free` which allows for those allocations to be marked in the shadow memory, but also a number of other functions. Consider `memcpy`, for example. This is instrumented to validate the parameters (test the source and destination buffers against the shadow memory). This is much easier than instrumenting those standard libraries, since first, it would require you to re-compile them and secondly it would mean that the instrumentation would be applied at a more expensive granular level. Lastly, load-widening (typically found in highly optimized code) can also make this instrumentation more difficult. Since the DSO is loaded before all of the standard libraries (in fact it insists on being first), the dynamic loader will use it to resolve imports from other modules which depend on it. ### FASAN implementation FASAN takes a similar approach. It requires the user to add the Address Sanitizer DSO to the `AFL_PRELOAD` environment variable such that it is loaded into the target. Again, it must be first in the list. This means that it is not necessary to instrument the standard libraries to detect when an application has provided an incorrect argument to `memcpy`, for example. This avoids issues with load-widening and should also mean a huge improvement in performance. FASAN then adds instrumentation for any instructions which use memory operands and then calls into the `__asan_loadN` and `__asan_storeN` functions provided by the DSO to validate memory accesses against the shadow memory. ## Collisions FRIDA mode has also introduced some improvements to reduce collisions in the map. For details, see [MapDensity.md](MapDensity.md). ## OSX library fuzzing An example of how to fuzz a dynamic library on OSX is included, see [test/osx-lib](test/osx-lib). This requires the use of a simple test harness executable which will load the library and call a target function within it. The dependent library can either be loaded in using `dlopen` and `dlsym` in a function marked `__attribute__((constructor()))` or the test harness can be linked against it. It is important that the target library is loaded before execution of `main`, since this is the point where 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 Should you encounter problems with FRIDA mode, refer to [DEBUGGING.md](DEBUGGING.md) for assistance. ## To do The next features to be added are Aarch32 support as well as looking at potential performance improvements. The intention is to achieve feature parity with QEMU mode in due course. Contributions are welcome, but please get in touch to ensure that efforts are deconflicted.