better OS version detection

This commit is contained in:
zeffy
2017-06-10 14:25:46 -07:00
parent 4ad3642db6
commit c837bfec2f
6 changed files with 69 additions and 68 deletions

View File

@@ -2,12 +2,10 @@
#include <Psapi.h> #include <Psapi.h>
#include <TlHelp32.h> #include <TlHelp32.h>
#include <tchar.h> #include <tchar.h>
#include <aclapi.h>
#include <sddl.h> #include <sddl.h>
#include "core.h"
#include "process.h"
#include "service.h" #include "service.h"
#include "util.h" #include "util.h"
#include "core.h"
DWORD WINAPI NewThreadProc(LPVOID lpParam) { DWORD WINAPI NewThreadProc(LPVOID lpParam) {
SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT); 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, LoadLibraryExA);
DETOUR_IAT(hm, LoadLibraryExW); DETOUR_IAT(hm, LoadLibraryExW);
TCHAR lpServiceDll[MAX_PATH + 1]; TCHAR lpServiceDll[MAX_PATH + 1];
get_svcdll(_T("wuauserv"), lpServiceDll, _countof(lpServiceDll)); get_svcdll(_T("wuauserv"), lpServiceDll, _countof(lpServiceDll));
HMODULE hwu = GetModuleHandle(lpServiceDll); HMODULE hwu = GetModuleHandle(lpServiceDll);
if (hwu) { if (hwu && PatchWUModule(hwu)) {
_tdbgprintf(_T("Found previously loaded wu module %s, applying patch..."), lpServiceDll); _tdbgprintf(_T("Patched previously loaded Windows Update module!"));
PatchWUModule(hwu);
} }
ResumeAndCloseThreads(lphThreads, cb); ResumeAndCloseThreads(lphThreads, cb);
WaitForSingleObject(hEvent, INFINITE); WaitForSingleObject(hEvent, INFINITE);
_tdbgprintf(_T("Unload event was set, removing hooks...")); _tdbgprintf(_T("Unload event was set."));
SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb); SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb);
RESTORE_IAT(hm, LoadLibraryExA); RESTORE_IAT(hm, LoadLibraryExA);
RESTORE_IAT(hm, LoadLibraryExW); RESTORE_IAT(hm, LoadLibraryExW);
ResumeAndCloseThreads(lphThreads, cb); ResumeAndCloseThreads(lphThreads, cb);
_tdbgprintf(_T("Unloading library. See ya!"));
CloseHandle(hEvent); CloseHandle(hEvent);
_tdbgprintf(_T("See ya!"));
FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0); FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0);
return 0; return 0;
} }
BOOL PatchWUModule(HMODULE hModule) { BOOL PatchWUModule(HMODULE hModule) {
if (!IsWindows7Or8Point1()) {
return FALSE;
}
LPSTR lpszPattern; LPSTR lpszPattern;
SIZE_T n1, n2; SIZE_T n1, n2;
#ifdef _WIN64 #ifdef _WIN64
@@ -88,7 +80,15 @@ BOOL PatchWUModule(HMODULE hModule) {
n1 = 10; n1 = 10;
n2 = 18; n2 = 18;
#elif defined(_WIN32) #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 <wuaueng.IsCPUSupported>
"A3????????"; // mov dword ptr ds:[????????],eax
n1 = 2;
n2 = 15;
} else if (WindowsVersionCompare(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)) {
lpszPattern = lpszPattern =
"8BFF" // mov edi,edi "8BFF" // mov edi,edi
"51" // push ecx "51" // push ecx
@@ -97,14 +97,6 @@ BOOL PatchWUModule(HMODULE hModule) {
"A1????????"; // mov eax,dword ptr ds:[????????] "A1????????"; // mov eax,dword ptr ds:[????????]
n1 = 5; n1 = 5;
n2 = 13; n2 = 13;
} else if (IsWindows7()) {
lpszPattern =
"833D????????00" // cmp dword ptr ds:[????????],0
"743E" // je $+3E
"E8????????" // call <wuaueng.IsCPUSupported>
"A3????????"; // mov dword ptr ds:[????????],eax
n1 = 2;
n2 = 15;
} }
#else #else
return FALSE; return FALSE;
@@ -115,11 +107,13 @@ BOOL PatchWUModule(HMODULE hModule) {
SIZE_T rva; SIZE_T rva;
if (!FindPattern(modinfo.lpBaseOfDll, modinfo.SizeOfImage, lpszPattern, 0, &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; return FALSE;
} }
SIZE_T fpIsDeviceServiceable = (SIZE_T)modinfo.lpBaseOfDll + rva; 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)); BOOL *lpbNotRunOnce = (BOOL *)(fpIsDeviceServiceable + n1 + sizeof(DWORD) + *(DWORD *)(fpIsDeviceServiceable + n1));
if (*lpbNotRunOnce) { if (*lpbNotRunOnce) {
@@ -128,7 +122,8 @@ BOOL PatchWUModule(HMODULE hModule) {
VirtualProtect(lpbNotRunOnce, sizeof(BOOL), flNewProtect, &flOldProtect); VirtualProtect(lpbNotRunOnce, sizeof(BOOL), flNewProtect, &flOldProtect);
*lpbNotRunOnce = FALSE; *lpbNotRunOnce = FALSE;
VirtualProtect(lpbNotRunOnce, sizeof(BOOL), flOldProtect, &flNewProtect); 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)); BOOL *lpbCachedResult = (BOOL *)(fpIsDeviceServiceable + n2 + sizeof(DWORD) + *(DWORD *)(fpIsDeviceServiceable + n2));
@@ -138,9 +133,10 @@ BOOL PatchWUModule(HMODULE hModule) {
VirtualProtect(lpbCachedResult, sizeof(BOOL), flNewProtect, &flOldProtect); VirtualProtect(lpbCachedResult, sizeof(BOOL), flNewProtect, &flOldProtect);
*lpbCachedResult = TRUE; *lpbCachedResult = TRUE;
VirtualProtect(lpbCachedResult, sizeof(BOOL), flOldProtect, &flNewProtect); 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( HMODULE WINAPI _LoadLibraryExA(
@@ -149,19 +145,16 @@ HMODULE WINAPI _LoadLibraryExA(
_In_ DWORD dwFlags _In_ DWORD dwFlags
) { ) {
HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags); HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags);
if (!result) { _dbgprintf("Loaded %s.", lpFileName);
return result; if (result) {
}
_dbgprintf("Loaded library: %s.", lpFileName);
CHAR path[MAX_PATH + 1]; CHAR path[MAX_PATH + 1];
if (!get_svcdllA("wuauserv", path, _countof(path))) { if (!get_svcdllA("wuauserv", path, _countof(path))) {
return result; return result;
} }
if (!_stricmp(lpFileName, path)) { if (!_stricmp(lpFileName, path) && PatchWUModule(result)) {
_dbgprintf("%s is wu module, applying patch...", lpFileName); _dbgprintf("Patched Windows Update module!");
PatchWUModule(result); }
} }
return result; return result;
} }
@@ -172,19 +165,16 @@ HMODULE WINAPI _LoadLibraryExW(
_In_ DWORD dwFlags _In_ DWORD dwFlags
) { ) {
HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags); HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags);
if (!result) {
return result;
}
_wdbgprintf(L"Loaded library: %s.", lpFileName); _wdbgprintf(L"Loaded library: %s.", lpFileName);
if (result) {
WCHAR path[MAX_PATH + 1]; WCHAR path[MAX_PATH + 1];
if (!get_svcdllW(L"wuauserv", path, _countof(path))) { if (!get_svcdllW(L"wuauserv", path, _countof(path))) {
return result; return result;
} }
if (!_wcsicmp(lpFileName, path)) { if (!_wcsicmp(lpFileName, path) && PatchWUModule(result)) {
_wdbgprintf(L"%s is wu module, applying patch...", lpFileName); _wdbgprintf(L"Patched Windows Update module!");
PatchWUModule(result); }
} }
return result; return result;
}; };

View File

@@ -1,13 +1,18 @@
#include <Windows.h> #include <Windows.h>
#include "core.h" #include "core.h"
#include "util.h"
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) { switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
{ {
DisableThreadLibraryCalls(hModule); DisableThreadLibraryCalls(hModule);
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); HANDLE hThread = CreateThread(NULL, 0, NewThreadProc, NULL, 0, NULL);
CloseHandle(hThread); CloseHandle(hThread);
}
break; break;
} }
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:

View File

@@ -2,10 +2,15 @@
#include <TlHelp32.h> #include <TlHelp32.h>
#include <tchar.h> #include <tchar.h>
#include "service.h" #include "service.h"
#include "process.h"
#include "util.h" #include "util.h"
void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { 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")); HANDLE hEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("Global\\wufuc_UnloadEvent"));
if (hEvent) { if (hEvent) {
CloseHandle(hEvent); CloseHandle(hEvent);

View File

@@ -2,8 +2,8 @@
#include <stdio.h> #include <stdio.h>
#include <tchar.h> #include <tchar.h>
#include "util.h" #include "util.h"
#include "service.h"
#include "shellapihelper.h" #include "shellapihelper.h"
#include "service.h"
BOOL get_svcdllA(LPCSTR lpServiceName, LPSTR lpServiceDll, DWORD dwSize) { BOOL get_svcdllA(LPCSTR lpServiceName, LPSTR lpServiceDll, DWORD dwSize) {
CHAR lpSubKey[MAX_PATH + 1]; CHAR lpSubKey[MAX_PATH + 1];

View File

@@ -1,6 +1,5 @@
#include <Windows.h> #include <Windows.h>
#include <stdio.h> #include <stdio.h>
#include <VersionHelpers.h>
#include <TlHelp32.h> #include <TlHelp32.h>
#include <tchar.h> #include <tchar.h>
#include "util.h" #include "util.h"
@@ -110,16 +109,22 @@ VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T cb) {
_tdbgprintf(_T("Resumed %d other threads."), cb); _tdbgprintf(_T("Resumed %d other threads."), cb);
} }
BOOL IsWindows7Or8Point1(void) { BOOL WindowsVersionCompare(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask) {
return IsWindows7() || IsWindows8Point1(); 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) { DWORDLONG dwlConditionMask = 0;
return IsWindows7OrGreater() && !IsWindows8OrGreater(); 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 VerifyVersionInfo(&osvi, dwTypeMask, dwlConditionMask);
return IsWindows8Point1OrGreater() && !IsWindows10OrGreater();
} }
VOID _wdbgprintf(LPCWSTR format, ...) { VOID _wdbgprintf(LPCWSTR format, ...) {

View File

@@ -20,11 +20,7 @@ VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThrea
VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T dwSize); VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T dwSize);
BOOL IsWindows7Or8Point1(void); BOOL WindowsVersionCompare(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask);
BOOL IsWindows7(void);
BOOL IsWindows8Point1(void);
VOID _wdbgprintf(LPCWSTR format, ...); VOID _wdbgprintf(LPCWSTR format, ...);
VOID _dbgprintf(LPCSTR format, ...); VOID _dbgprintf(LPCSTR format, ...);