changed context member types, add crash detection (untested!)

This commit is contained in:
zeffy
2018-03-02 19:06:42 -08:00
parent 24c6029bdd
commit 2db985a55b
5 changed files with 141 additions and 68 deletions

View File

@@ -3,13 +3,13 @@
#include <sddl.h>
static bool ctxp_remove_handle(context *ctx, unsigned Index)
static bool ctxp_remove_handle(context *ctx, DWORD Index)
{
if ( !ctx || Index > _countof(ctx->handles) || Index > ctx->count )
return false;
EnterCriticalSection(&ctx->cs);
for ( unsigned i = Index; i < ctx->count - 1; i++ ) {
for ( DWORD i = Index; i < ctx->count - 1; i++ ) {
ctx->handles[i] = ctx->handles[i + 1];
ctx->tags[i] = ctx->tags[i + 1];
}
@@ -83,15 +83,15 @@ static bool ctxp_create_event_with_string_security_descriptor(
return false;
}
static unsigned ctxp_find_handle_index(context *ctx, HANDLE Handle)
static DWORD ctxp_find_handle_index(context *ctx, HANDLE Handle)
{
unsigned result = -1;
DWORD result = -1;
if ( !ctx || !Handle || Handle == INVALID_HANDLE_VALUE )
return -1;
EnterCriticalSection(&ctx->cs);
for ( unsigned i = 0; i < ctx->count; i++ ) {
for ( DWORD i = 0; i < ctx->count; i++ ) {
if ( ctx->handles[i] == Handle ) {
result = i;
break;
@@ -103,10 +103,10 @@ static unsigned ctxp_find_handle_index(context *ctx, HANDLE Handle)
bool ctx_create(context *ctx,
const wchar_t *MutexName,
unsigned MutexTag,
DWORD MutexTag,
const wchar_t *EventName,
const wchar_t *EventStringSecurityDescriptor,
unsigned EventTag)
DWORD EventTag)
{
bool result = false;
@@ -146,16 +146,16 @@ bool ctx_delete(context *ctx)
return true;
}
unsigned ctx_add_handle(context *ctx, HANDLE Handle, unsigned Tag)
DWORD ctx_add_handle(context *ctx, HANDLE Handle, DWORD Tag)
{
unsigned result = -1;
DWORD result = -1;
if ( !ctx || !Handle )
return -1;
EnterCriticalSection(&ctx->cs);
result = ctxp_find_handle_index(ctx, Handle);
if ( result != -1) {
if ( result != -1 ) {
ctx->tags[result] = Tag;
} else if ( ctx->count < _countof(ctx->handles) ) {
ctx->handles[ctx->count] = Handle;
@@ -167,10 +167,10 @@ unsigned ctx_add_handle(context *ctx, HANDLE Handle, unsigned Tag)
return result;
}
bool ctx_get_tag(context *ctx, HANDLE Handle, unsigned *pTag)
bool ctx_get_tag(context *ctx, HANDLE Handle, DWORD *pTag)
{
bool result = false;
unsigned index;
DWORD index;
if ( !ctx || !Handle || !pTag )
return false;
@@ -187,14 +187,14 @@ bool ctx_get_tag(context *ctx, HANDLE Handle, unsigned *pTag)
return result;
}
unsigned ctx_add_new_mutex(context *ctx,
DWORD ctx_add_new_mutex(context *ctx,
bool InitialOwner,
const wchar_t *Name,
unsigned Tag,
DWORD Tag,
HANDLE *pMutexHandle)
{
HANDLE hMutex;
unsigned result = -1;
DWORD result = -1;
EnterCriticalSection(&ctx->cs);
if ( ctxp_create_new_mutex(InitialOwner, Name, &hMutex) ) {
@@ -210,15 +210,15 @@ unsigned ctx_add_new_mutex(context *ctx,
return result;
}
unsigned ctx_add_new_mutex_fmt(context *ctx,
DWORD ctx_add_new_mutex_fmt(context *ctx,
bool InitialOwner,
unsigned Tag,
DWORD Tag,
HANDLE *pMutexHandle,
const wchar_t *const NameFormat,
...)
{
HANDLE hMutex;
unsigned result = -1;
DWORD result = -1;
va_list arglist;
EnterCriticalSection(&ctx->cs);
@@ -237,13 +237,13 @@ unsigned ctx_add_new_mutex_fmt(context *ctx,
return result;
}
unsigned ctx_add_event(context *ctx,
DWORD ctx_add_event(context *ctx,
const wchar_t *Name,
const wchar_t *StringSecurityDescriptor,
unsigned Tag,
DWORD Tag,
HANDLE *pEventHandle)
{
unsigned result = -1;
DWORD result = -1;
HANDLE hEvent;
EnterCriticalSection(&ctx->cs);
@@ -265,10 +265,12 @@ unsigned ctx_add_event(context *ctx,
return result;
}
bool ctx_wait(context *ctx, bool WaitAll, bool Alertable, DWORD *pResult)
bool ctx_wait_all(context *ctx,
bool Alertable,
DWORD *pResult)
{
int ret;
unsigned count;
DWORD count;
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
EnterCriticalSection(&ctx->cs);
@@ -276,22 +278,63 @@ bool ctx_wait(context *ctx, bool WaitAll, bool Alertable, DWORD *pResult)
ret = memcpy_s(handles, sizeof(handles), ctx->handles, count * (sizeof *handles));
LeaveCriticalSection(&ctx->cs);
if ( !ret ) {
if ( ret )
return false;
*pResult = WaitForMultipleObjectsEx(count,
handles,
WaitAll,
TRUE,
INFINITE,
Alertable);
return true;
}
return false;
}
bool ctx_close_and_remove_handle(context *ctx,
HANDLE Handle)
DWORD ctx_wait_any(context *ctx,
bool Alertable,
DWORD *pResult,
HANDLE *pHandle,
DWORD *pTag)
{
DWORD count;
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
DWORD tags[MAXIMUM_WAIT_OBJECTS];
int ret;
DWORD result;
DWORD index;
EnterCriticalSection(&ctx->cs);
// make copies of the struct members on the stack before waiting, because
// WaitForMultipleObjects(Ex) doesn't like it when you modify the contents of
// the array it is waiting on.
count = ctx->count;
ret = memcpy_s(handles, sizeof(handles), ctx->handles, count * (sizeof *handles));
if ( !ret )
ret = memcpy_s(tags, sizeof(tags), ctx->tags, count * (sizeof *tags));
LeaveCriticalSection(&ctx->cs);
if ( ret )
return -1;
result = WaitForMultipleObjectsEx(count, handles, FALSE, INFINITE, Alertable);
if ( result >= WAIT_OBJECT_0 || result < WAIT_OBJECT_0 + count )
index = result - WAIT_OBJECT_0;
else if ( result >= WAIT_ABANDONED_0 || result < WAIT_ABANDONED_0 + count )
index = result - WAIT_ABANDONED_0;
if ( pHandle )
*pHandle = handles[index];
if ( pTag )
*pTag = tags[index];
*pResult = result;
return count;
}
bool ctx_close_and_remove_handle(context *ctx, HANDLE Handle)
{
bool result = false;
unsigned index;
DWORD index;
EnterCriticalSection(&ctx->cs);
index = ctxp_find_handle_index(ctx, Handle);
@@ -307,12 +350,12 @@ bool ctx_duplicate_context(const context *pSrc,
context *pDst,
HANDLE Handle,
DWORD DesiredAccess,
unsigned Tag)
DWORD Tag)
{
bool result = false;
HANDLE hSrcProcess;
HANDLE hTarget;
size_t index;
DWORD index;
hSrcProcess = GetCurrentProcess();

View File

@@ -4,7 +4,7 @@
typedef struct
{
CRITICAL_SECTION cs;
unsigned count;
DWORD count;
union
{
struct
@@ -18,54 +18,51 @@ typedef struct
{
struct
{
unsigned mutex_tag;
unsigned uevent_tag;
DWORD mutex_tag;
DWORD uevent_tag;
};
unsigned tags[MAXIMUM_WAIT_OBJECTS];
DWORD tags[MAXIMUM_WAIT_OBJECTS];
};
} context;
#pragma pack(pop)
bool ctx_create(context *ctx,
const wchar_t *MutexName,
unsigned MutexTag,
DWORD MutexTag,
const wchar_t *EventName,
const wchar_t *EventStringSecurityDescriptor,
unsigned EventTag);
DWORD EventTag);
bool ctx_delete(context *ctx);
unsigned ctx_add_handle(context *ctx, HANDLE Handle, unsigned Tag);
bool ctx_get_tag(context *ctx, HANDLE Handle, unsigned *pTag);
unsigned ctx_add_new_mutex(context *ctx,
DWORD ctx_add_handle(context *ctx, HANDLE Handle, DWORD Tag);
bool ctx_get_tag(context *ctx, HANDLE Handle, DWORD *pTag);
DWORD ctx_add_new_mutex(context *ctx,
bool InitialOwner,
const wchar_t *Name,
unsigned Tag,
DWORD Tag,
HANDLE *pMutexHandle);
unsigned ctx_add_new_mutex_fmt(context *ctx,
DWORD ctx_add_new_mutex_fmt(context *ctx,
bool InitialOwner,
unsigned Tag,
DWORD Tag,
HANDLE *pMutexHandle,
const wchar_t *const NameFormat,
...);
unsigned ctx_add_event(context *ctx,
DWORD ctx_add_event(context *ctx,
const wchar_t *Name,
const wchar_t *StringSecurityDescriptor,
unsigned Tag,
DWORD Tag,
HANDLE *pEventHandle);
bool ctx_wait(context *ctx, bool WaitAll, bool Alertable, DWORD *pResult);
bool ctx_close_and_remove_handle(context *ctx,
HANDLE Handle);
bool ctx_wait_all(context *ctx,
bool Alertable,
DWORD *pResult);
DWORD ctx_wait_any(context *ctx,
bool Alertable,
DWORD *pResult,
HANDLE *pHandle,
DWORD *pTag);
bool ctx_close_and_remove_handle(context *ctx, HANDLE Handle);
bool ctx_duplicate_context(const context *pSrc,
HANDLE hProcess,
context *pDst,
HANDLE Handle,
DWORD DesiredAccess,
unsigned Tag);
DWORD Tag);

View File

@@ -17,6 +17,10 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, in
SC_HANDLE hSCM;
SC_HANDLE hService;
SERVICE_NOTIFYW NotifyBuffer;
DWORD count;
DWORD ret;
HANDLE handle;
DWORD tag;
if ( !ctx_create(&ctx,
L"Global\\25020063-b5a7-4227-9fdf-25cb75e8c645", 0,
@@ -48,7 +52,30 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, in
SERVICE_NOTIFY_START_PENDING | SERVICE_NOTIFY_RUNNING,
&NotifyBuffer) ) {
case ERROR_SUCCESS:
Unloading = WaitForSingleObjectEx(ctx.uevent, INFINITE, TRUE) == WAIT_OBJECT_0;
count = ctx_wait_any(&ctx, true, &ret, &handle, &tag);
if ( count == -1 ) {
// Wait function failed while making static copy of handles/tags, wtf!
Unloading = true;
break;
} else if ( ret == WAIT_OBJECT_0 + 1 ) {
trace(L"Unload event was set!");
Unloading = true;
break;
} else if ( (ret >= ERROR_ABANDONED_WAIT_0 || ret < WAIT_ABANDONED_0 + count) ) {
g_ServiceHostCrashCount++;
trace(L"A process that wufuc injected into has crashed %Iu times!!! PID=%lu ",
g_ServiceHostCrashCount, tag);
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;
}
break;
case ERROR_SERVICE_NOTIFY_CLIENT_LAGGING:
trace(L"Client lagging!");

View File

@@ -9,6 +9,8 @@
#include <minhook.h>
size_t g_ServiceHostCrashCount;
bool wufuc_inject(DWORD dwProcessId,
LPTHREAD_START_ROUTINE pfnStart,
context *pContext)

View File

@@ -6,6 +6,10 @@ typedef struct
WORD wCodePage;
} LANGANDCODEPAGE, *PLANGANDCODEPAGE;
#define WUFUC_CRASH_THRESHOLD 3
extern size_t g_ServiceHostCrashCount;
bool wufuc_inject(DWORD dwProcessId,
LPTHREAD_START_ROUTINE pfnStart,
context *pContext);