better OS version detection
This commit is contained in:
90
wufuc/core.c
90
wufuc/core.c
@@ -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) {
|
||||||
}
|
CHAR path[MAX_PATH + 1];
|
||||||
_dbgprintf("Loaded library: %s.", lpFileName);
|
if (!get_svcdllA("wuauserv", path, _countof(path))) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
CHAR path[MAX_PATH + 1];
|
if (!_stricmp(lpFileName, path) && PatchWUModule(result)) {
|
||||||
if (!get_svcdllA("wuauserv", path, _countof(path))) {
|
_dbgprintf("Patched Windows Update module!");
|
||||||
return result;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!_stricmp(lpFileName, path)) {
|
|
||||||
_dbgprintf("%s is wu module, applying patch...", lpFileName);
|
|
||||||
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];
|
||||||
|
if (!get_svcdllW(L"wuauserv", path, _countof(path))) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
WCHAR path[MAX_PATH + 1];
|
if (!_wcsicmp(lpFileName, path) && PatchWUModule(result)) {
|
||||||
if (!get_svcdllW(L"wuauserv", path, _countof(path))) {
|
_wdbgprintf(L"Patched Windows Update module!");
|
||||||
return result;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!_wcsicmp(lpFileName, path)) {
|
|
||||||
_wdbgprintf(L"%s is wu module, applying patch...", lpFileName);
|
|
||||||
PatchWUModule(result);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
@@ -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);
|
||||||
HANDLE hThread = CreateThread(NULL, 0, NewThreadProc, NULL, 0, NULL);
|
if (WindowsVersionCompare(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)
|
||||||
CloseHandle(hThread);
|
|| WindowsVersionCompare(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)) {
|
||||||
|
|
||||||
|
HANDLE hThread = CreateThread(NULL, 0, NewThreadProc, NULL, 0, NULL);
|
||||||
|
CloseHandle(hThread);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
|
@@ -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);
|
||||||
|
@@ -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];
|
||||||
|
23
wufuc/util.c
23
wufuc/util.c
@@ -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, ...) {
|
||||||
|
@@ -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, ...);
|
||||||
|
Reference in New Issue
Block a user