From c837bfec2ff78c8aad9714961c6b6e48b412ebff Mon Sep 17 00:00:00 2001 From: zeffy Date: Sat, 10 Jun 2017 14:25:46 -0700 Subject: [PATCH] better OS version detection --- wufuc/core.c | 90 +++++++++++++++++++++--------------------------- wufuc/dllmain.c | 9 +++-- wufuc/rundll32.c | 7 +++- wufuc/service.c | 2 +- wufuc/util.c | 23 ++++++++----- wufuc/util.h | 6 +--- 6 files changed, 69 insertions(+), 68 deletions(-) diff --git a/wufuc/core.c b/wufuc/core.c index 9dcbec3..2cb221c 100644 --- a/wufuc/core.c +++ b/wufuc/core.c @@ -2,12 +2,10 @@ #include #include #include -#include #include -#include "core.h" -#include "process.h" #include "service.h" #include "util.h" +#include "core.h" DWORD WINAPI NewThreadProc(LPVOID lpParam) { SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT); @@ -44,37 +42,31 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam) { DETOUR_IAT(hm, LoadLibraryExA); DETOUR_IAT(hm, LoadLibraryExW); - TCHAR lpServiceDll[MAX_PATH + 1]; get_svcdll(_T("wuauserv"), lpServiceDll, _countof(lpServiceDll)); HMODULE hwu = GetModuleHandle(lpServiceDll); - if (hwu) { - _tdbgprintf(_T("Found previously loaded wu module %s, applying patch..."), lpServiceDll); - PatchWUModule(hwu); + if (hwu && PatchWUModule(hwu)) { + _tdbgprintf(_T("Patched previously loaded Windows Update module!")); } ResumeAndCloseThreads(lphThreads, cb); WaitForSingleObject(hEvent, INFINITE); - _tdbgprintf(_T("Unload event was set, removing hooks...")); + _tdbgprintf(_T("Unload event was set.")); SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb); RESTORE_IAT(hm, LoadLibraryExA); RESTORE_IAT(hm, LoadLibraryExW); ResumeAndCloseThreads(lphThreads, cb); - _tdbgprintf(_T("Unloading library. See ya!")); CloseHandle(hEvent); + _tdbgprintf(_T("See ya!")); FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0); return 0; } BOOL PatchWUModule(HMODULE hModule) { - if (!IsWindows7Or8Point1()) { - return FALSE; - } - LPSTR lpszPattern; SIZE_T n1, n2; #ifdef _WIN64 @@ -88,7 +80,15 @@ BOOL PatchWUModule(HMODULE hModule) { n1 = 10; n2 = 18; #elif defined(_WIN32) - if (IsWindows8Point1()) { + if (WindowsVersionCompare(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)) { + lpszPattern = + "833D????????00" // cmp dword ptr ds:[????????],0 + "743E" // je $+3E + "E8????????" // call + "A3????????"; // mov dword ptr ds:[????????],eax + n1 = 2; + n2 = 15; + } else if (WindowsVersionCompare(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)) { lpszPattern = "8BFF" // mov edi,edi "51" // push ecx @@ -97,14 +97,6 @@ BOOL PatchWUModule(HMODULE hModule) { "A1????????"; // mov eax,dword ptr ds:[????????] n1 = 5; n2 = 13; - } else if (IsWindows7()) { - lpszPattern = - "833D????????00" // cmp dword ptr ds:[????????],0 - "743E" // je $+3E - "E8????????" // call - "A3????????"; // mov dword ptr ds:[????????],eax - n1 = 2; - n2 = 15; } #else return FALSE; @@ -115,11 +107,13 @@ BOOL PatchWUModule(HMODULE hModule) { SIZE_T rva; if (!FindPattern(modinfo.lpBaseOfDll, modinfo.SizeOfImage, lpszPattern, 0, &rva)) { - _tdbgprintf(_T("Could not match byte pattern. Not good!")); + _tdbgprintf(_T("No pattern match!")); return FALSE; } SIZE_T fpIsDeviceServiceable = (SIZE_T)modinfo.lpBaseOfDll + rva; - _tdbgprintf(_T("Matched pattern at %p."), fpIsDeviceServiceable); + _tdbgprintf(_T("Pattern match at offset %p."), fpIsDeviceServiceable); + + BOOL result = FALSE; BOOL *lpbNotRunOnce = (BOOL *)(fpIsDeviceServiceable + n1 + sizeof(DWORD) + *(DWORD *)(fpIsDeviceServiceable + n1)); if (*lpbNotRunOnce) { @@ -128,7 +122,8 @@ BOOL PatchWUModule(HMODULE hModule) { VirtualProtect(lpbNotRunOnce, sizeof(BOOL), flNewProtect, &flOldProtect); *lpbNotRunOnce = FALSE; VirtualProtect(lpbNotRunOnce, sizeof(BOOL), flOldProtect, &flNewProtect); - _tdbgprintf(_T("Patched value at %p = %d."), lpbNotRunOnce, *lpbNotRunOnce); + _tdbgprintf(_T("Wrote value %d to address %p."), *lpbNotRunOnce, lpbNotRunOnce); + result = TRUE; } BOOL *lpbCachedResult = (BOOL *)(fpIsDeviceServiceable + n2 + sizeof(DWORD) + *(DWORD *)(fpIsDeviceServiceable + n2)); @@ -138,9 +133,10 @@ BOOL PatchWUModule(HMODULE hModule) { VirtualProtect(lpbCachedResult, sizeof(BOOL), flNewProtect, &flOldProtect); *lpbCachedResult = TRUE; VirtualProtect(lpbCachedResult, sizeof(BOOL), flOldProtect, &flNewProtect); - _tdbgprintf(_T("Patched value at %p = %d."), lpbCachedResult, *lpbCachedResult); + _tdbgprintf(_T("Wrote value %d to address %p."), *lpbCachedResult, lpbCachedResult); + result = TRUE; } - return TRUE; + return result; } HMODULE WINAPI _LoadLibraryExA( @@ -149,19 +145,16 @@ HMODULE WINAPI _LoadLibraryExA( _In_ DWORD dwFlags ) { HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags); - if (!result) { - return result; - } - _dbgprintf("Loaded library: %s.", lpFileName); + _dbgprintf("Loaded %s.", lpFileName); + if (result) { + CHAR path[MAX_PATH + 1]; + if (!get_svcdllA("wuauserv", path, _countof(path))) { + return result; + } - CHAR path[MAX_PATH + 1]; - if (!get_svcdllA("wuauserv", path, _countof(path))) { - return result; - } - - if (!_stricmp(lpFileName, path)) { - _dbgprintf("%s is wu module, applying patch...", lpFileName); - PatchWUModule(result); + if (!_stricmp(lpFileName, path) && PatchWUModule(result)) { + _dbgprintf("Patched Windows Update module!"); + } } return result; } @@ -172,19 +165,16 @@ HMODULE WINAPI _LoadLibraryExW( _In_ DWORD dwFlags ) { HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags); - if (!result) { - return result; - } _wdbgprintf(L"Loaded library: %s.", lpFileName); + if (result) { + WCHAR path[MAX_PATH + 1]; + if (!get_svcdllW(L"wuauserv", path, _countof(path))) { + return result; + } - WCHAR path[MAX_PATH + 1]; - if (!get_svcdllW(L"wuauserv", path, _countof(path))) { - return result; - } - - if (!_wcsicmp(lpFileName, path)) { - _wdbgprintf(L"%s is wu module, applying patch...", lpFileName); - PatchWUModule(result); + if (!_wcsicmp(lpFileName, path) && PatchWUModule(result)) { + _wdbgprintf(L"Patched Windows Update module!"); + } } return result; }; diff --git a/wufuc/dllmain.c b/wufuc/dllmain.c index 2afb60e..c7ab665 100644 --- a/wufuc/dllmain.c +++ b/wufuc/dllmain.c @@ -1,13 +1,18 @@ #include #include "core.h" +#include "util.h" BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { DisableThreadLibraryCalls(hModule); - HANDLE hThread = CreateThread(NULL, 0, NewThreadProc, NULL, 0, NULL); - CloseHandle(hThread); + if (WindowsVersionCompare(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION) + || WindowsVersionCompare(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)) { + + HANDLE hThread = CreateThread(NULL, 0, NewThreadProc, NULL, 0, NULL); + CloseHandle(hThread); + } break; } case DLL_PROCESS_DETACH: diff --git a/wufuc/rundll32.c b/wufuc/rundll32.c index a37e600..d09733a 100644 --- a/wufuc/rundll32.c +++ b/wufuc/rundll32.c @@ -2,10 +2,15 @@ #include #include #include "service.h" -#include "process.h" #include "util.h" void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { + if (!WindowsVersionCompare(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION) + && !WindowsVersionCompare(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)) { + + return; + } + HANDLE hEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("Global\\wufuc_UnloadEvent")); if (hEvent) { CloseHandle(hEvent); diff --git a/wufuc/service.c b/wufuc/service.c index 600bcbd..8d713c2 100644 --- a/wufuc/service.c +++ b/wufuc/service.c @@ -2,8 +2,8 @@ #include #include #include "util.h" -#include "service.h" #include "shellapihelper.h" +#include "service.h" BOOL get_svcdllA(LPCSTR lpServiceName, LPSTR lpServiceDll, DWORD dwSize) { CHAR lpSubKey[MAX_PATH + 1]; diff --git a/wufuc/util.c b/wufuc/util.c index f0f0cf4..2fe02ae 100644 --- a/wufuc/util.c +++ b/wufuc/util.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include "util.h" @@ -110,16 +109,22 @@ VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T cb) { _tdbgprintf(_T("Resumed %d other threads."), cb); } -BOOL IsWindows7Or8Point1(void) { - return IsWindows7() || IsWindows8Point1(); -} +BOOL WindowsVersionCompare(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask) { + OSVERSIONINFOEX osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + osvi.dwMajorVersion = dwMajorVersion; + osvi.dwMinorVersion = dwMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; + osvi.wServicePackMinor = wServicePackMinor; -BOOL IsWindows7(void) { - return IsWindows7OrGreater() && !IsWindows8OrGreater(); -} + DWORDLONG dwlConditionMask = 0; + VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, Operator); + VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, Operator); + VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, Operator); + VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMINOR, Operator); -BOOL IsWindows8Point1(void) { - return IsWindows8Point1OrGreater() && !IsWindows10OrGreater(); + return VerifyVersionInfo(&osvi, dwTypeMask, dwlConditionMask); } VOID _wdbgprintf(LPCWSTR format, ...) { diff --git a/wufuc/util.h b/wufuc/util.h index c62c48e..26ffeb6 100644 --- a/wufuc/util.h +++ b/wufuc/util.h @@ -20,11 +20,7 @@ VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThrea VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T dwSize); -BOOL IsWindows7Or8Point1(void); - -BOOL IsWindows7(void); - -BOOL IsWindows8Point1(void); +BOOL WindowsVersionCompare(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask); VOID _wdbgprintf(LPCWSTR format, ...); VOID _dbgprintf(LPCSTR format, ...);