googleprojectzero / winafl

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

Target function was never called. Incorrect target_offset? #20

Closed hugoMeier closed 8 years ago

hugoMeier commented 8 years ago

I have a question about the target_offset for functions other than main. I wrote a little program which should test myDll.dll

`void fuzz(int argc, char *argv[]) { FuncWithParams paramFunc; paramFunc = (FuncWithParams)GetProcAddress(hDLL, "process"); int result = paramFunc(argc, argv); }

int main(int argc, char *argv[]) { hDLL = LoadLibrary("myDll.dll"); fuzz(argc, argv); FreeLibrary(hDLL); return 0; }`

In WinDbg I'm getting the target_offset as follow:

ModLoad: 00da0000 00da9000 test.exe

with x test!main = 00da1060 -> offset is 0x1060 with x test!fuzz = 00da1020 -> offset is 0x1020

When I try to run winafl with target_offset 0x1060 (main) everything works fine but it's very slow (because LoadLibrary is called every time) ! When I try to run winafl with target_offset 0x1020 (fuzz) I'm getting an error that the initial testcase caused a hang -> drun -debug log says: Target function was never called. Incorrect target_offset?

What I'm doing wrong ?

mrpeppels commented 8 years ago

My advice is to have the fuzz function return like so:

int fuzz(int argc, char *argv[])
{
FuncWithParams paramFunc;
paramFunc = (FuncWithParams)GetProcAddress(hDLL, "process");
int result = paramFunc(argc, argv);
return result;
}

But i don't know for sure if failing to do this would cause your issue. I would imagine the pre_fuzz handler would still get called

ivanfratric commented 8 years ago

His function does return implicitly (I don't think there needs to be an explicit call to "return") and it should work as is, but if the got an "target function was never called" and if there aren't any pre_fuzz_handler lines in the debug log then the error means, well, just what it says. :-)

@hugoMeier it's impossible for me to tell what the issue is with just the info provided. Perhaps you recompiled the target and the offset changed. Also note that both the target_offset and target_module need to be correct (but if it works with the offset of main then I assume target_module is correct)

mrpeppels commented 8 years ago

@ivanfratric thanks for supporting us mortals in using the awesomely underappreciated piece of code you built :) . Coverage guided fuzzing on windows is just pure gold.

hugoMeier commented 8 years ago

I modified the example application test_gdiplus

`

include

include

include

using namespace Gdiplus;

void fuzz() { printf("hello fuzz..."); }

wchar_t* charToWChar(const char* text) { size_t size = strlen(text) + 1; wchar_t* wa = new wchar_t[size]; mbstowcs(wa,text,size); return wa; }

int main(int argc, char\ argv) { if(argc < 2) { printf("Usage: %s \n", argv[0]); return 0; } fuzz();

GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

Image *image = NULL, *thumbnail=NULL;

image = new Image(charToWChar(argv[1]));
if(image && (Ok == image->GetLastStatus())) {
    //printf("Image loaded\n");
    /*thumbnail = image->GetThumbnailImage(100, 100, NULL, NULL);
    if(thumbnail && (Ok == thumbnail->GetLastStatus())) {
        //printf("Thumbnail created\n");
    }*/
}

//printf("Done\n");

if(image) delete image;
if(thumbnail) delete thumbnail;

GdiplusShutdown(gdiplusToken);

return 0;

} `

My target offsets are: main = 0x1300 fuzz = 0x12F0

C:\DynamoRIO-Windows-6.2.0-2\bin32\drrun.exe -c winafl.dll -debug -target_module test_gdiplus.exe -target_offset 0x1300 -fuzz_iterations 5 -nargs 2 -- test_gdiplus.exe in/test.jpeg hello fuzz...hello fuzz...hello fuzz...hello fuzz...hello fuzz...

C:\DynamoRIO-Windows-6.2.0-2\bin32\drrun.exe -c winafl.dll -debug -target_module test_gdiplus.exe -target_offset 0x12F0 -fuzz_iterations 5 -nargs 2 -- test_gdiplus.exe in/test.jpeg hello fuzz...

The error log looks like this: Module loaded, test_gdiplus.exe Module loaded, drmgr.dll Module loaded, drx.dll Module loaded, drreg.dll Module loaded, drwrap.dll Module loaded, winafl.dll Module loaded, MSVCR120.dll Module loaded, gdiplus.dll Module loaded, dynamorio.dll Module loaded, sophos_detoured.dll Module loaded, bcryptPrimitives.dll Module loaded, CRYPTBASE.dll Module loaded, USER32.dll Module loaded, combase.dll Module loaded, SECHOST.dll Module loaded, SspiCli.dll Module loaded, MSCTF.dll Module loaded, KERNEL32.dll Module loaded, GDI32.dll Module loaded, KERNELBASE.dll Module loaded, msvcrt.dll Module loaded, IMM32.dll Module loaded, PSAPI.DLL Module loaded, RPCRT4.dll Module loaded, ntdll.dll Module loaded, UxTheme.dll Module loaded, tiptsf.dll Module loaded, OLEAUT32.dll Module loaded, WindowsCodecs.dll WARNING: Target function was never called. Incorrect target_offset? Coverage map follows:

hugoMeier commented 8 years ago

Ok I solved the problem.

The reason was that I used the CMakeList from WinAFL for building my target -> When I build with VS and use the target from there, it works as expected.

Thanks for helping me and bye the way AFL & WinAFL are awesome!

ivanfratric commented 8 years ago

Closing for now. Not sure why building with cmake or Visual Studio would cause it to behave differently. Please reopen if you figure out the root cause.