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/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..3980697 --- /dev/null +++ b/wufuc/helpers.h @@ -0,0 +1,19 @@ +#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/core.c b/wufuc/hooks.c similarity index 51% rename from wufuc/core.c rename to wufuc/hooks.c index 9787ae9..d49b430 100644 --- a/wufuc/core.c +++ b/wufuc/hooks.c @@ -3,10 +3,16 @@ #include #include #include + +#include "helpers.h" +#include "logging.h" #include "service.h" +#include "iathook.h" #include "patternfind.h" -#include "util.h" -#include "core.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); @@ -15,63 +21,85 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam) { get_svcpath(hSCManager, _T("wuauserv"), lpBinaryPathName, _countof(lpBinaryPathName)); CloseServiceHandle(hSCManager); - BOOL result = _tcsicmp(GetCommandLine(), lpBinaryPathName); - - if (result) { + if (_tcsicmp(GetCommandLine(), lpBinaryPathName)) return 0; - } - SECURITY_ATTRIBUTES sa; - ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES)); + 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) { + if (!hEvent) return 0; - } DWORD dwProcessId = GetCurrentProcessId(); DWORD dwThreadId = GetCurrentThreadId(); HANDLE lphThreads[0x1000]; - SIZE_T cb; + SIZE_T count; - SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb); + suspend_other_threads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &count); HMODULE hm = GetModuleHandle(NULL); - DETOUR_IAT(hm, LoadLibraryExA); - DETOUR_IAT(hm, LoadLibraryExW); + iat_hook(hm, "LoadLibraryExA", (LPVOID)&fpLoadLibraryExA, LoadLibraryExA_hook); + iat_hook(hm, "LoadLibraryExW", (LPVOID)&fpLoadLibraryExW, LoadLibraryExW_hook); HMODULE hwu = GetModuleHandle(get_wuauservdll()); - if (hwu && PatchWU(hwu)) { - dwprintf(L"Patched previously loaded Windows Update module!"); - } - ResumeAndCloseThreads(lphThreads, cb); + if (hwu && PatchWUA(hwu)) + trace(L"Successfully patched previously loaded WUA module!"); + + resume_and_close_threads(lphThreads, count); WaitForSingleObject(hEvent, INFINITE); + trace(L"Unloading..."); - dwprintf(L"Unloading..."); + suspend_other_threads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &count); - SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb); - RESTORE_IAT(hm, LoadLibraryExA); - RESTORE_IAT(hm, LoadLibraryExW); - ResumeAndCloseThreads(lphThreads, cb); + iat_hook(hm, "LoadLibraryExA", NULL, fpLoadLibraryExA); + iat_hook(hm, "LoadLibraryExW", NULL, fpLoadLibraryExW); + resume_and_close_threads(lphThreads, count); + + trace(L"Bye bye!"); CloseHandle(hEvent); - dwprintf(L"Bye bye!"); - close_log(); FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0); } -BOOL PatchWU(HMODULE hModule) { +HMODULE WINAPI LoadLibraryExA_hook( + _In_ LPCSTR lpFileName, + _Reserved_ HANDLE hFile, + _In_ DWORD dwFlags +) { + HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags); + if (result) { + trace(L"Loaded library: %S", lpFileName); + if (!_stricmp(lpFileName, get_wuauservdllA()) && PatchWUA(result)) + trace(L"Successfully patched WUA module!"); + } + return result; +} + +HMODULE WINAPI LoadLibraryExW_hook( + _In_ LPCWSTR lpFileName, + _Reserved_ HANDLE hFile, + _In_ DWORD dwFlags +) { + HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags); + if (result) { + trace(L"Loaded library: %s", lpFileName); + if (!_wcsicmp(lpFileName, get_wuauservdllW()) && PatchWUA(result)) + trace(L"Successfully patched WUA module!"); + } + 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; + pattern = "FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????"; + offset00 = 10; + offset01 = 18; #elif defined(_X86_) if (IsWindows7()) { pattern = "833D????????00 743E E8???????? A3????????"; @@ -81,71 +109,37 @@ BOOL PatchWU(HMODULE hModule) { 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!"); + LPBYTE ptr = patternfind(modinfo.lpBaseOfDll, modinfo.SizeOfImage, 0, pattern); + if (!ptr) { + trace(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); + trace(L"wuaueng!IsDeviceServiceable VA: %p", ptr); 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)); + 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 *)(lpfnIsDeviceServiceable + offset00)); - lpbIsCPUSupportedResult = (LPBOOL)(*(uintptr_t *)(lpfnIsDeviceServiceable + offset01)); + lpbFirstRun = (LPBOOL)(*(uintptr_t *)(ptr + offset00)); + lpbIsCPUSupportedResult = (LPBOOL)(*(uintptr_t *)(ptr + offset01)); #endif if (*lpbFirstRun) { *lpbFirstRun = FALSE; - dwprintf(L"Patched FirstRun variable: %p = %08x", lpbFirstRun, *lpbFirstRun); + trace(L"Patched boolean value #1: %p = %08x", lpbFirstRun, *lpbFirstRun); result = TRUE; } if (!*lpbIsCPUSupportedResult) { *lpbIsCPUSupportedResult = TRUE; - dwprintf(L"Patched cached wuaueng.dll!IsCPUSupported result: %p = %08x", lpbIsCPUSupportedResult, *lpbIsCPUSupportedResult); + trace(L"Patched boolean value #2: %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/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..736e486 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[0]) get_svcdllA("wuauserv", wuauservdllA, _countof(wuauservdllA)); - } + return wuauservdllA; } LPWSTR get_wuauservdllW(void) { - if (wuauservdllW[0] == L'\0') { + if (!wuauservdllW[0]) 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 @@ - + + + - + - + + + - + - +