diff --git a/src/wufuc/callbacks.c b/src/wufuc/callbacks.c index 791d787..0230edc 100644 --- a/src/wufuc/callbacks.c +++ b/src/wufuc/callbacks.c @@ -12,14 +12,14 @@ #include #include -VOID CALLBACK cb_service_notify(PSERVICE_NOTIFYW pNotifyBuffer) +VOID CALLBACK service_notify_callback(PSERVICE_NOTIFYW pNotifyBuffer) { switch ( pNotifyBuffer->dwNotificationStatus ) { case ERROR_SUCCESS: if ( pNotifyBuffer->ServiceStatus.dwProcessId ) wufuc_inject( pNotifyBuffer->ServiceStatus.dwProcessId, - (LPTHREAD_START_ROUTINE)cb_start, + (LPTHREAD_START_ROUTINE)thread_start_callback, (ptrlist_t *)pNotifyBuffer->pContext); break; case ERROR_SERVICE_MARKED_FOR_DELETE: @@ -30,7 +30,7 @@ VOID CALLBACK cb_service_notify(PSERVICE_NOTIFYW pNotifyBuffer) LocalFree((HLOCAL)pNotifyBuffer->pszServiceNames); } -DWORD WINAPI cb_start(HANDLE *pParam) +DWORD WINAPI thread_start_callback(HANDLE *pParam) { HANDLE handles[2]; HANDLE hCrashMutex; @@ -41,7 +41,7 @@ DWORD WINAPI cb_start(HANDLE *pParam) LPQUERY_SERVICE_CONFIGW pServiceConfig; DWORD dwServiceType; const wchar_t szKernel32Dll[] = L"kernel32.dll"; - const wchar_t szKernelBaseDll[] = L"KernelBase.dll"; + const wchar_t szKernelBaseDll[] = L"kernelbase.dll"; const wchar_t *pszModule; MH_STATUS status; int tmp; @@ -63,7 +63,7 @@ DWORD WINAPI cb_start(HANDLE *pParam) // acquire child mutex, this should be immediate. if ( WaitForSingleObject(hCrashMutex, 5000) != WAIT_OBJECT_0 ) { - log_error(L"Failed to acquire child mutex within five seconds. (%p)", hCrashMutex); + log_error(L"Failed to acquire crash mutex within five seconds. (%p)", hCrashMutex); goto close_handles; } SetEvent(hProceedEvent); @@ -112,7 +112,7 @@ DWORD WINAPI cb_start(HANDLE *pParam) } else log_error(L"Failed to create RegQueryValueExW hook! (Status=%hs)", MH_StatusToString(status)); } // query the ServiceDll path after applying our compat hook so that it - // is correct + // is consistent str = (wchar_t *)reg_query_value_alloc(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\services\\wuauserv\\Parameters", L"ServiceDll", NULL, NULL); @@ -142,7 +142,7 @@ abort_hook: || GetModuleHandleExW(0, PathFindFileNameW(g_pszWUServiceDll), &hModule) ) { // hook IsDeviceServiceable if wuaueng.dll is already loaded - wufuc_hook(hModule); + wufuc_patch(hModule); FreeLibrary(hModule); } // wait for unload event or the main mutex to be released or abandoned, diff --git a/src/wufuc/callbacks.h b/src/wufuc/callbacks.h index 63e8ad0..973f943 100644 --- a/src/wufuc/callbacks.h +++ b/src/wufuc/callbacks.h @@ -1,4 +1,4 @@ #pragma once -VOID CALLBACK cb_service_notify(PSERVICE_NOTIFYW pNotifyBuffer); -DWORD WINAPI cb_start(HANDLE *pParam); +VOID CALLBACK service_notify_callback(PSERVICE_NOTIFYW pNotifyBuffer); +DWORD WINAPI thread_start_callback(HANDLE *pParam); diff --git a/src/wufuc/hooks.c b/src/wufuc/hooks.c index 8c3da22..b036b35 100644 --- a/src/wufuc/hooks.c +++ b/src/wufuc/hooks.c @@ -9,7 +9,6 @@ wchar_t *g_pszWUServiceDll; LPFN_REGQUERYVALUEEXW g_pfnRegQueryValueExW; LPFN_LOADLIBRARYEXW g_pfnLoadLibraryExW; -LPFN_ISDEVICESERVICEABLE g_pfnIsDeviceServiceable; LSTATUS WINAPI RegQueryValueExW_hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) { @@ -88,13 +87,7 @@ HMODULE WINAPI LoadLibraryExW_hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFla && (!_wcsicmp(lpFileName, g_pszWUServiceDll) || !_wcsicmp(lpFileName, PathFindFileNameW(g_pszWUServiceDll))) ) { - wufuc_hook(result); + wufuc_patch(result); } return result; } - -BOOL WINAPI IsDeviceServiceable_hook(void) -{ - log_debug(L"Entered stub function."); - return TRUE; -} diff --git a/src/wufuc/hooks.h b/src/wufuc/hooks.h index 3fb53c3..7161e30 100644 --- a/src/wufuc/hooks.h +++ b/src/wufuc/hooks.h @@ -3,18 +3,14 @@ typedef LSTATUS(WINAPI *LPFN_REGQUERYVALUEEXW)(HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD); typedef HMODULE(WINAPI *LPFN_LOADLIBRARYEXW)(LPCWSTR, HANDLE, DWORD); -typedef BOOL(WINAPI *LPFN_ISDEVICESERVICEABLE)(void); extern wchar_t *g_pszWUServiceDll; extern LPFN_REGQUERYVALUEEXW g_pfnRegQueryValueExW; extern LPFN_LOADLIBRARYEXW g_pfnLoadLibraryExW; -extern LPFN_ISDEVICESERVICEABLE g_pfnIsDeviceServiceable; extern PVOID g_ptRegQueryValueExW; extern PVOID g_ptLoadLibraryExW; -extern PVOID g_ptIsDeviceServiceable; LSTATUS WINAPI RegQueryValueExW_hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData); HMODULE WINAPI LoadLibraryExW_hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags); -BOOL WINAPI IsDeviceServiceable_hook(void); diff --git a/src/wufuc/modulehelper.c b/src/wufuc/modulehelper.c index 4655e95..c48df35 100644 --- a/src/wufuc/modulehelper.c +++ b/src/wufuc/modulehelper.c @@ -49,7 +49,7 @@ bool mod_inject_and_begin_thread( hThread = CreateRemoteThread(hProcess, NULL, 0, - (LPTHREAD_START_ROUTINE)RtlOffsetToPointer(hRemoteModule, offset), + OffsetToPointer(hRemoteModule, offset), pBaseAddress, 0, NULL); diff --git a/src/wufuc/ptrlist.c b/src/wufuc/ptrlist.c index 5ec739e..09bb85a 100644 --- a/src/wufuc/ptrlist.c +++ b/src/wufuc/ptrlist.c @@ -46,7 +46,7 @@ bool ptrlist_create(ptrlist_t *list, size_t capacity, size_t maxCapacity) if ( tmp ) { ZeroMemory(tmp, vsize + tsize); list->values = tmp; - list->tags = (uint32_t *)RtlOffsetToPointer(tmp, vsize); + list->tags = OffsetToPointer(tmp, vsize); list->capacity = c; list->maxCapacity = maxCapacity; list->count = 0; @@ -129,7 +129,7 @@ bool ptrlist_add(ptrlist_t *list, void *value, uint32_t tag) ZeroMemory(tmp1, vsize); - tmp2 = (uint32_t *)RtlOffsetToPointer(tmp1, vsize); + tmp2 = OffsetToPointer(tmp1, vsize); ZeroMemory(tmp2, tsize); if ( memmove_s(tmp1, vsize, list->values, list->count * (sizeof *list->values)) diff --git a/src/wufuc/resourcehelper.c b/src/wufuc/resourcehelper.c new file mode 100644 index 0000000..537b733 --- /dev/null +++ b/src/wufuc/resourcehelper.c @@ -0,0 +1,84 @@ +#include "stdafx.h" +#include "resourcehelper.h" +#include "log.h" + +void *res_get_version_info(HMODULE hModule) +{ + HRSRC hResInfo; + DWORD dwSize; + HGLOBAL hResData; + LPVOID pRes; + void *result; + + hResInfo = FindResourceW(hModule, + MAKEINTRESOURCEW(VS_VERSION_INFO), + MAKEINTRESOURCEW(RT_VERSION)); + if ( !hResInfo ) return NULL; + + dwSize = SizeofResource(hModule, hResInfo); + if ( !dwSize ) return NULL; + + hResData = LoadResource(hModule, hResInfo); + if ( !hResData ) return NULL; + + pRes = LockResource(hResData); + if ( !pRes ) return NULL; + + result = malloc(dwSize); + if ( !result ) return NULL; + + if ( memcpy_s(result, dwSize, pRes, dwSize) ) { + free(result); + result = NULL; + } + return result; +} + +wchar_t *res_query_string_file_info(const void *pBlock, + LANGANDCODEPAGE lcp, + const wchar_t *pszStringName, + size_t *pcchLength) +{ + const wchar_t fmt[] = L"\\StringFileInfo\\%04x%04x\\%ls"; + int ret; + int count; + wchar_t *pszSubBlock; + wchar_t *result = NULL; + UINT uLen; + + ret = _scwprintf(fmt, lcp.wLanguage, lcp.wCodePage, pszStringName); + if ( ret == -1 ) return NULL; + + count = ret + 1; + pszSubBlock = calloc(count, sizeof *pszSubBlock); + if ( !pszSubBlock ) return NULL; + + ret = swprintf_s(pszSubBlock, count, fmt, lcp.wLanguage, lcp.wCodePage, pszStringName); + if ( ret != -1 + && VerQueryValueW(pBlock, pszSubBlock, &(LPVOID)result, &uLen) + && pcchLength ) + *pcchLength = uLen; + + free(pszSubBlock); + return result; +} + +PLANGANDCODEPAGE res_query_var_file_info(const void *pBlock, size_t *pCount) +{ + PLANGANDCODEPAGE result = NULL; + UINT uLen; + + if ( VerQueryValueW(pBlock, L"\\VarFileInfo\\Translation", &(LPVOID)result, &uLen) ) + *pCount = uLen / (sizeof *result); + return result; +} + +VS_FIXEDFILEINFO *res_query_fixed_file_info(const void *pBlock) +{ + VS_FIXEDFILEINFO *result; + UINT uLen; + + if ( VerQueryValueW(pBlock, L"\\", &(LPVOID)result, &uLen) ) + return result; + return NULL; +} diff --git a/src/wufuc/resourcehelper.h b/src/wufuc/resourcehelper.h new file mode 100644 index 0000000..8710339 --- /dev/null +++ b/src/wufuc/resourcehelper.h @@ -0,0 +1,18 @@ +#pragma once + +typedef struct +{ + WORD wLanguage; + WORD wCodePage; +} LANGANDCODEPAGE, *PLANGANDCODEPAGE; + +void *res_get_version_info(HMODULE hModule); + +wchar_t *res_query_string_file_info(const void *pBlock, + LANGANDCODEPAGE lcp, + const wchar_t *pszStringName, + size_t *pcchLength); + +PLANGANDCODEPAGE res_query_var_file_info(const void *pBlock, size_t *pcbData); + +VS_FIXEDFILEINFO *res_query_fixed_file_info(const void *pBlock); diff --git a/src/wufuc/rundll32.c b/src/wufuc/rundll32.c index b304ec3..ebd7596 100644 --- a/src/wufuc/rundll32.c +++ b/src/wufuc/rundll32.c @@ -59,11 +59,11 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd, dwProcessId = svc_heuristic_process_id(hSCM, hService); if ( dwProcessId ) - wufuc_inject(dwProcessId, (LPTHREAD_START_ROUTINE)cb_start, &list); + wufuc_inject(dwProcessId, (LPTHREAD_START_ROUTINE)thread_start_callback, &list); } ZeroMemory(&NotifyBuffer, sizeof NotifyBuffer); NotifyBuffer.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE; - NotifyBuffer.pfnNotifyCallback = (PFN_SC_NOTIFY_CALLBACK)cb_service_notify; + NotifyBuffer.pfnNotifyCallback = (PFN_SC_NOTIFY_CALLBACK)service_notify_callback; NotifyBuffer.pContext = (PVOID)&list; while ( !Unloading && !Lagging ) { e = NotifyServiceStatusChangeW(hService, diff --git a/src/wufuc/stdafx.h b/src/wufuc/stdafx.h index 51cad5d..4052852 100644 --- a/src/wufuc/stdafx.h +++ b/src/wufuc/stdafx.h @@ -29,4 +29,4 @@ extern IMAGE_DOS_HEADER __ImageBase; #define PIMAGEBASE ((HMODULE)&__ImageBase) - +#define OffsetToPointer(Base, Offset) ((void *)(((uint8_t *)(Base)) + ((ptrdiff_t)(Offset)))) diff --git a/src/wufuc/versionhelper.c b/src/wufuc/versionhelper.c index 4a2c2a8..86fe01e 100644 --- a/src/wufuc/versionhelper.c +++ b/src/wufuc/versionhelper.c @@ -14,81 +14,6 @@ int ver_compare_product_version(VS_FIXEDFILEINFO *pffi, WORD wMajor, WORD wMinor return 0; } -bool ver_get_version_info_from_hmodule(HMODULE hModule, const wchar_t *pszSubBlock, LPVOID pData, PUINT pcbData) -{ - bool result = false; - UINT cbData; - HRSRC hResInfo; - DWORD dwSize; - HGLOBAL hResData; - LPVOID pRes; - LPVOID pCopy; - LPVOID pBuffer; - UINT uLen; - - if ( !pcbData ) return result; - cbData = *pcbData; - - hResInfo = FindResourceW(hModule, - MAKEINTRESOURCEW(VS_VERSION_INFO), - RT_VERSION); - if ( !hResInfo ) return result; - - dwSize = SizeofResource(hModule, hResInfo); - if ( !dwSize ) return result; - - hResData = LoadResource(hModule, hResInfo); - if ( !hResData ) return result; - - pRes = LockResource(hResData); - if ( !pRes ) return result; - - pCopy = malloc(dwSize); - if ( !pCopy ) return result; - - if ( memcpy_s(pCopy, dwSize, pRes, dwSize) - || !VerQueryValueW(pCopy, pszSubBlock, &pBuffer, &uLen) ) - goto cleanup; - - if ( !_wcsnicmp(pszSubBlock, L"\\StringFileInfo\\", 16) ) - *pcbData = uLen * sizeof(wchar_t); - else - *pcbData = uLen; - - if ( !pData ) { - result = true; - goto cleanup; - } - if ( cbData < *pcbData - || memcpy_s(pData, cbData, pBuffer, *pcbData) ) - goto cleanup; - - result = true; -cleanup: - free(pCopy); - return result; -} - -LPVOID ver_get_version_info_from_hmodule_alloc(HMODULE hModule, const wchar_t *pszSubBlock, PUINT pcbData) -{ - UINT cbData = 0; - LPVOID result = NULL; - - if ( !ver_get_version_info_from_hmodule(hModule, pszSubBlock, NULL, &cbData) ) - return result; - - result = malloc(cbData); - if ( !result ) return result; - - if ( ver_get_version_info_from_hmodule(hModule, pszSubBlock, result, &cbData) ) { - *pcbData = cbData; - } else { - free(result); - result = NULL; - } - return result; -} - bool ver_verify_version_info(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) { DWORDLONG dwlConditionMask = 0; diff --git a/src/wufuc/versionhelper.h b/src/wufuc/versionhelper.h index c9a534a..11b1226 100644 --- a/src/wufuc/versionhelper.h +++ b/src/wufuc/versionhelper.h @@ -1,6 +1,4 @@ #pragma once int ver_compare_product_version(VS_FIXEDFILEINFO *pffi, WORD wMajor, WORD wMinor, WORD wBuild, WORD wRev); -bool ver_get_version_info_from_hmodule(HMODULE hModule, const wchar_t *pszSubBlock, LPVOID pData, PUINT pcbData); -LPVOID ver_get_version_info_from_hmodule_alloc(HMODULE hModule, const wchar_t *pszSubBlock, PUINT pcbData); bool ver_verify_version_info(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor); diff --git a/src/wufuc/wufuc.c b/src/wufuc/wufuc.c index 1cdf2cd..b54d1f4 100644 --- a/src/wufuc/wufuc.c +++ b/src/wufuc/wufuc.c @@ -6,13 +6,14 @@ #include "modulehelper.h" #include "mutexhelper.h" #include "patternfind.h" +#include "resourcehelper.h" #include "versionhelper.h" #include HANDLE g_hMainMutex; -bool close_remote_handle(HANDLE hProcess, HANDLE hObject) +static bool close_remote_handle(HANDLE hProcess, HANDLE hObject) { bool result = false; DWORD ExitCode; @@ -99,96 +100,119 @@ close_mutex: return result; } -bool wufuc_hook(HMODULE hModule) +static int wufuc_get_patch_info(VS_FIXEDFILEINFO *pffi, PATCHINFO *ppi) { - bool result = false; - PLANGANDCODEPAGE ptl; - HANDLE hProcess; - UINT cbtl; - wchar_t SubBlock[38]; +#ifdef _WIN64 + if ( ver_verify_version_info(6, 1, 0) && ver_compare_product_version(pffi, 7, 6, 7601, 23714) != -1 + || ver_verify_version_info(6, 3, 0) && ver_compare_product_version(pffi, 7, 9, 9600, 18621) != -1 ) { + + ppi->pattern = "FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????"; + ppi->off1 = 0xa; + ppi->off2 = 0x12; + return 0; + } +#elif _WIN32 + if ( ver_verify_version_info(6, 1, 0) + && ver_compare_product_version(pffi, 7, 6, 7601, 23714) != -1 ) { + + ppi->pattern = "833D????????00 743E E8???????? A3????????"; + ppi->off1 = 0x2; + ppi->off2 = 0xf; + return 0; + } else if ( ver_verify_version_info(6, 3, 0) + && ver_compare_product_version(pffi, 7, 9, 9600, 18621) != -1 ) { + + ppi->pattern = "8BFF 51 833D????????00 7507 A1????????"; + ppi->off1 = 0x5; + ppi->off2 = 0xd; + return 0; + } +#endif + return 1; +} + +static int wufuc_get_patch_ptrs(const PATCHINFO *ppi, uintptr_t pfn, PBOOL *ppval1, PBOOL *ppval2) +{ +#ifdef _WIN64 + *ppval1 = (PBOOL)(pfn + ppi->off1 + sizeof(uint32_t) + *(uint32_t *)(pfn + ppi->off1)); + *ppval2 = (PBOOL)(pfn + ppi->off2 + sizeof(uint32_t) + *(uint32_t *)(pfn + ppi->off2)); + return 0; +#elif _WIN32 + *ppval1 = (PBOOL)(*(uintptr_t *)(pfn + ppi->off1)); + *ppval2 = (PBOOL)(*(uintptr_t *)(pfn + ppi->off2)); + return 0; +#else + return 1; +#endif +} + +void wufuc_patch(HMODULE hModule) +{ + void *pBlock; + PATCHINFO pi; + size_t count; + PLANGANDCODEPAGE plcp; wchar_t *pInternalName; - UINT cbInternalName; VS_FIXEDFILEINFO *pffi; - UINT cbffi; - bool tmp; MODULEINFO modinfo; size_t offset; - LPVOID pTarget = NULL; - MH_STATUS status; + void *pfn; + DWORD fOldProtect; + PBOOL pval1; + PBOOL pval2; - ptl = ver_get_version_info_from_hmodule_alloc(hModule, L"\\VarFileInfo\\Translation", &cbtl); - if ( !ptl ) { - log_error(L"ver_get_version_info_from_hmodule_alloc failed!"); - return false; + pBlock = res_get_version_info(hModule); + if ( !pBlock ) goto free_pBlock; + + plcp = res_query_var_file_info(pBlock, &count); + if ( !plcp ) goto free_pBlock; + + for ( size_t i = 0; i < count; i++ ) { + pInternalName = res_query_string_file_info(pBlock, plcp[i], L"InternalName", NULL); + if ( pInternalName && !_wcsicmp(pInternalName, L"wuaueng.dll") ) + goto cont_patch; } - hProcess = GetCurrentProcess(); + goto free_pBlock; - for ( size_t i = 0, count = (cbtl / sizeof *ptl); i < count; i++ ) { - if ( swprintf_s(SubBlock, - _countof(SubBlock), - L"\\StringFileInfo\\%04x%04x\\InternalName", - ptl[i].wLanguage, - ptl[i].wCodePage) == -1 ) - continue; +cont_patch: + pffi = res_query_fixed_file_info(pBlock); + if ( !pffi ) goto free_pBlock; - pInternalName = ver_get_version_info_from_hmodule_alloc(hModule, SubBlock, &cbInternalName); - if ( !pInternalName ) { - log_error(L"ver_get_version_info_from_hmodule_alloc failed!"); - continue; - } - // identify wuaueng.dll by its resource data - if ( _wcsicmp(pInternalName, L"wuaueng.dll") ) { - log_error(L"Module internal name does not match! (InternalName=%ls)", pInternalName); - goto free_iname; - } - pffi = ver_get_version_info_from_hmodule_alloc(hModule, L"\\", &cbffi); - if ( !pffi ) { - log_error(L"ver_get_version_info_from_hmodule_alloc failed!"); - break; - } - // assure wuaueng.dll version is supported - tmp = ((ver_verify_version_info(6, 1, 0) && ver_compare_product_version(pffi, 7, 6, 7601, 23714) != -1) - || (ver_verify_version_info(6, 3, 0) && ver_compare_product_version(pffi, 7, 9, 9600, 18621) != -1)); - - log_info(L"%ls Windows Update Agent version: %hu.%hu.%hu.%hu", - tmp ? L"Supported" : L"Unsupported", + if ( wufuc_get_patch_info(pffi, &pi) ) { + log_warning(L"Unsupported Windows Update Agent version: %hu.%hu.%hu.%hu", HIWORD(pffi->dwProductVersionMS), LOWORD(pffi->dwProductVersionMS), HIWORD(pffi->dwProductVersionLS), LOWORD(pffi->dwProductVersionLS)); - free(pffi); - if ( !tmp ) break; - - if ( !GetModuleInformation(hProcess, hModule, &modinfo, sizeof modinfo) ) { - log_error(L"GetModuleInformation failed! (hModule=%p, GLE=%lu)", - hModule, GetLastError()); - break; - } - offset = patternfind(modinfo.lpBaseOfDll, modinfo.SizeOfImage, -#ifdef _WIN64 - "FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????" -#else - ver_verify_version_info(6, 1, 0) - ? "833D????????00 743E E8???????? A3????????" - : "8BFF 51 833D????????00 7507 A1????????" -#endif - ); - if ( offset != -1 ) { - pTarget = (LPVOID)RtlOffsetToPointer(modinfo.lpBaseOfDll, offset); - log_info(L"Matched IsDeviceServiceable function! (Offset=%IX, Address=%p)", offset, pTarget); - - status = MH_CreateHook(pTarget, IsDeviceServiceable_hook, NULL); - if ( status == MH_OK ) { - status = MH_EnableHook(pTarget); - if ( status == MH_OK ) - log_info(L"Hooked IsDeviceServiceable! (Address=%p)", pTarget); - else log_error(L"Failed to enable IsDeviceServiceable hook! (Status=%hs)", MH_StatusToString(status)); - } else log_error(L"Failed to create IsDeviceServiceable hook! (Status=%hs)", MH_StatusToString(status)); - } else log_info(L"Couldn't match IsDeviceServiceable function! (Already patched?)"); -free_iname: - free(pInternalName); - break; + goto free_pBlock; } - free(ptl); - return result; + log_info(L"Supported Windows Update Agent version: %hu.%hu.%hu.%hu", + HIWORD(pffi->dwProductVersionMS), + LOWORD(pffi->dwProductVersionMS), + HIWORD(pffi->dwProductVersionLS), + LOWORD(pffi->dwProductVersionLS)); + + if ( GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof modinfo) ) { + offset = patternfind(modinfo.lpBaseOfDll, modinfo.SizeOfImage, pi.pattern); + if ( offset != -1 ) { + pfn = OffsetToPointer(modinfo.lpBaseOfDll, offset); + log_info(L"Matched %ls!IsDeviceServiceable function! (Offset=%IX, Address=%p)", + pInternalName, offset, pfn); + + if ( !wufuc_get_patch_ptrs(&pi, (uintptr_t)pfn, &pval1, &pval2) ) { + if ( *pval1 && VirtualProtect(pval1, sizeof *pval1, PAGE_READWRITE, &fOldProtect) ) { + *pval1 = FALSE; + VirtualProtect(pval1, sizeof *pval1, fOldProtect, &fOldProtect); + log_info(L"Patched variable! (Address=%p)", pval1); + } + if ( !*pval2 && VirtualProtect(pval2, sizeof *pval2, PAGE_READWRITE, &fOldProtect) ) { + *pval2 = TRUE; + VirtualProtect(pval2, sizeof *pval2, fOldProtect, &fOldProtect); + log_info(L"Patched variable! (Address=%p)", pval2); + } + } + } else log_info(L"Couldn't match IsDeviceServiceable function!"); + } else log_error(L"GetModuleInformation failed! (hModule=%p, GLE=%lu)", hModule, GetLastError()); +free_pBlock: + free(pBlock); } diff --git a/src/wufuc/wufuc.h b/src/wufuc/wufuc.h index 5ecfa76..8c51863 100644 --- a/src/wufuc/wufuc.h +++ b/src/wufuc/wufuc.h @@ -1,10 +1,11 @@ #pragma once -typedef struct +typedef struct _PATCHINFO { - WORD wLanguage; - WORD wCodePage; -} LANGANDCODEPAGE, *PLANGANDCODEPAGE; + const char *pattern; + size_t off1; + size_t off2; +} PATCHINFO; #define SVCHOST_CRASH_THRESHOLD 3 extern HANDLE g_hMainMutex; @@ -12,4 +13,4 @@ extern HANDLE g_hMainMutex; bool wufuc_inject(DWORD dwProcessId, LPTHREAD_START_ROUTINE pStartAddress, ptrlist_t *list); -bool wufuc_hook(HMODULE hModule); +void wufuc_patch(HMODULE hModule); diff --git a/src/wufuc/wufuc.vcxproj b/src/wufuc/wufuc.vcxproj index 8a3e685..0b0095e 100644 --- a/src/wufuc/wufuc.vcxproj +++ b/src/wufuc/wufuc.vcxproj @@ -26,6 +26,7 @@ + @@ -41,6 +42,7 @@ + diff --git a/src/wufuc/wufuc.vcxproj.filters b/src/wufuc/wufuc.vcxproj.filters index 8d6feb2..6e347bc 100644 --- a/src/wufuc/wufuc.vcxproj.filters +++ b/src/wufuc/wufuc.vcxproj.filters @@ -57,6 +57,9 @@ Header Files + + Header Files + @@ -104,6 +107,9 @@ Source Files + + Source Files +