Edit FRIDA mode README.md

This commit is contained in:
llzmb
2021-11-25 15:15:43 +01:00
parent 0e9b208949
commit ce21346053

View File

@ -1,38 +1,40 @@
# FRIDA MODE # FRIDA mode
The purpose of FRIDA mode is to provide an alternative binary only fuzzer for The purpose of FRIDA mode is to provide an alternative binary only fuzzer for
AFL just like that provided by QEMU mode. The intention is to provide a very AFL++ just like that provided by QEMU mode. The intention is to provide a very
similar user experience, right down to the options provided through environment similar user experience, right down to the options provided through environment
variables. variables.
Whilst AFLplusplus already has some support for running on FRIDA [here](https://github.com/AFLplusplus/AFLplusplus/tree/stable/utils/afl_frida) Whilst AFL++ already has some support for running on FRIDA
[here](https://github.com/AFLplusplus/AFLplusplus/tree/stable/utils/afl_frida),
this requires the code to be fuzzed to be provided as a shared library, it this requires the code to be fuzzed to be provided as a shared library, it
cannot be used to fuzz executables. Additionally, it requires the user to write cannot be used to fuzz executables. Additionally, it requires the user to write
a small harness around their target code of interest. a small harness around their target code of interest. FRIDA mode instead takes a
FRIDA mode instead takes a different approach to avoid these limitations. different approach to avoid these limitations. In FRIDA mode, binary programs
In Frida mode binary programs are instrumented, similarly to QEMU mode. are instrumented, similarly to QEMU mode.
## Current Progress ## Current progress
As FRIDA mode is new, it is missing a lot of features. The design is such that it As FRIDA mode is new, it is missing a lot of features. The design is such that
should be possible to add these features in a similar manner to QEMU mode and it should be possible to add these features in a similar manner to QEMU mode and
perhaps leverage some of its design and implementation. perhaps leverage some of its design and implementation.
| Feature/Instrumentation | frida-mode | Notes | | Feature/Instrumentation | frida-mode | Notes |
| -------------------------|:----------:|:--------------------------------------------:| | -------------------------|:----------:|:--------------------------------------------:|
| NeverZero | x | | | NeverZero | x | |
| Persistent Mode | x | (x86/x64/aarch64 only) | | Persistent Mode | x | (x86/x64/aarch64 only) |
| LAF-Intel / CompCov | - | (CMPLOG is better 90% of the time) | | LAF-Intel / CompCov | - | (CMPLOG is better 90% of the time) |
| CMPLOG | x | (x86/x64/aarch64 only) | | CMPLOG | x | (x86/x64/aarch64 only) |
| Selective Instrumentation| x | | | Selective Instrumentation| x | |
| Non-Colliding Coverage | - | (Not possible in binary-only instrumentation | | Non-Colliding Coverage | - | (not possible in binary-only instrumentation) |
| Ngram prev_loc Coverage | - | | | Ngram prev_loc Coverage | - | |
| Context Coverage | - | | | Context Coverage | - | |
| Auto Dictionary | - | | | Auto Dictionary | - | |
| Snapshot LKM Support | - | | | Snapshot LKM Support | - | |
| In-Memory Test Cases | x | (x86/x64/aarch64 only) | | In-Memory Test Cases | x | (x86/x64/aarch64 only) |
## Compatibility ## Compatibility
Currently FRIDA mode supports Linux and macOS targets on both x86/x64 Currently FRIDA mode supports Linux and macOS targets on both x86/x64
architecture and aarch64. Later releases may add support for aarch32 and Windows architecture and aarch64. Later releases may add support for aarch32 and Windows
targets as well as embedded linux environments. targets as well as embedded linux environments.
@ -41,60 +43,58 @@ FRIDA has been used on various embedded targets using both uClibc and musl C
runtime libraries, so porting should be possible. However, the current build runtime libraries, so porting should be possible. However, the current build
system does not support cross compilation. system does not support cross compilation.
## Getting Started ## Getting started
To build everything run `make`. To build for x86 run `make 32`. Note that in To build everything, run `make`. To build for x86, run `make 32`. Note that in
x86 bit mode, it is not necessary for afl-fuzz to be built for 32-bit. However, x86 bit mode, it is not necessary for afl-fuzz to be built for 32-bit. However,
the shared library for frida_mode must be since it is injected into the target the shared library for frida_mode must be since it is injected into the target
process. process.
Various tests can be found in subfolders within the `test/` directory. To use Various tests can be found in subfolders within the `test/` directory. To use
these, first run `make` to build any dependencies. Then run `make qemu` or these, first run `make` to build any dependencies. Then run `make qemu` or `make
`make frida` to run on either QEMU of FRIDA mode respectively. To run frida frida` to run on either QEMU of FRIDA mode respectively. To run frida tests in
tests in 32-bit mode, run `make ARCH=x86 frida`. When switching between 32-bit mode, run `make ARCH=x86 frida`. When switching between architectures, it
architectures it may be necessary to run `make clean` first for a given build may be necessary to run `make clean` first for a given build target to remove
target to remove previously generated binaries for a different architecture. previously generated binaries for a different architecture.
### Android ### Android
In order to build, you need to download the Android SDK. In order to build, you need to download the Android SDK:
``` [https://developer.android.com/ndk/downloads](https://developer.android.com/ndk/downloads)
https://developer.android.com/ndk/downloads
```
Then creating locally a standalone chain as follow. Then creating locally a standalone chain as follows:
``` [https://developer.android.com/ndk/guides/standalone_toolchain](https://developer.android.com/ndk/guides/standalone_toolchain)
https://developer.android.com/ndk/guides/standalone_toolchain
```
## Usage ## Usage
FRIDA mode added some small modifications to `afl-fuzz` and similar tools FRIDA mode added some small modifications to `afl-fuzz` and similar tools in
in AFLplusplus. The intention was that it behaves identically to QEMU, but it uses AFL++. The intention was that it behaves identically to QEMU, but it uses the
the 'O' switch rather than 'Q'. Whilst the options 'f', 'F', 's' or 'S' may have 'O' switch rather than 'Q'. Whilst the options 'f', 'F', 's' or 'S' may have
made more sense for a mode powered by FRIDA Stalker, they were all taken, so made more sense for a mode powered by FRIDA Stalker, they were all taken, so
instead we use 'O' in hommage to the [author](https://github.com/oleavr) of instead we use 'O' in homage to the [author](https://github.com/oleavr) of
FRIDA. FRIDA.
Similarly, the intention is to mimic the use of environment variables used by Similarly, the intention is to mimic the use of environment variables used by
QEMU where possible (by replacing `s/QEMU/FRIDA/g`). Accordingly, the QEMU where possible (by replacing `s/QEMU/FRIDA/g`). Accordingly, the following
following options are currently supported: options are currently supported:
* `AFL_FRIDA_DEBUG_MAPS` - See `AFL_QEMU_DEBUG_MAPS` * `AFL_FRIDA_DEBUG_MAPS` - See `AFL_QEMU_DEBUG_MAPS`.
* `AFL_FRIDA_EXCLUDE_RANGES` - See `AFL_QEMU_EXCLUDE_RANGES` * `AFL_FRIDA_EXCLUDE_RANGES` - See `AFL_QEMU_EXCLUDE_RANGES`.
* `AFL_FRIDA_INST_RANGES` - See `AFL_QEMU_INST_RANGES` * `AFL_FRIDA_INST_RANGES` - See `AFL_QEMU_INST_RANGES`.
* `AFL_FRIDA_PERSISTENT_ADDR` - See `AFL_QEMU_PERSISTENT_ADDR` * `AFL_FRIDA_PERSISTENT_ADDR` - See `AFL_QEMU_PERSISTENT_ADDR`.
* `AFL_FRIDA_PERSISTENT_CNT` - See `AFL_QEMU_PERSISTENT_CNT` * `AFL_FRIDA_PERSISTENT_CNT` - See `AFL_QEMU_PERSISTENT_CNT`.
* `AFL_FRIDA_PERSISTENT_HOOK` - See `AFL_QEMU_PERSISTENT_HOOK` * `AFL_FRIDA_PERSISTENT_HOOK` - See `AFL_QEMU_PERSISTENT_HOOK`.
* `AFL_FRIDA_PERSISTENT_RET` - See `AFL_QEMU_PERSISTENT_RET` * `AFL_FRIDA_PERSISTENT_RET` - See `AFL_QEMU_PERSISTENT_RET`.
To enable the powerful CMPLOG mechanism, set `-c 0` for `afl-fuzz`. To enable the powerful CMPLOG mechanism, set `-c 0` for `afl-fuzz`.
## Scripting ## Scripting
One of the more powerful features of FRIDA mode is it's support for configuration by JavaScript, rather than using environment variables. For details of how this works see [here](Scripting.md). One of the more powerful features of FRIDA mode is it's support for
configuration by JavaScript, rather than using environment variables. For
details of how this works, see [Scripting.md](Scripting.md).
## Performance ## Performance
@ -118,7 +118,8 @@ FRIDA mode is supported by using `LD_PRELOAD` (`DYLD_INSERT_LIBRARIES` on macOS)
to inject a shared library (`afl-frida-trace.so`) into the target. This shared to inject a shared library (`afl-frida-trace.so`) into the target. This shared
library is built using the [frida-gum](https://github.com/frida/frida-gum) library is built using the [frida-gum](https://github.com/frida/frida-gum)
devkit from the [FRIDA](https://github.com/frida/frida) project. One of the devkit from the [FRIDA](https://github.com/frida/frida) project. One of the
components of frida-gum is [Stalker](https://medium.com/@oleavr/anatomy-of-a-code-tracer-b081aadb0df8), components of frida-gum is
[Stalker](https://medium.com/@oleavr/anatomy-of-a-code-tracer-b081aadb0df8),
this allows the dynamic instrumentation of running code for AARCH32, AARCH64, this allows the dynamic instrumentation of running code for AARCH32, AARCH64,
x86 and x64 architectures. Implementation details can be found x86 and x64 architectures. Implementation details can be found
[here](https://frida.re/docs/stalker/). [here](https://frida.re/docs/stalker/).
@ -127,7 +128,8 @@ Dynamic instrumentation is used to augment the target application with similar
coverage information to that inserted by `afl-gcc` or `afl-clang`. The shared coverage information to that inserted by `afl-gcc` or `afl-clang`. The shared
library is also linked to the `compiler-rt` component of AFLplusplus to feedback library is also linked to the `compiler-rt` component of AFLplusplus to feedback
this coverage information to AFL++ and also provide a fork server. It also makes this coverage information to AFL++ and also provide a fork server. It also makes
use of the FRIDA [prefetch](https://github.com/frida/frida-gum/blob/56dd9ba3ee9a5511b4b0c629394bf122775f1ab7/gum/gumstalker.h#L115) use of the FRIDA
[prefetch](https://github.com/frida/frida-gum/blob/56dd9ba3ee9a5511b4b0c629394bf122775f1ab7/gum/gumstalker.h#L115)
support to feedback instrumented blocks from the child to the parent using a support to feedback instrumented blocks from the child to the parent using a
shared memory region to avoid the need to regenerate instrumented blocks on each shared memory region to avoid the need to regenerate instrumented blocks on each
fork. fork.
@ -145,10 +147,12 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent
(only on CMP, SUB and CALL instructions) performance is not quite so critical. (only on CMP, SUB and CALL instructions) performance is not quite so critical.
## Advanced configuration options ## Advanced configuration options
* `AFL_FRIDA_INST_COVERAGE_FILE` - File to write DynamoRio format coverage
information (e.g. to be loaded within IDA lighthouse). * `AFL_FRIDA_INST_COVERAGE_FILE` - File to write DynamoRIO format coverage
information (e.g., to be loaded within IDA lighthouse).
* `AFL_FRIDA_INST_DEBUG_FILE` - File to write raw assembly of original blocks * `AFL_FRIDA_INST_DEBUG_FILE` - File to write raw assembly of original blocks
and their instrumented counterparts during block compilation. and their instrumented counterparts during block compilation.
``` ```
*** ***
@ -168,200 +172,209 @@ Generated block 0x7ffff75e98e2
*** ***
``` ```
* `AFL_FRIDA_INST_JIT` - Enable the instrumentation of Just-In-Time compiled * `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 code. Code is considered to be JIT if the executable segment is not backed by
file. a file.
* `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage * `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage
instrumentation (the default where available). Required to use instrumentation (the default where available). Required to use
`AFL_FRIDA_INST_TRACE`. `AFL_FRIDA_INST_TRACE`.
* `AFL_FRIDA_INST_NO_BACKPATCH` - Disable backpatching. At the end of executing * `AFL_FRIDA_INST_NO_BACKPATCH` - Disable backpatching. At the end of executing
each block, control will return to FRIDA to identify the next block to execute. each block, control will return to FRIDA to identify the next block to
* `AFL_FRIDA_INST_NO_PREFETCH` - Disable prefetching. By default the child will execute.
report instrumented blocks back to the parent so that it can also instrument * `AFL_FRIDA_INST_NO_PREFETCH` - Disable prefetching. By default, the child will
them and they be inherited by the next child on fork, implies report instrumented blocks back to the parent so that it can also instrument
`AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH`. 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 * `AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH` - Disable prefetching of stalker
backpatching information. By default the child will report applied backpatches backpatching information. By default, the child will report applied
to the parent so that they can be applied and then be inherited by the next backpatches to the parent so that they can be applied and then be inherited by
child on fork. the next child on fork.
* `AFL_FRIDA_INST_SEED` - Sets the initial seed for the hash function used to * `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 generate block (and hence edge) IDs. Setting this to a constant value may be
useful for debugging purposes, e.g. investigating unstable edges. useful for debugging purposes, e.g., investigating unstable edges.
* `AFL_FRIDA_INST_TRACE` - Log to stdout the address of executed blocks, * `AFL_FRIDA_INST_TRACE` - Log to stdout the address of executed blocks, implies
implies `AFL_FRIDA_INST_NO_OPTIMIZE`. `AFL_FRIDA_INST_NO_OPTIMIZE`.
* `AFL_FRIDA_INST_TRACE_UNIQUE` - As per `AFL_FRIDA_INST_TRACE`, but each edge * `AFL_FRIDA_INST_TRACE_UNIQUE` - As per `AFL_FRIDA_INST_TRACE`, but each edge
is logged only once, requires `AFL_FRIDA_INST_NO_OPTIMIZE`. is logged only once, requires `AFL_FRIDA_INST_NO_OPTIMIZE`.
* `AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE` - File to write DynamoRio format * `AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE` - File to write DynamoRIO format
coverage information for unstable edges (e.g. to be loaded within IDA coverage information for unstable edges (e.g., to be loaded within IDA
lighthouse). lighthouse).
* `AFL_FRIDA_OUTPUT_STDOUT` - Redirect the standard output of the target * `AFL_FRIDA_OUTPUT_STDOUT` - Redirect the standard output of the target
application to the named file (supersedes the setting of `AFL_DEBUG_CHILD`) application to the named file (supersedes the setting of `AFL_DEBUG_CHILD`).
* `AFL_FRIDA_OUTPUT_STDERR` - Redirect the standard error of the target * `AFL_FRIDA_OUTPUT_STDERR` - Redirect the standard error of the target
application to the named file (supersedes the setting of `AFL_DEBUG_CHILD`) application to the named file (supersedes the setting of `AFL_DEBUG_CHILD`).
* `AFL_FRIDA_PERSISTENT_DEBUG` - Insert a Breakpoint into the instrumented code * `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 at `AFL_FRIDA_PERSISTENT_HOOK` and `AFL_FRIDA_PERSISTENT_RET` to allow the
to detect issues in the persistent loop using a debugger. 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-executable> [my arguments]
```
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-executable> [my arguments]
```
* `AFL_FRIDA_SECCOMP_FILE` - Write a log of any syscalls made by the target to * `AFL_FRIDA_SECCOMP_FILE` - Write a log of any syscalls made by the target to
the specified file. the specified file.
* `AFL_FRIDA_STALKER_ADJACENT_BLOCKS` - Configure the number of adjacent blocks * `AFL_FRIDA_STALKER_ADJACENT_BLOCKS` - Configure the number of adjacent blocks
to fetch when generating instrumented code. By fetching blocks in the same 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 order they appear in the original program, rather than the order of execution
should help reduce locallity and adjacency. This includes allowing us to vector should help reduce locality and adjacency. This includes allowing us to vector
between adjancent blocks using a NOP slide rather than an immediate branch. between adjacent blocks using a NOP slide rather than an immediate branch.
* `AFL_FRIDA_STALKER_IC_ENTRIES` - Configure the number of inline cache entries * `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 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. call back into FRIDA to find the next block. Default is 32.
* `AFL_FRIDA_STATS_FILE` - Write statistics information about the code being * `AFL_FRIDA_STATS_FILE` - Write statistics information about the code being
instrumented to the given file name. The statistics are written only for the instrumented to the given file name. The statistics are written only for the
child process when new block is instrumented (when the child process when new block is instrumented (when the
`AFL_FRIDA_STATS_INTERVAL` has expired). Note that simply because a new path is `AFL_FRIDA_STATS_INTERVAL` has expired). Note that simply because a new path
found does not mean a new block needs to be compiled. It could simply be that is found does not mean a new block needs to be compiled. It could simply be
the existing blocks instrumented have been executed in a different order. that the existing blocks instrumented have been executed in a different order.
```
stats ```
----- stats
Time 2021-07-21 11:45:49 -----
Elapsed 1 seconds Time 2021-07-21 11:45:49
Elapsed 1 seconds
Transitions cumulative delta Transitions cumulative delta
----------- ---------- ----- ----------- ---------- -----
total 753619 17645 total 753619 17645
call_imm 9193 ( 1.22%) 344 ( 1.95%) [ 344/s] call_imm 9193 ( 1.22%) 344 ( 1.95%) [ 344/s]
call_reg 0 ( 0.00%) 0 ( 0.00%) [ 0/s] call_reg 0 ( 0.00%) 0 ( 0.00%) [ 0/s]
call_mem 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] ret_slow_path 67974 ( 9.02%) 2988 (16.93%) [ 2988/s]
post_call_invoke 7996 ( 1.06%) 299 ( 1.69%) [ 299/s] post_call_invoke 7996 ( 1.06%) 299 ( 1.69%) [ 299/s]
excluded_call_imm 3804 ( 0.50%) 200 ( 1.13%) [ 200/s] excluded_call_imm 3804 ( 0.50%) 200 ( 1.13%) [ 200/s]
jmp_imm 5445 ( 0.72%) 255 ( 1.45%) [ 255/s] jmp_imm 5445 ( 0.72%) 255 ( 1.45%) [ 255/s]
jmp_reg 42081 ( 5.58%) 1021 ( 5.79%) [ 1021/s] jmp_reg 42081 ( 5.58%) 1021 ( 5.79%) [ 1021/s]
jmp_mem 578092 (76.71%) 10956 (62.09%) [ 10956/s] jmp_mem 578092 (76.71%) 10956 (62.09%) [ 10956/s]
jmp_cond_imm 38951 ( 5.17%) 1579 ( 8.95%) [ 1579/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_mem 0 ( 0.00%) 0 ( 0.00%) [ 0/s]
jmp_cond_reg 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_cond_jcxz 0 ( 0.00%) 0 ( 0.00%) [ 0/s]
jmp_continuation 84 ( 0.01%) 3 ( 0.02%) [ 3/s] jmp_continuation 84 ( 0.01%) 3 ( 0.02%) [ 3/s]
Instrumentation Instrumentation
--------------- ---------------
Instructions 7907 Instructions 7907
Blocks 1764 Blocks 1764
Avg Instructions / Block 4 Avg Instructions / Block 4
EOB Instructions EOB Instructions
---------------- ----------------
Total 1763 (22.30%) Total 1763 (22.30%)
Call Immediates 358 ( 4.53%) Call Immediates 358 ( 4.53%)
Call Immediates Excluded 74 ( 0.94%) Call Immediates Excluded 74 ( 0.94%)
Call Register 0 ( 0.00%) Call Register 0 ( 0.00%)
Call Memory 0 ( 0.00%) Call Memory 0 ( 0.00%)
Jump Immediates 176 ( 2.23%) Jump Immediates 176 ( 2.23%)
Jump Register 8 ( 0.10%) Jump Register 8 ( 0.10%)
Jump Memory 10 ( 0.13%) Jump Memory 10 ( 0.13%)
Conditional Jump Immediates 1051 (13.29%) Conditional Jump Immediates 1051 (13.29%)
Conditional Jump CX Immediate 0 ( 0.00%) Conditional Jump CX Immediate 0 ( 0.00%)
Conditional Jump Register 0 ( 0.00%) Conditional Jump Register 0 ( 0.00%)
Conditional Jump Memory 0 ( 0.00%) Conditional Jump Memory 0 ( 0.00%)
Returns 160 ( 2.02%) Returns 160 ( 2.02%)
Relocated Instructions Relocated Instructions
---------------------- ----------------------
Total 232 ( 2.93%) Total 232 ( 2.93%)
addsd 2 ( 0.86%) addsd 2 ( 0.86%)
cmp 46 (19.83%) cmp 46 (19.83%)
comisd 2 ( 0.86%) comisd 2 ( 0.86%)
divsd 2 ( 0.86%) divsd 2 ( 0.86%)
divss 2 ( 0.86%) divss 2 ( 0.86%)
lea 142 (61.21%) lea 142 (61.21%)
mov 32 (13.79%) mov 32 (13.79%)
movsd 2 ( 0.86%) movsd 2 ( 0.86%)
ucomisd 2 ( 0.86%) ucomisd 2 ( 0.86%)
``` ```
* `AFL_FRIDA_STATS_INTERVAL` - The maximum frequency to output statistics * `AFL_FRIDA_STATS_INTERVAL` - The maximum frequency to output statistics
information. Stats will be written whenever they are updated if the given information. Stats will be written whenever they are updated if the given
interval has elapsed since last time they were written. interval has elapsed since last time they were written.
* `AFL_FRIDA_TRACEABLE` - Set the child process to be traceable by any process * `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 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 Linux only. Permits a non-root user to use `gcore` or similar to collect a
dump of the instrumented target. Note that in order to capture the core dump you core dump of the instrumented target. Note that in order to capture the core
must set a sufficient timeout (using `-t`) to avoid `afl-fuzz` killing the dump you must set a sufficient timeout (using `-t`) to avoid `afl-fuzz`
process whilst it is being dumped. killing the process whilst it is being dumped.
## FASAN - Frida Address Sanitizer Mode ## FASAN - FRIDA Address Sanitizer mode
Frida mode also supports FASAN. The design of this is actually quite simple and
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. very similar to that used when instrumenting applications compiled from source.
### Address Sanitizer Basics ### Address Sanitizer basics
When Address Sanitizer is used to instrument programs built from source, the When Address Sanitizer is used to instrument programs built from source, the
compiler first adds a dependency (`DT_NEEDED` entry) for the Address Sanitizer 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 dynamic shared object (DSO). This shared object contains the main logic for
Sanitizer, including setting and managing up the shadow memory. It also provides Address Sanitizer, including setting and managing up the shadow memory. It also
replacement implementations for a number of functions in standard libraries. provides replacement implementations for a number of functions in standard
libraries.
These replacements include things like `malloc` and `free` which allows for those These replacements include things like `malloc` and `free` which allows for
allocations to be marked in the shadow memory, but also a number of other fuctions. those allocations to be marked in the shadow memory, but also a number of other
Consider `memcpy` for example, this is instrumented to validate the paramters functions. Consider `memcpy`, for example. This is instrumented to validate the
(test the source and destination buffers against the shadow memory. This is much parameters (test the source and destination buffers against the shadow memory).
easier than instrumenting those standard libraries since, first it would require This is much easier than instrumenting those standard libraries, since first, it
you to re-compile them and secondly it would mean that the instrumentation would would require you to re-compile them and secondly it would mean that the
be applied at a more expensive granular level. Lastly, load-widening (typically instrumentation would be applied at a more expensive granular level. Lastly,
found in highy optimized code) can also make this instrumentation more difficult. 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 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 on being first), the dynamic loader will use it to resolve imports from other
modules which depend on it. modules which depend on it.
### FASAN Implementation ### FASAN implementation
FASAN takes a similar approach. It requires the user to add the Address Sanitizer FASAN takes a similar approach. It requires the user to add the Address
DSO to the `AFL_PRELOAD` environment variable such that it is loaded into the target. Sanitizer DSO to the `AFL_PRELOAD` environment variable such that it is loaded
Again, it must be first in the list. This means that it is not necessary to into the target. Again, it must be first in the list. This means that it is not
instrument the standard libraries to detect when an application has provided an necessary to instrument the standard libraries to detect when an application has
incorrect argument to `memcpy` for example. This avoids issues with load-widening provided an incorrect argument to `memcpy`, for example. This avoids issues with
and should also mean a huge improvement in performance. load-widening and should also mean a huge improvement in performance.
FASAN then adds instrumentation for any instrucutions which use memory operands and FASAN then adds instrumentation for any instructions which use memory operands
then calls into the `__asan_loadN` and `__asan_storeN` functions provided by the DSO and then calls into the `__asan_loadN` and `__asan_storeN` functions provided by
to validate memory accesses against the shadow memory. the DSO to validate memory accesses against the shadow memory.
# Collisions ## Collisions
FRIDA mode has also introduced some improvements to reduce collisions in the map.
See [here](MapDensity.md) for details.
# OSX Library Fuzzing FRIDA mode has also introduced some improvements to reduce collisions in the
An example of how to fuzz a dynamic library on OSX is included [here](test/osx-lib). map. For details, see [MapDensity.md](MapDensity.md).
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 simply 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 ## OSX library fuzzing
Please refer to the [debugging](#debugging) guide for assistant should you
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 simply
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
Please refer to the [debugging](#debugging) guide for assistance should you
encounter problems with FRIDA mode. encounter problems with FRIDA mode.
## TODO ## To do
The next features to be added are Aarch32 support as well as looking at 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 potential performance improvements. The intention is to achieve feature parity
QEMU mode in due course. Contributions are welcome, but please get in touch to with QEMU mode in due course. Contributions are welcome, but please get in touch
ensure that efforts are deconflicted. to ensure that efforts are deconflicted.