googleprojectzero / winafl

A fork of AFL for fuzzing Windows binaries
Apache License 2.0
2.36k stars 533 forks source link

Facing Issues with Offset Calculation and Starting Fuzzing in WinAFL #410

Closed bits4beethoven closed 1 year ago

bits4beethoven commented 1 year ago

I'm experiencing difficulties in setting up WinAFL with DynamoRIO and would appreciate any assistance.

What I did

My goal is to understand how fuzzing with WinAFL operates. For this reason, I downloaded DynamoRIO-Windows-9.93.19524, cloned WinAFL, updated submodules, and built it with the following code:

mkdir build64
cd build64
cmake -G"Visual Studio 16 2019" -A x64 .. -DDynamoRIO_DIR=..\path\to\DynamoRIO\cmake -DINTELPT=1 -DUSE_COLOR=1 -DUSE_DRSYMS=1
cmake --build . --config Release

I wrote a test program that I aim to fuzz:

// simple.c
#include <stdio.h>

__declspec(noinline) int main(int argc, char* argv[]) {
    if (argc < 2) {
        printf("Usage: %s <input file>\n", argv[0]);
        printf("The input file should contain two integers to be summed by the function.\n");
        return -1;
    }

    char* filename = argv[1];

    FILE* inputFile = NULL;
    errno_t err = fopen_s(&inputFile, filename, "r");
    if (err != 0 || inputFile == NULL) {
        printf("Error opening file\n");
        return -1;
    }

    int a, b;
    err = fscanf_s(inputFile, "%d %d", &a, &b);
    if (err != 2) {
        printf("Error reading file\n");
        return -1;
    }

    fclose(inputFile);

    int sum = a + b;
    printf("The sum is: %d\n", sum);

    return 0;
}

According to the README, this function opens an input file, parses it, closes it, and then returns normally. Therefore, main should be an appropriate target function for the fuzzer.

I then accessed the Dynamorio Instrumentation mode. I confirmed that the target runs correctly without instrumentation by opening simple.exe in WinDbg and using the following instructions:

> x simple!main
0000000140011a50 simple!main (int, char **)

> lm
...
0000000140000000     0000000140025000     simple     (pdb symbols)
...

> ? 0000000140011a50 - 0000000140000000
Evaluate expression: 72272 = 0000000000011a50

This resulted in an offset of 0x11a50. Afterward, I opened Ghidra, accessed the Symbol Table, and noticed entries for the main function:

main 1400111a4, Type: Thunk Function, Source: Default
main 140011a50, Type: Function, Source: Imported

Since simple.exe loads at 140000000, I ended up with two offsets,, 0x11a50 and 0x111a4.

What is the problem

Now, in line with the Dynamorio Instrumentation mode I needed to verify if my target operates correctly under DynamoRIO.

To achieve this, I attempted three different lines of code:

<absolute path to drrun.exe> -c <absolute path to winafl.dll> -debug -target_module <absolute path to simple.exe> -target_offset 0x11a50 -fuzz_iterations 10 -nargs 1 -- <absolute path to 1.txt>
<absolute path to drrun.exe> -c <absolute path to winafl.dll> -debug -target_module <absolute path to simple.exe> -target_offset 0x111a4 -fuzz_iterations 10 -nargs 1 -- <absolute path to 1.txt>
<absolute path to drrun.exe> -c <absolute path to winafl.dll> -debug -target_module <absolute path to simple.exe> -target_method main -fuzz_iterations 10 -nargs 1 -- <absolute path to 1.txt>

(Here, 1.txt is a file containing a single line with two integers: 15 20.)

Each line generates a .log file with the following content:

Module loaded, dynamorio.dll
Module loaded, winafl.dll
Module loaded, drx.dll
Module loaded, drreg.dll
Module loaded, drmgr.dll
Module loaded, drwrap.dll
Module loaded, drsyms.dll
Module loaded, simple.exe
Module loaded, ucrtbased.dll
Module loaded, VCRUNTIME140D.dll
Module loaded, KERNELBASE.dll
Module loaded, KERNEL32.dll
Module loaded, ntdll.dll
Module loaded, msvcrt.dll
Module loaded, RPCRT4.dll
Module loaded, AppCore.dll
WARNING: Target function was never called. Incorrect target_offset?
Coverage map follows:

Simultaneously, I see the output "The sum is: 35" in the console. At this point, it appears that my target isn't functioning correctly under DynamoRIO. Nevertheless, I continued testing with WinAFL:

<absolute path to afl-fuzz.exe> -i <absolute path to the input folder> -o <absolute path to the output folder> -t 5000+ -D <absolute path to ...\dynamorio\build\bin64> -- -coverage_module <absolute path to simple.exe> -target_module <absolute path to simple.exe> -target_offset 0x11a50 -fuzz_iterations 5000 -call_convention thiscall -nargs 1 -covtype edge -- <absolute path to simple.exe> @@

This attempt led to a series of errors. First, I encountered a pop-up message saying,

WinAFL Notice: ...\simple.exe: memory leak: 6192 bytes not freed

Following this, I received another message,

WinAFL Notice: ...\simple.exe: Application ...\simple.exe (15936) DynamoRIO usage error: memory leak detected

Then, I got the third message saying

WinAFL Notice: ...\simple.exe: Usage error: memory leak detected (...\dynamorio\core\heap.c, line 4011), version 9.93.19352, custom build, -no_dynamic_options -client_lib, "...\winafl.dll;0;" "-coverage_module" "...\simple.exe" "-target_module" "...\simple.exe" "-target_offset" "0x11a50" "-fuzz_iteration" 0x00000001400ee288 0x00000001400cf080 0x0000000015397bfd 0xccccccccccccc300 ...\dynamo_rio\dynamorio\build/lib64\debug\dynamorio.dll=0x0000000015000000

And this is the console output:

...
[+] No auto-generated dictionary tokens to reuse.
[*] Creating hard links for all input files...
[*] Attempting dry run with 'id_000000'...
process 15936 is not running under DR
0 processes nudged
nudge operation failed, verify permissions and parameters.
ERROR: The process with PID 15936 could not be terminated.
Reason: There is no running instance of the task.

[-] PROGRAM ABORT : Cannot kill child process

         Location : destroy_target_process(), ...\winafl\afl-fuzz.c:2651

General Question

What's going wrong here, and why? How can it be resolved?

Subquestions

ifratric commented 1 year ago

-target_module and -coverage_module flags do not take the absolute path, but rather the module name (same as printed in the log). In your case it should be -target_module simple.exe

bits4beethoven commented 1 year ago

I thank you so much!