diff --git a/wufuc.sln b/wufuc.sln index 800916a..4df93c1 100644 --- a/wufuc.sln +++ b/wufuc.sln @@ -8,6 +8,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8C2147FF-2B83-479B-813E-5ACB86F43042}" ProjectSection(SolutionItems) = preProject .gitignore = .gitignore + appveyor.yml = appveyor.yml LICENSE = LICENSE README.md = README.md EndProjectSection diff --git a/wufuc/core.c b/wufuc/core.c index 6075cc3..dac3717 100644 --- a/wufuc/core.c +++ b/wufuc/core.c @@ -65,12 +65,6 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam) { return 0; } -BOOL IsWUModule(HMODULE hModule) { - TCHAR lpBaseName[MAX_PATH + 1]; - GetModuleBaseName(GetCurrentProcess(), hModule, lpBaseName, _countof(lpBaseName)); - return !_tcsicmp(lpBaseName, _T("wuaueng.dll")); -} - BOOL PatchWUModule(HMODULE hModule) { if (!IsWindows7Or8Point1()) { return FALSE; @@ -119,17 +113,24 @@ BOOL PatchWUModule(HMODULE hModule) { return FALSE; } SIZE_T fpIsDeviceServiceable = (SIZE_T)modinfo.lpBaseOfDll + rva; - _tdbgprintf(_T("IsDeviceServiceable(void) matched at %p"), fpIsDeviceServiceable); BOOL *lpbNotRunOnce = (BOOL *)(fpIsDeviceServiceable + n1 + sizeof(DWORD) + *(DWORD *)(fpIsDeviceServiceable + n1)); if (*lpbNotRunOnce) { + DWORD flOldProtect; + DWORD flNewProtect = PAGE_READWRITE; + VirtualProtect(lpbNotRunOnce, sizeof(BOOL), flNewProtect, &flOldProtect); *lpbNotRunOnce = FALSE; + VirtualProtect(lpbNotRunOnce, sizeof(BOOL), flOldProtect, &flNewProtect); _tdbgprintf(_T("Patched %p=%d"), lpbNotRunOnce, *lpbNotRunOnce); } BOOL *lpbCachedResult = (BOOL *)(fpIsDeviceServiceable + n2 + sizeof(DWORD) + *(DWORD *)(fpIsDeviceServiceable + n2)); if (!*lpbCachedResult) { + DWORD flOldProtect; + DWORD flNewProtect = PAGE_READWRITE; + VirtualProtect(lpbCachedResult, sizeof(BOOL), flNewProtect, &flOldProtect); *lpbCachedResult = TRUE; + VirtualProtect(lpbCachedResult, sizeof(BOOL), flOldProtect, &flNewProtect); _tdbgprintf(_T("Patched %p=%d"), lpbCachedResult, *lpbCachedResult); } return TRUE; @@ -141,7 +142,11 @@ HMODULE WINAPI _LoadLibraryExA( _In_ DWORD dwFlags ) { HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags); - if (IsWUModule(result)) { + + CHAR path[MAX_PATH + 1]; + get_svcdllA("wuauserv", path, _countof(path)); + + if (!_stricmp(lpFileName, path)) { PatchWUModule(result); } return result; @@ -153,7 +158,11 @@ HMODULE WINAPI _LoadLibraryExW( _In_ DWORD dwFlags ) { HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags); - if (IsWUModule(result)) { + + WCHAR path[MAX_PATH + 1]; + get_svcdllW(L"wuauserv", path, _countof(path)); + + if (!_wcsicmp(lpFileName, path)) { PatchWUModule(result); } return result; diff --git a/wufuc/entrypoint.c b/wufuc/entrypoint.c index c9970c5..dc855bb 100644 --- a/wufuc/entrypoint.c +++ b/wufuc/entrypoint.c @@ -25,10 +25,7 @@ void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int n TCHAR lpLibFileName[MAX_PATH + 1]; GetModuleFileName(HINST_THISCOMPONENT, lpLibFileName, _countof(lpLibFileName)); - HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); - - InjectLibrary(hProcess, lpLibFileName, _countof(lpLibFileName)); - CloseHandle(hProcess); + InjectLibrary(dwProcessId, lpLibFileName, _countof(lpLibFileName)); } void CALLBACK Rundll32Unload(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { diff --git a/wufuc/service.c b/wufuc/service.c index d25630e..01f1d09 100644 --- a/wufuc/service.c +++ b/wufuc/service.c @@ -1,4 +1,5 @@ #include +#include #include #include "util.h" #include "service.h" @@ -22,6 +23,31 @@ BOOL get_svcpath(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPat return result; } +BOOL get_svcdllA(LPCSTR lpServiceName, LPSTR lpServiceDll, DWORD dwSize) { + CHAR lpSubKey[MAX_PATH + 1]; + sprintf_s(lpSubKey, _countof(lpSubKey), "SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", lpServiceName); + + DWORD uBytes = _MAX_PATH + 1; + LPBYTE pvData = malloc(uBytes); + + RegGetValueA(HKEY_LOCAL_MACHINE, lpSubKey, "ServiceDll", RRF_RT_REG_EXPAND_SZ | RRF_NOEXPAND, NULL, pvData, &uBytes); + + ExpandEnvironmentStringsA((LPSTR)pvData, lpServiceDll, dwSize); + return TRUE; +} + +BOOL get_svcdllW(LPCWSTR lpServiceName, LPWSTR lpServiceDll, DWORD dwSize) { + WCHAR lpSubKey[MAX_PATH + 1]; + swprintf_s(lpSubKey, _countof(lpSubKey), L"SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", lpServiceName); + + DWORD uBytes = _MAX_PATH + 1; + LPBYTE pvData = malloc(uBytes); + RegGetValueW(HKEY_LOCAL_MACHINE, lpSubKey, L"ServiceDll", RRF_RT_REG_EXPAND_SZ | RRF_NOEXPAND, NULL, pvData, &uBytes); + + ExpandEnvironmentStringsW((LPWSTR)pvData, lpServiceDll, dwSize); + return TRUE; +} + BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessId) { SC_HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_STATUS); if (!hService) { @@ -31,7 +57,9 @@ BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessI SERVICE_STATUS_PROCESS lpBuffer; DWORD cbBytesNeeded; BOOL result = FALSE; - if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&lpBuffer, sizeof(lpBuffer), &cbBytesNeeded) && lpBuffer.dwProcessId) { + if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&lpBuffer, sizeof(lpBuffer), &cbBytesNeeded) + && lpBuffer.dwProcessId) { + *lpdwProcessId = lpBuffer.dwProcessId; result = TRUE; } @@ -71,7 +99,8 @@ BOOL get_svcgpid(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwPro DWORD uBytes = 0x100000; LPBYTE pvData = malloc(uBytes); - RegGetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost"), lpServiceGroupName, RRF_RT_REG_MULTI_SZ, NULL, pvData, &uBytes); + RegGetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost"), + lpServiceGroupName, RRF_RT_REG_MULTI_SZ, NULL, pvData, &uBytes); BOOL result = FALSE; for (LPTSTR p = (LPTSTR)pvData; *p; p += _tcslen(p) + 1) { diff --git a/wufuc/service.h b/wufuc/service.h index 901188a..bb3d439 100644 --- a/wufuc/service.h +++ b/wufuc/service.h @@ -2,6 +2,10 @@ BOOL get_svcpath(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPathName, SIZE_T dwSize); +BOOL get_svcdllA(LPCSTR lpServiceName, LPSTR lpServiceDll, DWORD dwSize); + +BOOL get_svcdllW(LPCWSTR lpServiceName, LPWSTR lpServiceDll, DWORD dwSize); + BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessId); BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupName, SIZE_T dwSize); diff --git a/wufuc/util.c b/wufuc/util.c index 3f3a200..6a5c858 100644 --- a/wufuc/util.c +++ b/wufuc/util.c @@ -80,12 +80,12 @@ BOOL FindPattern(LPCBYTE pvData, SIZE_T nNumberOfBytes, LPSTR lpszPattern, SIZE_ return result; } -BOOL InjectLibrary(HANDLE hProcess, LPCTSTR lpLibFileName, DWORD cb) { +BOOL InjectLibrary(DWORD dwProcessId, LPCTSTR lpLibFileName, DWORD cb) { + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); LPVOID lpBaseAddress = VirtualAllocEx(hProcess, NULL, cb, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (!WriteProcessMemory(hProcess, lpBaseAddress, lpLibFileName, cb, NULL)) { return FALSE; } - DWORD dwProcessId = GetProcessId(hProcess); HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId); MODULEENTRY32 me; me.dwSize = sizeof(me); @@ -100,6 +100,7 @@ BOOL InjectLibrary(HANDLE hProcess, LPCTSTR lpLibFileName, DWORD cb) { _tdbgprintf(_T("Injecting %s into process %d"), lpLibFileName, dwProcessId); HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(me.hModule, _CRT_STRINGIZE(LoadLibrary)), lpBaseAddress, 0, NULL); CloseHandle(hThread); + CloseHandle(hProcess); return TRUE; } diff --git a/wufuc/util.h b/wufuc/util.h index 15cb760..23f30d9 100644 --- a/wufuc/util.h +++ b/wufuc/util.h @@ -16,7 +16,7 @@ LPVOID *FindIAT(HMODULE hModule, LPSTR lpFuncName); BOOL FindPattern(LPCBYTE lpBytes, SIZE_T nNumberOfBytes, LPSTR lpszPattern, SIZE_T nStart, SIZE_T *lpOffset); -BOOL InjectLibrary(HANDLE hProcess, LPCTSTR lpLibFileName, DWORD cb); +BOOL InjectLibrary(DWORD dwProcessId, LPCTSTR lpLibFileName, DWORD cb); VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb);