finished implementing crash detection

This commit is contained in:
zeffy
2018-03-08 17:51:23 -08:00
parent 093a4f8dc5
commit a6a79e03dc
3 changed files with 60 additions and 54 deletions

View File

@@ -360,10 +360,18 @@ leave:
return result; return result;
} }
void ptrlist_for_each_stdcall(ptrlist_t *list, void(__stdcall *f)(void *)) void ptrlist_for(ptrlist_t *list, size_t index, size_t count, void(__cdecl *f)(void *))
{ {
ptrlist_lock(list); ptrlist_lock(list);
ptrlist_for_stdcall(list, 0, list->count, f); for ( size_t i = index; i < count; i++ )
f(list->values[i]);
ptrlist_unlock(list);
}
void ptrlist_for_each(ptrlist_t *list, void(__cdecl *f)(void *))
{
ptrlist_lock(list);
ptrlist_for(list, 0, list->count, f);
ptrlist_unlock(list); ptrlist_unlock(list);
} }
@@ -375,17 +383,9 @@ void ptrlist_for_stdcall(ptrlist_t *list, size_t index, size_t count, void(__std
ptrlist_unlock(list); ptrlist_unlock(list);
} }
void ptrlist_for_each_cdecl(ptrlist_t *list, void(__cdecl *f)(void *)) void ptrlist_for_each_stdcall(ptrlist_t *list, void(__stdcall *f)(void *))
{ {
ptrlist_lock(list); ptrlist_lock(list);
ptrlist_for_cdecl(list, 0, list->count, f); ptrlist_for_stdcall(list, 0, list->count, f);
ptrlist_unlock(list);
}
void ptrlist_for_cdecl(ptrlist_t *list, size_t index, size_t count, void(__cdecl *f)(void *))
{
ptrlist_lock(list);
for ( size_t i = index; i < count; i++ )
f(list->values[i]);
ptrlist_unlock(list); ptrlist_unlock(list);
} }

View File

@@ -1,7 +1,8 @@
#pragma once #pragma once
#pragma pack(push, 1) #pragma pack(push, 1)
typedef struct ptrlist_t_ { typedef struct ptrlist_t_
{
void **values; void **values;
uint32_t *tags; uint32_t *tags;
size_t capacity; size_t capacity;
@@ -13,10 +14,6 @@ typedef struct ptrlist_t_ {
void ptrlist_lock(ptrlist_t *list); void ptrlist_lock(ptrlist_t *list);
void ptrlist_unlock(ptrlist_t *list); void ptrlist_unlock(ptrlist_t *list);
void ptrlist_for_each_stdcall(ptrlist_t *list, void(__stdcall *f)(void *));
void ptrlist_for_stdcall(ptrlist_t *list, size_t index, size_t count, void(__stdcall *f)(void *));
void ptrlist_for_each_cdecl(ptrlist_t *list, void(__cdecl *f)(void *));
void ptrlist_for_cdecl(ptrlist_t *list, size_t index, size_t count, void(__cdecl *f)(void *));
void *ptrlist_at(ptrlist_t *list, size_t index, uint32_t *pTag); void *ptrlist_at(ptrlist_t *list, size_t index, uint32_t *pTag);
bool ptrlist_create(ptrlist_t *list, size_t capacity, size_t maxCapacity); bool ptrlist_create(ptrlist_t *list, size_t capacity, size_t maxCapacity);
void ptrlist_destroy(ptrlist_t *list); void ptrlist_destroy(ptrlist_t *list);
@@ -34,3 +31,7 @@ bool ptrlist_contains(ptrlist_t *list, void *value);
void **ptrlist_copy_values(ptrlist_t *list, size_t *count); void **ptrlist_copy_values(ptrlist_t *list, size_t *count);
uint32_t *ptrlist_copy_tags(ptrlist_t *list, size_t *count); uint32_t *ptrlist_copy_tags(ptrlist_t *list, size_t *count);
bool ptrlist_copy(ptrlist_t *list, void ***values, uint32_t **tags, size_t *count); bool ptrlist_copy(ptrlist_t *list, void ***values, uint32_t **tags, size_t *count);
void ptrlist_for(ptrlist_t *list, size_t index, size_t count, void(__cdecl *f)(void *));
void ptrlist_for_each(ptrlist_t *list, void(__cdecl *f)(void *));
void ptrlist_for_stdcall(ptrlist_t *list, size_t index, size_t count, void(__stdcall *f)(void *));
void ptrlist_for_each_stdcall(ptrlist_t *list, void(__stdcall *f)(void *));

View File

@@ -28,7 +28,8 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd,
void **values; void **values;
uint32_t *tags; uint32_t *tags;
size_t count; size_t count;
DWORD ret; DWORD e;
DWORD r;
size_t index; size_t index;
size_t crashes = 0; size_t crashes = 0;
@@ -64,58 +65,62 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd,
NotifyBuffer.pfnNotifyCallback = (PFN_SC_NOTIFY_CALLBACK)cb_service_notify; NotifyBuffer.pfnNotifyCallback = (PFN_SC_NOTIFY_CALLBACK)cb_service_notify;
NotifyBuffer.pContext = (PVOID)&list; NotifyBuffer.pContext = (PVOID)&list;
while ( !Unloading && !Lagging ) { while ( !Unloading && !Lagging ) {
switch ( NotifyServiceStatusChangeW(hService, e = NotifyServiceStatusChangeW(hService,
SERVICE_NOTIFY_START_PENDING | SERVICE_NOTIFY_RUNNING, SERVICE_NOTIFY_START_PENDING | SERVICE_NOTIFY_RUNNING,
&NotifyBuffer) ) { &NotifyBuffer);
switch ( e ) {
case ERROR_SUCCESS: case ERROR_SUCCESS:
if ( !ptrlist_copy(&list, &values, &tags, &count) ) { do {
Unloading = true; if ( !ptrlist_copy(&list, &values, &tags, &count) ) {
break;
}
ret = WaitForMultipleObjectsEx((DWORD)count,
values, FALSE, INFINITE, TRUE);
if ( ret >= WAIT_OBJECT_0 && ret < WAIT_OBJECT_0 + count ) {
// object signaled
index = ret - WAIT_OBJECT_0;
if ( index == 0 ) { // Unload event
Unloading = true; Unloading = true;
break; break;
} else { // crash mutex was closed but the process didn't crash }
r = WaitForMultipleObjectsEx((DWORD)count,
values, FALSE, INFINITE, TRUE);
if ( r >= WAIT_OBJECT_0 && r < WAIT_OBJECT_0 + count ) {
// object signaled
index = r - WAIT_OBJECT_0;
if ( !index ) {
// Unload event
Unloading = true;
} else {
// crash mutex was released cleanly
ptrlist_remove(&list, values[index]);
ReleaseMutex(values[index]);
CloseHandle(values[index]);
}
} else if ( r >= WAIT_ABANDONED_0 && r < WAIT_ABANDONED_0 + count ) {
// object abandoned
// crash mutex was abandoned, process has most likely crashed.
index = r - WAIT_ABANDONED_0;
ptrlist_remove(&list, values[index]); ptrlist_remove(&list, values[index]);
ReleaseMutex(values[index]); ReleaseMutex(values[index]);
CloseHandle(values[index]); CloseHandle(values[index]);
}
} else if ( ret >= WAIT_ABANDONED_0 && ret < WAIT_ABANDONED_0 + count ) {
// object abandoned
// crash mutex was abandoned, process has most likely crashed.
index = ret - WAIT_ABANDONED_0;
ptrlist_remove(&list, values[index]); crashes++;
ReleaseMutex(values[index]); trace(L"A process that wufuc injected into has crashed %Iu time%ls!!! (PID=%lu)",
CloseHandle(values[index]); crashes, crashes != 1 ? L"s" : L"", tags[index]);
crashes++; if ( crashes >= SVCHOST_CRASH_THRESHOLD ) {
trace(L"A process that wufuc injected into has crashed %Iu time%ls!!! (PID=%lu)", trace(L"Crash threshold has been reached, disabling wufuc until next reboot!");
crashes, crashes != 1 ? L"s" : L"", tags[index]); Unloading = true;
}
if ( crashes >= SVCHOST_CRASH_THRESHOLD ) { } else if ( r == WAIT_FAILED ) {
trace(L"Crash threshold has been reached, disabling wufuc until next reboot!"); trace(L"WTF - Unexpected result from wait function!!!");
Unloading = true; Unloading = true;
} }
} else if ( ret == WAIT_FAILED ) { free(values);
trace(L"WTF - Unexpected result from wait function!!!"); free(tags);
Unloading = true; } while ( r != WAIT_IO_COMPLETION && !Unloading );
}
free(values);
free(tags);
break; break;
case ERROR_SERVICE_NOTIFY_CLIENT_LAGGING: case ERROR_SERVICE_NOTIFY_CLIENT_LAGGING:
trace(L"Client lagging!"); trace(L"Client lagging!");
Lagging = true; Lagging = true;
break; break;
default: default:
trace(L"NotifyServiceStatusChange failed, return value: %lu (%08X)", e);
Unloading = true; Unloading = true;
break; break;
} }