From dd40fdc30a47d1e3a6f7ca2d2c382634c0a042d3 Mon Sep 17 00:00:00 2001 From: zeffy Date: Fri, 30 Jun 2017 19:17:25 -0700 Subject: [PATCH] improved logging and more - write cpu and os info to log - revise some log messages to be more uniform - remove reference to .gitattributes :angry: - refactor some stuff - refuse to load when in wow64 mode --- wufuc.sln | 1 - wufuc/core.c | 26 +++++++++--------- wufuc/dllmain.c | 3 +-- wufuc/rundll32.c | 30 ++++++++++++++++++--- wufuc/service.c | 12 ++++----- wufuc/util.c | 69 +++++++++++++++++++++++++++++++++++++++++------- wufuc/util.h | 10 ++++--- 7 files changed, 112 insertions(+), 39 deletions(-) diff --git a/wufuc.sln b/wufuc.sln index 68df5f4..c4b19be 100644 --- a/wufuc.sln +++ b/wufuc.sln @@ -7,7 +7,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wufuc", "wufuc\wufuc.vcxpro EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8C2147FF-2B83-479B-813E-5ACB86F43042}" ProjectSection(SolutionItems) = preProject - .gitattributes = .gitattributes .gitignore = .gitignore appveyor.yml = appveyor.yml CONTRIBUTING.md = CONTRIBUTING.md diff --git a/wufuc/core.c b/wufuc/core.c index c4d21bd..7c0fe73 100644 --- a/wufuc/core.c +++ b/wufuc/core.c @@ -54,7 +54,7 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam) { WaitForSingleObject(hEvent, INFINITE); - dwprintf(L"Unload event was set."); + dwprintf(L"Unloading..."); SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb); RESTORE_IAT(hm, LoadLibraryExA); @@ -62,7 +62,7 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam) { ResumeAndCloseThreads(lphThreads, cb); CloseHandle(hEvent); - dwprintf(L"See ya!"); + dwprintf(L"Bye bye!"); close_log(); FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0); } @@ -75,11 +75,11 @@ BOOL PatchWUAgentHMODULE(HMODULE hModule) { offset00 = 10; offset01 = 18; #elif defined(_X86_) - if (g_IsWindows7) { + if (IsWindows7()) { pattern = "833D????????00 743E E8???????? A3????????"; offset00 = 2; offset01 = 15; - } else if (g_IsWindows8Point1) { + } else if (IsWindows8Point1()) { pattern = "8BFF 51 833D????????00 7507 A1????????"; offset00 = 5; offset01 = 13; @@ -97,13 +97,13 @@ BOOL PatchWUAgentHMODULE(HMODULE hModule) { return FALSE; } uintptr_t baseAddress = (uintptr_t)modinfo.lpBaseOfDll; - uintptr_t fpIsDeviceServiceable = baseAddress + rva; - dwprintf(L"Found address of IsDeviceServiceable. (%p)", fpIsDeviceServiceable); + uintptr_t lpfnIsDeviceServiceable = baseAddress + rva; + dwprintf(L"Address of wuaueng.dll!IsDeviceServiceable: %p", lpfnIsDeviceServiceable); BOOL result = FALSE; LPBOOL lpbFirstRun, lpbIsCPUSupportedResult; #ifdef _AMD64_ - lpbFirstRun = (LPBOOL)(fpIsDeviceServiceable + offset00 + sizeof(uint32_t) + *(uint32_t *)(fpIsDeviceServiceable + offset00)); - lpbIsCPUSupportedResult = (LPBOOL)(fpIsDeviceServiceable + offset01 + sizeof(uint32_t) + *(uint32_t *)(fpIsDeviceServiceable + offset01)); + lpbFirstRun = (LPBOOL)(lpfnIsDeviceServiceable + offset00 + sizeof(uint32_t) + *(uint32_t *)(lpfnIsDeviceServiceable + offset00)); + lpbIsCPUSupportedResult = (LPBOOL)(lpfnIsDeviceServiceable + offset01 + sizeof(uint32_t) + *(uint32_t *)(lpfnIsDeviceServiceable + offset01)); #elif defined(_X86_) lpbFirstRun = (LPBOOL)(*(uintptr_t *)(fpIsDeviceServiceable + offset00)); lpbIsCPUSupportedResult = (LPBOOL)(*(uintptr_t *)(fpIsDeviceServiceable + offset01)); @@ -111,12 +111,12 @@ BOOL PatchWUAgentHMODULE(HMODULE hModule) { if (*lpbFirstRun) { *lpbFirstRun = FALSE; - dwprintf(L"Unset first run var. (%p=%08x)", lpbFirstRun, *lpbFirstRun); + dwprintf(L"Patched FirstRun variable: %p = %08x", lpbFirstRun, *lpbFirstRun); result = TRUE; } if (!*lpbIsCPUSupportedResult) { *lpbIsCPUSupportedResult = TRUE; - dwprintf(L"Set cached result. (%p=%08x)", lpbIsCPUSupportedResult, *lpbIsCPUSupportedResult); + dwprintf(L"Patched cached wuaueng.dll!IsCPUSupported result: %p = %08x", lpbIsCPUSupportedResult, *lpbIsCPUSupportedResult); result = TRUE; } return result; @@ -129,12 +129,11 @@ HMODULE WINAPI _LoadLibraryExA( ) { HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags); if (result) { - dwprintf(L"Loaded %S.", lpFileName); + dwprintf(L"Loaded library: %S", lpFileName); CHAR path[MAX_PATH + 1]; if (!get_svcdllA("wuauserv", path, _countof(path))) { return result; } - if (!_stricmp(lpFileName, path) && PatchWUAgentHMODULE(result)) { dwprintf(L"Patched Windows Update module!"); } @@ -149,12 +148,11 @@ HMODULE WINAPI _LoadLibraryExW( ) { HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags); if (result) { - dwprintf(L"Loaded library: %s.", lpFileName); + dwprintf(L"Loaded library: %s", lpFileName); WCHAR path[MAX_PATH + 1]; if (!get_svcdllW(L"wuauserv", path, _countof(path))) { return result; } - if (!_wcsicmp(lpFileName, path) && PatchWUAgentHMODULE(result)) { dwprintf(L"Patched Windows Update module!"); } diff --git a/wufuc/dllmain.c b/wufuc/dllmain.c index a0446e2..18e48f2 100644 --- a/wufuc/dllmain.c +++ b/wufuc/dllmain.c @@ -6,10 +6,9 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { - if (!IsOperatingSystemSupported(&g_IsWindows7, &g_IsWindows8Point1)) { + if (!IsOperatingSystemSupported() || IsWow64()) { return FALSE; } - DisableThreadLibraryCalls(hModule); HANDLE hThread = CreateThread(NULL, 0, NewThreadProc, NULL, 0, NULL); CloseHandle(hThread); diff --git a/wufuc/rundll32.c b/wufuc/rundll32.c index a81e2c0..5d6fe7e 100644 --- a/wufuc/rundll32.c +++ b/wufuc/rundll32.c @@ -1,19 +1,41 @@ #include #include #include +#include #include "service.h" #include "util.h" void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { - if (!g_IsWindows7 && !g_IsWindows8Point1) { - return; - } - HANDLE hEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("Global\\wufuc_UnloadEvent")); if (hEvent) { CloseHandle(hEvent); return; } + + LPWSTR osname; + if (IsWindows7()) { + if (IsWindowsServer()) { + osname = L"Windows Server 2008 R2"; + } else { + osname = L"Windows 7"; + } + } else if (IsWindows8Point1()) { + if (IsWindowsServer()) { + osname = L"Windows Server 2012 R2"; + } else { + osname = L"Windows 8.1"; + } + } + dwprintf(L"Operating System: %s %d-bit", osname, sizeof(uintptr_t) * 8); + + char brand[0x31]; + get_cpuid_brand(brand); + SIZE_T i = 0; + while (i < _countof(brand) && isspace(*(brand + i))) { + i++; + } + dwprintf(L"Processor: %S", brand + i); + SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT); if (!hSCManager) { return; diff --git a/wufuc/service.c b/wufuc/service.c index 7fd19f7..58e23f3 100644 --- a/wufuc/service.c +++ b/wufuc/service.c @@ -44,9 +44,9 @@ BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessI *lpdwProcessId = lpBuffer.dwProcessId; #ifdef _UNICODE - dwprintf(L"Got pid for service %s: %d.", lpServiceName, *lpdwProcessId); + dwprintf(L"Service \"%s\" process ID: %d", lpServiceName, *lpdwProcessId); #else - dwprintf(L"Got pid for service %S: %d.", lpServiceName, *lpdwProcessId); + dwprintf(L"Service \"%S\" process ID: %d", lpServiceName, *lpdwProcessId); #endif result = TRUE; } @@ -75,9 +75,9 @@ BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupNam if (!_tcsicmp(*(p++), _T("-k")) && !_tcscpy_s(lpGroupName, dwSize, *p)) { result = TRUE; #ifdef _UNICODE - dwprintf(L"Got group name of service %s: %s.", lpServiceName, lpGroupName); + dwprintf(L"Service \"%s\" group name: %s", lpServiceName, lpGroupName); #else - dwprintf(L"Got group name of service %S: %S.", lpServiceName, lpGroupName); + dwprintf(L"Service \"%S\" group name: %S", lpServiceName, lpGroupName); #endif break; } @@ -120,9 +120,9 @@ BOOL get_svcgpid(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwPro *lpdwProcessId = dwProcessId; result = TRUE; #ifdef _UNICODE - dwprintf(L"Got pid for service group %s: %d.", lpServiceGroupName, *lpdwProcessId); + dwprintf(L"Service group \"%s\" process ID: %d", lpServiceGroupName, *lpdwProcessId); #else - dwprintf(L"Got pid for service group %S: %d.", lpServiceGroupName, *lpdwProcessId); + dwprintf(L"Service group \"%S\" process ID: %d", lpServiceGroupName, *lpdwProcessId); #endif break; } diff --git a/wufuc/util.c b/wufuc/util.c index 82ca60b..6b99e8e 100644 --- a/wufuc/util.c +++ b/wufuc/util.c @@ -1,13 +1,20 @@ #include #include -#include +#include +#include #include #include #include #include "util.h" -BOOL g_IsWindows7 = FALSE; -BOOL g_IsWindows8Point1 = FALSE; +static BOOL checkedIsWindows7 = FALSE; +static BOOL isWindows7 = FALSE; +static BOOL checkedIsWindows8Point1 = FALSE; +static BOOL isWindows8Point1 = FALSE; + +static LPFN_ISWOW64PROCESS fnIsWow64Process = NULL; +static BOOL checkedIsWow64 = FALSE; +static BOOL isWow64 = FALSE; static FILE *log_fp = NULL; @@ -40,7 +47,7 @@ VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID l if (lpOldAddress) { *lpOldAddress = *lpAddress; } - dwprintf(L"Detoured %S from %p to %p.", lpFuncName, *lpAddress, lpNewAddress); + dwprintf(L"Modified %S import address: %p => %p", lpFuncName, *lpAddress, lpNewAddress); *lpAddress = lpNewAddress; VirtualProtect(lpAddress, sizeof(LPVOID), flOldProtect, &flNewProtect); } @@ -64,7 +71,7 @@ VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThrea CloseHandle(hSnap); *lpcb = count; - dwprintf(L"Suspended %d other threads.", count); + dwprintf(L"Suspended %d other threads", count); } VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T cb) { @@ -72,7 +79,7 @@ VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T cb) { ResumeThread(lphThreads[i]); CloseHandle(lphThreads[i]); } - dwprintf(L"Resumed %d other threads.", cb); + dwprintf(L"Resumed %d other threads", cb); } BOOL CompareWindowsVersion(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask) { @@ -93,15 +100,59 @@ BOOL CompareWindowsVersion(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVer return VerifyVersionInfo(&osvi, dwTypeMask, dwlConditionMask); } -BOOL IsOperatingSystemSupported(LPBOOL lpbIsWindows7, LPBOOL lpbIsWindows8Point1) { +BOOL IsWindows7(void) { + if (!checkedIsWindows7) { + isWindows7 = CompareWindowsVersion(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION); + checkedIsWindows7 = TRUE; + } + return isWindows7; +} + +BOOL IsWindows8Point1(void) { + if (!checkedIsWindows8Point1) { + isWindows8Point1 = CompareWindowsVersion(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION); + checkedIsWindows8Point1 = TRUE; + } + return isWindows8Point1; +} + +BOOL IsOperatingSystemSupported(void) { #if !defined(_AMD64_) && !defined(_X86_) return FALSE; #else - return (*lpbIsWindows7 = CompareWindowsVersion(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)) - || (*lpbIsWindows8Point1 = CompareWindowsVersion(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)); + return IsWindows7() || IsWindows8Point1(); #endif } +BOOL IsWow64(void) { + if (!checkedIsWow64) { + if (!fnIsWow64Process) { + fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "IsWow64Process"); + } + if (fnIsWow64Process && fnIsWow64Process(GetCurrentProcess(), &isWow64)) { + checkedIsWow64 = TRUE; + } + } + return isWow64; +} + +void get_cpuid_brand(char* brand) { + int info[4]; + __cpuidex(info, 0x80000000, 0); + if (info[0] < 0x80000004) { + brand[0] = '\0'; + return; + } + uint32_t *char_as_int = (uint32_t *)brand; + for (int op = 0x80000002; op <= 0x80000004; op++) { + __cpuidex(info, op, 0); + *(char_as_int++) = info[0]; + *(char_as_int++) = info[1]; + *(char_as_int++) = info[2]; + *(char_as_int++) = info[3]; + } +} + BOOL init_log(void) { if (log_fp) { return TRUE; diff --git a/wufuc/util.h b/wufuc/util.h index b87f4a1..723b4bc 100644 --- a/wufuc/util.h +++ b/wufuc/util.h @@ -3,8 +3,7 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase; #define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase) -extern BOOL g_IsWindows7; -extern BOOL g_IsWindows8Point1; +typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); LPVOID *FindIAT(HMODULE hModule, LPSTR lpFuncName); VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress); @@ -13,7 +12,12 @@ VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThrea VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T dwSize); BOOL CompareWindowsVersion(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask); -BOOL IsOperatingSystemSupported(LPBOOL lpbIsWindows7, LPBOOL lpbIsWindows8Point1); +BOOL IsWindows7(void); +BOOL IsWindows8Point1(void); +BOOL IsOperatingSystemSupported(void); +BOOL IsWow64(void); + +void get_cpuid_brand(char *brand); VOID dwprintf_(LPCWSTR format, ...);