Skip to content

Commit

Permalink
Do it properly
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaacMarovitz committed Sep 18, 2024
1 parent 56a3f46 commit cdcf0d0
Showing 1 changed file with 47 additions and 29 deletions.
76 changes: 47 additions & 29 deletions dlls/ntdll/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -3064,15 +3064,17 @@ 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;
const void *before, *after;
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.
Expand Down Expand Up @@ -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.
Expand All @@ -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

Expand Down

0 comments on commit cdcf0d0

Please sign in to comment.