Dr. Memory |

Loading...
Searching...
No Matches
Fuzz Testing Mode

Dr. Memory provides a fuzz testing mode that repeatedly executes one function in the target application, mutating the value of one argument before each iteration. Fuzz mode is configured using a set of runtime options that all share a `-fuzz_` prefix. For example, `-fuzz_function` specifies the function name for fuzzing. The aggregate runtime option `-fuzz_target` can also be used to configure the fuzz target. An overview of each option and descriptor format is provided in the Dr. Memory Runtime Option Reference (and the command line help text). Many of these options require a more complete explanation, which is provided in the following sections.

- Fuzzer Target
- C++ Targets
- Calling Conventions
- Mutator
- Corpus-Based Fuzzing

# Fuzzer Target

The fuzzer is capable of testing one target function on potentially multiple concurrent threads.

The fuzzer can locate the target function via either its symbol name or its offset from the start of the module with the following options:

- `-fuzz_module:` the module name that refers to a single binary image file such as a library (.so or .dll) or an application executable (.exe on Windows);
- `-fuzz_function` or `-fuzz_offset`
  - `-fuzz_function:` the target function name;
  - `-fuzz_offset:` the offset from the module base.

In addition, to repeatedly execute the target function, the fuzzer needs to know

- `-fuzz_num_args:` how many arguments are passed to the function;
- `-fuzz_data_idx:` the ordinal number of the argument that should be fuzzed;
- `-fuzz_size_idx:` the ordinal number of the argument that specifies the size of the fuzzed argument;
- `-fuzz_num_iters:` how many iterations the function is to be repeated.

For example, to fuzz the following C function in the "a.out" executable:

    void DrMemFuzzFunc(unsigned char *buffer, size_t size);

you would specify the following command-line option to `drmemory:`

    -fuzz_module a.out -fuzz_function DrMemFuzzFunc -fuzz_num_args 2 -fuzz_data_idx 0 -fuzz_size_idx 1 -fuzz_num_iters 100

Alternatively, users can specify the target function on the Dr. Memory command line using the aggregate option `-fuzz_target:`

    -fuzz_target 'a.out!DrMemFuzzFunc|2|0|1|100'

In bash, use single-quotes to avoid special behaviors of the '!' and '|' characters.

Users can skip an option if its value is the same as its default value. For the example above, the shortest command-line option is:

    -fuzz

# C++ Targets

Specifying C function targets is much simpler than C++ targets because the symbol name is the plain text name of the function, and the calling convention is almost always the default. For C++ functions, the mangled or de-mangled name is required. On Unix the fuzzer only accepts mangled names, while on Windows it accepts both the mangled and de-mangled names (for the former, use Windows-only option `-fuzz_mangled_names`). To fuzz the following function on Unix (compiling the app as 32-bit with gcc):

    void CryptoMagic::MungeBuffer(unsigned int *buffer, size_t size);

you would specify the following option to `drmemory:`

    -fuzz_target 'crypto!_ZN11CryptoMagic11MungeBufferEPjj|2|0|1|0'

# Calling Conventions

The fuzzer's default calling convention is `cdecl` on 32-bit x86 platforms, `AMD64` on 64-bit *nix, and `Microsoft` `x64` for Visual Studio 64-bit applications. Use the option `-fuzz_call_convention` to specify a different calling convention for fuzz target functions. For example, to fuzz a C++ non-static member function, you would specify the following command-line option to `drmemory:`

    -fuzz_call_convention \p thiscall

Possible -fuzz_call_convention value includes:

- amd64: AMD64
- arm32: ARM32
- fastcall: fastcall
- ms64: Microsoft x64 (Visual Studio)
- stdcall: cdecl or stdcall
- thiscall: thiscall

It is also possible to use the optional last field of option `-fuzz_target` to specify a different calling convention. For example, to fuzz the following function on Windows (compiling the app with Visual Studio):

    void CryptoMagic::MungeBuffer(unsigned int *buffer, size_t size);

you would specify:

    -fuzz_target 'crypto.exe!?MungeBuffer-CryptoMagic--QAEXPAII-Z|3|1|2|0|6'

The value `6` at the last field specifies the calling convention '`thiscall'` (as defined by the enum `drwrap_callconv_t` in the DynamoRIO header file `drwrap.h`). Since the `MungeBuffer()` method is a non-static class member, the first argument is reserved by the compiler for the `this` pointer. Accordingly, the argument indexes in the descriptor (fields 3 and 4, `"|1|2|"`) have been adjusted to account for the implicit first argument, along with the argument count (field 2, `"|3|"`). Notice that the `'@'` characters in the symbol have been escaped with `'-'` for compatibility with the Dr. Memory command-line processor.

# Mutator

The mutator is responsible for modifying the input to the target function on each iteration. A default mutator with a variety of options, including various random and sequential mutation strategies, is provided. Dr. Memory exposes all of the options for Dr. Fuzz's default mutator as front-end options. Please see the documentation under Dr. Fuzz Mutators as well as the `-fuzz_mutator_*` options listed under Dr. Memory Runtime Option Reference. The option `-fuzz_coverage` must be specified for any custom mutator that implements feedback guided mutation.

# Dumping and Loading Fuzz Input Data

On reporting an error during fuzzing, Dr. Memory dumps the fuzz input data to a file in the log directory. The dumped file can be used for reproducing the error later with the option `-fuzz_input_file`. For example, to load input.dat for reproducing an error, you would specify the following command-line option to `drmemory:`

    -fuzz_input_file input.dat -fuzz_num_iters 0

# Corpus-Based Fuzzing

Dr. Memory supports corpus-based fuzzing through the following options:

- `-fuzz_corpus:` the directory for loading and storing the corpus inputs
- `-fuzz_corpus_out:` the directory for storing the minimized corpus inputs

Each input is stored by itself in a separate file in a specified directory, and that there should be nothing else in the directory.

For example, to fuzz the function `DrMemFuzzFunc` with a set of inputs stored in /path/to/inputs/ and dump the minimized corpus inputs to /path/to/min_corpus/, you would specify the following command-line option to `drmemory:`

    -fuzz_corpus /path/to/inputs -fuzz_corpus_out /path/to/min_corpus/

# Per-Iteration Leak Scanning

Dr. Memory's fuzz mode typically performs a leak scan only at the end of the entire fuzz run or on request. This option allows you to perform leak detection after every target function execution.

- `-fuzz_per_iter_leak_scan:` whether to run a leak scan after every target function execution.

Enabling this option is useful for precisely isolating the input iteration that causes a memory leak, which aids in reproduction and minimization. The outputs of these leak scans are stored in the fuzz_results.txt file. The types of leaks reported are additionally controlled by the `-possible_leaks` and `-show_reachable` options.

Note that the leak scan results include all leaks found to date, which will overlap with leaks found in prior iterations. The user must currently infer manually which leaks are newly found in the displayed iteration.

For example, to fuzz the function `DrMemFuzzFunc` with per-iteration leak scanning enabled, you would specify the following command-line option to `drmemory:`

    -fuzz_module a.out -fuzz_function DrMemFuzzFunc -fuzz_per_iter_leak_scan