crash detection fixes
This commit is contained in:
@@ -112,9 +112,14 @@ abort_hook:
|
||||
}
|
||||
MH_EnableHook(MH_ALL_HOOKS);
|
||||
|
||||
// wait for unload event or parent mutex to be abandoned.
|
||||
// wait for unload event or the main mutex to be released or abandoned,
|
||||
// for example if the user killed rundll32.exe with task manager.
|
||||
result = WaitForMultipleObjects(ctx->count, ctx->handles, FALSE, INFINITE);
|
||||
|
||||
// we use ctx_wait_any_unsafe here because contexts created by
|
||||
// ctx_duplicate_context are not initialized by ctx_create,
|
||||
// and have no critical section to lock, so they are only used to
|
||||
// hold static values to send to another process.
|
||||
ctx_wait_any_unsafe(ctx, false);
|
||||
trace(L"Unload condition has been met.");
|
||||
|
||||
switch ( result ) {
|
||||
@@ -133,7 +138,7 @@ close_handles:
|
||||
CloseHandle(ctx->uevent);
|
||||
VirtualFree(ctx, 0, MEM_RELEASE);
|
||||
unload:
|
||||
trace(L"Freeing library and exiting thread.");
|
||||
trace(L"Unloading wufuc and exiting thread.");
|
||||
FreeLibraryAndExitThread(PIMAGEBASE, 0);
|
||||
}
|
||||
|
||||
|
@@ -265,6 +265,16 @@ DWORD ctx_add_event(context *ctx,
|
||||
return result;
|
||||
}
|
||||
|
||||
DWORD ctx_wait_all_unsafe(context *ctx,
|
||||
bool Alertable)
|
||||
{
|
||||
return WaitForMultipleObjectsEx(ctx->count,
|
||||
ctx->handles,
|
||||
TRUE,
|
||||
INFINITE,
|
||||
Alertable);
|
||||
}
|
||||
|
||||
bool ctx_wait_all(context *ctx,
|
||||
bool Alertable,
|
||||
DWORD *pResult)
|
||||
@@ -289,6 +299,16 @@ bool ctx_wait_all(context *ctx,
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD ctx_wait_any_unsafe(context *ctx,
|
||||
bool Alertable)
|
||||
{
|
||||
return WaitForMultipleObjectsEx(ctx->count,
|
||||
ctx->handles,
|
||||
FALSE,
|
||||
INFINITE,
|
||||
Alertable);
|
||||
}
|
||||
|
||||
DWORD ctx_wait_any(context *ctx,
|
||||
bool Alertable,
|
||||
DWORD *pResult,
|
||||
@@ -361,13 +381,16 @@ bool ctx_duplicate_context(const context *pSrc,
|
||||
|
||||
if ( !DuplicateHandle(hSrcProcess, pSrc->mutex, hProcess, &pDst->mutex, SYNCHRONIZE, FALSE, 0) )
|
||||
return false;
|
||||
pDst->count++;
|
||||
|
||||
if ( !DuplicateHandle(hSrcProcess, pSrc->uevent, hProcess, &pDst->uevent, SYNCHRONIZE, FALSE, 0) ) {
|
||||
close_mutex:
|
||||
CloseHandle(pDst->mutex);
|
||||
pDst->mutex = INVALID_HANDLE_VALUE;
|
||||
pDst->count = 0;
|
||||
return false;
|
||||
}
|
||||
pDst->count++;
|
||||
if ( !DuplicateHandle(hSrcProcess, Handle, hProcess, &hTarget, 0, FALSE, DesiredAccess)
|
||||
|| (index = ctx_add_handle(pDst, hTarget, Tag)) == -1 ) {
|
||||
|
||||
@@ -376,6 +399,6 @@ close_mutex:
|
||||
goto close_mutex;
|
||||
|
||||
}
|
||||
pDst->tags[0] = index;
|
||||
pDst->mutex_tag = index;
|
||||
return true;
|
||||
}
|
||||
|
@@ -51,9 +51,13 @@ DWORD ctx_add_event(context *ctx,
|
||||
const wchar_t *StringSecurityDescriptor,
|
||||
DWORD Tag,
|
||||
HANDLE *pEventHandle);
|
||||
DWORD ctx_wait_all_unsafe(context *ctx,
|
||||
bool Alertable);
|
||||
bool ctx_wait_all(context *ctx,
|
||||
bool Alertable,
|
||||
DWORD *pResult);
|
||||
DWORD ctx_wait_any_unsafe(context *ctx,
|
||||
bool Alertable);
|
||||
DWORD ctx_wait_any(context *ctx,
|
||||
bool Alertable,
|
||||
DWORD *pResult,
|
||||
|
@@ -58,7 +58,7 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, in
|
||||
Unloading = true;
|
||||
break;
|
||||
} else if ( ret == WAIT_OBJECT_0 + 1 ) {
|
||||
trace(L"Unload event was set!");
|
||||
trace(L"Unload event was signaled!");
|
||||
Unloading = true;
|
||||
break;
|
||||
} else if ( (ret >= ERROR_ABANDONED_WAIT_0 || ret < WAIT_ABANDONED_0 + count) ) {
|
||||
@@ -66,12 +66,12 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, in
|
||||
trace(L"A process that wufuc injected into has crashed %Iu times!!! PID=%lu",
|
||||
g_ServiceHostCrashCount, tag);
|
||||
|
||||
ReleaseMutex(handle); // release the abandoned mutex
|
||||
ctx_close_and_remove_handle(&ctx, handle);
|
||||
if ( g_ServiceHostCrashCount >= WUFUC_CRASH_THRESHOLD ) {
|
||||
trace(L"Crash threshold has been reached, disabling wufuc until next reboot!");
|
||||
Unloading = true;
|
||||
}
|
||||
|
||||
Unloading = true;
|
||||
} else if ( ret == WAIT_FAILED ) {
|
||||
trace(L"Wait failed! GLE=%lu", GetLastError());
|
||||
Unloading = true;
|
||||
|
Reference in New Issue
Block a user