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_NTDLLHEAPFREE_CALLBACK ProviderNtdllHeapFreeCallback;
|
||||||
} RTL_VERIFIER_PROVIDER_DESCRIPTOR, *PRTL_VERIFIER_PROVIDER_DESCRIPTOR;
|
} RTL_VERIFIER_PROVIDER_DESCRIPTOR, *PRTL_VERIFIER_PROVIDER_DESCRIPTOR;
|
||||||
|
|
||||||
extern RTL_VERIFIER_THUNK_DESCRIPTOR g_vfADVAPIThunkDescriptors[];
|
typedef LSTATUS(WINAPI *LPFN_REGQUERYVALUEEXW)(HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD);
|
||||||
extern RTL_VERIFIER_THUNK_DESCRIPTOR g_vfK32ThunkDescriptors[];
|
typedef HMODULE(WINAPI *LPFN_LOADLIBRARYEXW)(LPCWSTR, HANDLE, DWORD);
|
||||||
extern RTL_VERIFIER_DLL_DESCRIPTOR g_vfDllDescriptors[];
|
|
||||||
extern RTL_VERIFIER_PROVIDER_DESCRIPTOR g_vfProviderDescriptor;
|
extern LPFN_REGQUERYVALUEEXW *g_plpfnRegQueryValueExW;
|
||||||
|
extern LPFN_LOADLIBRARYEXW *g_plpfnLoadLibraryExW;
|
||||||
|
@@ -8,20 +8,21 @@
|
|||||||
#include <phnt_windows.h>
|
#include <phnt_windows.h>
|
||||||
#include <phnt.h>
|
#include <phnt.h>
|
||||||
|
|
||||||
RTL_VERIFIER_THUNK_DESCRIPTOR g_vfK32ThunkDescriptors[] = {
|
RTL_VERIFIER_THUNK_DESCRIPTOR g_vfThunkDescriptors[] = {
|
||||||
{ "RegQueryValueExW", NULL, (PVOID)&RegQueryValueExW_Hook },
|
{ "RegQueryValueExW", NULL, (PVOID)&RegQueryValueExW_Hook },
|
||||||
{ "LoadLibraryExW", NULL, (PVOID)&LoadLibraryExW_Hook },
|
{ "LoadLibraryExW", NULL, (PVOID)&LoadLibraryExW_Hook },
|
||||||
{ 0 } };
|
{ 0 } };
|
||||||
RTL_VERIFIER_DLL_DESCRIPTOR g_vfDllDescriptors[] = {
|
|
||||||
{ L"kernel32.dll", 0, NULL, g_vfK32ThunkDescriptors },
|
RTL_VERIFIER_DLL_DESCRIPTOR g_vfDllDescriptors[2];
|
||||||
{ 0 } };
|
|
||||||
RTL_VERIFIER_DLL_DESCRIPTOR g_vfNullDllDescriptor = { 0 };
|
|
||||||
RTL_VERIFIER_PROVIDER_DESCRIPTOR g_vfProviderDescriptor = {
|
RTL_VERIFIER_PROVIDER_DESCRIPTOR g_vfProviderDescriptor = {
|
||||||
sizeof(RTL_VERIFIER_PROVIDER_DESCRIPTOR),
|
sizeof(RTL_VERIFIER_PROVIDER_DESCRIPTOR),
|
||||||
&g_vfNullDllDescriptor,
|
g_vfDllDescriptors/*,
|
||||||
//(RTL_VERIFIER_DLL_LOAD_CALLBACK)&VerifierDllLoadCallback,
|
(RTL_VERIFIER_DLL_LOAD_CALLBACK)&VerifierDllLoadCallback,
|
||||||
//(RTL_VERIFIER_DLL_UNLOAD_CALLBACK)&VerifierDllUnloadCallback
|
(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)
|
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;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_VERIFIER:;
|
case DLL_PROCESS_VERIFIER:
|
||||||
if ( verify_winver(6, 1, 0, 0, 0, VER_EQUAL, VER_EQUAL, 0, 0, 0)
|
if ( verify_win7() || verify_win81 ) {
|
||||||
|| verify_winver(6, 3, 0, 0, 0, VER_EQUAL, VER_EQUAL, 0, 0, 0) ) {
|
UNICODE_STRING ImagePath;
|
||||||
|
RtlInitUnicodeString(&ImagePath, NULL);
|
||||||
|
|
||||||
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
||||||
RtlSecureZeroMemory(&QueryTable, sizeof(QueryTable));
|
RtlSecureZeroMemory(&QueryTable, sizeof(QueryTable));
|
||||||
QueryTable[0].Name = L"ImagePath";
|
QueryTable[0].Name = L"ImagePath";
|
||||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
||||||
UNICODE_STRING ImagePath;
|
|
||||||
RtlInitUnicodeString(&ImagePath, NULL);
|
|
||||||
QueryTable[0].EntryContext = &ImagePath;
|
QueryTable[0].EntryContext = &ImagePath;
|
||||||
|
|
||||||
//TODO: check status and maybe fix implementation? idk...
|
if ( RtlQueryRegistryValues(RTL_REGISTRY_SERVICES, L"wuauserv", QueryTable, NULL, NULL) == STATUS_SUCCESS
|
||||||
NTSTATUS Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
|
&& !RtlCompareUnicodeString(&NtCurrentPeb()->ProcessParameters->CommandLine, &ImagePath, TRUE) ) {
|
||||||
L"wuauserv",
|
|
||||||
QueryTable,
|
if ( verify_win7() )
|
||||||
NULL,
|
g_vfDllDescriptors[0].DllName = L"kernel32.dll";
|
||||||
NULL);
|
else if ( verify_win81() )
|
||||||
|
g_vfDllDescriptors[0].DllName = L"kernelbase.dll";
|
||||||
if ( !RtlCompareUnicodeString(&NtCurrentPeb()->ProcessParameters->CommandLine, &ImagePath, TRUE) )
|
|
||||||
g_vfProviderDescriptor.ProviderDlls = g_vfDllDescriptors;
|
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;
|
*(PRTL_VERIFIER_PROVIDER_DESCRIPTOR *)lpReserved = &g_vfProviderDescriptor;
|
||||||
break;
|
break;
|
||||||
|
@@ -53,6 +53,26 @@ bool verify_winver(
|
|||||||
return RtlVerifyVersionInfo(&osvi, TypeMask, ConditionMask) == STATUS_SUCCESS;
|
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 *find_fname(wchar_t *pPath)
|
||||||
{
|
{
|
||||||
wchar_t *pwc = wcsrchr(pPath, L'\\');
|
wchar_t *pwc = wcsrchr(pPath, L'\\');
|
||||||
@@ -62,7 +82,7 @@ wchar_t *find_fname(wchar_t *pPath)
|
|||||||
return pPath;
|
return pPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL file_exists(const wchar_t *path)
|
bool file_exists(const wchar_t *path)
|
||||||
{
|
{
|
||||||
return GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES;
|
return GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES;
|
||||||
}
|
}
|
||||||
|
@@ -16,9 +16,11 @@ bool verify_winver(
|
|||||||
BYTE ServicePackMajorCondition,
|
BYTE ServicePackMajorCondition,
|
||||||
BYTE ServicePackMinorCondition
|
BYTE ServicePackMinorCondition
|
||||||
);
|
);
|
||||||
|
bool verify_win7(void);
|
||||||
|
bool verify_win81(void);
|
||||||
|
|
||||||
wchar_t *find_fname(wchar_t *pPath);
|
wchar_t *find_fname(wchar_t *pPath);
|
||||||
BOOL file_exists(const wchar_t *path);
|
bool file_exists(const wchar_t *path);
|
||||||
int compare_versions(
|
int compare_versions(
|
||||||
WORD wMajorA, WORD wMinorA, WORD wBuildA, WORD wRevisionA,
|
WORD wMajorA, WORD wMinorA, WORD wBuildA, WORD wRevisionA,
|
||||||
WORD wMajorB, WORD wMinorB, WORD wBuildB, WORD wRevisionB);
|
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;
|
DWORD cbData = *lpcbData;
|
||||||
size_t MaxCount = cbData / sizeof(wchar_t);
|
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);
|
result = RegGetValueW(hKey, NULL, lpValueName, RRF_RT_REG_EXPAND_SZ | RRF_NOEXPAND, lpType, lpData, lpcbData);
|
||||||
if ( result != ERROR_SUCCESS )
|
if ( result != ERROR_SUCCESS )
|
||||||
goto L_ret;
|
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);
|
Status = NtQueryKey((HANDLE)hKey, KeyNameInformation, (PVOID)pkni, ResultLength, &ResultLength);
|
||||||
if ( Status == STATUS_SUCCESS ) {
|
if ( Status == STATUS_SUCCESS ) {
|
||||||
size_t BufferCount = pkni->NameLength / sizeof(wchar_t);
|
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;
|
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 ) {
|
&& pos == BufferCount ) {
|
||||||
|
|
||||||
wchar_t drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
|
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) ) {
|
if ( file_exists(lpDst) ) {
|
||||||
_wmakepath_s((wchar_t *)lpData, MaxCount, drive, dir, L"wuaueng", ext);
|
_wmakepath_s((wchar_t *)lpData, MaxCount, drive, dir, L"wuaueng", ext);
|
||||||
*lpcbData = (DWORD)((wcslen((wchar_t *)lpData) + 1) * sizeof(wchar_t));
|
*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);
|
rtl_free(lpDst);
|
||||||
}
|
}
|
||||||
@@ -77,7 +82,7 @@ LSTATUS WINAPI RegQueryValueExW_Hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpR
|
|||||||
rtl_free(pkni);
|
rtl_free(pkni);
|
||||||
} else {
|
} else {
|
||||||
// handle normally
|
// 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:
|
L_ret:
|
||||||
return result;
|
return result;
|
||||||
@@ -85,17 +90,19 @@ L_ret:
|
|||||||
|
|
||||||
HMODULE WINAPI LoadLibraryExW_Hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags)
|
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 ) {
|
if ( !result ) {
|
||||||
trace(L"Failed to load library: %ls (error code=%08X)", lpFileName, GetLastError());
|
trace(L"Failed to load library: %ls (error code=%08X)", lpFileName, GetLastError());
|
||||||
goto L_ret;
|
goto L_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace(L"Loaded library: %ls", lpFileName);
|
trace(L"Loaded library: %ls", lpFileName);
|
||||||
DWORD dwLen = GetFileVersionInfoSizeW(lpFileName, NULL);
|
DWORD dwLen = GetFileVersionInfoSizeW(lpFileName, NULL);
|
||||||
if ( !dwLen ) {
|
if ( !dwLen ) {
|
||||||
trace(L"Failed to get file version info size for file %ls (error code=%08X)", lpFileName, GetLastError());
|
trace(L"Failed to get file version info size for file %ls (error code=%08X)", lpFileName, GetLastError());
|
||||||
goto L_ret;
|
goto L_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPVOID pBlock = rtl_malloc(dwLen);
|
LPVOID pBlock = rtl_malloc(dwLen);
|
||||||
if ( GetFileVersionInfoW(lpFileName, 0, dwLen, pBlock) ) {
|
if ( GetFileVersionInfoW(lpFileName, 0, dwLen, pBlock) ) {
|
||||||
PLANGANDCODEPAGE ptl;
|
PLANGANDCODEPAGE ptl;
|
||||||
|
@@ -8,8 +8,5 @@ typedef struct tagLANGANDCODEPAGE
|
|||||||
WORD wCodePage;
|
WORD wCodePage;
|
||||||
} LANGANDCODEPAGE, *PLANGANDCODEPAGE;
|
} 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);
|
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);
|
HMODULE WINAPI LoadLibraryExW_Hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags);
|
||||||
|
@@ -4,7 +4,6 @@
|
|||||||
#include "patternfind.h"
|
#include "patternfind.h"
|
||||||
#include "tracing.h"
|
#include "tracing.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
@@ -40,10 +39,12 @@ bool patch_wua(void *lpBaseOfDll, size_t SizeOfImage, wchar_t *fname)
|
|||||||
#ifdef _M_AMD64
|
#ifdef _M_AMD64
|
||||||
pps = &X64PatchSet;
|
pps = &X64PatchSet;
|
||||||
#elif defined(_M_IX86)
|
#elif defined(_M_IX86)
|
||||||
if ( verify_winver(6, 1, 0, 0, 0, VER_EQUAL, VER_EQUAL, 0, 0, 0) )
|
if ( verify_win7() )
|
||||||
pps = &Win7X86PatchSet;
|
pps = &Win7X86PatchSet;
|
||||||
else if ( verify_winver(6, 3, 0, 0, 0, VER_EQUAL, VER_EQUAL, 0, 0, 0) )
|
else if ( verify_win81() )
|
||||||
pps = &Win81X86PatchSet;
|
pps = &Win81X86PatchSet;
|
||||||
|
else
|
||||||
|
goto L_ret;
|
||||||
#endif
|
#endif
|
||||||
unsigned char *ptr = patternfind(lpBaseOfDll, SizeOfImage, pps->Pattern);
|
unsigned char *ptr = patternfind(lpBaseOfDll, SizeOfImage, pps->Pattern);
|
||||||
if ( !ptr ) {
|
if ( !ptr ) {
|
||||||
|
Reference in New Issue
Block a user