fix win 8.1 (needs more testing)
This commit is contained in:
@@ -38,7 +38,8 @@ typedef struct tagRTL_VERIFIER_PROVIDER_DESCRIPTOR
|
||||
RTL_VERIFIER_NTDLLHEAPFREE_CALLBACK ProviderNtdllHeapFreeCallback;
|
||||
} RTL_VERIFIER_PROVIDER_DESCRIPTOR, *PRTL_VERIFIER_PROVIDER_DESCRIPTOR;
|
||||
|
||||
extern RTL_VERIFIER_THUNK_DESCRIPTOR g_vfADVAPIThunkDescriptors[];
|
||||
extern RTL_VERIFIER_THUNK_DESCRIPTOR g_vfK32ThunkDescriptors[];
|
||||
extern RTL_VERIFIER_DLL_DESCRIPTOR g_vfDllDescriptors[];
|
||||
extern RTL_VERIFIER_PROVIDER_DESCRIPTOR g_vfProviderDescriptor;
|
||||
typedef LSTATUS(WINAPI *LPFN_REGQUERYVALUEEXW)(HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD);
|
||||
typedef HMODULE(WINAPI *LPFN_LOADLIBRARYEXW)(LPCWSTR, HANDLE, DWORD);
|
||||
|
||||
extern LPFN_REGQUERYVALUEEXW *g_plpfnRegQueryValueExW;
|
||||
extern LPFN_LOADLIBRARYEXW *g_plpfnLoadLibraryExW;
|
||||
|
@@ -8,20 +8,21 @@
|
||||
#include <phnt_windows.h>
|
||||
#include <phnt.h>
|
||||
|
||||
RTL_VERIFIER_THUNK_DESCRIPTOR g_vfK32ThunkDescriptors[] = {
|
||||
RTL_VERIFIER_THUNK_DESCRIPTOR g_vfThunkDescriptors[] = {
|
||||
{ "RegQueryValueExW", NULL, (PVOID)&RegQueryValueExW_Hook },
|
||||
{ "LoadLibraryExW", NULL, (PVOID)&LoadLibraryExW_Hook },
|
||||
{ 0 } };
|
||||
RTL_VERIFIER_DLL_DESCRIPTOR g_vfDllDescriptors[] = {
|
||||
{ L"kernel32.dll", 0, NULL, g_vfK32ThunkDescriptors },
|
||||
{ 0 } };
|
||||
RTL_VERIFIER_DLL_DESCRIPTOR g_vfNullDllDescriptor = { 0 };
|
||||
|
||||
RTL_VERIFIER_DLL_DESCRIPTOR g_vfDllDescriptors[2];
|
||||
|
||||
RTL_VERIFIER_PROVIDER_DESCRIPTOR g_vfProviderDescriptor = {
|
||||
sizeof(RTL_VERIFIER_PROVIDER_DESCRIPTOR),
|
||||
&g_vfNullDllDescriptor,
|
||||
//(RTL_VERIFIER_DLL_LOAD_CALLBACK)&VerifierDllLoadCallback,
|
||||
//(RTL_VERIFIER_DLL_UNLOAD_CALLBACK)&VerifierDllUnloadCallback
|
||||
};
|
||||
g_vfDllDescriptors/*,
|
||||
(RTL_VERIFIER_DLL_LOAD_CALLBACK)&VerifierDllLoadCallback,
|
||||
(RTL_VERIFIER_DLL_UNLOAD_CALLBACK)&VerifierDllUnloadCallback*/ };
|
||||
|
||||
LPFN_REGQUERYVALUEEXW *g_plpfnRegQueryValueExW;
|
||||
LPFN_LOADLIBRARYEXW *g_plpfnLoadLibraryExW;
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
@@ -31,27 +32,31 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
case DLL_PROCESS_VERIFIER:;
|
||||
if ( verify_winver(6, 1, 0, 0, 0, VER_EQUAL, VER_EQUAL, 0, 0, 0)
|
||||
|| verify_winver(6, 3, 0, 0, 0, VER_EQUAL, VER_EQUAL, 0, 0, 0) ) {
|
||||
case DLL_PROCESS_VERIFIER:
|
||||
if ( verify_win7() || verify_win81 ) {
|
||||
UNICODE_STRING ImagePath;
|
||||
RtlInitUnicodeString(&ImagePath, NULL);
|
||||
|
||||
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
||||
RtlSecureZeroMemory(&QueryTable, sizeof(QueryTable));
|
||||
QueryTable[0].Name = L"ImagePath";
|
||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
||||
UNICODE_STRING ImagePath;
|
||||
RtlInitUnicodeString(&ImagePath, NULL);
|
||||
QueryTable[0].EntryContext = &ImagePath;
|
||||
|
||||
//TODO: check status and maybe fix implementation? idk...
|
||||
NTSTATUS Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
|
||||
L"wuauserv",
|
||||
QueryTable,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if ( !RtlCompareUnicodeString(&NtCurrentPeb()->ProcessParameters->CommandLine, &ImagePath, TRUE) )
|
||||
g_vfProviderDescriptor.ProviderDlls = g_vfDllDescriptors;
|
||||
if ( RtlQueryRegistryValues(RTL_REGISTRY_SERVICES, L"wuauserv", QueryTable, NULL, NULL) == STATUS_SUCCESS
|
||||
&& !RtlCompareUnicodeString(&NtCurrentPeb()->ProcessParameters->CommandLine, &ImagePath, TRUE) ) {
|
||||
|
||||
if ( verify_win7() )
|
||||
g_vfDllDescriptors[0].DllName = L"kernel32.dll";
|
||||
else if ( verify_win81() )
|
||||
g_vfDllDescriptors[0].DllName = L"kernelbase.dll";
|
||||
|
||||
g_vfDllDescriptors[0].DllThunks = g_vfThunkDescriptors;
|
||||
|
||||
g_plpfnRegQueryValueExW = (LPFN_REGQUERYVALUEEXW *)&g_vfThunkDescriptors[0].ThunkOldAddress;
|
||||
g_plpfnLoadLibraryExW = (LPFN_LOADLIBRARYEXW *)&g_vfThunkDescriptors[1].ThunkOldAddress;
|
||||
}
|
||||
RtlFreeUnicodeString(&ImagePath);
|
||||
}
|
||||
*(PRTL_VERIFIER_PROVIDER_DESCRIPTOR *)lpReserved = &g_vfProviderDescriptor;
|
||||
break;
|
||||
|
@@ -53,6 +53,26 @@ bool verify_winver(
|
||||
return RtlVerifyVersionInfo(&osvi, TypeMask, ConditionMask) == STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
bool verify_win7(void)
|
||||
{
|
||||
static bool a, b;
|
||||
if ( !a ) {
|
||||
b = verify_winver(6, 1, 0, 0, 0, VER_EQUAL, VER_EQUAL, 0, 0, 0);
|
||||
a = true;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
bool verify_win81(void)
|
||||
{
|
||||
static bool a, b;
|
||||
if ( !a ) {
|
||||
b = verify_winver(6, 3, 0, 0, 0, VER_EQUAL, VER_EQUAL, 0, 0, 0);
|
||||
a = true;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
wchar_t *find_fname(wchar_t *pPath)
|
||||
{
|
||||
wchar_t *pwc = wcsrchr(pPath, L'\\');
|
||||
@@ -62,7 +82,7 @@ wchar_t *find_fname(wchar_t *pPath)
|
||||
return pPath;
|
||||
}
|
||||
|
||||
BOOL file_exists(const wchar_t *path)
|
||||
bool file_exists(const wchar_t *path)
|
||||
{
|
||||
return GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES;
|
||||
}
|
||||
|
@@ -16,9 +16,11 @@ bool verify_winver(
|
||||
BYTE ServicePackMajorCondition,
|
||||
BYTE ServicePackMinorCondition
|
||||
);
|
||||
bool verify_win7(void);
|
||||
bool verify_win81(void);
|
||||
|
||||
wchar_t *find_fname(wchar_t *pPath);
|
||||
BOOL file_exists(const wchar_t *path);
|
||||
bool file_exists(const wchar_t *path);
|
||||
int compare_versions(
|
||||
WORD wMajorA, WORD wMinorA, WORD wBuildA, WORD wRevisionA,
|
||||
WORD wMajorB, WORD wMinorB, WORD wBuildB, WORD wRevisionB);
|
||||
|
@@ -25,7 +25,7 @@ LSTATUS WINAPI RegQueryValueExW_Hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpR
|
||||
DWORD cbData = *lpcbData;
|
||||
size_t MaxCount = cbData / sizeof(wchar_t);
|
||||
|
||||
// this way the dll path is garunteed to be null terminated
|
||||
// this way the dll path is guaranteed to be null-terminated
|
||||
result = RegGetValueW(hKey, NULL, lpValueName, RRF_RT_REG_EXPAND_SZ | RRF_NOEXPAND, lpType, lpData, lpcbData);
|
||||
if ( result != ERROR_SUCCESS )
|
||||
goto L_ret;
|
||||
@@ -39,8 +39,13 @@ LSTATUS WINAPI RegQueryValueExW_Hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpR
|
||||
Status = NtQueryKey((HANDLE)hKey, KeyNameInformation, (PVOID)pkni, ResultLength, &ResultLength);
|
||||
if ( Status == STATUS_SUCCESS ) {
|
||||
size_t BufferCount = pkni->NameLength / sizeof(wchar_t);
|
||||
|
||||
// change key name to lower-case because there is no case-insensitive version of _snwscanf_s
|
||||
for ( size_t i = 0; i < BufferCount; i++ )
|
||||
pkni->Name[i] = towlower(pkni->Name[i]);
|
||||
|
||||
int current, pos;
|
||||
if ( _snwscanf_s(pkni->Name, BufferCount, L"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet%03d\\services\\wuauserv\\Parameters%n", ¤t, &pos) == 1
|
||||
if ( _snwscanf_s(pkni->Name, BufferCount, L"\\registry\\machine\\system\\controlset%03d\\services\\wuauserv\\parameters%n", ¤t, &pos) == 1
|
||||
&& pos == BufferCount ) {
|
||||
|
||||
wchar_t drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
|
||||
@@ -68,7 +73,7 @@ LSTATUS WINAPI RegQueryValueExW_Hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpR
|
||||
if ( file_exists(lpDst) ) {
|
||||
_wmakepath_s((wchar_t *)lpData, MaxCount, drive, dir, L"wuaueng", ext);
|
||||
*lpcbData = (DWORD)((wcslen((wchar_t *)lpData) + 1) * sizeof(wchar_t));
|
||||
trace(L"Fixed wuauserv ServiceDll path: %ls", lpDst);
|
||||
trace(L"Fixed wuauserv %ls path: %ls", lpValueName, lpDst);
|
||||
}
|
||||
rtl_free(lpDst);
|
||||
}
|
||||
@@ -77,7 +82,7 @@ LSTATUS WINAPI RegQueryValueExW_Hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpR
|
||||
rtl_free(pkni);
|
||||
} else {
|
||||
// handle normally
|
||||
result = ((LPFN_REGQUERYVALUEEXW)g_vfK32ThunkDescriptors[0].ThunkOldAddress)(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
|
||||
result = (*g_plpfnRegQueryValueExW)(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
|
||||
}
|
||||
L_ret:
|
||||
return result;
|
||||
@@ -85,17 +90,19 @@ L_ret:
|
||||
|
||||
HMODULE WINAPI LoadLibraryExW_Hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags)
|
||||
{
|
||||
HMODULE result = ((LPFN_LOADLIBRARYEXW)g_vfK32ThunkDescriptors[1].ThunkOldAddress)(lpFileName, hFile, dwFlags);
|
||||
HMODULE result = (*g_plpfnLoadLibraryExW)(lpFileName, hFile, dwFlags);
|
||||
if ( !result ) {
|
||||
trace(L"Failed to load library: %ls (error code=%08X)", lpFileName, GetLastError());
|
||||
goto L_ret;
|
||||
}
|
||||
|
||||
trace(L"Loaded library: %ls", lpFileName);
|
||||
DWORD dwLen = GetFileVersionInfoSizeW(lpFileName, NULL);
|
||||
if ( !dwLen ) {
|
||||
trace(L"Failed to get file version info size for file %ls (error code=%08X)", lpFileName, GetLastError());
|
||||
goto L_ret;
|
||||
}
|
||||
|
||||
LPVOID pBlock = rtl_malloc(dwLen);
|
||||
if ( GetFileVersionInfoW(lpFileName, 0, dwLen, pBlock) ) {
|
||||
PLANGANDCODEPAGE ptl;
|
||||
|
@@ -8,8 +8,5 @@ typedef struct tagLANGANDCODEPAGE
|
||||
WORD wCodePage;
|
||||
} LANGANDCODEPAGE, *PLANGANDCODEPAGE;
|
||||
|
||||
typedef LSTATUS(WINAPI *LPFN_REGQUERYVALUEEXW)(HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD);
|
||||
typedef HMODULE(WINAPI *LPFN_LOADLIBRARYEXW)(LPCWSTR, HANDLE, DWORD);
|
||||
|
||||
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);
|
||||
|
@@ -4,7 +4,6 @@
|
||||
#include "patternfind.h"
|
||||
#include "tracing.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -40,10 +39,12 @@ bool patch_wua(void *lpBaseOfDll, size_t SizeOfImage, wchar_t *fname)
|
||||
#ifdef _M_AMD64
|
||||
pps = &X64PatchSet;
|
||||
#elif defined(_M_IX86)
|
||||
if ( verify_winver(6, 1, 0, 0, 0, VER_EQUAL, VER_EQUAL, 0, 0, 0) )
|
||||
if ( verify_win7() )
|
||||
pps = &Win7X86PatchSet;
|
||||
else if ( verify_winver(6, 3, 0, 0, 0, VER_EQUAL, VER_EQUAL, 0, 0, 0) )
|
||||
else if ( verify_win81() )
|
||||
pps = &Win81X86PatchSet;
|
||||
else
|
||||
goto L_ret;
|
||||
#endif
|
||||
unsigned char *ptr = patternfind(lpBaseOfDll, SizeOfImage, pps->Pattern);
|
||||
if ( !ptr ) {
|
||||
|
Reference in New Issue
Block a user