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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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