diff --git a/src/wufuc/ptrlist.c b/src/wufuc/ptrlist.c index 67bfa45..b9db9b9 100644 --- a/src/wufuc/ptrlist.c +++ b/src/wufuc/ptrlist.c @@ -360,10 +360,18 @@ leave: 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_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); } @@ -375,17 +383,9 @@ void ptrlist_for_stdcall(ptrlist_t *list, size_t index, size_t count, void(__std 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_for_cdecl(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_for_stdcall(list, 0, list->count, f); ptrlist_unlock(list); } diff --git a/src/wufuc/ptrlist.h b/src/wufuc/ptrlist.h index 39f0cc7..e14034c 100644 --- a/src/wufuc/ptrlist.h +++ b/src/wufuc/ptrlist.h @@ -1,7 +1,8 @@ #pragma once #pragma pack(push, 1) -typedef struct ptrlist_t_ { +typedef struct ptrlist_t_ +{ void **values; uint32_t *tags; size_t capacity; @@ -13,10 +14,6 @@ typedef struct ptrlist_t_ { void ptrlist_lock(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); bool ptrlist_create(ptrlist_t *list, size_t capacity, size_t maxCapacity); void ptrlist_destroy(ptrlist_t *list); @@ -33,4 +30,8 @@ size_t ptrlist_get_max_capacity(ptrlist_t *list); bool ptrlist_contains(ptrlist_t *list, void *value); void **ptrlist_copy_values(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); \ No newline at end of file +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 *)); diff --git a/src/wufuc/rundll32.c b/src/wufuc/rundll32.c index a7e9ec3..c7332b5 100644 --- a/src/wufuc/rundll32.c +++ b/src/wufuc/rundll32.c @@ -28,7 +28,8 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd, void **values; uint32_t *tags; size_t count; - DWORD ret; + DWORD e; + DWORD r; size_t index; size_t crashes = 0; @@ -64,58 +65,62 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd, NotifyBuffer.pfnNotifyCallback = (PFN_SC_NOTIFY_CALLBACK)cb_service_notify; NotifyBuffer.pContext = (PVOID)&list; while ( !Unloading && !Lagging ) { - switch ( NotifyServiceStatusChangeW(hService, + e = NotifyServiceStatusChangeW(hService, SERVICE_NOTIFY_START_PENDING | SERVICE_NOTIFY_RUNNING, - &NotifyBuffer) ) { + &NotifyBuffer); + switch ( e ) { case ERROR_SUCCESS: - if ( !ptrlist_copy(&list, &values, &tags, &count) ) { - Unloading = true; - 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 + do { + if ( !ptrlist_copy(&list, &values, &tags, &count) ) { Unloading = true; 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]); ReleaseMutex(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]); - ReleaseMutex(values[index]); - CloseHandle(values[index]); + crashes++; + trace(L"A process that wufuc injected into has crashed %Iu time%ls!!! (PID=%lu)", + crashes, crashes != 1 ? L"s" : L"", tags[index]); - crashes++; - trace(L"A process that wufuc injected into has crashed %Iu time%ls!!! (PID=%lu)", - crashes, crashes != 1 ? L"s" : L"", tags[index]); - - if ( crashes >= SVCHOST_CRASH_THRESHOLD ) { - trace(L"Crash threshold has been reached, disabling wufuc until next reboot!"); + if ( crashes >= SVCHOST_CRASH_THRESHOLD ) { + trace(L"Crash threshold has been reached, disabling wufuc until next reboot!"); + Unloading = true; + } + } else if ( r == WAIT_FAILED ) { + trace(L"WTF - Unexpected result from wait function!!!"); Unloading = true; } - } else if ( ret == WAIT_FAILED ) { - trace(L"WTF - Unexpected result from wait function!!!"); - Unloading = true; - } - free(values); - free(tags); + free(values); + free(tags); + } while ( r != WAIT_IO_COMPLETION && !Unloading ); break; case ERROR_SERVICE_NOTIFY_CLIENT_LAGGING: trace(L"Client lagging!"); Lagging = true; break; default: + trace(L"NotifyServiceStatusChange failed, return value: %lu (%08X)", e); Unloading = true; break; }