fix win 8.1 (needs more testing)

This commit is contained in:
zeffy
2017-10-05 20:36:25 -07:00
parent c8fa45f002
commit 94e8c9ccea
7 changed files with 73 additions and 40 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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", &current, &pos) == 1
if ( _snwscanf_s(pkni->Name, BufferCount, L"\\registry\\machine\\system\\controlset%03d\\services\\wuauserv\\parameters%n", &current, &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;

View File

@@ -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);

View File

@@ -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 ) {