winafl icon indicating copy to clipboard operation
winafl copied to clipboard

WARNING: Target function was never called. Incorrect target_offset?

Open jonesmz opened this issue 4 years ago • 23 comments

I'm attempting to follow the instructions here: https://github.com/googleprojectzero/winafl/blob/master/readme_dr.md

I've compiled afl-win using these steps:

# download and extract https://github.com/DynamoRIO/dynamorio/releases/download/release_8.0.0-1/DynamoRIO-Windows-8.0.0-1.zip
# to C:\users\mjones\DynamoRIO-Windows-8.0.0-1\

git clone --recursive https://github.com/googleprojectzero/winafl.git
mkdir build-winafl

&'C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe' -G"Visual Studio 16 2019" -A x64 -S .\winafl\ -B .\build-winafl\ -DDynamoRIO_DIR=C:\users\mjones\DynamoRIO-Windows-8.0.0-1\cmake
&'C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe' --build .\build-winafl\ --config Release

I have my program-under-test that is exactly the following

#include <iostream>

extern "C" __declspec(dllexport) void fuzz(char const* const filename)
{
    std::cout << "Entered fuzz function: " << filename << std::endl;
} // fuzz

int main(int argc, char * argv[])
{
    if(argc > 1)
    {
        fuzz(argv[1]);
    }

    return 0;
} // main

I compile that cpp file into "minimal_fuzzer-w64d-1-0.exe", and copy afl-fuzzer and winafl.dll into the same folder as my new exe. I create ./testin/0001.json and attempt to use the DynamoRio drrun.exe program.

C:\Users\mjones\DynamoRIO-Windows-8.0.0-1\bin64\drrun.exe -c winafl.dll -debug -target_module minimal_fuzzer-w64d-1-0.exe -target_method fuzz -fuzz_iterations 10 -nargs 1 -- minimal_fuzzer-w64d-1-0.exe .\testin\0001.json

does not work. Claims it can't find the "fuzz" function.

Changing the -target_module parameter to minimal_fuzzer_w64d_1_0 gets past that.

C:\Users\mjones\DynamoRIO-Windows-8.0.0-1\bin64\drrun.exe -c winafl.dll -debug -target_module minimal_fuzzer-w64d-1-0.exe -target_method fuzz -fuzz_iterations 10 -nargs 1 -- minimal_fuzzer-w64d-1-0.exe .\testin\0001.json

I see the output

Entered fuzz function: .\testin\0001.json

Once and only once, and then drrun.exe exits.

The log file from drrun.exe gives me:

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, minimal_fuzzer-w64d-1-0.exe
Module loaded, ucrtbased.dll
Module loaded, MSVCP140D.dll
Module loaded, Protector64.dll
Module loaded, VCRUNTIME140D.dll
Module loaded, VERSION.dll
Module loaded, VCRUNTIME140_1D.dll
Module loaded, apphelp.dll
Module loaded, NTMARTA.dll
Module loaded, gdi32full.dll
Module loaded, msvcp_win.dll
Module loaded, ucrtbase.dll
Module loaded, KERNELBASE.dll
Module loaded, win32u.dll
Module loaded, RPCRT4.dll
Module loaded, USER32.dll
Module loaded, combase.dll
Module loaded, KERNEL32.dll
Module loaded, SECHOST.dll
Module loaded, OLEAUT32.dll
Module loaded, GDI32.dll
Module loaded, IMM32.dll
Module loaded, ADVAPI32.dll
Module loaded, msvcrt.dll
Module loaded, SHLWAPI.dll
Module loaded, ntdll.dll
In OpenFileW, reading C:\Windows\SYSTEM32\ntdll.dll
In OpenFileW, reading C:\Windows\SYSTEM32\ntdll.dll
In OpenFileW, reading C:\Windows\SYSTEM32\ntdll.dll
In OpenFileW, reading C:\Windows\SYSTEM32\ntdll.dll
In OpenFileW, reading C:\Windows\SYSTEM32\ntdll.dll
In OpenFileW, reading C:\Windows\SYSTEM32\ntdll.dll
In OpenFileW, reading C:\Windows\SYSTEM32\ntdll.dll
In OpenFileW, reading C:\Windows\SYSTEM32\ntdll.dll
In OpenFileW, reading C:\Windows\SYSTEM32\ntdll.dll
In OpenFileW, reading C:\Windows\SYSTEM32\ntdll.dll
In OpenFileW, reading C:\Windows\System32\r_pdwyeany.dll
In OpenFileW, reading C:\Windows\System32\r_pdwyeany.dll
In OpenFileW, reading C:\Windows\SYSTEM32\ntdll.dll
In OpenFileW, reading C:\Windows\SYSTEM32\ntdll.dll
In OpenFileW, reading C:\Windows\SYSTEM32\ntdll.dll
In OpenFileW, reading C:\Windows\SYSTEM32\ntdll.dll
Module loaded, AppCore.dll
In OpenFileW, reading C:\Windows\SYSTEM32\ntdll.dll
WARNING: Target function was never called. Incorrect target_offset?
Coverage map follows: (lots of 'nul' characters here)

Attempting to run with afl-fuzzer.exe just to see if I get any new information, gives me this:

.\afl-fuzz.exe -D C:\Users\mjones\DynamoRIO-Windows-8.0.0-1\bin64 -i testin -o testout -t 200000 -- -coverage_module minimal_fuzzer_w64d_1_0 -target_module minimal_fuzzer_w64d_1_0 -target_method fuzz -fuzz_iterations 10 -nargs 1 -- minimal_fuzzer-w64d-1-0.exe \@@
WinAFL 1.16b by <[email protected]>
Based on AFL 2.43b by <[email protected]>
[+] You have 24 CPU cores and 0 runnable tasks (utilization: 0%).
[+] Try parallel jobs - see afl_docs\parallel_fuzzing.txt.
[*] Checking CPU core loadout...
[+] Found a free CPU core, binding to #0.
[+] Process affinity is set to 1.

[*] Setting up output directories...
[+] Output directory exists but deemed OK to reuse.
[*] Deleting old session data...
[+] Output dir cleanup successful.
[*] Scanning 'testin'...
[+] No auto-generated dictionary tokens to reuse.
[*] Creating hard links for all input files...
[*] Attempting dry run with 'id_000000'...

[-] The program took more than 200000 ms to process one of the initial test cases.
    Usually, the right thing to do is to relax the -t option - or to delete it
    altogether and allow the fuzzer to auto-calibrate. That said, if you know
    what you are doing and want to simply skip the unruly test cases, append
    '+' at the end of the value passed to -t ('-t 200000+').

[-] PROGRAM ABORT : Test case 'id_000000' results in a timeout
         Location : perform_dry_run(), C:\Users\mjones\winafl\afl-fuzz.c:3019

process 21780 is not running under DR
0 processes nudged
nudge operation failed, verify permissions and parameters.

Notably, the program did not take 200,000 ms to process a test case. I get this output within 5 seconds of running the program.

This is Windows 10 20H2 19042.867

What can I do to diagnose this problem further?

jonesmz avatar Mar 23 '21 23:03 jonesmz

I guess it's possible that the fuzz() got inlined in main().

On newer Windows versions, you should also grab a more recent DynamoRIO version from https://github.com/DynamoRIO/dynamorio/releases and rebuild WinAFL with it.

ifratric avatar Mar 24 '21 09:03 ifratric

On newer Windows versions, you should also grab a more recent DynamoRIO version from https://github.com/DynamoRIO/dynamorio/releases and rebuild WinAFL with it.

Is there a release of Dynamorio newer than 8.0.0-1 ? That's the newest release on the project's official website.

jonesmz avatar Mar 24 '21 16:03 jonesmz

I guess it's possible that the fuzz() got inlined in main().

Ok.

To eliminate the possibility of function inlining, I've re-written my app as such:

main.cpp

extern "C" __declspec(dllexport) void fuzz(char const* const filename);
int main(int argc, char * argv[])
{
    if(argc > 1)
    {
        fuzz(argv[1]);
    }
    return 0;
} // main

impl.cpp

#include <iostream>
extern "C" __declspec(dllexport) void fuzz(char const* const filename)
{
    std::cout << "Entered fuzz function:" << filename << std::endl;
} // fuzz

No behavior difference.

Anything else I can try?

jonesmz avatar Mar 24 '21 16:03 jonesmz

I've "updated" to the newest weekly build of DynamoRIO-Windows-8.0.18705

Recompiled:

&'C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe' -G"Visual Studio 16 2019" -A x64 -S .\winafl\ -B .\build-winafl\ -DDynamoRIO_DIR=C:\users\mjones\DynamoRIO-Windows-8.0.18705\cmake
&'C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe' --build .\build-winafl\ --config Release

Now drrun.exe works.

C:\Users\mjones\DynamoRIO-Windows-8.0.18705\bin64\drrun.exe -c winafl.dll -debug -target_module minimal_fuzzer-w64d-1-0.exe -target_method fuzz -fuzz_iterations 10 -nargs 1 -- minimal_fuzzer-w64d-1-0.exe .\testin\0001.json
Entered fuzz function:.\testin\0001.json
Entered fuzz function:.\testin\0001.json
Entered fuzz function:.\testin\0001.json
Entered fuzz function:.\testin\0001.json
Entered fuzz function:.\testin\0001.json
Entered fuzz function:.\testin\0001.json
Entered fuzz function:.\testin\0001.json
Entered fuzz function:.\testin\0001.json
Entered fuzz function:.\testin\0001.json
Entered fuzz function:.\testin\0001.json

But WinAFL does not.

.\afl-fuzz.exe -D C:\Users\mjones\DynamoRIO-Windows-8.0.18705\bin64 -i testin -o testout -t 200000 -- -coverage_module minimal_fuzzer_w64d_1_0 -target_module minimal_fuzzer_w64d_1_0 -target_method fuzz -fuzz_iterations 10 -nargs 2 -- minimal_fuzzer-w64d-1-0.exe \@@
WinAFL 1.16b by <[email protected]>
Based on AFL 2.43b by <[email protected]>
[+] You have 24 CPU cores and 0 runnable tasks (utilization: 0%).
[+] Try parallel jobs - see afl_docs\parallel_fuzzing.txt.
[*] Checking CPU core loadout...
[+] Found a free CPU core, binding to #0.
[+] Process affinity is set to 1.

[*] Setting up output directories...
[+] Output directory exists but deemed OK to reuse.
[*] Deleting old session data...
[+] Output dir cleanup successful.
[*] Scanning 'testin'...
[+] No auto-generated dictionary tokens to reuse.
[*] Creating hard links for all input files...
[*] Attempting dry run with 'id_000000'...

[-] The program took more than 200000 ms to process one of the initial test cases.
    Usually, the right thing to do is to relax the -t option - or to delete it
    altogether and allow the fuzzer to auto-calibrate. That said, if you know
    what you are doing and want to simply skip the unruly test cases, append
    '+' at the end of the value passed to -t ('-t 200000+').

[-] PROGRAM ABORT : Test case 'id_000000' results in a timeout
         Location : perform_dry_run(), C:\Users\mjones\winafl\afl-fuzz.c:3019

process 17600 is not running under DR
0 processes nudged
nudge operation failed, verify permissions and parameters.

I ran it in:

  • Powershell
  • Admin powershell
  • cmd
  • admin cmd

jonesmz avatar Mar 25 '21 18:03 jonesmz

Can you run against the provided example (test.exe)?

I just rebuilt everything and it worked for me. My configuration:

Windows 10 64-bit 20H2 DynamoRIO-Windows-8.0.18712.zip Visual Studio 2017

Command line (32-bit and 64-bit):

afl-fuzz.exe -i in -o out -D D:\work\DynamoRIO-Windows-8.0.18712\bin32 -t 20000 -- -coverage_module test.exe -fuzz_iterations 5000 -target_module test.exe -target_offset 0x1630 -nargs 2 -- D:\work\winafl\bin32\test.exe @@

afl-fuzz.exe -i in -o out -D D:\work\DynamoRIO-Windows-8.0.18712\bin64 -t 20000 -- -coverage_module test.exe -fuzz_iterations 5000 -target_module test.exe -target_offset 0x1610 -nargs 2 -- D:\work\winafl\bin64\test.exe @@

Note: offset is that of main. If you rebuild the binaries, the offset will likely change. The offsets above are valid for the pre-built target binaries located in bin32 and bin64 directories.

ifratric avatar Mar 29 '21 10:03 ifratric

There also seems to be an error with your command line:

.\afl-fuzz.exe -D C:\Users\mjones\DynamoRIO-Windows-8.0.18705\bin64 -i testin -o testout -t 200000 -- -coverage_module minimal_fuzzer_w64d_1_0 -target_module minimal_fuzzer_w64d_1_0 -target_method fuzz -fuzz_iterations 10 -nargs 2 -- minimal_fuzzer-w64d-1-0.exe \@@

-target_module and -coverage_module should probably be minimal_fuzzer-w64d-1-0.exe and not minimal_fuzzer_w64d_1_0 (extension is important, and there seem to be differences in slashes vs. underscores)

ifratric avatar Mar 29 '21 10:03 ifratric

There also seems to be an error with your command line:

.\afl-fuzz.exe -D C:\Users\mjones\DynamoRIO-Windows-8.0.18705\bin64 -i testin -o testout -t 200000 -- -coverage_module minimal_fuzzer_w64d_1_0 -target_module minimal_fuzzer_w64d_1_0 -target_method fuzz -fuzz_iterations 10 -nargs 2 -- minimal_fuzzer-w64d-1-0.exe \@@

-target_module and -coverage_module should probably be minimal_fuzzer-w64d-1-0.exe and not minimal_fuzzer_w64d_1_0 (extension is important, and there seem to be differences in slashes vs. underscores)

See my original post for why I am using the names that I am using.

I have no explanation for why I need to use the modified module name, but I get much farther with it than without it.

I compile that cpp file into "minimal_fuzzer-w64d-1-0.exe", and copy afl-fuzzer and winafl.dll into the same folder as my new exe. I create ./testin/0001.json and attempt to use the DynamoRio drrun.exe program.

C:\Users\mjones\DynamoRIO-Windows-8.0.0-1\bin64\drrun.exe -c winafl.dll -debug -target_module minimal_fuzzer-w64d-1-0.exe -target_method fuzz -fuzz_iterations 10 -nargs 1 -- minimal_fuzzer-w64d-1-0.exe .\testin\0001.json

does not work. Claims it can't find the "fuzz" function.

Changing the -target_module parameter to minimal_fuzzer_w64d_1_0 gets past that.

C:\Users\mjones\DynamoRIO-Windows-8.0.0-1\bin64\drrun.exe -c winafl.dll -debug -target_module minimal_fuzzer-w64d-1-0.exe -target_method fuzz -fuzz_iterations 10 -nargs 1 -- minimal_fuzzer-w64d-1-0.exe .\testin\0001.json

I see the output

Entered fuzz function: .\testin\0001.json

Once and only once, and then drrun.exe exits.

jonesmz avatar Mar 29 '21 15:03 jonesmz

Visual Studio 2017

Why are you using VS2017? That's 4 years old.

jonesmz avatar Mar 29 '21 15:03 jonesmz

test.exe doesn't work.

PS C:\Users\mjones\build-winafl\bin\Release>.\afl-fuzz.exe -i in -o out -D C:\users\mjones\DynamoRIO-Windows-8.0.0-1\bin64 -t 20000 -- -coverage_module .\test.exe -fuzz_iterations 5000 -target_module .\test.exe -target_method main -nargs 2 -- D:\work\winafl\bin64\test.exe \@@
WinAFL 1.16b by <[email protected]>
Based on AFL 2.43b by <[email protected]>
[+] You have 24 CPU cores and 0 runnable tasks (utilization: 0%).
[+] Try parallel jobs - see afl_docs\parallel_fuzzing.txt.
[*] Checking CPU core loadout...
[+] Found a free CPU core, binding to #0.
[+] Process affinity is set to 1.

[*] Setting up output directories...
[+] Output directory exists but deemed OK to reuse.
[*] Deleting old session data...
[+] Output dir cleanup successful.
[*] Scanning 'in'...
[+] No auto-generated dictionary tokens to reuse.
[*] Creating hard links for all input files...
[*] Attempting dry run with 'id_000000'...

[-] PROGRAM ABORT : Error opening pidfile.txt
         Location : create_target_process(), C:\Users\mjones\winafl\afl-fuzz.c:2365

jonesmz avatar Mar 29 '21 15:03 jonesmz

You need to change the path to point to your test.exe. Also not sure why you have a backslash before the last param (\@@)

ifratric avatar Mar 29 '21 15:03 ifratric

And you're pointing to an older DR version.

ifratric avatar Mar 29 '21 15:03 ifratric

PS C:\Users\mjones\build-winafl\bin\Release>C:\Users\mjones\DynamoRIO-Windows-8.0.0-1\bin64\drrun.exe -c winafl.dll -debug -target_module .\test.exe -target_method main -fuzz_iterations 10 -nargs 1 -- .\test.exe .\in\tracing.h
Error 1

PS C:\Users\mjones\build-winafl\bin\Release>C:\Users\mjones\DynamoRIO-Windows-8.0.0-1\bin64\drrun.exe -c winafl.dll -debug -target_module .\test.exe -target_method main -fuzz_iterations 10 -nargs 2 -- .\test.exe .\in\tracing.h
Error 1

PS C:\Users\mjones\build-winafl\bin\Release>C:\Users\mjones\DynamoRIO-Windows-8.0.0-1\bin64\drrun.exe -c winafl.dll -debug -target_module test -target_method main -fuzz_iterations 10 -nargs 2 -- .\test.exe .\in\tracing.h
Error 1

and with the DynamoRIO nightly build

PS C:\Users\mjones\build-winafl\bin\Release>C:\Users\mjones\DynamoRIO-Windows-8.0.18705\bin64\drrun.exe -c winafl.dll -debug -target_module .\test.exe -target_method main -fuzz_iterations 10 -nargs 2 -- test.exe .\in\tracing.h
Error 1

PS C:\Users\mjones\build-winafl\bin\Release>C:\Users\mjones\DynamoRIO-Windows-8.0.18705\bin64\drrun.exe -c winafl.dll -debug -target_module test.exe -target_method main -fuzz_iterations 10 -nargs 2 -- test.exe .\in\tracing.h
ASSERT FAILURE: C:\Users\mjones\winafl\winafl.c:700: to_warp (Can't find specified method in fuzz_module).

Is there no way for winafl to search for modules in the provided binary that are mutations of the provided path? E.g. strip out leading path separators, and add/remove .exe and variations of underscores/dashes?

jonesmz avatar Mar 29 '21 15:03 jonesmz

And you're pointing to an older DR version.

Yes, you're right. My mistake, sorry. Early morning for me. Trying again.

jonesmz avatar Mar 29 '21 15:03 jonesmz

Also not sure why you have a backslash before the last param (\@@)

PS C:\Users\mjones\build-winafl\bin\Release>.\afl-fuzz.exe -i in -o out -D C:\users\mjones\DynamoRIO-Windows-8.0.18705\bin64 -t 20000 -- -coverage_module .\test.exe -fuzz_iterations 5000 -target_module .\test.exe -target_method main -nargs 2 -- test.exe \@@
WinAFL 1.16b by <[email protected]>
Based on AFL 2.43b by <[email protected]>
[+] You have 24 CPU cores and 0 runnable tasks (utilization: 0%).
[+] Try parallel jobs - see afl_docs\parallel_fuzzing.txt.
[*] Checking CPU core loadout...
[+] Found a free CPU core, binding to #0.
[+] Process affinity is set to 1.

[*] Setting up output directories...
[+] Output directory exists but deemed OK to reuse.
[*] Deleting old session data...
[+] Output dir cleanup successful.
[*] Scanning 'in'...
[+] No auto-generated dictionary tokens to reuse.
[*] Creating hard links for all input files...
[*] Attempting dry run with 'id_000000'...

[-] The program took more than 20000 ms to process one of the initial test cases.
    Usually, the right thing to do is to relax the -t option - or to delete it
    altogether and allow the fuzzer to auto-calibrate. That said, if you know
    what you are doing and want to simply skip the unruly test cases, append
    '+' at the end of the value passed to -t ('-t 20000+').

[-] PROGRAM ABORT : Test case 'id_000000' results in a timeout
         Location : perform_dry_run(), C:\Users\mjones\winafl\afl-fuzz.c:3019

process 18532 is not running under DR
0 processes nudged
nudge operation failed, verify permissions and parameters.


PS C:\Users\mjones\build-winafl\bin\Release>.\afl-fuzz.exe -i in -o out -D C:\users\mjones\DynamoRIO-Windows-8.0.18705\bin64 -t 20000 -- -coverage_module .\test.exe -fuzz_iterations 5000 -target_module .\test.exe -target_method main -nargs 2 -- test.exe @@
At line:1 char:211
+ ... -target_module .\test.exe -target_method main -nargs 2 -- test.exe @@
+                                                                        ~
Unrecognized token in source text.
At line:1 char:212
+ ... -target_module .\test.exe -target_method main -nargs 2 -- test.exe @@
+                                                                         ~
Unrecognized token in source text.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnrecognizedToken

That's why

jonesmz avatar Mar 29 '21 15:03 jonesmz

You shouldn't use a path in -target_module and -coverage_module flags, e.g. -target_module test.exe instead of -target_module .\test.exe. My earlier comment about the path was referring to changing the path in the target command line, not instrumentation flags.

ifratric avatar Mar 29 '21 15:03 ifratric

You shouldn't use a path in -target_module and -coverage_module flags, e.g. -target_module test.exe instead of -target_module .\test.exe. My earlier comment about the path was referring to changing the path in the target command line, not instrumentation flags.

Ok. This isn't really ergonomic, since powershell is automatically adding path characters when I use it's in-built auto-complete functionality.


PS C:\Users\mjones\build-winafl\bin\Release>.\afl-fuzz.exe -i in -o out -D C:\users\mjones\DynamoRIO-Windows-8.0.18705\bin64 -t 20000 -- -coverage_module test.exe -fuzz_iterations 5000 -target_module test.exe -target_method main -nargs 2 -- test.exe \@@
WinAFL 1.16b by <[email protected]>
Based on AFL 2.43b by <[email protected]>
[+] You have 24 CPU cores and 0 runnable tasks (utilization: 0%).
[+] Try parallel jobs - see afl_docs\parallel_fuzzing.txt.
[*] Checking CPU core loadout...
[+] Found a free CPU core, binding to #0.
[+] Process affinity is set to 1.

[*] Setting up output directories...
[+] Output directory exists but deemed OK to reuse.
[*] Deleting old session data...
[+] Output dir cleanup successful.
[*] Scanning 'in'...
[+] No auto-generated dictionary tokens to reuse.
[*] Creating hard links for all input files...
[*] Attempting dry run with 'id_000000'...

[-] The program took more than 20000 ms to process one of the initial test cases.
    Usually, the right thing to do is to relax the -t option - or to delete it
    altogether and allow the fuzzer to auto-calibrate. That said, if you know
    what you are doing and want to simply skip the unruly test cases, append
    '+' at the end of the value passed to -t ('-t 20000+').

[-] PROGRAM ABORT : Test case 'id_000000' results in a timeout
         Location : perform_dry_run(), C:\Users\mjones\winafl\afl-fuzz.c:3019

process 14716 is not running under DR
0 processes nudged
nudge operation failed, verify permissions and parameters.

This gives me the assert popup

ASSERT FAILURE: C:\Users\mjones\winafl\winafl.c:700: to_warp (Can't find specified method in fuzz_module).

jonesmz avatar Mar 29 '21 15:03 jonesmz

Rebuilt WinAFL as debug, tried again.

mkdir build-winafl-debug
&'C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe' -G"Visual Studio 16 2019" -A x64 -S .\winafl\ -B .\build-winafl-debug\ -DDynamoRIO_DIR=C:\users\mjones\DynamoRIO-Windows-8.0.18705\cmake\
&'C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe' --build .\build-winafl-debug\ --config Debug
PS C:\Users\mjones\build-winafl-debug\bin\Debug>.\afl-fuzz.exe -i in -o out -D C:\users\mjones\DynamoRIO-Windows-8.0.18705\bin64 -t 20000 -- -coverage_module test.exe -fuzz_iterations 5000 -target_module test.exe -target_method main -nargs 2 -- test.exe \@@
WinAFL 1.16b by <[email protected]>
Based on AFL 2.43b by <[email protected]>
[+] You have 24 CPU cores and 0 runnable tasks (utilization: 0%).
[+] Try parallel jobs - see afl_docs\parallel_fuzzing.txt.
[*] Checking CPU core loadout...
[+] Found a free CPU core, binding to #0.
[+] Process affinity is set to 1.

[*] Setting up output directories...
[+] Output directory exists but deemed OK to reuse.
[*] Deleting old session data...
[+] Output dir cleanup successful.
[*] Scanning 'in'...
[+] No auto-generated dictionary tokens to reuse.
[*] Creating hard links for all input files...
[*] Attempting dry run with 'id_000000'...

[-] The program took more than 20000 ms to process one of the initial test cases.
    Usually, the right thing to do is to relax the -t option - or to delete it
    altogether and allow the fuzzer to auto-calibrate. That said, if you know
    what you are doing and want to simply skip the unruly test cases, append
    '+' at the end of the value passed to -t ('-t 20000+').

[-] PROGRAM ABORT : Test case 'id_000000' results in a timeout
         Location : perform_dry_run(), C:\Users\mjones\winafl\afl-fuzz.c:3019

process 10528 is not running under DR
0 processes nudged
nudge operation failed, verify permissions and parameters.

ASSERT FAILURE: C:\Users\mjones\winafl\winafl.c:700: to_warp (Can't find specified method in fuzz_module).

jonesmz avatar Mar 29 '21 15:03 jonesmz

Yep, likely no symbols are available (release build) and, additionally, WinAFL needs to be compiled with -DUSE_DRSYMS=1 in order to recognize the name (main). Otherwise, offset should be used.

ifratric avatar Mar 29 '21 15:03 ifratric

Yep, likely no symbols are available (release build) and, additionally, WinAFL needs to be compiled with -DUSE_DRSYMS=1 in order to recognize the name (main). Otherwise, offset should be used.

Locating the offset is way too error prone. Until last week, I had no idea how to even get a copy of WinDbg, much less how to use it. Nearly unusable tool.

I suggest that if WinAFL isn't compiled with the needed flag, it should pop up a warning saying

WinAFL needs to be compiled with -DUSE_DRSYMS=1 in order to recognize the name (main). Otherwise, offset should be used.

jonesmz avatar Mar 29 '21 16:03 jonesmz

Now that I've added -DUSE_DRSYMS=1, running

.\afl-fuzz.exe -i in -o out -D C:\users\mjones\DynamoRIO-Windows-8.0.18705\bin64 -t 20000 -- -coverage_module test.exe -fuzz_iterations 5000 -target_module test.exe -target_method main -nargs 2 -- test.exe \@@

works!

Great.

Going to try my application now.

jonesmz avatar Mar 29 '21 16:03 jonesmz

I'm in business. Fantastic.

Lesson learned appears to be that -DUSE_DRSYMS=1 was required.

There's no documentation in github about this flag that I can find:

https://github.com/googleprojectzero/winafl/search?q=USE_DRSYMS

.\afl-fuzz.exe -D C:\Users\mjones\DynamoRIO-Windows-8.0.18705\bin64\ -i testin -o testout -t 200000 -- -coverage_module minimal_fuzzer-w64d-1-0.exe -target_module minimal_fuzzer-w64d-1-0.exe -target_method fuzz -fuzz_iterations 10 -nargs 2 -- minimal_fuzzer-w64d-1-0.exe \@@
WinAFL 1.16b by <[email protected]>
Based on AFL 2.43b by <[email protected]>
[+] You have 24 CPU cores and 0 runnable tasks (utilization: 0%).
[+] Try parallel jobs - see afl_docs\parallel_fuzzing.txt.
[*] Checking CPU core loadout...
[+] Found a free CPU core, binding to #0.
[+] Process affinity is set to 1.

[*] Setting up output directories...
[+] Output directory exists but deemed OK to reuse.
[*] Deleting old session data...
[+] Output dir cleanup successful.
[*] Scanning 'testin'...
[+] No auto-generated dictionary tokens to reuse.
[*] Creating hard links for all input files...
[*] Attempting dry run with 'id_000000'...
    len = 59, map size = 49, exec speed = 39900 us
[!] WARNING: Instrumentation output varies across runs.
[+] All test cases processed.

[!] WARNING: The target binary is pretty slow! See afl_docs\perf_tips.txt.
[+] Here are some useful stats:

    Test case count : 1 favored, 1 variable, 1 total
       Bitmap range : 49 to 49 bits (average: 49.00 bits)
        Exec timing : 39.9k to 39.9k us (average: 39.9k us)

[+] All set and ready to roll!

         WinAFL 1.16b based on AFL 2.43b (minimal_fuzzer-w64d-1-0.exe)

+- process timing -------------------------------------+- overall results ----+
|        run time : 0 days, 0 hrs, 0 min, 1 sec        |  cycles done : 0     |
|   last new path : none seen yet                      |  total paths : 1     |
| last uniq crash : none seen yet                      | uniq crashes : 0     |
|  last uniq hang : none seen yet                      |   uniq hangs : 0     |
+- cycle progress --------------------+- map coverage -+----------------------+
|  now processing : 0 (0.00%)         |    map density : 0.07% / 0.10%        |
| paths timed out : 0 (0.00%)         | count coverage : 1.00 bits/tuple      |
+- stage progress --------------------+ findings in depth --------------------+
|  now trying : init                  | favored paths : 1 (100.00%)           |
| stage execs : 0/-                   |  new edges on : 1 (100.00%)           |
| total execs : 40                    | total crashes : 0 (0 unique)          |
|  exec speed : 25.02/sec (slow!)     |  total tmouts : 0 (0 unique)          |
+- fuzzing strategy yields -----------+---------------+- path geometry -------+
|   bit flips : 0/0, 0/0, 0/0                         |    levels : 1         |
|  byte flips : 0/0, 0/0, 0/0                         |   pending : 1         |
| arithmetics : 0/0, 0/0, 0/0                         |  pend fav : 1         |
|  known ints : 0/0, 0/0, 0/0                         | own finds : 0         |
|  dictionary : 0/0, 0/0, 0/0                         |  imported : n/a       |
|       havoc : 0/0, 0/0                              | stability : 71.21%    |
|        trim : n/a, n/a                              +-----------------------+
[*] Entering queue cycle 1.---------------------------+             [cpu:  0%]
[*] Fuzzing test case #0 (1 total)...

         WinAFL 1.16b based on AFL 2.43b (minimal_fuzzer-w64d-1-0.exe)

+- process timing -------------------------------------+- overall results ----+
|        run time : 0 days, 0 hrs, 0 min, 2 sec        |  cycles done : 0     |
|   last new path : none seen yet                      |  total paths : 1     |
| last uniq crash : none seen yet                      | uniq crashes : 0     |
|  last uniq hang : none seen yet                      |   uniq hangs : 0     |
+- cycle progress --------------------+- map coverage -+----------------------+
|  now processing : 0 (0.00%)         |    map density : 0.07% / 0.10%        |
| paths timed out : 0 (0.00%)         | count coverage : 1.00 bits/tuple      |
+- stage progress --------------------+ findings in depth --------------------+
|  now trying : bitflip 1\1           | favored paths : 1 (100.00%)           |
| stage execs : 6/408 (1.47%)         |  new edges on : 1 (100.00%)           |
| total execs : 61                    | total crashes : 0 (0 unique)          |
|  exec speed : 24.55/sec (slow!)     |  total tmouts : 0 (0 unique)          |
+- fuzzing strategy yields -----------+---------------+- path geometry -------+
|   bit flips : 0/0, 0/0, 0/0                         |    levels : 1         |
|  byte flips : 0/0, 0/0, 0/0                         |   pending : 1         |
| arithmetics : 0/0, 0/0, 0/0                         |  pend fav : 1         |
|  known ints : 0/0, 0/0, 0/0                         | own finds : 0         |
|  dictionary : 0/0, 0/0, 0/0                         |  imported : n/a       |
|       havoc : 0/0, 0/0                              | stability : 71.21%    |
|        trim : 13.56%/14, n/a                        +-----------------------+
+-----------------------------------------------------+             [cpu:  0%]
         WinAFL 1.16b based on AFL 2.43b (minimal_fuzzer-w64d-1-0.exe)

+- process timing -------------------------------------+- overall results ----+
|        run time : 0 days, 0 hrs, 0 min, 4 sec        |  cycles done : 0     |
|   last new path : none seen yet                      |  total paths : 1     |
| last uniq crash : none seen yet                      | uniq crashes : 0     |
|  last uniq hang : none seen yet                      |   uniq hangs : 0     |
+- cycle progress --------------------+- map coverage -+----------------------+
|  now processing : 0 (0.00%)         |    map density : 0.07% / 0.10%        |
| paths timed out : 0 (0.00%)         | count coverage : 1.00 bits/tuple      |
+- stage progress --------------------+ findings in depth --------------------+
|  now trying : bitflip 1\1           | favored paths : 1 (100.00%)           |
| stage execs : 36/408 (8.82%)        |  new edges on : 1 (100.00%)           |
| total execs : 91                    | total crashes : 0 (0 unique)          |
|  exec speed : 24.57/sec (slow!)     |  total tmouts : 0 (0 unique)          |
+- fuzzing strategy yields -----------+---------------+- path geometry -------+
|   bit flips : 0/0, 0/0, 0/0                         |    levels : 1         |
|  byte flips : 0/0, 0/0, 0/0                         |   pending : 1         |
| arithmetics : 0/0, 0/0, 0/0                         |  pend fav : 1         |
|  known ints : 0/0, 0/0, 0/0                         | own finds : 0         |
|  dictionary : 0/0, 0/0, 0/0                         |  imported : n/a       |
|       havoc : 0/0, 0/0                              | stability : 71.21%    |
|        trim : 13.56%/14, n/a                        +-----------------------+
+-----------------------------------------------------+             [cpu:  0%]
         WinAFL 1.16b based on AFL 2.43b (minimal_fuzzer-w64d-1-0.exe)

+- process timing -------------------------------------+- overall results ----+
|        run time : 0 days, 0 hrs, 0 min, 5 sec        |  cycles done : 0     |
|   last new path : none seen yet                      |  total paths : 1     |
| last uniq crash : none seen yet                      | uniq crashes : 0     |
|  last uniq hang : none seen yet                      |   uniq hangs : 0     |
+- cycle progress --------------------+- map coverage -+----------------------+
|  now processing : 0 (0.00%)         |    map density : 0.07% / 0.10%        |
| paths timed out : 0 (0.00%)         | count coverage : 1.00 bits/tuple      |
+- stage progress --------------------+ findings in depth --------------------+
|  now trying : bitflip 1\1           | favored paths : 1 (100.00%)           |
| stage execs : 66/408 (16.18%)       |  new edges on : 1 (100.00%)           |
| total execs : 121                   | total crashes : 0 (0 unique)          |
|  exec speed : 24.60/sec (slow!)     |  total tmouts : 0 (0 unique)          |
+- fuzzing strategy yields -----------+---------------+- path geometry -------+
|   bit flips : 0/0, 0/0, 0/0                         |    levels : 1         |
|  byte flips : 0/0, 0/0, 0/0                         |   pending : 1         |
| arithmetics : 0/0, 0/0, 0/0                         |  pend fav : 1         |
|  known ints : 0/0, 0/0, 0/0                         | own finds : 0         |
|  dictionary : 0/0, 0/0, 0/0                         |  imported : n/a       |
|       havoc : 0/0, 0/0                              | stability : 71.21%    |
|        trim : 13.56%/14, n/a                        +-----------------------+

That being said, why is win_afl claiming that my binary is pretty slow when the function being fuzzed is a 1-liner?

#include <iostream>
extern "C" __declspec(dllexport) void fuzz(char const* const filename)
{
    std::cout << "Entered fuzz function:" << filename << std::endl;
} // fuzz

That's confusing.

jonesmz avatar Mar 29 '21 16:03 jonesmz

USE_DRSYMS is a WinAFL flag (affecting whether drsyms module will be used) so you won't find it in other projects.

To get some extra speed, increase -fuzz_iterations. -fuzz_iterations 10 means the target process will be restarted every 10 iterations, which is a slow operation (and even more so under instrumentation).

ifratric avatar Mar 29 '21 16:03 ifratric

Is that what

[!] WARNING: The target binary is pretty slow! See afl_docs\perf_tips.txt.

is complaining about?

jonesmz avatar Mar 29 '21 17:03 jonesmz