diff --git a/.gitignore b/.gitignore index 28ab44b..7e81e5a 100644 --- a/.gitignore +++ b/.gitignore @@ -254,3 +254,6 @@ paket-files/ # Advanced Installer **/*-cache/ **/*-SetupFiles/ + +# Other +setup-batch/*.dll diff --git a/appveyor.yml b/appveyor.yml index 0dc8492..2fb3bc6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,8 +1,8 @@ version: 0.7.2.{build} skip_commits: files: - - README.md - - CONTRIBUTING.md + - **/*.md + - **/*.aip image: Visual Studio 2017 configuration: Release platform: diff --git a/wufuc/callbacks.c b/wufuc/callbacks.c new file mode 100644 index 0000000..949a815 --- /dev/null +++ b/wufuc/callbacks.c @@ -0,0 +1,106 @@ +#include "callbacks.h" + +#include "service.h" +#include "iathook.h" +#include "hooks.h" +#include "patchwua.h" +#include "helpers.h" +#include "ntdllhelper.h" +#include "logging.h" + +#include + +#define WIN32_NO_STATUS +#include +#undef WIN32_NO_STATUS + +#include +#include +#include +#include + +DWORD WINAPI ThreadProcCallback(LPVOID lpParam) { + TCHAR lpServiceCommandLine[0x8000]; + GetServiceCommandLine(NULL, _T("wuauserv"), lpServiceCommandLine, _countof(lpServiceCommandLine)); + if ( _tcsicmp(GetCommandLine(), lpServiceCommandLine) ) + return 0; + + SECURITY_ATTRIBUTES sa = { 0 }; + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.bInheritHandle = FALSE; + if ( !ConvertStringSecurityDescriptorToSecurityDescriptor(_T("D:(A;;0x001F0003;;;BA)"), SDDL_REVISION_1, &sa.lpSecurityDescriptor, NULL) ) { + trace(_T("Failed to convert string security descriptor to security descriptor (error code=%08X)"), GetLastError()); + return 0; + } + + HANDLE hEvent = CreateEvent(&sa, TRUE, FALSE, _T("Global\\wufuc_UnloadEvent")); + if ( hEvent ) { + iat_hook(GetModuleHandle(NULL), "LoadLibraryExW", (LPVOID)&fpLoadLibraryExW, LoadLibraryExW_hook); + + PVOID cookie; + NTSTATUS status; + if ( TryLdrRegisterDllNotification(0, (PLDR_DLL_NOTIFICATION_FUNCTION)LdrDllNotificationCallback, NULL, &cookie, &status) ) { + if ( NT_SUCCESS(status) ) { + trace(_T("Registered LdrDllNotificationCallback (status code=%d)"), status); + HMODULE hm = GetModuleHandleW(GetWindowsUpdateServiceDllW()); + if ( hm ) { + MODULEINFO modinfo; + if ( GetModuleInformation(GetCurrentProcess(), hm, &modinfo, sizeof(MODULEINFO)) ) + PatchWUA((void *)modinfo.lpBaseOfDll, (size_t)modinfo.SizeOfImage); + } + + WaitForSingleObject(hEvent, INFINITE); + trace(_T("Unload event was set")); + + if ( cookie ) { + if ( TryLdrUnregisterDllNotification(cookie, &status) ) { + if ( NT_SUCCESS(status) ) + trace(_T("Unregistered LdrDllNotificationCallback (status code=%d)"), status); + else + trace(_T("Failed to unregister LdrDllNotificationCallback (status code=%d)"), status); + } else + trace(_T("Failed to get LdrUnregisterDllNotification proc address")); + } + } else + trace(_T("Failed to register LdrDllNotificationCallback (status code=%d)"), status); + } else + trace(_T("Failed to get LdrRegisterDllNotification proc address")); + + iat_hook(GetModuleHandle(NULL), "LoadLibraryExW", NULL, fpLoadLibraryExW); + CloseHandle(hEvent); + } else { + trace(_T("Failed to create unload event (error code=%08X)"), GetLastError()); + return 0; + } + trace(_T("Bye bye!")); + FreeLibraryAndExitThread((HMODULE)lpParam, 0); +} + +VOID CALLBACK LdrDllNotificationCallback(ULONG NotificationReason, PCLDR_DLL_NOTIFICATION_DATA NotificationData, PVOID Context) { + switch ( NotificationReason ) { + case LDR_DLL_NOTIFICATION_REASON_LOADED: + { + LDR_DLL_LOADED_NOTIFICATION_DATA data = NotificationData->Loaded; + + trace(_T("Loaded library: %wZ"), data.FullDllName); + + wchar_t buffer[MAX_PATH]; + wcscpy_s(buffer, _countof(buffer), (wchar_t *)GetWindowsUpdateServiceDllW()); + ApplyUpdatePack7R2ShimIfNeeded(buffer, _countof(buffer), buffer, _countof(buffer)); + + if ( !_wcsnicmp((wchar_t *)data.FullDllName->Buffer, buffer, (size_t)data.FullDllName->Length) ) + PatchWUA(data.DllBase, data.SizeOfImage); + return; + } + case LDR_DLL_NOTIFICATION_REASON_UNLOADED: + { + LDR_DLL_UNLOADED_NOTIFICATION_DATA data = NotificationData->Unloaded; + + trace(_T("Unloaded library: %wZ"), data.FullDllName); + return; + } + default: + return; + } +} + diff --git a/wufuc/callbacks.h b/wufuc/callbacks.h new file mode 100644 index 0000000..1d0f2e8 --- /dev/null +++ b/wufuc/callbacks.h @@ -0,0 +1,11 @@ +#ifndef CALLBACKS_H +#define CALLBACKS_H +#pragma once + +#include "ntdllhelper.h" + +#include + +DWORD WINAPI ThreadProcCallback(LPVOID lpParam); +VOID CALLBACK LdrDllNotificationCallback(ULONG NotificationReason, PCLDR_DLL_NOTIFICATION_DATA NotificationData, PVOID Context); +#endif diff --git a/wufuc/dllmain.c b/wufuc/dllmain.c index 51e3969..2c8117c 100644 --- a/wufuc/dllmain.c +++ b/wufuc/dllmain.c @@ -1,23 +1,25 @@ -#include - +#include "callbacks.h" #include "helpers.h" #include "logging.h" -#include "hooks.h" + +#include BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { - switch (ul_reason_for_call) { + switch ( ul_reason_for_call ) { case DLL_PROCESS_ATTACH: { - if (!IsOperatingSystemSupported() || IsWow64()) + if ( !IsOperatingSystemSupported() || IsWow64() ) return FALSE; - + DisableThreadLibraryCalls(hModule); - HANDLE hThread = CreateThread(NULL, 0, NewThreadProc, NULL, 0, NULL); + HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProcCallback, (LPVOID)hModule, 0, NULL); CloseHandle(hThread); break; } case DLL_PROCESS_DETACH: - logging_free(); + if ( !lpReserved ) + FreeNTDLL(); + FreeLogging(); break; default: break; diff --git a/wufuc/exports.def b/wufuc/exports.def deleted file mode 100644 index e90f4df..0000000 --- a/wufuc/exports.def +++ /dev/null @@ -1,3 +0,0 @@ -EXPORTS - Rundll32Entry - Rundll32Unload diff --git a/wufuc/helpers.c b/wufuc/helpers.c index cde5586..9ee9bca 100644 --- a/wufuc/helpers.c +++ b/wufuc/helpers.c @@ -1,26 +1,16 @@ -#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; +#include "logging.h" -static ISWOW64PROCESS fpIsWow64Process = NULL; -static BOOL m_checkedIsWow64 = FALSE; -static BOOL m_isWow64 = FALSE; +#include -static TCHAR m_emod_basename[MAX_PATH]; +#include +#include +#include +#include -BOOL CompareWindowsVersion(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask) { - OSVERSIONINFOEX osvi; - ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); +static BOOL CompareWindowsVersion(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask) { + OSVERSIONINFOEX osvi = { 0 }; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); osvi.dwMajorVersion = dwMajorVersion; osvi.dwMinorVersion = dwMinorVersion; @@ -37,7 +27,10 @@ BOOL CompareWindowsVersion(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVer } BOOL IsWindows7(void) { - if (!m_checkedIsWindows7) { + static BOOL m_checkedIsWindows7 = FALSE; + static BOOL m_isWindows7 = FALSE; + + if ( !m_checkedIsWindows7 ) { m_isWindows7 = CompareWindowsVersion(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION); m_checkedIsWindows7 = TRUE; } @@ -45,7 +38,10 @@ BOOL IsWindows7(void) { } BOOL IsWindows8Point1(void) { - if (!m_checkedIsWindows8Point1) { + static BOOL m_checkedIsWindows8Point1 = FALSE; + static BOOL m_isWindows8Point1 = FALSE; + + if ( !m_checkedIsWindows8Point1 ) { m_isWindows8Point1 = CompareWindowsVersion(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION); m_checkedIsWindows8Point1 = TRUE; } @@ -61,56 +57,60 @@ BOOL IsOperatingSystemSupported(void) { } BOOL IsWow64(void) { - if (!m_checkedIsWow64) { - if (!fpIsWow64Process) + static BOOL m_checkedIsWow64 = FALSE; + static BOOL m_isWow64 = FALSE; + static ISWOW64PROCESS fpIsWow64Process = NULL; + + if ( !m_checkedIsWow64 ) { + if ( !fpIsWow64Process ) fpIsWow64Process = (ISWOW64PROCESS)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "IsWow64Process"); - - if (fpIsWow64Process && fpIsWow64Process(GetCurrentProcess(), &m_isWow64)) + + 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) { +void suspend_other_threads(LPHANDLE lphThreads, size_t *lpcb) { + DWORD dwProcessId = GetCurrentProcessId(); + DWORD dwThreadId = GetCurrentThreadId(); + HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); - THREADENTRY32 te; - ZeroMemory(&te, sizeof(THREADENTRY32)); + THREADENTRY32 te = { 0 }; te.dwSize = sizeof(te); Thread32First(hSnap, &te); - SIZE_T count = 0; - + size_t count = 0; do { - if (te.th32OwnerProcessID != dwProcessId || te.th32ThreadID == dwThreadId) + 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)); + } while ( count < *lpcb && Thread32Next(hSnap, &te) ); CloseHandle(hSnap); - *lpcb = count; - trace(L"Suspended %d other threads", count); + trace(_T("Suspended %d other threads"), count); } -VOID resume_and_close_threads(LPHANDLE lphThreads, SIZE_T cb) { - for (SIZE_T i = 0; i < cb; i++) { +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); + trace(_T("Resumed %d threads"), cb); } void get_cpuid_brand(char *brand) { int info[4]; __cpuidex(info, 0x80000000, 0); - if (info[0] < 0x80000004) { + if ( info[0] < 0x80000004 ) { brand[0] = '\0'; return; } uint32_t *char_as_int = (uint32_t *)brand; - for (int op = 0x80000002; op <= 0x80000004; op++) { + for ( int op = 0x80000002; op <= 0x80000004; op++ ) { __cpuidex(info, op, 0); *(char_as_int++) = info[0]; *(char_as_int++) = info[1]; diff --git a/wufuc/helpers.h b/wufuc/helpers.h index afdf16f..243952e 100644 --- a/wufuc/helpers.h +++ b/wufuc/helpers.h @@ -1,20 +1,21 @@ +#ifndef HELPERS_H +#define HELPERS_H #pragma once -EXTERN_C IMAGE_DOS_HEADER __ImageBase; -#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase) +#include 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 suspend_other_threads(LPHANDLE lphThreads, size_t *lpcb); +void resume_and_close_threads(LPHANDLE lphThreads, size_t cb); void get_cpuid_brand(char *brand); #define STRINGIZE_(x) #x #define STRINGIZE(x) STRINGIZE_(x) +#endif diff --git a/wufuc/hooks.c b/wufuc/hooks.c index 7ab0d90..bce0738 100644 --- a/wufuc/hooks.c +++ b/wufuc/hooks.c @@ -1,192 +1,67 @@ -#include -#include -#include -#include -#include - -#include "helpers.h" -#include "logging.h" -#include "service.h" -#include "iathook.h" -#include "patternfind.h" #include "hooks.h" +#include "service.h" +#include "helpers.h" +//#include "ntdllhelper.h" +#include "logging.h" + +#include + +//#define WIN32_NO_STATUS +#include +//#undef WIN32_NO_STATUS + +//#include +//#include +#include +#include + +//REGQUERYVALUEEXW fpRegQueryValueExW = NULL; LOADLIBRARYEXW fpLoadLibraryExW = NULL; -LOADLIBRARYEXA fpLoadLibraryExA = NULL; -DWORD WINAPI NewThreadProc(LPVOID lpParam) { - SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT); +//LRESULT WINAPI RegQueryValueExW_hook(HKEY hKey, LPCTSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) { +// static NTQUERYKEY fpNtQueryKey = NULL; +// +// DWORD cbData = *lpcbData; +// +// LRESULT result = fpRegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); +// if ( !result && lpData && !_wcsicmp((const wchar_t *)lpValueName, L"ServiceDll") ) { +// if ( InitNTDLL() ) { +// if ( !fpNtQueryKey ) +// fpNtQueryKey = (NTQUERYKEY)GetProcAddress(g_hNTDLL, "NtQueryKey"); +// +// if ( fpNtQueryKey ) { +// ULONG ResultLength; +// NTSTATUS status = fpNtQueryKey((HANDLE)hKey, KeyNameInformation, NULL, 0, &ResultLength); +// if ( status == STATUS_BUFFER_OVERFLOW || status == STATUS_BUFFER_TOO_SMALL ) { +// PVOID buffer = malloc(ResultLength); +// if ( NT_SUCCESS(fpNtQueryKey((HANDLE)hKey, KeyNameInformation, buffer, ResultLength, &ResultLength)) +// && !_wcsnicmp(buffer, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\services\\wuauserv", (size_t)ResultLength) ) { +// +// wchar_t path[MAX_PATH], newpath[MAX_PATH]; +// wcsncpy_s(path, _countof(path), (wchar_t *)lpData, (rsize_t)*lpcbData); +// +// if ( ApplyUpdatePack7R2ShimIfNeeded(path, _countof(path), newpath, _countof(newpath)) ) { +// trace(_T("UpdatePack7R2 shim: \"%ls\" -> \"%ls\""), path, newpath); +// wcscpy_s((wchar_t *)lpData, (rsize_t)cbData, newpath); +// } +// } +// free(buffer); +// } +// } +// } +// } +// return result; +//} - 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]; +HMODULE WINAPI LoadLibraryExW_hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags) { + wchar_t 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); - } - } + if ( !_wcsicmp(buffer, GetWindowsUpdateServiceDllW()) + && ApplyUpdatePack7R2ShimIfNeeded(buffer, _countof(buffer), buffer, _countof(buffer)) ) { + trace(_T("UpdatePack7R2 shim: %ls -> %ls"), 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; + return fpLoadLibraryExW((LPWSTR)buffer, hFile, dwFlags); } diff --git a/wufuc/hooks.h b/wufuc/hooks.h index af03435..1dbc519 100644 --- a/wufuc/hooks.h +++ b/wufuc/hooks.h @@ -1,23 +1,33 @@ +#ifndef HOOKS_H +#define HOOKS_H #pragma once -typedef HMODULE(WINAPI *LOADLIBRARYEXA)(LPCSTR, HANDLE, DWORD); +//#define WIN32_NO_STATUS +#include +//#undef WIN32_NO_STATUS + +//typedef enum _KEY_INFORMATION_CLASS { +// KeyBasicInformation = 0, +// KeyNodeInformation = 1, +// KeyFullInformation = 2, +// KeyNameInformation = 3, +// KeyCachedInformation = 4, +// KeyFlagsInformation = 5, +// KeyVirtualizationInformation = 6, +// KeyHandleTagsInformation = 7, +// MaxKeyInfoClass = 8 +//} KEY_INFORMATION_CLASS; +// +//typedef NTSTATUS(NTAPI *NTQUERYKEY)(HANDLE, KEY_INFORMATION_CLASS, PVOID, ULONG, PULONG); +// +//typedef LRESULT(WINAPI *REGQUERYVALUEEXW)(HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD); typedef HMODULE(WINAPI *LOADLIBRARYEXW)(LPCWSTR, HANDLE, DWORD); +//extern REGQUERYVALUEEXW fpRegQueryValueExW; extern LOADLIBRARYEXW fpLoadLibraryExW; -extern LOADLIBRARYEXA fpLoadLibraryExA; -DWORD WINAPI NewThreadProc(LPVOID lpParam); +LRESULT WINAPI RegQueryValueExW_hook(HKEY hKey, LPCTSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData); -HMODULE WINAPI LoadLibraryExA_hook( - _In_ LPCSTR lpFileName, - _Reserved_ HANDLE hFile, - _In_ DWORD dwFlags -); +HMODULE WINAPI LoadLibraryExW_hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags); -HMODULE WINAPI LoadLibraryExW_hook( - _In_ LPCWSTR lpFileName, - _Reserved_ HANDLE hFile, - _In_ DWORD dwFlags -); - -BOOL PatchWUA(HMODULE hModule); +#endif diff --git a/wufuc/iathook.c b/wufuc/iathook.c index c742d2e..f99ad3e 100644 --- a/wufuc/iathook.c +++ b/wufuc/iathook.c @@ -1,39 +1,41 @@ -#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; +#include "logging.h" - 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); -} +#include +#include 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++) { + 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)) + for ( size_t i = 0; *(pp = i + (LPVOID *)(hm + iid->FirstThunk)); i++ ) { + LPSTR fn = (LPSTR)(hm + *(i + (PSIZE_T)(hm + iid->OriginalFirstThunk)) + 2); + if ( !((uintptr_t)fn & IMAGE_ORDINAL_FLAG) && !_stricmp((const char *)lpFunctionName, (char *)fn) ) return pp; } } return NULL; } + +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(_T("Modified IAT: hModule=%p, Name=%hs, OldAddress=%p, NewAddress=%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); +} diff --git a/wufuc/iathook.h b/wufuc/iathook.h index 9f7b3a4..3c564ed 100644 --- a/wufuc/iathook.h +++ b/wufuc/iathook.h @@ -1,5 +1,8 @@ +#ifndef IATHOOK_H +#define IATHOOK_H #pragma once -VOID iat_hook(HMODULE hModule, LPCSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress); +#include -static LPVOID *iat_find(HMODULE hModule, LPCSTR lpFunctionName); +void iat_hook(HMODULE hModule, LPCSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress); +#endif diff --git a/wufuc/logging.c b/wufuc/logging.c index d5a791a..7e65a6c 100644 --- a/wufuc/logging.c +++ b/wufuc/logging.c @@ -1,53 +1,59 @@ -#include +#include "logging.h" + #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) +BOOL InitLogging(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); + TCHAR filename[MAX_PATH]; + GetModuleFileName(HINST_THISCOMPONENT, filename, _countof(filename)); - WCHAR basename[MAX_PATH]; + TCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME]; + _tsplitpath_s(filename, drive, _countof(drive), dir, _countof(dir), fname, _countof(fname), NULL, 0); + + TCHAR 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"); + _tcscat_s(fname, _countof(fname), _T(".")); + _tcscat_s(fname, _countof(fname), basename); + _tmakepath_s(filename, _countof(filename), drive, dir, fname, _T(".log")); - HANDLE hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE hFile = CreateFile(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); + fp = _tfsopen(filename, size.QuadPart < (1 << 20) ? _T("at") : _T("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()); +void trace_(LPCTSTR format, ...) { + static DWORD dwProcessId = 0; + + if ( InitLogging() ) { + if ( !dwProcessId ) + dwProcessId = GetCurrentProcessId(); + + TCHAR datebuf[9], timebuf[9]; + _tstrdate_s(datebuf, _countof(datebuf)); + _tstrtime_s(timebuf, _countof(timebuf)); + _ftprintf_s(fp, _T("%s %s [%d] "), datebuf, timebuf, dwProcessId); va_list argptr; va_start(argptr, format); - vfwprintf_s(fp, format, argptr); + _vftprintf_s(fp, format, argptr); va_end(argptr); fflush(fp); } } -BOOL logging_free(void) { +BOOL FreeLogging(void) { return fp && !fclose(fp); } diff --git a/wufuc/logging.h b/wufuc/logging.h index e387471..0107e54 100644 --- a/wufuc/logging.h +++ b/wufuc/logging.h @@ -1,13 +1,20 @@ +#ifndef LOGGING_H +#define LOGGING_H #pragma once -BOOL logging_init(void); -VOID trace_(LPCWSTR format, ...); -BOOL logging_free(void); +#include +#include + +extern IMAGE_DOS_HEADER __ImageBase; +#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase) + +BOOL InitLogging(void); +void trace_(LPCTSTR format, ...); +BOOL FreeLogging(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__) +#define __LINESTR__ STRINGIZE(__LINE__) +#define trace(format, ...) trace_(_T(__FILE__) _T(":") _T(__LINESTR__) _T("(") _T(__FUNCTION__) _T("): ") format _T("\n"), ##__VA_ARGS__) +#endif diff --git a/wufuc/ntdllhelper.c b/wufuc/ntdllhelper.c new file mode 100644 index 0000000..80190bc --- /dev/null +++ b/wufuc/ntdllhelper.c @@ -0,0 +1,56 @@ +#include "ntdllhelper.h" + +#define WIN32_NO_STATUS +#include +#undef WIN32_NO_STATUS + +#include +#include + +HMODULE g_hNTDLL = NULL; + +BOOL InitNTDLL(void) { + if ( !g_hNTDLL ) + g_hNTDLL = LoadLibrary(_T("ntdll")); + return (g_hNTDLL != NULL); +} + +BOOL FreeNTDLL(void) { + if ( g_hNTDLL ) { + BOOL result = FreeLibrary(g_hNTDLL); + if ( result ) + g_hNTDLL = NULL; + return result; + } + return FALSE; +} + +BOOL TryLdrRegisterDllNotification(ULONG Flags, PLDR_DLL_NOTIFICATION_FUNCTION NotificationFunction, PVOID Context, PVOID *Cookie, NTSTATUS *result) { + static LDRREGISTERDLLNOTIFICATION fpLdrRegisterDllNotification = NULL; + + if ( InitNTDLL() ) { + if ( !fpLdrRegisterDllNotification ) + fpLdrRegisterDllNotification = (LDRREGISTERDLLNOTIFICATION)GetProcAddress(g_hNTDLL, "LdrRegisterDllNotification"); + + if ( fpLdrRegisterDllNotification ) { + *result = fpLdrRegisterDllNotification(Flags, NotificationFunction, Context, Cookie); + return TRUE; + } + } + return FALSE; +} + +BOOL TryLdrUnregisterDllNotification(PVOID Cookie, NTSTATUS *result) { + static LDRUNREGISTERDLLNOTIFICATION fpLdrUnregisterDllNotification = NULL; + + if ( InitNTDLL() ) { + if ( !fpLdrUnregisterDllNotification ) + fpLdrUnregisterDllNotification = (LDRUNREGISTERDLLNOTIFICATION)GetProcAddress(g_hNTDLL, "LdrUnregisterDllNotification"); + + if ( fpLdrUnregisterDllNotification ) { + *result = fpLdrUnregisterDllNotification(Cookie); + return TRUE; + } + } + return FALSE; +} \ No newline at end of file diff --git a/wufuc/ntdllhelper.h b/wufuc/ntdllhelper.h new file mode 100644 index 0000000..cf76f43 --- /dev/null +++ b/wufuc/ntdllhelper.h @@ -0,0 +1,49 @@ +#ifndef NTDLLHELPER_H +#define NTDLLHELPER_H +#pragma once + +#define WIN32_NO_STATUS +#include +#undef WIN32_NO_STATUS + +#include + +typedef struct _LDR_DLL_LOADED_NOTIFICATION_DATA { + ULONG Flags; + PUNICODE_STRING FullDllName; + PUNICODE_STRING BaseDllName; + PVOID DllBase; + ULONG SizeOfImage; +} LDR_DLL_LOADED_NOTIFICATION_DATA, *PLDR_DLL_LOADED_NOTIFICATION_DATA; + +typedef struct _LDR_DLL_UNLOADED_NOTIFICATION_DATA { + ULONG Flags; + PCUNICODE_STRING FullDllName; + PCUNICODE_STRING BaseDllName; + PVOID DllBase; + ULONG SizeOfImage; +} LDR_DLL_UNLOADED_NOTIFICATION_DATA, *PLDR_DLL_UNLOADED_NOTIFICATION_DATA; + +typedef union _LDR_DLL_NOTIFICATION_DATA { + LDR_DLL_LOADED_NOTIFICATION_DATA Loaded; + LDR_DLL_UNLOADED_NOTIFICATION_DATA Unloaded; +} LDR_DLL_NOTIFICATION_DATA, *PLDR_DLL_NOTIFICATION_DATA; +typedef const LDR_DLL_NOTIFICATION_DATA *PCLDR_DLL_NOTIFICATION_DATA; + +typedef VOID(CALLBACK *PLDR_DLL_NOTIFICATION_FUNCTION)(ULONG, PCLDR_DLL_NOTIFICATION_DATA, PVOID); + +#define LDR_DLL_NOTIFICATION_REASON_LOADED 1 +#define LDR_DLL_NOTIFICATION_REASON_UNLOADED 2 + +typedef NTSTATUS(NTAPI *LDRREGISTERDLLNOTIFICATION)(ULONG, PLDR_DLL_NOTIFICATION_FUNCTION, PVOID, PVOID *); +typedef NTSTATUS(NTAPI *LDRUNREGISTERDLLNOTIFICATION)(PVOID); + +extern HMODULE g_hNTDLL; + +BOOL InitNTDLL(void); + +BOOL FreeNTDLL(void); + +BOOL TryLdrRegisterDllNotification(ULONG Flags, PLDR_DLL_NOTIFICATION_FUNCTION NotificationFunction, PVOID Context, PVOID *Cookie, NTSTATUS *result); +BOOL TryLdrUnregisterDllNotification(PVOID Cookie, NTSTATUS *result); +#endif diff --git a/wufuc/patchwua.c b/wufuc/patchwua.c new file mode 100644 index 0000000..4b42aa6 --- /dev/null +++ b/wufuc/patchwua.c @@ -0,0 +1,68 @@ +#include "patchwua.h" + +#include "patternfind.h" +#include "logging.h" + +#include + +#include +#include +#include + + +BOOL PatchWUA(void *lpBaseOfDll, size_t SizeOfImage) { + char *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 + + unsigned char *ptr = patternfind(lpBaseOfDll, SizeOfImage, 0, pattern); + if ( !ptr ) { + trace(_T("No pattern match!")); + return FALSE; + } + trace(_T("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(_T("Patched boolean value #1: %p = %s"), lpbFirstRun, *lpbFirstRun ? L"TRUE" : L"FALSE"); + result = TRUE; + } + if ( !*lpbIsCPUSupportedResult ) { + VirtualProtect(lpbIsCPUSupportedResult, sizeof(BOOL), flNewProtect, &flOldProtect); + *lpbIsCPUSupportedResult = TRUE; + VirtualProtect(lpbIsCPUSupportedResult, sizeof(BOOL), flOldProtect, &flNewProtect); + trace(_T("Patched boolean value #2: %p = %s"), lpbIsCPUSupportedResult, *lpbIsCPUSupportedResult ? L"TRUE" : L"FALSE"); + result = TRUE; + } + if ( result ) + trace(_T("Successfully patched WUA module!")); + + return result; +} \ No newline at end of file diff --git a/wufuc/patchwua.h b/wufuc/patchwua.h new file mode 100644 index 0000000..145182e --- /dev/null +++ b/wufuc/patchwua.h @@ -0,0 +1,8 @@ +#ifndef PATCHWUA_H +#define PATCHWUA_H +#pragma once + +#include + +BOOL PatchWUA(void *lpBaseOfDll, size_t SizeOfImage); +#endif diff --git a/wufuc/patternfind.c b/wufuc/patternfind.c index 6bec055..6b3b558 100644 --- a/wufuc/patternfind.c +++ b/wufuc/patternfind.c @@ -1,30 +1,31 @@ -#include #include "patternfind.h" +#include + /* 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 */ -int hexchtoint(CHAR c) { +static 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; } -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) +static size_t formathexpattern(const char *patterntext, char *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 ) formattext[result] = patterntext[i]; result++; @@ -33,21 +34,21 @@ SIZE_T formathexpattern(LPCSTR patterntext, LPSTR formattext, SIZE_T formattexts return result; } -BOOL patterntransform(LPCSTR patterntext, LPPATTERNBYTE pattern, SIZE_T *patternsize) { - SIZE_T cb = formathexpattern(patterntext, NULL, 0); - if (!cb || cb > *patternsize) +static BOOL patterntransform(const char *patterntext, LPPATTERNBYTE pattern, size_t *patternsize) { + size_t cb = formathexpattern(patterntext, NULL, 0); + if ( !cb || cb > *patternsize ) return FALSE; - LPSTR formattext = calloc(cb, sizeof(CHAR)); + char *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] == '?') + for ( size_t i = 0, j = 0, k = 0; i < cb; i++, j ^= 1, k = (i - j) >> 1 ) { + if ( formattext[i] == '?' ) pattern[k].nibble[j].wildcard = TRUE; else { pattern[k].nibble[j].wildcard = FALSE; @@ -59,21 +60,61 @@ BOOL patterntransform(LPCSTR patterntext, LPPATTERNBYTE pattern, SIZE_T *pattern return TRUE; } -LPBYTE patternfind(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR pattern) { - LPBYTE result = NULL; - SIZE_T searchpatternsize = strlen(pattern); +static void patternwritebyte(unsigned char *byte, LPPATTERNBYTE pbyte) { + unsigned char n1 = (*byte >> 4) & 0xf; + unsigned char n2 = *byte & 0xf; + if ( !pbyte->nibble[0].wildcard ) + n1 = pbyte->nibble[0].data; + + if ( !pbyte->nibble[1].wildcard ) + n2 = pbyte->nibble[1].data; + *byte = ((n1 << 4) & 0xf0) | (n2 & 0xf); +} + +static BOOL patternwrite(unsigned char *data, size_t datasize, const char *pattern) { + size_t writepatternsize = strlen(pattern); + if ( writepatternsize > datasize ) + writepatternsize = datasize; + + BOOL result = FALSE; + LPPATTERNBYTE writepattern = calloc(writepatternsize, sizeof(PATTERNBYTE)); + if ( patterntransform(pattern, writepattern, &writepatternsize) ) { + DWORD flNewProtect = PAGE_READWRITE; + DWORD flOldProtect; + + if ( result = 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); + return result; +} + +unsigned char *patternfind(unsigned char *data, size_t datasize, size_t startindex, const char *pattern) { + unsigned char *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 - 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 ( patterntransform(pattern, searchpattern, &searchpatternsize) ) { + 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 + if ( ++j == searchpatternsize ) { //everything matched result = data + (i - searchpatternsize + 1); break; } - } else if (j > 0) { //fix by Computer_Angel + } else if ( j > 0 ) { //fix by Computer_Angel i -= j; j = 0; //reset current pattern position } @@ -83,51 +124,9 @@ LPBYTE patternfind(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR patte return result; } -VOID patternwritebyte(LPBYTE byte, LPPATTERNBYTE pbyte) { - BYTE n1 = (*byte >> 4) & 0xf; - BYTE n2 = *byte & 0xf; - if (!pbyte->nibble[0].wildcard) - n1 = pbyte->nibble[0].data; - - if (!pbyte->nibble[1].wildcard) - n2 = pbyte->nibble[1].data; - *byte = ((n1 << 4) & 0xf0) | (n2 & 0xf); -} - -BOOL patternwrite(LPBYTE data, SIZE_T datasize, LPCSTR pattern) { - - SIZE_T writepatternsize = strlen(pattern); - if (writepatternsize > datasize) - writepatternsize = datasize; - - BOOL result = FALSE; - LPPATTERNBYTE writepattern = calloc(writepatternsize, sizeof(PATTERNBYTE)); - if (patterntransform(pattern, writepattern, &writepatternsize)) { - 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); - 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) +unsigned char *patternsnr(unsigned char *data, size_t datasize, size_t startindex, const char *searchpattern, const char *replacepattern) { + unsigned char *result = patternfind(data, datasize, startindex, searchpattern); + if ( !result ) return result; patternwrite(result, datasize, replacepattern); diff --git a/wufuc/patternfind.h b/wufuc/patternfind.h index 4f65890..6826b37 100644 --- a/wufuc/patternfind.h +++ b/wufuc/patternfind.h @@ -1,16 +1,16 @@ +#ifndef PATTERNFIND_H +#define PATTERNFIND_H #pragma once +#include + typedef struct _PATTERNBYTE { struct _PATTERNNIBBLE { - BYTE data; + unsigned char data; BOOL wildcard; } nibble[2]; } PATTERNBYTE, *PPATTERNBYTE, *LPPATTERNBYTE; -int hexchtoint(CHAR ch); -SIZE_T formathexpattern(LPCSTR patterntext, LPSTR formattext, SIZE_T formattextsize); -BOOL patterntransform(LPCSTR patterntext, LPPATTERNBYTE pattern, SIZE_T *patternsize); -LPBYTE patternfind(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR pattern); -VOID patternwritebyte(LPBYTE byte, LPPATTERNBYTE pbyte); -BOOL patternwrite(LPBYTE data, SIZE_T datasize, LPCSTR pattern); -LPBYTE patternsnr(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR searchpattern, LPCSTR replacepattern); +unsigned char *patternfind(unsigned char *data, size_t datasize, size_t startindex, const char *pattern); +unsigned char *patternsnr(unsigned char *data, size_t datasize, size_t startindex, const char *searchpattern, const char *replacepattern); +#endif diff --git a/wufuc/rundll32.c b/wufuc/rundll32.c index 70389e3..51c34d3 100644 --- a/wufuc/rundll32.c +++ b/wufuc/rundll32.c @@ -1,87 +1,84 @@ -#include -#include -#include -#include - +#include "service.h" #include "helpers.h" #include "logging.h" -#include "service.h" +#include +#include +#include +#include + +__declspec(dllexport) void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { HANDLE hEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("Global\\wufuc_UnloadEvent")); - if (hEvent) { + if ( hEvent ) { CloseHandle(hEvent); return; } - LPWSTR osname; - if (IsWindows7()) { - if (IsWindowsServer()) - osname = L"Windows Server 2008 R2"; + wchar_t *osname; + if ( IsWindows7() ) { + if ( IsWindowsServer() ) + osname = _T("Windows Server 2008 R2"); else - osname = L"Windows 7"; - } else if (IsWindows8Point1()) { - if (IsWindowsServer()) - osname = L"Windows Server 2012 R2"; + osname = _T("Windows 7"); + } else if ( IsWindows8Point1() ) { + if ( IsWindowsServer() ) + osname = _T("Windows Server 2012 R2"); else - osname = L"Windows 8.1"; + osname = _T("Windows 8.1"); } - trace(L"Operating System: %s %d-bit", osname, sizeof(uintptr_t) * 8); + trace(_T("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))) + size_t i = 0; + while ( i < _countof(brand) && isspace(brand[i]) ) i++; - trace(L"Processor: %S", brand + i); + trace(_T("Processor: %hs"), 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))) - result = get_svcgpid(hSCManager, lpGroupName, &dwProcessId); + BOOL result = GetServiceProcessId(hSCManager, _T("wuauserv"), &dwProcessId); + if ( !result && GetServiceGroupName(hSCManager, _T("wuauserv"), lpGroupName, _countof(lpGroupName)) ) + result = GetServiceGroupProcessId(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); - + SIZE_T size = (SIZE_T)((_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)) { + + if ( lpBaseAddress && WriteProcessMemory(hProcess, lpBaseAddress, lpLibFileName, size, NULL) ) { HANDLE hThread = CreateRemoteThread( - hProcess, - NULL, - 0, - (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), - STRINGIZE(LoadLibrary)), - lpBaseAddress, - 0, - NULL + hProcess, NULL, 0, + (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), STRINGIZE(LoadLibrary)), + lpBaseAddress, 0, NULL ); WaitForSingleObject(hThread, INFINITE); - trace(L"Injected into process: %d", dwProcessId); + trace(_T("Injected into process: %d"), dwProcessId); CloseHandle(hThread); } VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE); CloseHandle(hProcess); } +__declspec(dllexport) void CALLBACK Rundll32Unload(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, _T("Global\\wufuc_UnloadEvent")); - if (hEvent) { - trace(L"Setting unload event..."); + if ( hEvent ) { + trace(_T("Setting unload event...")); SetEvent(hEvent); CloseHandle(hEvent); } diff --git a/wufuc/service.c b/wufuc/service.c index 84a50f7..9b3e301 100644 --- a/wufuc/service.c +++ b/wufuc/service.c @@ -1,98 +1,120 @@ -#include +#include "service.h" + #include + +#include #include #include "helpers.h" #include "shellapihelper.h" #include "logging.h" -#include "service.h" -static CHAR wuauservdllA[MAX_PATH]; -static WCHAR wuauservdllW[MAX_PATH]; - -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)) - return FALSE; - - trace(L"Service \"%S\" DLL path: %S", lpServiceName, lpServiceDll); - return TRUE; -} - -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)) - return FALSE; - - trace(L"Service \"%s\" DLL path: %s", lpServiceName, lpServiceDll); - return TRUE; -} - -LPSTR get_wuauservdllA(void) { - if (!*wuauservdllA) - get_svcdllA("wuauserv", wuauservdllA, _countof(wuauservdllA)); - - return wuauservdllA; -} - -LPWSTR get_wuauservdllW(void) { - 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) - return FALSE; - - SERVICE_STATUS_PROCESS lpBuffer; - DWORD cbBytesNeeded; +static BOOL OpenServiceParametersKey(LPCWSTR lpSubKey, PHKEY phkResult) { BOOL result = FALSE; - if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&lpBuffer, sizeof(lpBuffer), &cbBytesNeeded) - && lpBuffer.dwProcessId) { + HKEY hKey, hSubKey; + if ( !RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\services", 0, KEY_READ, &hKey) + && !RegOpenKeyExW(hKey, lpSubKey, 0, KEY_READ, &hSubKey) + && !RegOpenKeyExW(hSubKey, L"Parameters", 0, KEY_READ, phkResult) ) { - *lpdwProcessId = lpBuffer.dwProcessId; -#ifdef _UNICODE - trace(L"Service \"%s\" process ID: %d", lpServiceName, *lpdwProcessId); -#else - trace(L"Service \"%S\" process ID: %d", lpServiceName, *lpdwProcessId); -#endif + result = TRUE; + } + if ( hKey ) + RegCloseKey(hKey); + + if ( hSubKey ) + RegCloseKey(hSubKey); + return result; +} + +BOOL FindServiceDllW(LPCWSTR lpServiceName, LPWSTR lpServiceDll, DWORD dwSize) { + BOOL result = FALSE; + HKEY hKey; + if ( OpenServiceParametersKey(lpServiceName, &hKey) ) { + DWORD cb = dwSize; + if ( !RegGetValueW(hKey, NULL, L"ServiceDll", RRF_RT_REG_SZ, NULL, lpServiceDll, &cb) ) { + trace(_T("Service \"%s\" DLL path: %ls"), lpServiceName, lpServiceDll); + result = TRUE; + } + RegCloseKey(hKey); + } + return result; +} + +LPWSTR GetWindowsUpdateServiceDllW(void) { + static WCHAR path[MAX_PATH]; + + if ( !path[0] ) { + if ( !FindServiceDllW(L"wuauserv", path, _countof(path)) ) + path[0] = L'\0'; + } + + return path; +} + +BOOL ApplyUpdatePack7R2ShimIfNeeded(const wchar_t *path, size_t pathsize, wchar_t *newpath, size_t newpathsize) { + wchar_t drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT]; + _wsplitpath_s(path, drive, _countof(drive), dir, _countof(dir), fname, _countof(fname), ext, _countof(ext)); + if ( !_wcsicmp(fname, L"wuaueng2") ) { + _wmakepath_s(newpath, newpathsize, drive, dir, L"wuaueng", ext); + return GetFileAttributesW(newpath) != INVALID_FILE_ATTRIBUTES; + } + return FALSE; +} + +BOOL GetServiceProcessId(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPDWORD lpdwProcessId) { + BOOL result = FALSE; + BOOL selfclose = !hSCManager; + if ( selfclose && !(hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT)) ) + return result; + + SC_HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_STATUS); + + if ( selfclose ) + CloseServiceHandle(hSCManager); + + if ( !hService ) + return result; + + SERVICE_STATUS_PROCESS buffer; + DWORD cb; + if ( QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&buffer, sizeof(buffer), &cb) + && buffer.dwProcessId ) { + + *lpdwProcessId = buffer.dwProcessId; + trace(_T("Service \"%s\" process ID: %d"), lpServiceName, *lpdwProcessId); result = TRUE; } CloseServiceHandle(hService); return result; } -BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupName, SIZE_T dwSize) { +BOOL GetServiceGroupName(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupName, SIZE_T dwSize) { + BOOL result = FALSE; + BOOL selfclose = !hSCManager; + if ( selfclose && !(hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT)) ) + return result; + TCHAR lpBinaryPathName[0x8000]; - if (!get_svcpath(hSCManager, lpServiceName, lpBinaryPathName, _countof(lpBinaryPathName))) - return FALSE; - + if ( !GetServiceCommandLine(hSCManager, lpServiceName, lpBinaryPathName, _countof(lpBinaryPathName)) ) + return result; + + if ( selfclose ) + CloseServiceHandle(hSCManager); + int numArgs; LPWSTR *argv = CommandLineToArgv(lpBinaryPathName, &numArgs); - if (numArgs < 3) - return FALSE; + if ( numArgs < 3 ) + return result; TCHAR fname[_MAX_FNAME]; _tsplitpath_s(argv[0], NULL, 0, NULL, 0, fname, _countof(fname), NULL, 0); - BOOL result = FALSE; - if (!_tcsicmp(fname, _T("svchost"))) { + if ( !_tcsicmp(fname, _T("svchost")) ) { LPWSTR *p = argv; - for (int i = 1; i < numArgs; i++) { - if (!_tcsicmp(*(p++), _T("-k")) && !_tcscpy_s(lpGroupName, dwSize, *p)) { + for ( int i = 1; i < numArgs; i++ ) { + if ( !_tcsicmp(*(p++), _T("-k")) && !_tcscpy_s(lpGroupName, dwSize, *p) ) { result = TRUE; -#ifdef _UNICODE - trace(L"Service \"%s\" group name: %s", lpServiceName, lpGroupName); -#else - trace(L"Service \"%S\" group name: %S", lpServiceName, lpGroupName); -#endif + trace(_T("Service \"%s\" group name: %s"), lpServiceName, lpGroupName); break; } } @@ -100,16 +122,22 @@ BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupNam return result; } -BOOL get_svcpath(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPathName, SIZE_T dwSize) { - HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_CONFIG); - if (!hService) - return FALSE; - - DWORD cbBytesNeeded; +BOOL GetServiceCommandLine(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPathName, SIZE_T dwSize) { BOOL result = FALSE; - if (!QueryServiceConfig(hService, NULL, 0, &cbBytesNeeded) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + if ( !hSCManager && !(hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT)) ) + return result; + + HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_CONFIG); + if ( !hService ) + return result; + + DWORD cbBytesNeeded; + 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); } @@ -117,29 +145,32 @@ BOOL get_svcpath(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPat return result; } -BOOL get_svcgpid(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwProcessId) { +BOOL GetServiceGroupProcessId(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, LPDWORD lpdwProcessId) { + BOOL result = FALSE; + BOOL selfclose = !hSCManager; + if ( selfclose && !(hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT)) ) + return result; + DWORD uBytes = 1 << 20; LPBYTE pvData = malloc(uBytes); RegGetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost"), lpServiceGroupName, RRF_RT_REG_MULTI_SZ, NULL, pvData, &uBytes); - BOOL result = FALSE; - for (LPTSTR p = (LPTSTR)pvData; *p; p += _tcslen(p) + 1) { + for ( LPTSTR p = (LPTSTR)pvData; *p; p += _tcslen(p) + 1 ) { DWORD dwProcessId; TCHAR group[256]; - if (get_svcpid(hSCManager, p, &dwProcessId) - && (get_svcgname(hSCManager, p, group, _countof(group)) && !_tcsicmp(group, lpServiceGroupName))) { + if ( GetServiceProcessId(hSCManager, p, &dwProcessId) + && (GetServiceGroupName(hSCManager, p, group, _countof(group)) + && !_tcsicmp(group, lpServiceGroupName)) ) { *lpdwProcessId = dwProcessId; result = TRUE; -#ifdef _UNICODE - trace(L"Service group \"%s\" process ID: %d", lpServiceGroupName, *lpdwProcessId); -#else - trace(L"Service group \"%S\" process ID: %d", lpServiceGroupName, *lpdwProcessId); -#endif + trace(_T("Service group \"%s\" process ID: %d"), lpServiceGroupName, *lpdwProcessId); break; } } free(pvData); + if ( selfclose ) + CloseServiceHandle(hSCManager); return result; } diff --git a/wufuc/service.h b/wufuc/service.h index df3f310..9a6f2c5 100644 --- a/wufuc/service.h +++ b/wufuc/service.h @@ -1,18 +1,14 @@ +#ifndef SERVICE_H +#define SERVICE_H #pragma once -BOOL get_svcdllA(LPCSTR lpServiceName, LPSTR lpServiceDll, DWORD dwSize); -BOOL get_svcdllW(LPCWSTR lpServiceName, LPWSTR lpServiceDll, DWORD dwSize); -BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessId); -BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupName, SIZE_T dwSize); -BOOL get_svcpath(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPathName, SIZE_T dwSize); -BOOL get_svcgpid(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwProcessId); -LPSTR get_wuauservdllA(void); -LPWSTR get_wuauservdllW(void); +#include -#ifdef UNICODE -#define get_svcdll get_svcdllW -#define get_wuauservdll get_wuauservdllW -#else -#define get_svcdll get_svcdllA -#define get_wuauservdll get_wuauservdllA +BOOL FindServiceDllW(LPCWSTR lpServiceName, LPWSTR lpServiceDll, DWORD nCount); +LPWSTR GetWindowsUpdateServiceDllW(void); +BOOL ApplyUpdatePack7R2ShimIfNeeded(const wchar_t *path, size_t pathsize, wchar_t *newpath, size_t newpathsize); +BOOL GetServiceProcessId(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPDWORD lpdwProcessId); +BOOL GetServiceGroupName(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupName, SIZE_T dwSize); +BOOL GetServiceCommandLine(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPathName, SIZE_T dwSize); +BOOL GetServiceGroupProcessId(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, LPDWORD lpdwProcessId); #endif diff --git a/wufuc/shellapihelper.h b/wufuc/shellapihelper.h index c5fec9a..2c1f7cd 100644 --- a/wufuc/shellapihelper.h +++ b/wufuc/shellapihelper.h @@ -1,7 +1,10 @@ +#ifndef SHELLAPIHELPER_H +#define SHELLAPIHELPER_H #pragma once #ifdef UNICODE #define CommandLineToArgv CommandLineToArgvW #else #define CommandLineToArgv CommandLineToArgvA -#endif // !UNICODE +#endif +#endif diff --git a/wufuc/wufuc.vcxproj b/wufuc/wufuc.vcxproj index dce8c08..57e6622 100644 --- a/wufuc/wufuc.vcxproj +++ b/wufuc/wufuc.vcxproj @@ -107,7 +107,6 @@ Windows - exports.def %(AdditionalDependencies) @@ -120,7 +119,6 @@ Windows - exports.def %(AdditionalDependencies) @@ -140,7 +138,6 @@ Windows true true - exports.def false %(AdditionalDependencies) @@ -165,7 +162,6 @@ Windows true true - exports.def false %(AdditionalDependencies) @@ -175,22 +171,25 @@ + + + - - - + + + diff --git a/wufuc/wufuc.vcxproj.filters b/wufuc/wufuc.vcxproj.filters new file mode 100644 index 0000000..e1388f1 --- /dev/null +++ b/wufuc/wufuc.vcxproj.filters @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/wufuc_aihelper/aihelper.c b/wufuc_aihelper/aihelper.c index d098e0e..0191667 100644 --- a/wufuc_aihelper/aihelper.c +++ b/wufuc_aihelper/aihelper.c @@ -2,9 +2,10 @@ #include #include +__declspec(dllexport) UINT __stdcall AIHelper_SetUnloadEvent(MSIHANDLE hInstall) { HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, _T("Global\\wufuc_UnloadEvent")); - if (hEvent) { + if ( hEvent ) { SetEvent(hEvent); CloseHandle(hEvent); } diff --git a/wufuc_aihelper/dllmain.c b/wufuc_aihelper/dllmain.c index b8eb2f6..b72b423 100644 --- a/wufuc_aihelper/dllmain.c +++ b/wufuc_aihelper/dllmain.c @@ -1,7 +1,7 @@ #include BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { - switch (ul_reason_for_call) { + switch ( ul_reason_for_call ) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: diff --git a/wufuc_aihelper/exports.def b/wufuc_aihelper/exports.def deleted file mode 100644 index f93cca8..0000000 --- a/wufuc_aihelper/exports.def +++ /dev/null @@ -1,2 +0,0 @@ -EXPORTS - AIHelper_SetUnloadEvent diff --git a/wufuc_aihelper/wufuc_aihelper.vcxproj b/wufuc_aihelper/wufuc_aihelper.vcxproj index 7d68274..d763f7a 100644 --- a/wufuc_aihelper/wufuc_aihelper.vcxproj +++ b/wufuc_aihelper/wufuc_aihelper.vcxproj @@ -111,7 +111,6 @@ true Msi.lib;%(AdditionalDependencies) false - exports.def @@ -123,7 +122,6 @@ Windows - exports.def @@ -135,7 +133,6 @@ Windows - exports.def @@ -153,16 +150,12 @@ true Msi.lib;%(AdditionalDependencies) false - exports.def - - -