-
-
Notifications
You must be signed in to change notification settings - Fork 334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Capture __fastfail exceptions on windows #395
Comments
For the record, the problem indeed exist, here is the walkthrough How to repro#include <string.h>
extern "C"
{
__declspec(dllexport)
void fuzz_function(const char *src, size_t len)
{
char buf[512];
if (len < 4)
return;
if (src[0] != 'B')
return;
if (src[1] != 'O')
return;
if (src[2] != 'O')
return;
if (src[3] != 'M')
return;
memset(buf, 0, sizeof(buf)*2);
return;
}
}
compile string: You'll see the debugger popped up, if you have postmortem one installed debugsecurity_check_cookie -> __report_gsfailure void __fastcall __noreturn _report_gsfailure(unsigned __int64 stack_cookie)
{
void *retaddr; // [rsp+38h] [rbp+0h]
unsigned __int64 stack_cookiea; // [rsp+40h] [rbp+8h] BYREF
stack_cookiea = stack_cookie;
if ( IsProcessorFeaturePresent(0x17u) )
__fastfail(2u);
capture_previous_context(&GS_ContextRecord);
GS_ContextRecord.Rip = (unsigned __int64)retaddr;
GS_ContextRecord.Rsp = (unsigned __int64)&stack_cookiea;
GS_ExceptionRecord.ExceptionAddress = retaddr;
GS_ContextRecord.Rcx = stack_cookiea;
GS_ExceptionRecord.ExceptionCode = 0xC0000409;
GS_ExceptionRecord.ExceptionFlags = 1;
GS_ExceptionRecord.NumberParameters = 1;
GS_ExceptionRecord.ExceptionInformation[0] = 2i64;
j___raise_securityfailure(&GS_ExceptionPointers);
}
...
void __fastcall _raise_securityfailure(_EXCEPTION_POINTERS *const exception_pointers)
{
HANDLE CurrentProcess; // rax
SetUnhandledExceptionFilter(0i64);
UnhandledExceptionFilter(exception_pointers);
CurrentProcess = GetCurrentProcess();
TerminateProcess(CurrentProcess, 0xC0000409);
}
And IsProcessorFeaturePresent just checks KUSER_SHARED_DATA.ProcessorFeatures: char __fastcall RtlIsProcessorFeaturePresent(unsigned int a1)
{
if ( a1 >= 0x40 )
return 0;
else
return *(_BYTE *)(a1 + 0x7FFE0274i64);
} the solutionWinAFL's solution is partially right, to catch the exception we need to hook the implementationSo far stuck on hook part. @tokatoka have any link how to hook win api with Frida? I found so far only this and libafl_frida\src\asan\hook_funcs.rs which is somewhat hard to grasp. |
Confirmed, VEH handler is called if |
nice! |
Actually I was wrong, it's not the case. I confused it with exit process code 😆 Anyway I'll try to use hook |
Somehow the PR works:
|
This is not done yet... |
maybe we can use something like this (although, it looks really old) and then in the constructor for windows executor, hook IsProcessFeaturePresent |
Requires nightly though, doesn't work on aarch, and is not maintained anymore/archived |
There's a pr for newer (nightly) versions though |
yeah I suppose we can do this hooking manually, shouldn't be difficult here's a good blogpost about how to do this manually |
somehow missed the latest conversation, @tokatoka what is inprocess-fuzzing in general, and how is that separated from Frida? I thought currently Frida is the only option for windows binary targets. If you have compiler instrumentation, perhaps you don't need this hook? |
You can build inprocess-fuzzers with clang from source, and those will run into the same exception issues. We'll need a solution for these, too. |
#258
When software call __fastfail, the exception can't be caught
https://github.com/googleprojectzero/winafl/blob/ea5f6b85572980bb2cf636910f622f36906940aa/winafl.c#L728
winafl wraps two functions in kernelbase.dll
for frida fuzzers, I think this can be done in a similar way as winafl,
but for sancov backend fuzzers, we would have to look at what libfuzzer is doing.
The text was updated successfully, but these errors were encountered: