crash detection fixes
This commit is contained in:
@@ -112,9 +112,14 @@ abort_hook:
|
|||||||
}
|
}
|
||||||
MH_EnableHook(MH_ALL_HOOKS);
|
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.
|
// 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.");
|
trace(L"Unload condition has been met.");
|
||||||
|
|
||||||
switch ( result ) {
|
switch ( result ) {
|
||||||
@@ -133,7 +138,7 @@ close_handles:
|
|||||||
CloseHandle(ctx->uevent);
|
CloseHandle(ctx->uevent);
|
||||||
VirtualFree(ctx, 0, MEM_RELEASE);
|
VirtualFree(ctx, 0, MEM_RELEASE);
|
||||||
unload:
|
unload:
|
||||||
trace(L"Freeing library and exiting thread.");
|
trace(L"Unloading wufuc and exiting thread.");
|
||||||
FreeLibraryAndExitThread(PIMAGEBASE, 0);
|
FreeLibraryAndExitThread(PIMAGEBASE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -265,6 +265,16 @@ DWORD ctx_add_event(context *ctx,
|
|||||||
return result;
|
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 ctx_wait_all(context *ctx,
|
||||||
bool Alertable,
|
bool Alertable,
|
||||||
DWORD *pResult)
|
DWORD *pResult)
|
||||||
@@ -289,6 +299,16 @@ bool ctx_wait_all(context *ctx,
|
|||||||
return true;
|
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,
|
DWORD ctx_wait_any(context *ctx,
|
||||||
bool Alertable,
|
bool Alertable,
|
||||||
DWORD *pResult,
|
DWORD *pResult,
|
||||||
@@ -361,13 +381,16 @@ bool ctx_duplicate_context(const context *pSrc,
|
|||||||
|
|
||||||
if ( !DuplicateHandle(hSrcProcess, pSrc->mutex, hProcess, &pDst->mutex, SYNCHRONIZE, FALSE, 0) )
|
if ( !DuplicateHandle(hSrcProcess, pSrc->mutex, hProcess, &pDst->mutex, SYNCHRONIZE, FALSE, 0) )
|
||||||
return false;
|
return false;
|
||||||
|
pDst->count++;
|
||||||
|
|
||||||
if ( !DuplicateHandle(hSrcProcess, pSrc->uevent, hProcess, &pDst->uevent, SYNCHRONIZE, FALSE, 0) ) {
|
if ( !DuplicateHandle(hSrcProcess, pSrc->uevent, hProcess, &pDst->uevent, SYNCHRONIZE, FALSE, 0) ) {
|
||||||
close_mutex:
|
close_mutex:
|
||||||
CloseHandle(pDst->mutex);
|
CloseHandle(pDst->mutex);
|
||||||
pDst->mutex = INVALID_HANDLE_VALUE;
|
pDst->mutex = INVALID_HANDLE_VALUE;
|
||||||
|
pDst->count = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
pDst->count++;
|
||||||
if ( !DuplicateHandle(hSrcProcess, Handle, hProcess, &hTarget, 0, FALSE, DesiredAccess)
|
if ( !DuplicateHandle(hSrcProcess, Handle, hProcess, &hTarget, 0, FALSE, DesiredAccess)
|
||||||
|| (index = ctx_add_handle(pDst, hTarget, Tag)) == -1 ) {
|
|| (index = ctx_add_handle(pDst, hTarget, Tag)) == -1 ) {
|
||||||
|
|
||||||
@@ -376,6 +399,6 @@ close_mutex:
|
|||||||
goto close_mutex;
|
goto close_mutex;
|
||||||
|
|
||||||
}
|
}
|
||||||
pDst->tags[0] = index;
|
pDst->mutex_tag = index;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -51,9 +51,13 @@ DWORD ctx_add_event(context *ctx,
|
|||||||
const wchar_t *StringSecurityDescriptor,
|
const wchar_t *StringSecurityDescriptor,
|
||||||
DWORD Tag,
|
DWORD Tag,
|
||||||
HANDLE *pEventHandle);
|
HANDLE *pEventHandle);
|
||||||
|
DWORD ctx_wait_all_unsafe(context *ctx,
|
||||||
|
bool Alertable);
|
||||||
bool ctx_wait_all(context *ctx,
|
bool ctx_wait_all(context *ctx,
|
||||||
bool Alertable,
|
bool Alertable,
|
||||||
DWORD *pResult);
|
DWORD *pResult);
|
||||||
|
DWORD ctx_wait_any_unsafe(context *ctx,
|
||||||
|
bool Alertable);
|
||||||
DWORD ctx_wait_any(context *ctx,
|
DWORD ctx_wait_any(context *ctx,
|
||||||
bool Alertable,
|
bool Alertable,
|
||||||
DWORD *pResult,
|
DWORD *pResult,
|
||||||
|
@@ -58,20 +58,20 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, in
|
|||||||
Unloading = true;
|
Unloading = true;
|
||||||
break;
|
break;
|
||||||
} else if ( ret == WAIT_OBJECT_0 + 1 ) {
|
} else if ( ret == WAIT_OBJECT_0 + 1 ) {
|
||||||
trace(L"Unload event was set!");
|
trace(L"Unload event was signaled!");
|
||||||
Unloading = true;
|
Unloading = true;
|
||||||
break;
|
break;
|
||||||
} else if ( (ret >= ERROR_ABANDONED_WAIT_0 || ret < WAIT_ABANDONED_0 + count) ) {
|
} else if ( (ret >= ERROR_ABANDONED_WAIT_0 || ret < WAIT_ABANDONED_0 + count) ) {
|
||||||
g_ServiceHostCrashCount++;
|
g_ServiceHostCrashCount++;
|
||||||
trace(L"A process that wufuc injected into has crashed %Iu times!!! PID=%lu ",
|
trace(L"A process that wufuc injected into has crashed %Iu times!!! PID=%lu",
|
||||||
g_ServiceHostCrashCount, tag);
|
g_ServiceHostCrashCount, tag);
|
||||||
|
|
||||||
|
ReleaseMutex(handle); // release the abandoned mutex
|
||||||
|
ctx_close_and_remove_handle(&ctx, handle);
|
||||||
if ( g_ServiceHostCrashCount >= WUFUC_CRASH_THRESHOLD ) {
|
if ( g_ServiceHostCrashCount >= WUFUC_CRASH_THRESHOLD ) {
|
||||||
trace(L"Crash threshold has been reached, disabling wufuc until next reboot!");
|
trace(L"Crash threshold has been reached, disabling wufuc until next reboot!");
|
||||||
Unloading = true;
|
Unloading = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unloading = true;
|
|
||||||
} else if ( ret == WAIT_FAILED ) {
|
} else if ( ret == WAIT_FAILED ) {
|
||||||
trace(L"Wait failed! GLE=%lu", GetLastError());
|
trace(L"Wait failed! GLE=%lu", GetLastError());
|
||||||
Unloading = true;
|
Unloading = true;
|
||||||
|
Reference in New Issue
Block a user