finish implementing updatepack7 fix (shared process only)
This commit is contained in:
@@ -7,11 +7,15 @@
|
|||||||
|
|
||||||
VOID CALLBACK ServiceNotifyCallback(PSERVICE_NOTIFYW pNotifyBuffer)
|
VOID CALLBACK ServiceNotifyCallback(PSERVICE_NOTIFYW pNotifyBuffer)
|
||||||
{
|
{
|
||||||
trace(L"Enter service notify callback. (NotifyStatus=%ld ServiceStatus=%ld)", pNotifyBuffer->dwNotificationStatus, pNotifyBuffer->ServiceStatus);
|
trace(L"Enter service notify callback. (NotifyStatus=%ld ServiceStatus=%ld)",
|
||||||
|
pNotifyBuffer->dwNotificationStatus, pNotifyBuffer->ServiceStatus);
|
||||||
|
|
||||||
switch ( pNotifyBuffer->dwNotificationStatus ) {
|
switch ( pNotifyBuffer->dwNotificationStatus ) {
|
||||||
case ERROR_SUCCESS:
|
case ERROR_SUCCESS:
|
||||||
if ( pNotifyBuffer->ServiceStatus.dwProcessId )
|
if ( pNotifyBuffer->ServiceStatus.dwProcessId )
|
||||||
wufuc_InjectLibrary(pNotifyBuffer->ServiceStatus.dwProcessId, (ContextHandles *)pNotifyBuffer->pContext);
|
wufuc_InjectLibrary(
|
||||||
|
pNotifyBuffer->ServiceStatus.dwProcessId,
|
||||||
|
(ContextHandles *)pNotifyBuffer->pContext);
|
||||||
break;
|
break;
|
||||||
case ERROR_SERVICE_MARKED_FOR_DELETE:
|
case ERROR_SERVICE_MARKED_FOR_DELETE:
|
||||||
SetEvent(((ContextHandles *)pNotifyBuffer->pContext)->hUnloadEvent);
|
SetEvent(((ContextHandles *)pNotifyBuffer->pContext)->hUnloadEvent);
|
||||||
@@ -25,8 +29,11 @@ DWORD WINAPI ThreadStartCallback(LPVOID pParam)
|
|||||||
{
|
{
|
||||||
ContextHandles ctx;
|
ContextHandles ctx;
|
||||||
SC_HANDLE hSCM;
|
SC_HANDLE hSCM;
|
||||||
|
SC_HANDLE hService;
|
||||||
DWORD dwProcessId;
|
DWORD dwProcessId;
|
||||||
DWORD cbData;
|
LPQUERY_SERVICE_CONFIGW pServiceConfig;
|
||||||
|
DWORD dwServiceType;
|
||||||
|
LPWSTR str;
|
||||||
HMODULE hModule;
|
HMODULE hModule;
|
||||||
DWORD result;
|
DWORD result;
|
||||||
|
|
||||||
@@ -42,7 +49,7 @@ DWORD WINAPI ThreadStartCallback(LPVOID pParam)
|
|||||||
|
|
||||||
// acquire child mutex, should be immediate.
|
// acquire child mutex, should be immediate.
|
||||||
if ( WaitForSingleObject(ctx.hChildMutex, 5000) != WAIT_OBJECT_0 ) {
|
if ( WaitForSingleObject(ctx.hChildMutex, 5000) != WAIT_OBJECT_0 ) {
|
||||||
trace(L"Failed to acquire aux mutex within five seconds. (%p)", ctx.hChildMutex);
|
trace(L"Failed to acquire child mutex within five seconds. (%p)", ctx.hChildMutex);
|
||||||
goto close_handles;
|
goto close_handles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,31 +59,51 @@ DWORD WINAPI ThreadStartCallback(LPVOID pParam)
|
|||||||
goto release;
|
goto release;
|
||||||
}
|
}
|
||||||
|
|
||||||
dwProcessId = HeuristicServiceProcessIdByName(hSCM, L"wuauserv");
|
hService = OpenServiceW(hSCM, L"wuauserv", SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG);
|
||||||
|
dwProcessId = HeuristicServiceProcessId(hSCM, hService);
|
||||||
|
pServiceConfig = QueryServiceConfigAlloc(hSCM, hService, NULL);
|
||||||
|
dwServiceType = pServiceConfig->dwServiceType;
|
||||||
|
free(pServiceConfig);
|
||||||
|
CloseServiceHandle(hService);
|
||||||
CloseServiceHandle(hSCM);
|
CloseServiceHandle(hSCM);
|
||||||
|
|
||||||
if ( dwProcessId != GetCurrentProcessId() ) {
|
if ( dwProcessId != GetCurrentProcessId() ) {
|
||||||
trace(L"Injected into wrong process!", GetCurrentProcessId(), dwProcessId);
|
trace(L"Injected into wrong process!", GetCurrentProcessId(), dwProcessId);
|
||||||
goto release;
|
goto release;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pszWUServiceDll = RegGetValueAlloc(HKEY_LOCAL_MACHINE,
|
|
||||||
L"SYSTEM\\CurrentControlSet\\services\\wuauserv\\Parameters",
|
|
||||||
L"ServiceDll",
|
|
||||||
RRF_RT_REG_SZ,
|
|
||||||
NULL,
|
|
||||||
&cbData);
|
|
||||||
|
|
||||||
trace(L"Installing hooks...");
|
trace(L"Installing hooks...");
|
||||||
|
|
||||||
|
if ( dwServiceType == SERVICE_WIN32_SHARE_PROCESS ) {
|
||||||
|
DetourTransactionBegin();
|
||||||
|
DetourUpdateThread(GetCurrentThread());
|
||||||
|
|
||||||
|
// assume wuaueng.dll hasn't been loaded yet, apply
|
||||||
|
// RegQueryValueExW hook to fix incompatibility with
|
||||||
|
// UpdatePack7R2 and other patches that work by
|
||||||
|
// modifying the Windows Update ServiceDll path in the
|
||||||
|
// registry.
|
||||||
|
g_pfnRegQueryValueExW = DetourFindFunction("kernel32.dll", "RegQueryValueExW");
|
||||||
|
if ( g_pfnRegQueryValueExW )
|
||||||
|
DetourAttach(&(PVOID)g_pfnRegQueryValueExW, RegQueryValueExW_hook);
|
||||||
|
DetourTransactionCommit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// query the ServiceDll path after applying our compat hook so that it
|
||||||
|
// is correct
|
||||||
|
str = (LPWSTR)RegQueryValueExAlloc(HKEY_LOCAL_MACHINE,
|
||||||
|
L"SYSTEM\\CurrentControlSet\\services\\wuauserv\\Parameters",
|
||||||
|
L"ServiceDll", NULL, NULL);
|
||||||
|
g_pszWUServiceDll = ExpandEnvironmentStringsAlloc(str);
|
||||||
|
free(str);
|
||||||
|
|
||||||
DetourTransactionBegin();
|
DetourTransactionBegin();
|
||||||
DetourUpdateThread(GetCurrentThread());
|
DetourUpdateThread(GetCurrentThread());
|
||||||
|
|
||||||
// hook LoadLibraryExW
|
|
||||||
g_pfnLoadLibraryExW = DetourFindFunction("kernel32.dll", "LoadLibraryExW");
|
g_pfnLoadLibraryExW = DetourFindFunction("kernel32.dll", "LoadLibraryExW");
|
||||||
if ( g_pfnLoadLibraryExW )
|
if ( g_pfnLoadLibraryExW )
|
||||||
DetourAttach(&(PVOID)g_pfnLoadLibraryExW, LoadLibraryExW_hook);
|
DetourAttach(&(PVOID)g_pfnLoadLibraryExW, LoadLibraryExW_hook);
|
||||||
|
|
||||||
// hook IsDeviceServiceable
|
|
||||||
if ( g_pszWUServiceDll ) {
|
if ( g_pszWUServiceDll ) {
|
||||||
hModule = GetModuleHandleW(g_pszWUServiceDll);
|
hModule = GetModuleHandleW(g_pszWUServiceDll);
|
||||||
if ( hModule ) {
|
if ( hModule ) {
|
||||||
@@ -88,19 +115,9 @@ DWORD WINAPI ThreadStartCallback(LPVOID pParam)
|
|||||||
} else {
|
} else {
|
||||||
trace(L"No pattern matched!");
|
trace(L"No pattern matched!");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// assume wuaueng.dll hasn't been loaded yet, apply
|
|
||||||
// RegQueryValueExW hook to fix incompatibility with
|
|
||||||
// UpdatePack7R2 and other patches that work by
|
|
||||||
// modifying the Windows Update ServiceDll path in the
|
|
||||||
// registry.
|
|
||||||
g_pfnRegQueryValueExW = DetourFindFunction("advapi.dll", "RegQueryValueExW");
|
|
||||||
if ( g_pfnRegQueryValueExW )
|
|
||||||
DetourAttach(&(PVOID)g_pfnRegQueryValueExW, RegQueryValueExW_hook);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DetourTransactionCommit();
|
DetourTransactionCommit();
|
||||||
|
|
||||||
// wait for unload event or parent mutex to be abandoned.
|
// wait for unload event or parent mutex to be abandoned.
|
||||||
@@ -112,7 +129,7 @@ DWORD WINAPI ThreadStartCallback(LPVOID pParam)
|
|||||||
trace(L"Unload condition has been met.");
|
trace(L"Unload condition has been met.");
|
||||||
|
|
||||||
// unhook
|
// unhook
|
||||||
if ( g_pfnLoadLibraryExW || g_pfnIsDeviceServiceable || g_pfnRegQueryValueExW) {
|
if ( g_pfnLoadLibraryExW || g_pfnIsDeviceServiceable || g_pfnRegQueryValueExW ) {
|
||||||
trace(L"Removing hooks...");
|
trace(L"Removing hooks...");
|
||||||
DetourTransactionBegin();
|
DetourTransactionBegin();
|
||||||
DetourUpdateThread(GetCurrentThread());
|
DetourUpdateThread(GetCurrentThread());
|
||||||
|
@@ -138,8 +138,6 @@ bool InjectLibraryAndCreateRemoteThread(
|
|||||||
goto vfree;
|
goto vfree;
|
||||||
}
|
}
|
||||||
if ( InjectLibrary(hProcess, hModule, &hRemoteModule) ) {
|
if ( InjectLibrary(hProcess, hModule, &hRemoteModule) ) {
|
||||||
trace(L"Injected library. (%p)", hRemoteModule);
|
|
||||||
|
|
||||||
hThread = CreateRemoteThread(hProcess,
|
hThread = CreateRemoteThread(hProcess,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
@@ -275,7 +273,8 @@ bool wufuc_InjectLibrary(DWORD dwProcessId, ContextHandles *pContext)
|
|||||||
&& DuplicateHandle(hSrcProcess, pContext->hUnloadEvent, hProcess, ¶m.hUnloadEvent, SYNCHRONIZE, FALSE, 0)
|
&& DuplicateHandle(hSrcProcess, pContext->hUnloadEvent, hProcess, ¶m.hUnloadEvent, SYNCHRONIZE, FALSE, 0)
|
||||||
&& DuplicateHandle(hSrcProcess, hChildMutex, hProcess, ¶m.hChildMutex, 0, FALSE, DUPLICATE_SAME_ACCESS) ) {
|
&& DuplicateHandle(hSrcProcess, hChildMutex, hProcess, ¶m.hChildMutex, 0, FALSE, DUPLICATE_SAME_ACCESS) ) {
|
||||||
|
|
||||||
InjectLibraryAndCreateRemoteThread(hProcess, PIMAGEBASE, ThreadStartCallback, ¶m, sizeof param);
|
if ( InjectLibraryAndCreateRemoteThread(hProcess, PIMAGEBASE, ThreadStartCallback, ¶m, sizeof param) )
|
||||||
|
trace(L"Injected into process. (%lu)", dwProcessId);
|
||||||
} else {
|
} else {
|
||||||
trace(L"Failed to duplicate context handles! (GetLastError=%lu", GetLastError());
|
trace(L"Failed to duplicate context handles! (GetLastError=%lu", GetLastError());
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
#include "hlpmisc.h"
|
#include "hlpmisc.h"
|
||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
|
|
||||||
bool InitializeMutex(bool InitialOwner, const wchar_t *pMutexName, HANDLE *phMutex)
|
bool InitializeMutex(bool InitialOwner, LPCWSTR pMutexName, HANDLE *phMutex)
|
||||||
{
|
{
|
||||||
HANDLE hMutex;
|
HANDLE hMutex;
|
||||||
|
|
||||||
@@ -21,10 +21,10 @@ bool InitializeMutex(bool InitialOwner, const wchar_t *pMutexName, HANDLE *phMut
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool CreateEventWithStringSecurityDescriptor(
|
bool CreateEventWithStringSecurityDescriptor(
|
||||||
const wchar_t *pStringSecurityDescriptor,
|
LPCWSTR pStringSecurityDescriptor,
|
||||||
bool ManualReset,
|
bool ManualReset,
|
||||||
bool InitialState,
|
bool InitialState,
|
||||||
const wchar_t *pName,
|
LPCWSTR pName,
|
||||||
HANDLE *phEvent)
|
HANDLE *phEvent)
|
||||||
{
|
{
|
||||||
SECURITY_ATTRIBUTES sa = { sizeof sa };
|
SECURITY_ATTRIBUTES sa = { sizeof sa };
|
||||||
@@ -47,8 +47,8 @@ bool CreateEventWithStringSecurityDescriptor(
|
|||||||
|
|
||||||
PVOID RegGetValueAlloc(
|
PVOID RegGetValueAlloc(
|
||||||
HKEY hkey,
|
HKEY hkey,
|
||||||
const wchar_t *pSubKey,
|
LPCWSTR pSubKey,
|
||||||
const wchar_t *pValue,
|
LPCWSTR pValue,
|
||||||
DWORD dwFlags,
|
DWORD dwFlags,
|
||||||
LPDWORD pdwType,
|
LPDWORD pdwType,
|
||||||
LPDWORD pcbData)
|
LPDWORD pcbData)
|
||||||
@@ -63,7 +63,45 @@ PVOID RegGetValueAlloc(
|
|||||||
if ( !result ) return result;
|
if ( !result ) return result;
|
||||||
|
|
||||||
if ( RegGetValueW(hkey, pSubKey, pValue, dwFlags, pdwType, result, &cbData) == ERROR_SUCCESS ) {
|
if ( RegGetValueW(hkey, pSubKey, pValue, dwFlags, pdwType, result, &cbData) == ERROR_SUCCESS ) {
|
||||||
*pcbData = cbData;
|
if ( pcbData )
|
||||||
|
*pcbData = cbData;
|
||||||
|
} else {
|
||||||
|
free(result);
|
||||||
|
result = NULL;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPBYTE RegQueryValueExAlloc(
|
||||||
|
HKEY hKey,
|
||||||
|
LPCWSTR pSubKey,
|
||||||
|
LPCWSTR pValueName,
|
||||||
|
LPDWORD pType,
|
||||||
|
LPDWORD pcbData)
|
||||||
|
{
|
||||||
|
HKEY hSubKey;
|
||||||
|
DWORD cbData = 0;
|
||||||
|
size_t length;
|
||||||
|
LPBYTE result = NULL;
|
||||||
|
|
||||||
|
if ( pSubKey && *pSubKey ) {
|
||||||
|
if ( RegOpenKeyW(hKey, pSubKey, &hSubKey) != ERROR_SUCCESS )
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
hSubKey = hKey;
|
||||||
|
}
|
||||||
|
if ( RegQueryValueExW(hSubKey, pValueName, NULL, pType, result, &cbData) != ERROR_SUCCESS )
|
||||||
|
return result;
|
||||||
|
|
||||||
|
length = cbData + sizeof(WCHAR); // make sure it is null-terminated
|
||||||
|
result = malloc(length);
|
||||||
|
|
||||||
|
if ( !result ) return result;
|
||||||
|
ZeroMemory(result, length);
|
||||||
|
|
||||||
|
if ( RegQueryValueExW(hSubKey, pValueName, NULL, pType, result, &cbData) == ERROR_SUCCESS ) {
|
||||||
|
if ( pcbData )
|
||||||
|
*pcbData = cbData;
|
||||||
} else {
|
} else {
|
||||||
free(result);
|
free(result);
|
||||||
result = NULL;
|
result = NULL;
|
||||||
@@ -94,20 +132,18 @@ PVOID NtQueryKeyAlloc(HANDLE KeyHandle, KEY_INFORMATION_CLASS KeyInformationClas
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LPWSTR ExpandEnvironmentStringsAlloc(LPCWSTR src)
|
||||||
bool FileExistsExpandEnvironmentStrings(const wchar_t *path)
|
|
||||||
{
|
{
|
||||||
bool result;
|
wchar_t *result;
|
||||||
LPWSTR dst;
|
|
||||||
DWORD buffersize;
|
DWORD buffersize;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
|
|
||||||
buffersize = ExpandEnvironmentStringsW(path, NULL, 0);
|
buffersize = ExpandEnvironmentStringsW(src, NULL, 0);
|
||||||
dst = calloc(buffersize, sizeof *dst);
|
result = calloc(buffersize, sizeof *result);
|
||||||
size = ExpandEnvironmentStringsW(path, dst, buffersize);
|
size = ExpandEnvironmentStringsW(src, result, buffersize);
|
||||||
if ( !size || size > buffersize )
|
if ( !size || size > buffersize ) {
|
||||||
return false;
|
free(result);
|
||||||
result = PathFileExistsW(dst);
|
result = NULL;
|
||||||
free(dst);
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@@ -1,18 +1,24 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
bool InitializeMutex(bool InitialOwner, const wchar_t *pMutexName, HANDLE *phMutex);
|
bool InitializeMutex(bool InitialOwner, LPCWSTR pMutexName, HANDLE *phMutex);
|
||||||
bool CreateEventWithStringSecurityDescriptor(
|
bool CreateEventWithStringSecurityDescriptor(
|
||||||
const wchar_t *pStringSecurityDescriptor,
|
LPCWSTR pStringSecurityDescriptor,
|
||||||
bool ManualReset,
|
bool ManualReset,
|
||||||
bool InitialState,
|
bool InitialState,
|
||||||
const wchar_t *pName,
|
LPCWSTR pName,
|
||||||
HANDLE *phEvent);
|
HANDLE *phEvent);
|
||||||
PVOID RegGetValueAlloc(
|
PVOID RegGetValueAlloc(
|
||||||
HKEY hkey,
|
HKEY hkey,
|
||||||
const wchar_t *pSubKey,
|
LPCWSTR pSubKey,
|
||||||
const wchar_t *pValue,
|
LPCWSTR pValue,
|
||||||
DWORD dwFlags,
|
DWORD dwFlags,
|
||||||
LPDWORD pdwType,
|
LPDWORD pdwType,
|
||||||
LPDWORD pcbData);
|
LPDWORD pcbData);
|
||||||
|
LPBYTE RegQueryValueExAlloc(
|
||||||
|
HKEY hKey,
|
||||||
|
LPCWSTR pSubKey,
|
||||||
|
LPCWSTR pValueName,
|
||||||
|
LPDWORD pType,
|
||||||
|
LPDWORD pcbData);
|
||||||
PVOID NtQueryKeyAlloc(HANDLE KeyHandle, KEY_INFORMATION_CLASS KeyInformationClass, PULONG pResultLength);
|
PVOID NtQueryKeyAlloc(HANDLE KeyHandle, KEY_INFORMATION_CLASS KeyInformationClass, PULONG pResultLength);
|
||||||
bool FileExistsExpandEnvironmentStrings(const wchar_t *path);
|
LPWSTR ExpandEnvironmentStringsAlloc(LPCWSTR src);
|
||||||
|
@@ -33,7 +33,8 @@ LPQUERY_SERVICE_CONFIGW QueryServiceConfigAlloc(
|
|||||||
result = malloc(cbBytesNeeded);
|
result = malloc(cbBytesNeeded);
|
||||||
if ( result ) {
|
if ( result ) {
|
||||||
if ( QueryServiceConfigW(hService, result, cbBytesNeeded, &cbBytesNeeded) ) {
|
if ( QueryServiceConfigW(hService, result, cbBytesNeeded, &cbBytesNeeded) ) {
|
||||||
*pcbBufSize = cbBytesNeeded;
|
if ( pcbBufSize )
|
||||||
|
*pcbBufSize = cbBytesNeeded;
|
||||||
} else {
|
} else {
|
||||||
free(result);
|
free(result);
|
||||||
result = NULL;
|
result = NULL;
|
||||||
@@ -53,10 +54,8 @@ bool QueryServiceStatusProcessInfoByName(
|
|||||||
DWORD cbBytesNeeded;
|
DWORD cbBytesNeeded;
|
||||||
|
|
||||||
hService = OpenServiceW(hSCM, pServiceName, SERVICE_QUERY_STATUS);
|
hService = OpenServiceW(hSCM, pServiceName, SERVICE_QUERY_STATUS);
|
||||||
if ( !hService ) {
|
if ( !hService )
|
||||||
trace(L"Failed to open service %ls! (GetLastError=%ul)", pServiceName, GetLastError());
|
|
||||||
return result;
|
return result;
|
||||||
}
|
|
||||||
|
|
||||||
result = !!QueryServiceStatusEx(hService,
|
result = !!QueryServiceStatusEx(hService,
|
||||||
SC_STATUS_PROCESS_INFO,
|
SC_STATUS_PROCESS_INFO,
|
||||||
@@ -119,12 +118,11 @@ DWORD QueryServiceProcessIdByName(SC_HANDLE hSCM, const wchar_t *pServiceName)
|
|||||||
DWORD HeuristicServiceGroupProcessId(SC_HANDLE hSCM, const wchar_t *pGroupNameSearch)
|
DWORD HeuristicServiceGroupProcessId(SC_HANDLE hSCM, const wchar_t *pGroupNameSearch)
|
||||||
{
|
{
|
||||||
wchar_t *pData;
|
wchar_t *pData;
|
||||||
DWORD cbData;
|
|
||||||
DWORD result = 0;
|
DWORD result = 0;
|
||||||
DWORD dwProcessId;
|
DWORD dwProcessId;
|
||||||
DWORD cbBufSize;
|
DWORD cbBufSize;
|
||||||
LPQUERY_SERVICE_CONFIGW pServiceConfig;
|
LPQUERY_SERVICE_CONFIGW pServiceConfig;
|
||||||
bool success;
|
bool success = false;
|
||||||
LPWSTR pGroupName;
|
LPWSTR pGroupName;
|
||||||
HLOCAL hMem;
|
HLOCAL hMem;
|
||||||
|
|
||||||
@@ -133,27 +131,25 @@ DWORD HeuristicServiceGroupProcessId(SC_HANDLE hSCM, const wchar_t *pGroupNameSe
|
|||||||
pGroupNameSearch,
|
pGroupNameSearch,
|
||||||
RRF_RT_REG_MULTI_SZ,
|
RRF_RT_REG_MULTI_SZ,
|
||||||
NULL,
|
NULL,
|
||||||
&cbData);
|
NULL);
|
||||||
|
|
||||||
if ( !pData ) return result;
|
if ( !pData ) return result;
|
||||||
|
|
||||||
for ( wchar_t *pName = pData; *pName; pName += wcslen(pName) + 1 ) {
|
for ( wchar_t *pName = pData; *pName; pName += wcslen(pName) + 1 ) {
|
||||||
dwProcessId = QueryServiceProcessIdByName(hSCM, pName);
|
dwProcessId = QueryServiceProcessIdByName(hSCM, pName);
|
||||||
trace(L"pName=%ls dwProcessId=%lu", pName, dwProcessId);
|
|
||||||
if ( !dwProcessId ) continue;
|
if ( !dwProcessId ) continue;
|
||||||
|
|
||||||
pServiceConfig = QueryServiceConfigByNameAlloc(hSCM, pName, &cbBufSize);
|
pServiceConfig = QueryServiceConfigByNameAlloc(hSCM, pName, &cbBufSize);
|
||||||
if ( !pServiceConfig ) continue;
|
if ( !pServiceConfig ) continue;
|
||||||
|
|
||||||
success = QueryServiceGroupName(pServiceConfig, &pGroupName, &hMem);
|
if ( pServiceConfig->dwServiceType == SERVICE_WIN32_SHARE_PROCESS
|
||||||
free(pServiceConfig);
|
&& QueryServiceGroupName(pServiceConfig, &pGroupName, &hMem) ) {
|
||||||
if ( !success )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
success = !_wcsicmp(pGroupNameSearch, pGroupName);
|
success = !_wcsicmp(pGroupNameSearch, pGroupName);
|
||||||
LocalFree(hMem);
|
LocalFree(hMem);
|
||||||
|
}
|
||||||
|
free(pServiceConfig);
|
||||||
if ( success ) {
|
if ( success ) {
|
||||||
trace(L"Found PID: %lu", dwProcessId);
|
|
||||||
result = dwProcessId;
|
result = dwProcessId;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -168,13 +164,12 @@ DWORD HeuristicServiceProcessId(SC_HANDLE hSCM, SC_HANDLE hService)
|
|||||||
LPQUERY_SERVICE_CONFIGW pServiceConfig;
|
LPQUERY_SERVICE_CONFIGW pServiceConfig;
|
||||||
LPWSTR pGroupName;
|
LPWSTR pGroupName;
|
||||||
HLOCAL hMem;
|
HLOCAL hMem;
|
||||||
DWORD cbBufSize;
|
|
||||||
|
|
||||||
result = QueryServiceProcessId(hSCM, hService);
|
result = QueryServiceProcessId(hSCM, hService);
|
||||||
if ( result )
|
if ( result )
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
pServiceConfig = QueryServiceConfigAlloc(hSCM, hService, &cbBufSize);
|
pServiceConfig = QueryServiceConfigAlloc(hSCM, hService, NULL);
|
||||||
if ( pServiceConfig ) {
|
if ( pServiceConfig ) {
|
||||||
switch ( pServiceConfig->dwServiceType ) {
|
switch ( pServiceConfig->dwServiceType ) {
|
||||||
case SERVICE_WIN32_OWN_PROCESS:
|
case SERVICE_WIN32_OWN_PROCESS:
|
||||||
@@ -190,12 +185,12 @@ DWORD HeuristicServiceProcessId(SC_HANDLE hSCM, SC_HANDLE hService)
|
|||||||
if ( QueryServiceGroupName(pServiceConfig, &pGroupName, &hMem) ) {
|
if ( QueryServiceGroupName(pServiceConfig, &pGroupName, &hMem) ) {
|
||||||
result = HeuristicServiceGroupProcessId(hSCM, pGroupName);
|
result = HeuristicServiceGroupProcessId(hSCM, pGroupName);
|
||||||
LocalFree(hMem);
|
LocalFree(hMem);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free(pServiceConfig);
|
free(pServiceConfig);
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD HeuristicServiceProcessIdByName(SC_HANDLE hSCM, const wchar_t *pServiceName)
|
DWORD HeuristicServiceProcessIdByName(SC_HANDLE hSCM, const wchar_t *pServiceName)
|
||||||
|
@@ -21,13 +21,19 @@ LSTATUS WINAPI RegQueryValueExW_hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpR
|
|||||||
int pos;
|
int pos;
|
||||||
LPWSTR fname;
|
LPWSTR fname;
|
||||||
const WCHAR realpath[] = L"%systemroot%\\system32\\wuaueng.dll";
|
const WCHAR realpath[] = L"%systemroot%\\system32\\wuaueng.dll";
|
||||||
|
wchar_t *expandedpath;
|
||||||
|
|
||||||
// save original buffer size
|
// save original buffer size
|
||||||
if ( lpData && lpcbData )
|
if ( lpData && lpcbData )
|
||||||
MaximumLength = *lpcbData;
|
MaximumLength = *lpcbData;
|
||||||
result = g_pfnRegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
|
result = g_pfnRegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
|
||||||
|
|
||||||
if ( result != ERROR_SUCCESS || !MaximumLength || !lpValueName || _wcsicmp(lpValueName, L"ServiceDll") )
|
|
||||||
|
if ( result != ERROR_SUCCESS
|
||||||
|
|| !MaximumLength
|
||||||
|
|| !lpValueName
|
||||||
|
|| (lpType && *lpType != REG_EXPAND_SZ)
|
||||||
|
|| _wcsicmp(lpValueName, L"ServiceDll") )
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
pBuffer = (PWCH)lpData;
|
pBuffer = (PWCH)lpData;
|
||||||
@@ -36,22 +42,28 @@ LSTATUS WINAPI RegQueryValueExW_hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpR
|
|||||||
pkni = NtQueryKeyAlloc((HANDLE)hKey, KeyNameInformation, &ResultLength);
|
pkni = NtQueryKeyAlloc((HANDLE)hKey, KeyNameInformation, &ResultLength);
|
||||||
if ( !pkni )
|
if ( !pkni )
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
NameCount = pkni->NameLength / sizeof *pkni->Name;
|
NameCount = pkni->NameLength / sizeof *pkni->Name;
|
||||||
|
|
||||||
// change key name to lower-case because there is no case-insensitive version of _snwscanf_s
|
// change key name to lower-case because there is no case-insensitive version of _snwscanf_s
|
||||||
if ( !_wcslwr_s(pkni->Name, NameCount)
|
for ( size_t i = 0; i < NameCount; i++ )
|
||||||
&& _snwscanf_s(pkni->Name, NameCount, L"\\registry\\machine\\system\\controlset%03d\\services\\wuauserv\\parameters%n", ¤t, &pos) == 1
|
pkni->Name[i] = towlower(pkni->Name[i]);
|
||||||
|
|
||||||
|
if ( _snwscanf_s(pkni->Name, NameCount, L"\\registry\\machine\\system\\controlset%03d\\services\\wuauserv\\parameters%n", ¤t, &pos) == 1
|
||||||
&& pos == NameCount ) {
|
&& pos == NameCount ) {
|
||||||
|
|
||||||
fname = PathFindFileNameW(pBuffer);
|
fname = PathFindFileNameW(pBuffer);
|
||||||
|
|
||||||
if ( (!_wcsicmp(fname, L"wuaueng2.dll") // UpdatePack7R2
|
if ( (!_wcsicmp(fname, L"wuaueng2.dll") // UpdatePack7R2
|
||||||
|| !_wcsicmp(fname, L"WuaCpuFix64.dll") // WuaCpuFix
|
|| !_wcsicmp(fname, L"WuaCpuFix64.dll") // WuaCpuFix
|
||||||
|| !_wcsicmp(fname, L"WuaCpuFix.dll"))
|
|| !_wcsicmp(fname, L"WuaCpuFix.dll")) ) {
|
||||||
&& FileExistsExpandEnvironmentStrings(realpath)
|
|
||||||
&& SUCCEEDED(StringCbCopyW(pBuffer, MaximumLength, realpath)) ) {
|
|
||||||
|
|
||||||
*lpcbData = sizeof realpath;
|
expandedpath = ExpandEnvironmentStringsAlloc(realpath);
|
||||||
|
|
||||||
|
trace(L"Fixed path to wuauserv ServiceDll: %ls -> %ls", fname, PathFindFileNameW(expandedpath));
|
||||||
|
|
||||||
|
if ( SUCCEEDED(StringCbCopyW(pBuffer, MaximumLength, expandedpath)) )
|
||||||
|
*lpcbData = sizeof realpath;
|
||||||
|
free(expandedpath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(pkni);
|
free(pkni);
|
||||||
|
Reference in New Issue
Block a user