From cdcf0d068a46a1d38d8c16a0e6dc2c51642e93f4 Mon Sep 17 00:00:00 2001 From: Isaac Marovitz Date: Thu, 19 Sep 2024 00:00:39 +0200 Subject: [PATCH] Do it properly --- dlls/ntdll/loader.c | 76 ++++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index dfb5f6236977..8e1ebe71445c 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -3064,7 +3064,7 @@ static void apply_binary_patches( WINE_MODREF* wm ) C_ASSERT( sizeof(before_epic_cmd_line_args_90_6_7) == sizeof(after_epic_cmd_line_args_90_6_7) ); - struct + struct patch_info { const WCHAR *libname; const char *name; @@ -3072,7 +3072,9 @@ static void apply_binary_patches( WINE_MODREF* wm ) size_t size; ULONG_PTR offset; BOOL stop_patching_after_success; - } static const patches[] = + }; + + static const struct patch_info gs_patches[] = { /* CW HACK 22584L * libcef.dll 85.3.11, for an updated Rockstar Games Social Club/Launcher. @@ -3188,7 +3190,10 @@ static void apply_binary_patches( WINE_MODREF* wm ) 0x2810f8d, TRUE }, + }; + static const struct patch_info patches[] = + { /* CW HACK 23854: * Ignore the command_line_args_disabled flag in the cef_settings_t * passed to cef_inititalize. Always set it to 0. @@ -3204,39 +3209,52 @@ static void apply_binary_patches( WINE_MODREF* wm ) }, }; - unsigned int i; - SIZE_T pagesize = page_size; - WCHAR *libname = wm->ldr.BaseDllName.Buffer; - - for (i = 0; i < ARRAY_SIZE(patches); i++) + // Function to apply patches from a given array + void apply_patches(const struct patch_info *patch_array, unsigned int patch_count) { - DWORD old_prot; - void *dllbase = wm->ldr.DllBase; - void *target = (void *)((ULONG_PTR)dllbase + patches[i].offset); - void *target_page = (void *)((ULONG_PTR)target & ~(page_size-1)); - - if (wcscmp( libname, patches[i].libname )) - continue; + unsigned int i; + SIZE_T pagesize = page_size; + WCHAR *libname = wm->ldr.BaseDllName.Buffer; - if (wm->ldr.SizeOfImage < patches[i].offset) + for (i = 0; i < patch_count; i++) { - TRACE( "%s too small to match patch '%s'\n", debugstr_w(libname), patches[i].name ); - continue; - } - if (memcmp( target, patches[i].before, patches[i].size )) - { - TRACE( "%s doesn't match patch '%s'\n", debugstr_w(libname), patches[i].name ); - continue; - } + DWORD old_prot; + void *dllbase = wm->ldr.DllBase; + const struct patch_info *patch = &patch_array[i]; + void *target = (void *)((ULONG_PTR)dllbase + patch->offset); + void *target_page = (void *)((ULONG_PTR)target & ~(page_size - 1)); - TRACE( "Found matching %s, applying patch '%s'\n", debugstr_w(libname), patches[i].name ); - NtProtectVirtualMemory( NtCurrentProcess(), &target_page, &pagesize, PAGE_EXECUTE_READWRITE, &old_prot ); - memcpy( target, patches[i].after, patches[i].size ); - NtProtectVirtualMemory( NtCurrentProcess(), &target_page, &pagesize, old_prot, &old_prot ); + if (wcscmp(libname, patch->libname)) + continue; - if (patches[i].stop_patching_after_success) - break; + if (wm->ldr.SizeOfImage < patch->offset) + { + TRACE("%s too small to match patch '%s'\n", debugstr_w(libname), patch->name); + continue; + } + if (memcmp(target, patch->before, patch->size)) + { + TRACE("%s doesn't match patch '%s'\n", debugstr_w(libname), patch->name); + continue; + } + + TRACE("Found matching %s, applying patch '%s'\n", debugstr_w(libname), patch->name); + NtProtectVirtualMemory(NtCurrentProcess(), &target_page, &pagesize, PAGE_EXECUTE_READWRITE, &old_prot); + memcpy(target, patch->after, patch->size); + NtProtectVirtualMemory(NtCurrentProcess(), &target_page, &pagesize, old_prot, &old_prot); + + if (patch->stop_patching_after_success) + break; + } } + + // Apply %gs patches if needed + if (unix_funcs->gs_patching_needed()) + { + apply_patches(gs_patches, ARRAY_SIZE(gs_patches)); + } + + apply_patches(patches, ARRAY_SIZE(patches)); } #endif