diff --git a/CONTRIBUTING.de-DE.md b/CONTRIBUTING.de-DE.md
index 9890e9a..8fef0f8 100644
--- a/CONTRIBUTING.de-DE.md
+++ b/CONTRIBUTING.de-DE.md
@@ -1,6 +1,6 @@
-# Richtlinien für die Fehlermeldung
+# Richtlinien für die Fehlermeldung
-[English](CONTRIBUTING.md) | [русский](CONTRIBUTING.ru-RU.md) | [Français](CONTRIBUTING.fr-FR.md) | **Deutsch** | [Magyar](CONTRIBUTING.hu-HU.md) | [Portuguese (Brazil)](CONTRIBUTING.pt-BR.md)
+[English](../CONTRIBUTING.md) | [русский](CONTRIBUTING.ru-RU.md) | [Français](CONTRIBUTING.fr-FR.md) | **Deutsch** | [Magyar](CONTRIBUTING.hu-HU.md) | [Portuguese (Brazil)](CONTRIBUTING.pt-BR.md)
## Fehler melden [](https://isitmaintained.com/project/zeffy/wufuc)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b30f369..1fc58b0 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,6 +1,6 @@
# Contributing guidelines
-**English** | [русский](CONTRIBUTING.ru-RU.md) | [Français](CONTRIBUTING.fr-FR.md) | [Deutsch](CONTRIBUTING.de-DE.md) | [Magyar](CONTRIBUTING.de-HU.md) | [Portuguese (Brazil)](CONTRIBUTING.pt-BR.md)
+**English** | [русский](translations/CONTRIBUTING.ru-RU.md) | [Français](translations/CONTRIBUTING.fr-FR.md) | [Deutsch](translations/CONTRIBUTING.de-DE.md) | [Magyar](translations/CONTRIBUTING.hu-HU.md) | [Portuguese (Brazil)](translations/CONTRIBUTING.pt-BR.md)
## Reporting an issue [](https://isitmaintained.com/project/zeffy/wufuc)
diff --git a/README.md b/README.md
index bfe0d39..f34cc9d 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# wufuc [](https://ci.appveyor.com/project/zeffy/wufuc)
-**English** | [русский](README.ru-RU.md) | [Français](README.fr-FR.md) | [Deutsch](README.de-DE.md) | [Magyar](README.hu-HU.md) | [Portuguese (Brazil)](README.pt-BR.md)
+**English** | [русский](translations/README.ru-RU.md) | [Français](translations/README.fr-FR.md) | [Deutsch](translations/README.de-DE.md) | [Magyar](translations/README.hu-HU.md) | [Portuguese (Brazil)](translations/README.pt-BR.md)
[](https://pledgie.com/campaigns/34055)
diff --git a/appveyor.yml b/appveyor.yml
index 55ec2b3..0dc8492 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-version: 0.7.1.{build}
+version: 0.7.2.{build}
skip_commits:
files:
- README.md
diff --git a/docs/Patch_Offsets.md b/docs/Patch_Offsets.md
deleted file mode 100644
index 689ef35..0000000
--- a/docs/Patch_Offsets.md
+++ /dev/null
@@ -1,34 +0,0 @@
-## Windows 7
-
-Hotfix ID | Architecture | wuaueng.dll version | File offset | Original value | Patched value
---------- | ------------ | ------------------- | ----------- | -------------- | -------------
-[KB4012218] | x64 | 7.6.7601.23714 | `0x26C948` | `0x01` | `0x00`
-[KB4012218] | x86 | 7.6.7601.23714 | `0x1E4638` | `0x01` | `0x00`
-[KB4015546], [KB4015549], [KB4015552], [KB4019264] | x64 | 7.6.7601.23735 | `0x26C948` | `0x01` | `0x00`
-[KB4015546], [KB4015549], [KB4015552], [KB4019264] | x86 | 7.6.7601.23735 | `0x1E4838` | `0x01` | `0x00`
-[KB4019265] | x64 | 7.6.7601.23775 | `0x26C948` | `0x01` | `0x00`
-[KB4019265] | x86 | 7.6.7601.23775 | `0x1E4838` | `0x01` | `0x00`
-
-## Windows 8.1
-
-Hotfix ID | Architecture | wuaueng.dll version | File offset | Original value | Patched value
---------- | ------------ | ------------------- | ----------- | -------------- | -------------
-[KB4012219] | x64 | 7.9.9600.18621 | `0x34D3BC` | `0x01` | `0x00`
-[KB4012219] | x86 | 7.9.9600.18621 | `0x2BFA50` | `0x01` | `0x00`
-[KB4015547], [KB4015550], [KB4015553], [KB4019215], [KB4019217] | x64 | 7.9.9600.18628 | `0x34D5BC` | `0x01` | `0x00`
-[KB4015547], [KB4015550], [KB4015553], [KB4019215], [KB4019217] | x86 | 7.9.9600.18628 | `0x2BFA50` | `0x01` | `0x00`
-
-
-[KB4012218]: https://www.catalog.update.microsoft.com/search.aspx?q=KB4012218
-[KB4015546]: https://www.catalog.update.microsoft.com/search.aspx?q=KB4015546
-[KB4015549]: https://www.catalog.update.microsoft.com/search.aspx?q=KB4015549
-[KB4015552]: https://www.catalog.update.microsoft.com/search.aspx?q=KB4015552
-[KB4019264]: https://www.catalog.update.microsoft.com/search.aspx?q=KB4019264
-[KB4019265]: https://www.catalog.update.microsoft.com/search.aspx?q=KB4019265
-
-[KB4012219]: https://www.catalog.update.microsoft.com/search.aspx?q=kb4012219
-[KB4015547]: https://www.catalog.update.microsoft.com/search.aspx?q=KB4015547
-[KB4015550]: https://www.catalog.update.microsoft.com/search.aspx?q=KB4015550
-[KB4015553]: https://www.catalog.update.microsoft.com/search.aspx?q=KB4015553
-[KB4019215]: https://www.catalog.update.microsoft.com/search.aspx?q=KB4019215
-[KB4019217]: https://www.catalog.update.microsoft.com/search.aspx?q=KB4019217
diff --git a/setup-ai/wufuc.aip b/setup-ai/wufuc.aip
index 94d1852..b67d744 100644
--- a/setup-ai/wufuc.aip
+++ b/setup-ai/wufuc.aip
@@ -1,5 +1,5 @@
-
+
@@ -17,10 +17,10 @@
-
+
-
+
@@ -287,8 +287,8 @@
-
-
+
+
diff --git a/setup-batch/install_wufuc.bat b/setup-batch/install_wufuc.bat
index f96e5fd..0d9babd 100644
--- a/setup-batch/install_wufuc.bat
+++ b/setup-batch/install_wufuc.bat
@@ -124,6 +124,9 @@ if errorlevel 1 (
echo.
echo ERROR - Detected that wuaueng.dll is below the minimum supported version.
echo.
+ echo You must first run Windows Update until the "Unsupported Hardware" window
+ echo pops up, then try again.
+ echo.
goto :die
)
echo Detected supported Windows Update agent version: %Version%
diff --git a/CONTRIBUTING.fr-FR.md b/translations/CONTRIBUTING.fr-FR.md
similarity index 85%
rename from CONTRIBUTING.fr-FR.md
rename to translations/CONTRIBUTING.fr-FR.md
index 2c26583..e6225e9 100644
--- a/CONTRIBUTING.fr-FR.md
+++ b/translations/CONTRIBUTING.fr-FR.md
@@ -1,6 +1,6 @@
# Directives de contribution
-[English](CONTRIBUTING.md) | [русский](CONTRIBUTING.ru-RU.md) | **Français** | [Deutsch](CONTRIBUTING.de-DE.md) | [Magyar](CONTRIBUTING.hu-HU.md) | [Portuguese (Brazil)](CONTRIBUTING.pt-BR.md)
+[English](../CONTRIBUTING.md) | [русский](CONTRIBUTING.ru-RU.md) | **Français** | [Deutsch](CONTRIBUTING.de-DE.md) | [Magyar](CONTRIBUTING.hu-HU.md) | [Portuguese (Brazil)](CONTRIBUTING.pt-BR.md)
## Reporter un problème [](https://isitmaintained.com/project/zeffy/wufuc)
diff --git a/CONTRIBUTING.hu-HU.md b/translations/CONTRIBUTING.hu-HU.md
similarity index 84%
rename from CONTRIBUTING.hu-HU.md
rename to translations/CONTRIBUTING.hu-HU.md
index a29bcc3..c68a851 100644
--- a/CONTRIBUTING.hu-HU.md
+++ b/translations/CONTRIBUTING.hu-HU.md
@@ -1,6 +1,6 @@
# Hozzájárulási irányelvek
-[English](CONTRIBUTING.md) | [русский](CONTRIBUTING.ru-RU.md) | [Français](CONTRIBUTING.fr-FR.md) | [Deutsch](CONTRIBUTING.de-DE.md) | **Magyar** | [Portuguese (Brazil)](CONTRIBUTING.pt-BR.md)
+[English](../CONTRIBUTING.md) | [русский](CONTRIBUTING.ru-RU.md) | [Français](CONTRIBUTING.fr-FR.md) | [Deutsch](CONTRIBUTING.de-DE.md) | **Magyar** | [Portuguese (Brazil)](CONTRIBUTING.pt-BR.md)
## Hiba jelentése [](https://isitmaintained.com/project/zeffy/wufuc)
diff --git a/CONTRIBUTING.pt-BR.md b/translations/CONTRIBUTING.pt-BR.md
similarity index 84%
rename from CONTRIBUTING.pt-BR.md
rename to translations/CONTRIBUTING.pt-BR.md
index 8019ab1..24f6950 100644
--- a/CONTRIBUTING.pt-BR.md
+++ b/translations/CONTRIBUTING.pt-BR.md
@@ -1,6 +1,6 @@
# Contributing guidelines
-[English](CONTRIBUTING.md) | [русский](CONTRIBUTING.ru-RU.md) | [Français](CONTRIBUTING.fr-FR.md) | [Deutsch](CONTRIBUTING.de-DE.md) | [Magyar](CONTRIBUTING.de-HU.md) | **Portuguese (Brazil)**
+[English](../CONTRIBUTING.md) | [русский](CONTRIBUTING.ru-RU.md) | [Français](CONTRIBUTING.fr-FR.md) | [Deutsch](CONTRIBUTING.de-DE.md) | [Magyar](CONTRIBUTING.hu-HU.md) | **Portuguese (Brazil)**
## Reportando problemas [](https://isitmaintained.com/project/zeffy/wufuc)
diff --git a/CONTRIBUTING.ru-RU.md b/translations/CONTRIBUTING.ru-RU.md
similarity index 89%
rename from CONTRIBUTING.ru-RU.md
rename to translations/CONTRIBUTING.ru-RU.md
index f22321c..a0c3259 100644
--- a/CONTRIBUTING.ru-RU.md
+++ b/translations/CONTRIBUTING.ru-RU.md
@@ -1,6 +1,6 @@
# Инструкция для тех, кто желает помочь, внести вклад
-[English](CONTRIBUTING.md) | **русский** | [Français](CONTRIBUTING.fr-FR.md) | [Deutsch](CONTRIBUTING.de-DE.md) | [Magyar](CONTRIBUTING.de-HU.md) | [Portuguese (Brazil)](CONTRIBUTING.pt-BR.md)
+[English](../CONTRIBUTING.md) | **русский** | [Français](CONTRIBUTING.fr-FR.md) | [Deutsch](CONTRIBUTING.de-DE.md) | [Magyar](CONTRIBUTING.hu-HU.md) | [Portuguese (Brazil)](CONTRIBUTING.pt-BR.md)
## Сообщайте об ошибках [](https://isitmaintained.com/project/zeffy/wufuc)
diff --git a/README.de-DE.md b/translations/README.de-DE.md
similarity index 95%
rename from README.de-DE.md
rename to translations/README.de-DE.md
index 1a01ecf..ec7d9dd 100644
--- a/README.de-DE.md
+++ b/translations/README.de-DE.md
@@ -1,6 +1,6 @@
# wufuc [](https://ci.appveyor.com/project/zeffy/wufuc)
-[English](README.md) | [русский](README.ru-RU.md) | [Français](README.fr-FR.md) | **Deutsch** | [Magyar](README.hu-HU.md) | [Portuguese (Brazil)](README.pt-BR.md)
+[English](../README.md) | [русский](README.ru-RU.md) | [Français](README.fr-FR.md) | **Deutsch** | [Magyar](README.hu-HU.md) | [Portuguese (Brazil)](README.pt-BR.md)
[](https://pledgie.com/campaigns/34055)
diff --git a/README.fr-FR.md b/translations/README.fr-FR.md
similarity index 96%
rename from README.fr-FR.md
rename to translations/README.fr-FR.md
index 6237c65..8b738a1 100644
--- a/README.fr-FR.md
+++ b/translations/README.fr-FR.md
@@ -1,6 +1,6 @@
# wufuc [](https://ci.appveyor.com/project/zeffy/wufuc)
-[English](README.md) | [русский](README.ru-RU.md) | **Français** | [Deutsch](README.de-DE.md) | [Magyar](README.hu-HU.md) | [Portuguese (Brazil)](README.pt-BR.md)
+[English](../README.md) | [русский](README.ru-RU.md) | **Français** | [Deutsch](README.de-DE.md) | [Magyar](README.hu-HU.md) | [Portuguese (Brazil)](README.pt-BR.md)
[](https://pledgie.com/campaigns/34055)
diff --git a/README.hu-HU.md b/translations/README.hu-HU.md
similarity index 95%
rename from README.hu-HU.md
rename to translations/README.hu-HU.md
index 369cd07..9b3996d 100644
--- a/README.hu-HU.md
+++ b/translations/README.hu-HU.md
@@ -1,6 +1,6 @@
# wufuc [](https://ci.appveyor.com/project/zeffy/wufuc)
-[English](README.md) | [русский](README.ru-RU.md) | [Français](README.fr-FR.md) | [Deutsch](README.de-DE.md) | **Magyar** | [Portuguese (Brazil)](README.pt-BR.md)
+[English](../README.md) | [русский](README.ru-RU.md) | [Français](README.fr-FR.md) | [Deutsch](README.de-DE.md) | **Magyar** | [Portuguese (Brazil)](README.pt-BR.md)
[](https://pledgie.com/campaigns/34055)
diff --git a/README.pt-BR.md b/translations/README.pt-BR.md
similarity index 96%
rename from README.pt-BR.md
rename to translations/README.pt-BR.md
index fa162f2..00dd0f0 100644
--- a/README.pt-BR.md
+++ b/translations/README.pt-BR.md
@@ -1,6 +1,6 @@
# wufuc [](https://ci.appveyor.com/project/zeffy/wufuc)
-[English](README.md) | [русский](README.ru-RU.md) | [Français](README.fr-FR.md) | [Deutsch](README.de-DE.md) | [Magyar](README.hu-HU.md) | **Portuguese (Brazil)**
+[English](../README.md) | [русский](README.ru-RU.md) | [Français](README.fr-FR.md) | [Deutsch](README.de-DE.md) | [Magyar](README.hu-HU.md) | **Portuguese (Brazil)**
[](https://pledgie.com/campaigns/34055)
diff --git a/README.ru-RU.md b/translations/README.ru-RU.md
similarity index 97%
rename from README.ru-RU.md
rename to translations/README.ru-RU.md
index 362f43d..40a012e 100644
--- a/README.ru-RU.md
+++ b/translations/README.ru-RU.md
@@ -1,6 +1,6 @@
# wufuc [](https://ci.appveyor.com/project/zeffy/wufuc)
-[English](README.md) | **русский** | [Français](README.fr-FR.md) | [Deutsch](README.de-DE.md) | [Magyar](README.hu-HU.md) | [Portuguese (Brazil)](README.pt-BR.md)
+[English](../README.md) | **русский** | [Français](README.fr-FR.md) | [Deutsch](README.de-DE.md) | [Magyar](README.hu-HU.md) | [Portuguese (Brazil)](README.pt-BR.md)
[](https://pledgie.com/campaigns/34055)
diff --git a/wufuc/core.c b/wufuc/core.c
deleted file mode 100644
index 9787ae9..0000000
--- a/wufuc/core.c
+++ /dev/null
@@ -1,151 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include "service.h"
-#include "patternfind.h"
-#include "util.h"
-#include "core.h"
-
-DWORD WINAPI NewThreadProc(LPVOID lpParam) {
- SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
-
- TCHAR lpBinaryPathName[0x8000];
- get_svcpath(hSCManager, _T("wuauserv"), lpBinaryPathName, _countof(lpBinaryPathName));
- CloseServiceHandle(hSCManager);
-
- BOOL result = _tcsicmp(GetCommandLine(), lpBinaryPathName);
-
- if (result) {
- return 0;
- }
-
- SECURITY_ATTRIBUTES sa;
- ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- ConvertStringSecurityDescriptorToSecurityDescriptor(_T("D:PAI(A;;FA;;;BA)"), SDDL_REVISION_1, &sa.lpSecurityDescriptor, NULL);
- sa.bInheritHandle = FALSE;
-
- HANDLE hEvent = CreateEvent(&sa, TRUE, FALSE, _T("Global\\wufuc_UnloadEvent"));
-
- if (!hEvent) {
- return 0;
- }
-
- DWORD dwProcessId = GetCurrentProcessId();
- DWORD dwThreadId = GetCurrentThreadId();
- HANDLE lphThreads[0x1000];
- SIZE_T cb;
-
- SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb);
-
- HMODULE hm = GetModuleHandle(NULL);
- DETOUR_IAT(hm, LoadLibraryExA);
- DETOUR_IAT(hm, LoadLibraryExW);
-
- HMODULE hwu = GetModuleHandle(get_wuauservdll());
- if (hwu && PatchWU(hwu)) {
- dwprintf(L"Patched previously loaded Windows Update module!");
- }
- ResumeAndCloseThreads(lphThreads, cb);
-
- WaitForSingleObject(hEvent, INFINITE);
-
- dwprintf(L"Unloading...");
-
- SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb);
- RESTORE_IAT(hm, LoadLibraryExA);
- RESTORE_IAT(hm, LoadLibraryExW);
- ResumeAndCloseThreads(lphThreads, cb);
-
- CloseHandle(hEvent);
- dwprintf(L"Bye bye!");
- close_log();
- FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0);
-}
-
-BOOL PatchWU(HMODULE hModule) {
- LPSTR pattern;
- SIZE_T offset00, offset01;
-#ifdef _AMD64_
- pattern = "FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????";
- offset00 = 10;
- offset01 = 18;
-#elif defined(_X86_)
- if (IsWindows7()) {
- pattern = "833D????????00 743E E8???????? A3????????";
- offset00 = 2;
- offset01 = 15;
- } else if (IsWindows8Point1()) {
- pattern = "8BFF 51 833D????????00 7507 A1????????";
- offset00 = 5;
- offset01 = 13;
- } else {
- return FALSE;
- }
-#endif
-
- MODULEINFO modinfo;
- GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(MODULEINFO));
-
- SIZE_T rva = patternfind(modinfo.lpBaseOfDll, modinfo.SizeOfImage, 0, pattern);
- if (rva == -1) {
- dwprintf(L"No pattern match!");
- return FALSE;
- }
- uintptr_t baseAddress = (uintptr_t)modinfo.lpBaseOfDll;
- uintptr_t lpfnIsDeviceServiceable = baseAddress + rva;
- dwprintf(L"Address of wuaueng.dll!IsDeviceServiceable: %p", lpfnIsDeviceServiceable);
- BOOL result = FALSE;
- LPBOOL lpbFirstRun, lpbIsCPUSupportedResult;
-#ifdef _AMD64_
- 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 *)(lpfnIsDeviceServiceable + offset00));
- lpbIsCPUSupportedResult = (LPBOOL)(*(uintptr_t *)(lpfnIsDeviceServiceable + offset01));
-#endif
-
- if (*lpbFirstRun) {
- *lpbFirstRun = FALSE;
- dwprintf(L"Patched FirstRun variable: %p = %08x", lpbFirstRun, *lpbFirstRun);
- result = TRUE;
- }
- if (!*lpbIsCPUSupportedResult) {
- *lpbIsCPUSupportedResult = TRUE;
- dwprintf(L"Patched cached wuaueng.dll!IsCPUSupported result: %p = %08x", lpbIsCPUSupportedResult, *lpbIsCPUSupportedResult);
- result = TRUE;
- }
- return result;
-}
-
-HMODULE WINAPI _LoadLibraryExA(
- _In_ LPCSTR lpFileName,
- _Reserved_ HANDLE hFile,
- _In_ DWORD dwFlags
-) {
- HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags);
- if (result) {
- dwprintf(L"Loaded library: %S", lpFileName);
- if (!_stricmp(lpFileName, get_wuauservdllA()) && PatchWU(result)) {
- dwprintf(L"Patched Windows Update module!");
- }
- }
- return result;
-}
-
-HMODULE WINAPI _LoadLibraryExW(
- _In_ LPCWSTR lpFileName,
- _Reserved_ HANDLE hFile,
- _In_ DWORD dwFlags
-) {
- HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags);
- if (result) {
- dwprintf(L"Loaded library: %s", lpFileName);
- if (!_wcsicmp(lpFileName, get_wuauservdllW()) && PatchWU(result)) {
- dwprintf(L"Patched Windows Update module!");
- }
- }
- return result;
-};
diff --git a/wufuc/core.h b/wufuc/core.h
deleted file mode 100644
index b0d8dea..0000000
--- a/wufuc/core.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-DWORD WINAPI NewThreadProc(LPVOID lpParam);
-BOOL PatchWU(HMODULE hModule);
-
-HMODULE WINAPI _LoadLibraryExA(
- _In_ LPCSTR lpFileName,
- _Reserved_ HANDLE hFile,
- _In_ DWORD dwFlags
-);
-
-HMODULE WINAPI _LoadLibraryExW(
- _In_ LPCWSTR lpFileName,
- _Reserved_ HANDLE hFile,
- _In_ DWORD dwFlags
-);
diff --git a/wufuc/dllmain.c b/wufuc/dllmain.c
index 18e48f2..51e3969 100644
--- a/wufuc/dllmain.c
+++ b/wufuc/dllmain.c
@@ -1,20 +1,23 @@
#include
-#include "core.h"
-#include "util.h"
+
+#include "helpers.h"
+#include "logging.h"
+#include "hooks.h"
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
{
- if (!IsOperatingSystemSupported() || IsWow64()) {
+ if (!IsOperatingSystemSupported() || IsWow64())
return FALSE;
- }
+
DisableThreadLibraryCalls(hModule);
HANDLE hThread = CreateThread(NULL, 0, NewThreadProc, NULL, 0, NULL);
CloseHandle(hThread);
break;
}
case DLL_PROCESS_DETACH:
+ logging_free();
break;
default:
break;
diff --git a/wufuc/helpers.c b/wufuc/helpers.c
new file mode 100644
index 0000000..cde5586
--- /dev/null
+++ b/wufuc/helpers.c
@@ -0,0 +1,120 @@
+#include
+#include
+#include
+#include
+#include
+
+#include "logging.h"
+#include "helpers.h"
+
+static BOOL m_checkedIsWindows7 = FALSE;
+static BOOL m_isWindows7 = FALSE;
+static BOOL m_checkedIsWindows8Point1 = FALSE;
+static BOOL m_isWindows8Point1 = FALSE;
+
+static ISWOW64PROCESS fpIsWow64Process = NULL;
+static BOOL m_checkedIsWow64 = FALSE;
+static BOOL m_isWow64 = FALSE;
+
+static TCHAR m_emod_basename[MAX_PATH];
+
+BOOL CompareWindowsVersion(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;
+
+ 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);
+
+ return VerifyVersionInfo(&osvi, dwTypeMask, dwlConditionMask);
+}
+
+BOOL IsWindows7(void) {
+ if (!m_checkedIsWindows7) {
+ m_isWindows7 = CompareWindowsVersion(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION);
+ m_checkedIsWindows7 = TRUE;
+ }
+ return m_isWindows7;
+}
+
+BOOL IsWindows8Point1(void) {
+ if (!m_checkedIsWindows8Point1) {
+ m_isWindows8Point1 = CompareWindowsVersion(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION);
+ m_checkedIsWindows8Point1 = TRUE;
+ }
+ return m_isWindows8Point1;
+}
+
+BOOL IsOperatingSystemSupported(void) {
+#if !defined(_AMD64_) && !defined(_X86_)
+ return FALSE;
+#else
+ return IsWindows7() || IsWindows8Point1();
+#endif
+}
+
+BOOL IsWow64(void) {
+ if (!m_checkedIsWow64) {
+ if (!fpIsWow64Process)
+ fpIsWow64Process = (ISWOW64PROCESS)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "IsWow64Process");
+
+ if (fpIsWow64Process && fpIsWow64Process(GetCurrentProcess(), &m_isWow64))
+ m_checkedIsWow64 = TRUE;
+ }
+ return m_isWow64;
+}
+
+VOID suspend_other_threads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb) {
+ HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
+ THREADENTRY32 te;
+ ZeroMemory(&te, sizeof(THREADENTRY32));
+ te.dwSize = sizeof(te);
+ Thread32First(hSnap, &te);
+
+ SIZE_T count = 0;
+
+ do {
+ if (te.th32OwnerProcessID != dwProcessId || te.th32ThreadID == dwThreadId)
+ continue;
+
+ lphThreads[count] = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID);
+ SuspendThread(lphThreads[count]);
+ count++;
+ } while (count < dwSize && Thread32Next(hSnap, &te));
+ CloseHandle(hSnap);
+
+ *lpcb = count;
+ trace(L"Suspended %d other threads", count);
+}
+
+VOID resume_and_close_threads(LPHANDLE lphThreads, SIZE_T cb) {
+ for (SIZE_T i = 0; i < cb; i++) {
+ ResumeThread(lphThreads[i]);
+ CloseHandle(lphThreads[i]);
+ }
+ trace(L"Resumed %d threads", cb);
+}
+
+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];
+ }
+}
diff --git a/wufuc/helpers.h b/wufuc/helpers.h
new file mode 100644
index 0000000..afdf16f
--- /dev/null
+++ b/wufuc/helpers.h
@@ -0,0 +1,20 @@
+#pragma once
+
+EXTERN_C IMAGE_DOS_HEADER __ImageBase;
+#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
+
+typedef BOOL(WINAPI *ISWOW64PROCESS)(HANDLE, PBOOL);
+
+BOOL CompareWindowsVersion(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask);
+BOOL IsWindows7(void);
+BOOL IsWindows8Point1(void);
+BOOL IsOperatingSystemSupported(void);
+BOOL IsWow64(void);
+
+VOID suspend_other_threads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb);
+VOID resume_and_close_threads(LPHANDLE lphThreads, SIZE_T dwSize);
+
+void get_cpuid_brand(char *brand);
+
+#define STRINGIZE_(x) #x
+#define STRINGIZE(x) STRINGIZE_(x)
diff --git a/wufuc/hooks.c b/wufuc/hooks.c
new file mode 100644
index 0000000..7ab0d90
--- /dev/null
+++ b/wufuc/hooks.c
@@ -0,0 +1,192 @@
+#include
+#include
+#include
+#include
+#include
+
+#include "helpers.h"
+#include "logging.h"
+#include "service.h"
+#include "iathook.h"
+#include "patternfind.h"
+#include "hooks.h"
+
+LOADLIBRARYEXW fpLoadLibraryExW = NULL;
+LOADLIBRARYEXA fpLoadLibraryExA = NULL;
+
+DWORD WINAPI NewThreadProc(LPVOID lpParam) {
+ SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
+
+ TCHAR lpBinaryPathName[0x8000];
+ get_svcpath(hSCManager, _T("wuauserv"), lpBinaryPathName, _countof(lpBinaryPathName));
+ CloseServiceHandle(hSCManager);
+
+ if (_tcsicmp(GetCommandLine(), lpBinaryPathName))
+ return 0;
+
+ SECURITY_ATTRIBUTES sa = { 0 };
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ ConvertStringSecurityDescriptorToSecurityDescriptor(_T("D:PAI(A;;FA;;;BA)"), SDDL_REVISION_1, &sa.lpSecurityDescriptor, NULL);
+ sa.bInheritHandle = FALSE;
+
+ HANDLE hEvent = CreateEvent(&sa, TRUE, FALSE, _T("Global\\wufuc_UnloadEvent"));
+ if (!hEvent)
+ return 0;
+
+ DWORD dwProcessId = GetCurrentProcessId();
+ DWORD dwThreadId = GetCurrentThreadId();
+ HANDLE lphThreads[0x1000];
+ SIZE_T count;
+
+ suspend_other_threads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &count);
+
+ HMODULE hm = GetModuleHandle(NULL);
+ iat_hook(hm, "LoadLibraryExA", (LPVOID)&fpLoadLibraryExA, LoadLibraryExA_hook);
+ iat_hook(hm, "LoadLibraryExW", (LPVOID)&fpLoadLibraryExW, LoadLibraryExW_hook);
+
+ HMODULE hwu = GetModuleHandle(get_wuauservdll());
+ if (hwu && PatchWUA(hwu))
+ trace(L"Successfully patched previously loaded WUA module!");
+
+ resume_and_close_threads(lphThreads, count);
+
+ WaitForSingleObject(hEvent, INFINITE);
+ trace(L"Unloading...");
+
+ suspend_other_threads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &count);
+
+ iat_hook(hm, "LoadLibraryExA", NULL, fpLoadLibraryExA);
+ iat_hook(hm, "LoadLibraryExW", NULL, fpLoadLibraryExW);
+
+ resume_and_close_threads(lphThreads, count);
+
+ trace(L"Bye bye!");
+ CloseHandle(hEvent);
+ FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0);
+}
+
+HMODULE WINAPI LoadLibraryExA_hook(
+ _In_ LPCSTR lpFileName,
+ _Reserved_ HANDLE hFile,
+ _In_ DWORD dwFlags
+) {
+ CHAR buffer[MAX_PATH];
+ strcpy_s(buffer, _countof(buffer), lpFileName);
+
+ BOOL isWUA = !_stricmp(buffer, get_wuauservdllA());
+ if (isWUA) {
+ CHAR drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
+ _splitpath_s(buffer, drive, _countof(drive), dir, _countof(dir), fname, _countof(fname), ext, _countof(ext));
+
+ if (!_stricmp(fname, "wuaueng2")) {
+ CHAR newpath[MAX_PATH];
+ _makepath_s(newpath, _countof(buffer), drive, dir, "wuaueng", ext);
+
+ if (GetFileAttributesA(newpath) != INVALID_FILE_ATTRIBUTES) {
+ strcpy_s(buffer, _countof(buffer), newpath);
+ trace(L"UpdatePack7R2 compatibility fix: redirecting %S -> %S", lpFileName, buffer);
+ }
+ }
+ }
+
+ HMODULE result = fpLoadLibraryExA(buffer, hFile, dwFlags);
+ trace(L"Loaded library: %S", buffer);
+
+ if (isWUA)
+ PatchWUA(result);
+
+ return result;
+}
+
+HMODULE WINAPI LoadLibraryExW_hook(
+ _In_ LPCWSTR lpFileName,
+ _Reserved_ HANDLE hFile,
+ _In_ DWORD dwFlags
+) {
+ WCHAR buffer[MAX_PATH];
+ wcscpy_s(buffer, _countof(buffer), lpFileName);
+
+ BOOL isWUA = !_wcsicmp(buffer, get_wuauservdllW());
+ if (isWUA) {
+ WCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
+ _wsplitpath_s(buffer, drive, _countof(drive), dir, _countof(dir), fname, _countof(fname), ext, _countof(ext));
+
+ if (!_wcsicmp(fname, L"wuaueng2")) {
+ WCHAR newpath[MAX_PATH];
+ _wmakepath_s(newpath, _countof(buffer), drive, dir, L"wuaueng", ext);
+
+ if (GetFileAttributesW(newpath) != INVALID_FILE_ATTRIBUTES) {
+ wcscpy_s(buffer, _countof(buffer), newpath);
+ trace(L"UpdatePack7R2 compatibility fix: redirecting %s -> %s", lpFileName, buffer);
+ }
+ }
+ }
+
+ HMODULE result = fpLoadLibraryExW(buffer, hFile, dwFlags);
+ trace(L"Loaded library: %s", buffer);
+
+ if (isWUA)
+ PatchWUA(result);
+
+ return result;
+}
+
+BOOL PatchWUA(HMODULE hModule) {
+ LPSTR pattern;
+ SIZE_T offset00, offset01;
+#ifdef _AMD64_
+ pattern = "FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????";
+ offset00 = 10;
+ offset01 = 18;
+#elif defined(_X86_)
+ if (IsWindows7()) {
+ pattern = "833D????????00 743E E8???????? A3????????";
+ offset00 = 2;
+ offset01 = 15;
+ } else if (IsWindows8Point1()) {
+ pattern = "8BFF 51 833D????????00 7507 A1????????";
+ offset00 = 5;
+ offset01 = 13;
+ }
+#endif
+
+ MODULEINFO modinfo;
+ GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(MODULEINFO));
+
+ LPBYTE ptr = patternfind(modinfo.lpBaseOfDll, modinfo.SizeOfImage, 0, pattern);
+ if (!ptr) {
+ trace(L"No pattern match!");
+ return FALSE;
+ }
+ trace(L"wuaueng!IsDeviceServiceable VA: %p", ptr);
+ BOOL result = FALSE;
+ LPBOOL lpbFirstRun, lpbIsCPUSupportedResult;
+#ifdef _AMD64_
+ lpbFirstRun = (LPBOOL)(ptr + offset00 + sizeof(uint32_t) + *(uint32_t *)(ptr + offset00));
+ lpbIsCPUSupportedResult = (LPBOOL)(ptr + offset01 + sizeof(uint32_t) + *(uint32_t *)(ptr + offset01));
+#elif defined(_X86_)
+ lpbFirstRun = (LPBOOL)(*(uintptr_t *)(ptr + offset00));
+ lpbIsCPUSupportedResult = (LPBOOL)(*(uintptr_t *)(ptr + offset01));
+#endif
+
+ DWORD flNewProtect = PAGE_READWRITE;
+ DWORD flOldProtect;
+ if (*lpbFirstRun) {
+ VirtualProtect(lpbFirstRun, sizeof(BOOL), flNewProtect, &flOldProtect);
+ *lpbFirstRun = FALSE;
+ VirtualProtect(lpbFirstRun, sizeof(BOOL), flOldProtect, &flNewProtect);
+ trace(L"Patched boolean value #1: %p = %08x", lpbFirstRun, *lpbFirstRun);
+ result = TRUE;
+ }
+ if (!*lpbIsCPUSupportedResult) {
+ VirtualProtect(lpbIsCPUSupportedResult, sizeof(BOOL), flNewProtect, &flOldProtect);
+ *lpbIsCPUSupportedResult = TRUE;
+ VirtualProtect(lpbIsCPUSupportedResult, sizeof(BOOL), flOldProtect, &flNewProtect);
+ trace(L"Patched boolean value #2: %p = %08x", lpbIsCPUSupportedResult, *lpbIsCPUSupportedResult);
+ result = TRUE;
+ }
+ if (result)
+ trace(L"Successfully patched WUA module!");
+
+ return result;
+}
diff --git a/wufuc/hooks.h b/wufuc/hooks.h
new file mode 100644
index 0000000..af03435
--- /dev/null
+++ b/wufuc/hooks.h
@@ -0,0 +1,23 @@
+#pragma once
+
+typedef HMODULE(WINAPI *LOADLIBRARYEXA)(LPCSTR, HANDLE, DWORD);
+typedef HMODULE(WINAPI *LOADLIBRARYEXW)(LPCWSTR, HANDLE, DWORD);
+
+extern LOADLIBRARYEXW fpLoadLibraryExW;
+extern LOADLIBRARYEXA fpLoadLibraryExA;
+
+DWORD WINAPI NewThreadProc(LPVOID lpParam);
+
+HMODULE WINAPI LoadLibraryExA_hook(
+ _In_ LPCSTR lpFileName,
+ _Reserved_ HANDLE hFile,
+ _In_ DWORD dwFlags
+);
+
+HMODULE WINAPI LoadLibraryExW_hook(
+ _In_ LPCWSTR lpFileName,
+ _Reserved_ HANDLE hFile,
+ _In_ DWORD dwFlags
+);
+
+BOOL PatchWUA(HMODULE hModule);
diff --git a/wufuc/iathook.c b/wufuc/iathook.c
new file mode 100644
index 0000000..c742d2e
--- /dev/null
+++ b/wufuc/iathook.c
@@ -0,0 +1,39 @@
+#include
+
+#include "logging.h"
+#include "iathook.h"
+
+VOID iat_hook(HMODULE hModule, LPCSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress) {
+ LPVOID *lpAddress = iat_find(hModule, lpFuncName);
+ if (!lpAddress || *lpAddress == lpNewAddress)
+ return;
+
+ if (!hModule)
+ hModule = GetModuleHandle(NULL);
+
+ trace(L"Modified import address: hmod=%p, import=%S, old addr=%p, new addr=%p", hModule, lpFuncName, *lpAddress, lpNewAddress);
+
+ DWORD flOldProtect;
+ DWORD flNewProtect = PAGE_READWRITE;
+ VirtualProtect(lpAddress, sizeof(LPVOID), flNewProtect, &flOldProtect);
+ if (lpOldAddress)
+ *lpOldAddress = *lpAddress;
+ *lpAddress = lpNewAddress;
+ VirtualProtect(lpAddress, sizeof(LPVOID), flOldProtect, &flNewProtect);
+}
+
+static LPVOID *iat_find(HMODULE hModule, LPCSTR lpFunctionName) {
+ uintptr_t hm = (uintptr_t)hModule;
+
+ for (PIMAGE_IMPORT_DESCRIPTOR iid = (PIMAGE_IMPORT_DESCRIPTOR)(hm + ((PIMAGE_NT_HEADERS)(hm + ((PIMAGE_DOS_HEADER)hm)->e_lfanew))
+ ->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); iid->Name; iid++) {
+
+ LPVOID *pp;
+ for (SIZE_T i = 0; *(pp = i + (LPVOID *)(hm + iid->FirstThunk)); i++) {
+ LPSTR fn = (LPSTR)(hm + *(i + (SIZE_T *)(hm + iid->OriginalFirstThunk)) + 2);
+ if (!((uintptr_t)fn & IMAGE_ORDINAL_FLAG) && !_stricmp(lpFunctionName, fn))
+ return pp;
+ }
+ }
+ return NULL;
+}
diff --git a/wufuc/iathook.h b/wufuc/iathook.h
new file mode 100644
index 0000000..9f7b3a4
--- /dev/null
+++ b/wufuc/iathook.h
@@ -0,0 +1,5 @@
+#pragma once
+
+VOID iat_hook(HMODULE hModule, LPCSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress);
+
+static LPVOID *iat_find(HMODULE hModule, LPCSTR lpFunctionName);
diff --git a/wufuc/logging.c b/wufuc/logging.c
new file mode 100644
index 0000000..d5a791a
--- /dev/null
+++ b/wufuc/logging.c
@@ -0,0 +1,53 @@
+#include
+#include
+#include
+#include
+#include
+
+#include "helpers.h"
+#include "logging.h"
+
+static FILE *fp;
+static BOOL logging_enabled = FALSE;
+
+BOOL logging_init(void) {
+ if (fp)
+ return TRUE;
+
+ WCHAR filename[MAX_PATH];
+ GetModuleFileNameW(HINST_THISCOMPONENT, filename, _countof(filename));
+ WCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME];
+ _wsplitpath_s(filename, drive, _countof(drive), dir, _countof(dir), fname, _countof(fname), NULL, 0);
+
+ WCHAR basename[MAX_PATH];
+ GetModuleBaseNameW(GetCurrentProcess(), NULL, basename, _countof(basename));
+ wcscat_s(fname, _countof(fname), L".");
+ wcscat_s(fname, _countof(fname), basename);
+ _wmakepath_s(filename, _countof(filename), drive, dir, fname, L".log");
+
+ HANDLE hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ LARGE_INTEGER size;
+ GetFileSizeEx(hFile, &size);
+ CloseHandle(hFile);
+ fp = _wfsopen(filename, size.QuadPart < (1 << 20) ? L"at" : L"wt", _SH_DENYWR);
+ return (fp != NULL);
+}
+
+VOID trace_(LPCWSTR format, ...) {
+ if (logging_init()) {
+ WCHAR datebuf[9], timebuf[9];
+ _wstrdate_s(datebuf, _countof(datebuf));
+ _wstrtime_s(timebuf, _countof(timebuf));
+ fwprintf_s(fp, L"%s %s [%d] ", datebuf, timebuf, GetCurrentProcessId());
+
+ va_list argptr;
+ va_start(argptr, format);
+ vfwprintf_s(fp, format, argptr);
+ va_end(argptr);
+ fflush(fp);
+ }
+}
+
+BOOL logging_free(void) {
+ return fp && !fclose(fp);
+}
diff --git a/wufuc/logging.h b/wufuc/logging.h
new file mode 100644
index 0000000..e387471
--- /dev/null
+++ b/wufuc/logging.h
@@ -0,0 +1,13 @@
+#pragma once
+
+BOOL logging_init(void);
+VOID trace_(LPCWSTR format, ...);
+BOOL logging_free(void);
+
+#define STRINGIZE_(x) #x
+#define STRINGIZE(x) STRINGIZE_(x)
+
+#define STRINGIZEW_(x) L#x
+#define STRINGIZEW(x) STRINGIZEW_(x)
+#define __LINEWSTR__ STRINGIZEW(__LINE__)
+#define trace(format, ...) trace_(__FILEW__ L":" __LINEWSTR__ L"(" __FUNCTIONW__ L"): " format L"\n", ##__VA_ARGS__)
diff --git a/wufuc/patternfind.c b/wufuc/patternfind.c
index f55b80f..21cc436 100644
--- a/wufuc/patternfind.c
+++ b/wufuc/patternfind.c
@@ -1,32 +1,32 @@
#include
#include "patternfind.h"
-/* Ported to C from x64dbg's patternfind.cpp:
-
+/* Ported to C from x64dbg's patternfind.cpp:
+ * https://github.com/x64dbg/x64dbg/blob/development/src/dbg/patternfind.cpp
+ * x64dbg license (GPL-3.0):
+ * https://github.com/x64dbg/x64dbg/blob/development/LICENSE>
+ */
- x64dbg license (GPL-3.0):
- */
-
-static int hexchtoint(CHAR c) {
+int hexchtoint(CHAR c) {
int result = -1;
- if (c >= '0' && c <= '9') {
+ if (c >= '0' && c <= '9')
result = c - '0';
- } else if (c >= 'A' && c <= 'F') {
+ else if (c >= 'A' && c <= 'F')
result = c - 'A' + 10;
- } else if (c >= 'a' && c <= 'f') {
+ else if (c >= 'a' && c <= 'f')
result = c - 'a' + 10;
- }
+
return result;
}
-static SIZE_T formathexpattern(LPCSTR patterntext, LPSTR formattext, SIZE_T formattextsize) {
+SIZE_T formathexpattern(LPCSTR patterntext, LPSTR formattext, SIZE_T formattextsize) {
SIZE_T len = strlen(patterntext);
SIZE_T result = 0;
for (SIZE_T i = 0; i < len && (!formattext || result < formattextsize); i++) {
if (patterntext[i] == '?' || hexchtoint(patterntext[i]) != -1) {
- if (formattext) {
+ if (formattext)
formattext[result] = patterntext[i];
- }
+
result++;
}
}
@@ -35,21 +35,21 @@ static SIZE_T formathexpattern(LPCSTR patterntext, LPSTR formattext, SIZE_T form
BOOL patterntransform(LPCSTR patterntext, LPPATTERNBYTE pattern, SIZE_T *patternsize) {
SIZE_T cb = formathexpattern(patterntext, NULL, 0);
- if (!cb || cb > *patternsize) {
+ if (!cb || cb > *patternsize)
return FALSE;
- }
+
LPSTR formattext = calloc(cb, sizeof(CHAR));
cb = formathexpattern(patterntext, formattext, cb);
- if (cb % 2) {
+ if (cb % 2)
formattext[cb++] = '?';
- }
+
formattext[cb] = '\0';
for (SIZE_T i = 0, j = 0, k = 0; i < cb; i++, j ^= 1, k = (i - j) >> 1) {
- if (formattext[i] == '?') {
+ if (formattext[i] == '?')
pattern[k].nibble[j].wildcard = TRUE;
- } else {
+ else {
pattern[k].nibble[j].wildcard = FALSE;
pattern[k].nibble[j].data = hexchtoint(formattext[i]) & 0xf;
}
@@ -59,19 +59,18 @@ BOOL patterntransform(LPCSTR patterntext, LPPATTERNBYTE pattern, SIZE_T *pattern
return TRUE;
}
-SIZE_T patternfind(LPCBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR pattern) {
- SIZE_T result = -1;
+LPBYTE patternfind(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR pattern) {
+ LPBYTE result = NULL;
SIZE_T searchpatternsize = strlen(pattern);
LPPATTERNBYTE searchpattern = calloc(searchpatternsize, sizeof(PATTERNBYTE));
-
+
if (patterntransform(pattern, searchpattern, &searchpatternsize)) {
- for (SIZE_T i = startindex, j = 0; i < datasize; i++) //search for the pattern
- {
+ for (SIZE_T i = startindex, j = 0; i < datasize; i++) { //search for the pattern
if ((searchpattern[j].nibble[0].wildcard || searchpattern[j].nibble[0].data == ((data[i] >> 4) & 0xf))
&& (searchpattern[j].nibble[1].wildcard || searchpattern[j].nibble[1].data == (data[i] & 0xf))) { //check if our pattern matches the current byte
if (++j == searchpatternsize) { //everything matched
- result = i - searchpatternsize + 1;
+ result = data + (i - searchpatternsize + 1);
break;
}
} else if (j > 0) { //fix by Computer_Angel
@@ -87,33 +86,50 @@ SIZE_T patternfind(LPCBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR patt
VOID patternwritebyte(LPBYTE byte, LPPATTERNBYTE pbyte) {
BYTE n1 = (*byte >> 4) & 0xf;
BYTE n2 = *byte & 0xf;
- if (!pbyte->nibble[0].wildcard) {
+ if (!pbyte->nibble[0].wildcard)
n1 = pbyte->nibble[0].data;
- }
- if (!pbyte->nibble[1].wildcard) {
+
+ if (!pbyte->nibble[1].wildcard)
n2 = pbyte->nibble[1].data;
- }
*byte = ((n1 << 4) & 0xf0) | (n2 & 0xf);
}
-VOID patternwrite(LPBYTE data, SIZE_T datasize, LPCSTR pattern) {
+BOOL patternwrite(LPBYTE data, SIZE_T datasize, LPCSTR pattern) {
+
SIZE_T writepatternsize = strlen(pattern);
- if (writepatternsize > datasize) {
+ if (writepatternsize > datasize)
writepatternsize = datasize;
- }
+
+ BOOL result = FALSE;
LPPATTERNBYTE writepattern = calloc(writepatternsize, sizeof(PATTERNBYTE));
if (patterntransform(pattern, writepattern, &writepatternsize)) {
- for (size_t i = 0; i < writepatternsize; i++) {
- patternwritebyte(&data[i], &writepattern[i]);
+ DWORD flNewProtect = PAGE_READWRITE;
+ DWORD flOldProtect;
+
+ if (VirtualProtect(data, writepatternsize, flNewProtect, &flOldProtect)) {
+ for (size_t i = 0; i < writepatternsize; i++) {
+ BYTE n1 = (data[i] >> 4) & 0xf;
+ BYTE n2 = data[i] & 0xf;
+ if (!writepattern[i].nibble[0].wildcard)
+ n1 = writepattern[i].nibble[0].data;
+
+ if (!writepattern[i].nibble[1].wildcard)
+ n2 = writepattern[i].nibble[1].data;
+ data[i] = ((n1 << 4) & 0xf0) | (n2 & 0xf);
+
+ }
+ result = VirtualProtect(data, writepatternsize, flOldProtect, &flNewProtect);
}
}
free(writepattern);
-}
-
-SIZE_T patternsnr(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR searchpattern, LPCSTR replacepattern) {
- SIZE_T result = patternfind(data, datasize, startindex, searchpattern);
- if (result == -1)
- return result;
- patternwrite(data + result, datasize - result, replacepattern);
+ return result;
+}
+
+LPBYTE patternsnr(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR searchpattern, LPCSTR replacepattern) {
+ LPBYTE result = patternfind(data, datasize, startindex, searchpattern);
+ if (result == NULL)
+ return result;
+
+ patternwrite(result, datasize, replacepattern);
return result;
}
diff --git a/wufuc/patternfind.h b/wufuc/patternfind.h
index dfc0731..4f65890 100644
--- a/wufuc/patternfind.h
+++ b/wufuc/patternfind.h
@@ -10,7 +10,7 @@ typedef struct _PATTERNBYTE {
int hexchtoint(CHAR ch);
SIZE_T formathexpattern(LPCSTR patterntext, LPSTR formattext, SIZE_T formattextsize);
BOOL patterntransform(LPCSTR patterntext, LPPATTERNBYTE pattern, SIZE_T *patternsize);
-SIZE_T patternfind(LPCBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR pattern);
+LPBYTE patternfind(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR pattern);
VOID patternwritebyte(LPBYTE byte, LPPATTERNBYTE pbyte);
-VOID patternwrite(LPBYTE data, SIZE_T datasize, LPCSTR pattern);
-SIZE_T patternsnr(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR searchpattern, LPCSTR replacepattern);
+BOOL patternwrite(LPBYTE data, SIZE_T datasize, LPCSTR pattern);
+LPBYTE patternsnr(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR searchpattern, LPCSTR replacepattern);
diff --git a/wufuc/rundll32.c b/wufuc/rundll32.c
index 5659c05..70389e3 100644
--- a/wufuc/rundll32.c
+++ b/wufuc/rundll32.c
@@ -2,8 +2,10 @@
#include
#include
#include
+
+#include "helpers.h"
+#include "logging.h"
#include "service.h"
-#include "util.h"
void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) {
HANDLE hEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("Global\\wufuc_UnloadEvent"));
@@ -14,74 +16,72 @@ void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int n
LPWSTR osname;
if (IsWindows7()) {
- if (IsWindowsServer()) {
+ if (IsWindowsServer())
osname = L"Windows Server 2008 R2";
- } else {
+ else
osname = L"Windows 7";
- }
} else if (IsWindows8Point1()) {
- if (IsWindowsServer()) {
+ if (IsWindowsServer())
osname = L"Windows Server 2012 R2";
- } else {
+ else
osname = L"Windows 8.1";
- }
}
- dwprintf(L"Operating System: %s %d-bit", osname, sizeof(uintptr_t) * 8);
+ trace(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))) {
+ while (i < _countof(brand) && isspace(*(brand + i)))
i++;
- }
- dwprintf(L"Processor: %S", brand + i);
+
+ trace(L"Processor: %S", brand + i);
SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
- if (!hSCManager) {
+ if (!hSCManager)
return;
- }
+
TCHAR lpGroupName[256];
DWORD dwProcessId;
BOOL result = get_svcpid(hSCManager, _T("wuauserv"), &dwProcessId);
- if (!result && get_svcgname(hSCManager, _T("wuauserv"), lpGroupName, _countof(lpGroupName))) {
+ if (!result && get_svcgname(hSCManager, _T("wuauserv"), lpGroupName, _countof(lpGroupName)))
result = get_svcgpid(hSCManager, lpGroupName, &dwProcessId);
- }
+
CloseServiceHandle(hSCManager);
- if (!result) {
+ if (!result)
return;
- }
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
- if (!hProcess) {
+ if (!hProcess)
return;
- }
-
+
TCHAR lpLibFileName[MAX_PATH];
GetModuleFileName(HINST_THISCOMPONENT, lpLibFileName, _countof(lpLibFileName));
-
SIZE_T size = (_tcslen(lpLibFileName) + 1) * sizeof(TCHAR);
LPVOID lpBaseAddress = VirtualAllocEx(hProcess, NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (lpBaseAddress && WriteProcessMemory(hProcess, lpBaseAddress, lpLibFileName, size, NULL)) {
-
- HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
- (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"kernel32.dll"),
- STRINGIZE(LoadLibrary)),
- lpBaseAddress, 0, NULL
+ HANDLE hThread = CreateRemoteThread(
+ hProcess,
+ NULL,
+ 0,
+ (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("kernel32.dll")),
+ STRINGIZE(LoadLibrary)),
+ lpBaseAddress,
+ 0,
+ NULL
);
WaitForSingleObject(hThread, INFINITE);
- dwprintf(L"Injected into process: %d", dwProcessId);
+ trace(L"Injected into process: %d", dwProcessId);
CloseHandle(hThread);
}
VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE);
CloseHandle(hProcess);
- close_log();
}
void CALLBACK Rundll32Unload(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) {
HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, _T("Global\\wufuc_UnloadEvent"));
if (hEvent) {
- dwprintf(L"Setting unload event...");
+ trace(L"Setting unload event...");
SetEvent(hEvent);
CloseHandle(hEvent);
}
diff --git a/wufuc/service.c b/wufuc/service.c
index 5ac84cc..84a50f7 100644
--- a/wufuc/service.c
+++ b/wufuc/service.c
@@ -1,8 +1,10 @@
#include
#include
#include
-#include "util.h"
+
+#include "helpers.h"
#include "shellapihelper.h"
+#include "logging.h"
#include "service.h"
static CHAR wuauservdllA[MAX_PATH];
@@ -12,10 +14,10 @@ BOOL get_svcdllA(LPCSTR lpServiceName, LPSTR lpServiceDll, DWORD dwSize) {
CHAR lpSubKey[257];
sprintf_s(lpSubKey, _countof(lpSubKey), "SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", lpServiceName);
DWORD cb = dwSize;
- if (RegGetValueA(HKEY_LOCAL_MACHINE, lpSubKey, "ServiceDll", RRF_RT_REG_SZ, NULL, lpServiceDll, &cb)) {
+ if (RegGetValueA(HKEY_LOCAL_MACHINE, lpSubKey, "ServiceDll", RRF_RT_REG_SZ, NULL, lpServiceDll, &cb))
return FALSE;
- }
- dwprintf(L"Service \"%S\" DLL path: %S", lpServiceName, lpServiceDll);
+
+ trace(L"Service \"%S\" DLL path: %S", lpServiceName, lpServiceDll);
return TRUE;
}
@@ -23,32 +25,31 @@ BOOL get_svcdllW(LPCWSTR lpServiceName, LPWSTR lpServiceDll, DWORD dwSize) {
WCHAR lpSubKey[257];
swprintf_s(lpSubKey, _countof(lpSubKey), L"SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", lpServiceName);
DWORD cb = dwSize;
- if (RegGetValueW(HKEY_LOCAL_MACHINE, lpSubKey, L"ServiceDll", RRF_RT_REG_SZ, NULL, lpServiceDll, &cb)) {
+ if (RegGetValueW(HKEY_LOCAL_MACHINE, lpSubKey, L"ServiceDll", RRF_RT_REG_SZ, NULL, lpServiceDll, &cb))
return FALSE;
- }
- dwprintf(L"Service \"%s\" DLL path: %s", lpServiceName, lpServiceDll);
+
+ trace(L"Service \"%s\" DLL path: %s", lpServiceName, lpServiceDll);
return TRUE;
}
LPSTR get_wuauservdllA(void) {
- if (wuauservdllA[0] == '\0') {
+ if (!*wuauservdllA)
get_svcdllA("wuauserv", wuauservdllA, _countof(wuauservdllA));
- }
+
return wuauservdllA;
}
LPWSTR get_wuauservdllW(void) {
- if (wuauservdllW[0] == L'\0') {
+ if (!*wuauservdllW)
get_svcdllW(L"wuauserv", wuauservdllW, _countof(wuauservdllW));
- }
+
return wuauservdllW;
}
BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessId) {
SC_HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_STATUS);
- if (!hService) {
+ if (!hService)
return FALSE;
- }
SERVICE_STATUS_PROCESS lpBuffer;
DWORD cbBytesNeeded;
@@ -58,9 +59,9 @@ BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessI
*lpdwProcessId = lpBuffer.dwProcessId;
#ifdef _UNICODE
- dwprintf(L"Service \"%s\" process ID: %d", lpServiceName, *lpdwProcessId);
+ trace(L"Service \"%s\" process ID: %d", lpServiceName, *lpdwProcessId);
#else
- dwprintf(L"Service \"%S\" process ID: %d", lpServiceName, *lpdwProcessId);
+ trace(L"Service \"%S\" process ID: %d", lpServiceName, *lpdwProcessId);
#endif
result = TRUE;
}
@@ -70,15 +71,13 @@ BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessI
BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupName, SIZE_T dwSize) {
TCHAR lpBinaryPathName[0x8000];
- if (!get_svcpath(hSCManager, lpServiceName, lpBinaryPathName, _countof(lpBinaryPathName))) {
+ if (!get_svcpath(hSCManager, lpServiceName, lpBinaryPathName, _countof(lpBinaryPathName)))
return FALSE;
- }
int numArgs;
LPWSTR *argv = CommandLineToArgv(lpBinaryPathName, &numArgs);
- if (numArgs < 3) {
+ if (numArgs < 3)
return FALSE;
- }
TCHAR fname[_MAX_FNAME];
_tsplitpath_s(argv[0], NULL, 0, NULL, 0, fname, _countof(fname), NULL, 0);
@@ -90,9 +89,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"Service \"%s\" group name: %s", lpServiceName, lpGroupName);
+ trace(L"Service \"%s\" group name: %s", lpServiceName, lpGroupName);
#else
- dwprintf(L"Service \"%S\" group name: %S", lpServiceName, lpGroupName);
+ trace(L"Service \"%S\" group name: %S", lpServiceName, lpGroupName);
#endif
break;
}
@@ -103,16 +102,15 @@ BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupNam
BOOL get_svcpath(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPathName, SIZE_T dwSize) {
HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_CONFIG);
- if (!hService) {
+ if (!hService)
return FALSE;
- }
+
DWORD cbBytesNeeded;
BOOL result = FALSE;
if (!QueryServiceConfig(hService, NULL, 0, &cbBytesNeeded) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
LPQUERY_SERVICE_CONFIG sc = malloc(cbBytesNeeded);
- if (QueryServiceConfig(hService, sc, cbBytesNeeded, &cbBytesNeeded) && !_tcscpy_s(lpBinaryPathName, dwSize, sc->lpBinaryPathName)) {
+ if (QueryServiceConfig(hService, sc, cbBytesNeeded, &cbBytesNeeded) && !_tcscpy_s(lpBinaryPathName, dwSize, sc->lpBinaryPathName))
result = TRUE;
- }
free(sc);
}
CloseServiceHandle(hService);
@@ -135,9 +133,9 @@ BOOL get_svcgpid(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwPro
*lpdwProcessId = dwProcessId;
result = TRUE;
#ifdef _UNICODE
- dwprintf(L"Service group \"%s\" process ID: %d", lpServiceGroupName, *lpdwProcessId);
+ trace(L"Service group \"%s\" process ID: %d", lpServiceGroupName, *lpdwProcessId);
#else
- dwprintf(L"Service group \"%S\" process ID: %d", lpServiceGroupName, *lpdwProcessId);
+ trace(L"Service group \"%S\" process ID: %d", lpServiceGroupName, *lpdwProcessId);
#endif
break;
}
diff --git a/wufuc/util.c b/wufuc/util.c
deleted file mode 100644
index 505ce1f..0000000
--- a/wufuc/util.c
+++ /dev/null
@@ -1,202 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "util.h"
-
-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;
-
-LPVOID *FindIAT(HMODULE hModule, LPSTR lpFunctionName) {
- uintptr_t hm = (uintptr_t)hModule;
-
- for (PIMAGE_IMPORT_DESCRIPTOR iid = (PIMAGE_IMPORT_DESCRIPTOR)(hm + ((PIMAGE_NT_HEADERS)(hm + ((PIMAGE_DOS_HEADER)hm)->e_lfanew))
- ->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); iid->Name; iid++) {
-
- LPVOID *p;
- for (SIZE_T i = 0; *(p = i + (LPVOID *)(hm + iid->FirstThunk)); i++) {
- LPSTR fn = (LPSTR)(hm + *(i + (SIZE_T *)(hm + iid->OriginalFirstThunk)) + 2);
- if (!((uintptr_t)fn & IMAGE_ORDINAL_FLAG) && !_stricmp(lpFunctionName, fn)) {
- return p;
- }
- }
- }
- return NULL;
-}
-
-VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress) {
- LPVOID *lpAddress = FindIAT(hModule, lpFuncName);
- if (!lpAddress || *lpAddress == lpNewAddress) {
- return;
- }
-
- DWORD flOldProtect;
- DWORD flNewProtect = PAGE_READWRITE;
- VirtualProtect(lpAddress, sizeof(LPVOID), flNewProtect, &flOldProtect);
- if (lpOldAddress) {
- *lpOldAddress = *lpAddress;
- }
- dwprintf(L"Modified %S import address: %p => %p", lpFuncName, *lpAddress, lpNewAddress);
- *lpAddress = lpNewAddress;
- VirtualProtect(lpAddress, sizeof(LPVOID), flOldProtect, &flNewProtect);
-}
-
-VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb) {
- HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
- THREADENTRY32 te;
- ZeroMemory(&te, sizeof(THREADENTRY32));
- te.dwSize = sizeof(te);
- Thread32First(hSnap, &te);
-
- SIZE_T count = 0;
-
- do {
- if (te.th32OwnerProcessID != dwProcessId || te.th32ThreadID == dwThreadId) {
- continue;
- }
- lphThreads[count] = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID);
- SuspendThread(lphThreads[count]);
- count++;
- } while (count < dwSize && Thread32Next(hSnap, &te));
- CloseHandle(hSnap);
-
- *lpcb = count;
- dwprintf(L"Suspended %d other threads", count);
-}
-
-VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T cb) {
- for (SIZE_T i = 0; i < cb; i++) {
- ResumeThread(lphThreads[i]);
- CloseHandle(lphThreads[i]);
- }
- dwprintf(L"Resumed %d other threads", cb);
-}
-
-BOOL CompareWindowsVersion(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;
-
- 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);
-
- return VerifyVersionInfo(&osvi, dwTypeMask, dwlConditionMask);
-}
-
-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 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;
- }
- WCHAR filename[MAX_PATH];
- GetModuleFileNameW(HINST_THISCOMPONENT, filename, _countof(filename));
- WCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME];
- _wsplitpath_s(filename, drive, _countof(drive), dir, _countof(dir), fname, _countof(fname), NULL, 0);
-
- WCHAR basename[MAX_PATH];
- GetModuleBaseNameW(GetCurrentProcess(), NULL, basename, _countof(basename));
- wcscat_s(fname, _countof(fname), L".");
- wcscat_s(fname, _countof(fname), basename);
- _wmakepath_s(filename, _countof(filename), drive, dir, fname, L".log");
-
- HANDLE hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- LARGE_INTEGER size;
- GetFileSizeEx(hFile, &size);
- CloseHandle(hFile);
- log_fp = _wfsopen(filename, size.QuadPart < (1 << 20) ? L"at" : L"wt", _SH_DENYWR);
- if (!log_fp) {
- return FALSE;
- }
- return TRUE;
-}
-
-VOID close_log(void) {
- if (log_fp) {
- fclose(log_fp);
- }
-}
-
-VOID dwprintf_(LPCWSTR format, ...) {
- if (init_log()) {
- WCHAR datebuf[9], timebuf[9];
- _wstrdate_s(datebuf, _countof(datebuf));
- _wstrtime_s(timebuf, _countof(timebuf));
- fwprintf_s(log_fp, L"%s %s [%d] ", datebuf, timebuf, GetCurrentProcessId());
-
- va_list argptr;
- va_start(argptr, format);
- vfwprintf_s(log_fp, format, argptr);
- va_end(argptr);
- fflush(log_fp);
- }
-}
diff --git a/wufuc/util.h b/wufuc/util.h
deleted file mode 100644
index 723b4bc..0000000
--- a/wufuc/util.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#pragma once
-
-EXTERN_C IMAGE_DOS_HEADER __ImageBase;
-#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
-
-typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
-
-LPVOID *FindIAT(HMODULE hModule, LPSTR lpFuncName);
-VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress);
-
-VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb);
-VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T dwSize);
-
-BOOL CompareWindowsVersion(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask);
-BOOL IsWindows7(void);
-BOOL IsWindows8Point1(void);
-BOOL IsOperatingSystemSupported(void);
-BOOL IsWow64(void);
-
-void get_cpuid_brand(char *brand);
-
-VOID dwprintf_(LPCWSTR format, ...);
-
-#define DETOUR_IAT(x, y) \
- LPVOID _LPORIGINAL##y; \
- DetourIAT(x, #y, &_LPORIGINAL##y, &_##y)
-#define RESTORE_IAT(x, y) \
- DetourIAT(x, #y, NULL, _LPORIGINAL##y)
-
-BOOL init_log(void);
-VOID close_log(void);
-
-#define STRINGIZE_(x) #x
-#define STRINGIZE(x) STRINGIZE_(x)
-
-#define STRINGIZEW_(x) L#x
-#define STRINGIZEW(x) STRINGIZEW_(x)
-#define __LINEWSTR__ STRINGIZEW(__LINE__)
-#define dwprintf(format, ...) dwprintf_(__FILEW__ L"(" __LINEWSTR__ L"): " format L"\n", ##__VA_ARGS__)
diff --git a/wufuc/version.rc b/wufuc/wufuc.rc
similarity index 89%
rename from wufuc/version.rc
rename to wufuc/wufuc.rc
index f500439..f51334b 100644
Binary files a/wufuc/version.rc and b/wufuc/wufuc.rc differ
diff --git a/wufuc/wufuc.vcxproj b/wufuc/wufuc.vcxproj
index f85c591..dce8c08 100644
--- a/wufuc/wufuc.vcxproj
+++ b/wufuc/wufuc.vcxproj
@@ -108,7 +108,7 @@
Windows
exports.def
- Shlwapi.lib;%(AdditionalDependencies)
+ %(AdditionalDependencies)
@@ -121,7 +121,7 @@
Windows
exports.def
- Shlwapi.lib;%(AdditionalDependencies)
+ %(AdditionalDependencies)
@@ -142,7 +142,7 @@
true
exports.def
false
- Shlwapi.lib;%(AdditionalDependencies)
+ %(AdditionalDependencies)
@@ -167,7 +167,7 @@
true
exports.def
false
- Shlwapi.lib;%(AdditionalDependencies)
+ %(AdditionalDependencies)
@@ -175,25 +175,29 @@
-
+
+
+
-
+
-
+
+
+
-
+
-
+