From 85e77dec61c4b192541051a6685cf7a8b4c10dca Mon Sep 17 00:00:00 2001 From: Isaac Marovitz Date: Fri, 17 May 2024 15:38:05 -0400 Subject: [PATCH 1/3] Proton & CXWine Simulate Write Copy HACK --- dlls/ntdll/unix/loader.c | 15 +++++++++++++++ dlls/ntdll/unix/unix_private.h | 1 + dlls/ntdll/unix/virtual.c | 27 +++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 8e54c9942771..734aebb53907 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -2465,6 +2465,20 @@ static void dlopen_32on64_opengl32(void) } #endif +BOOL simulate_writecopy; + +static void hacks_init(void) +{ + const char *env_str; + + env_str = getenv("WINE_SIMULATE_WRITECOPY"); + if (env_str) simulate_writecopy = atoi(env_str); + else simulate_writecopy = main_argc > 1 && ( + strstr(main_argv[1], "UplayWebCore.exe") + || strstr(main_argv[1], "Battle.net.exe") /* CW HACK 23072 */ + ); +} + /*********************************************************************** * start_main_thread */ @@ -2479,6 +2493,7 @@ static void start_main_thread(void) signal_init_thread( teb ); dbg_init(); startup_info_size = server_init_process(); + hacks_init(); msync_init(); esync_init(); virtual_map_user_shared_data(); diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index f5f410ae8701..fcad50f232af 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -163,6 +163,7 @@ extern USHORT ds32_sel DECLSPEC_HIDDEN; extern USHORT cs64_sel DECLSPEC_HIDDEN; #endif +extern BOOL simulate_writecopy; extern void init_environment( int argc, char *argv[], char *envp[] ) DECLSPEC_HIDDEN; extern void init_startup_info(void) DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 8ead2cc99d7f..24083571ca50 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -4134,6 +4134,33 @@ NTSTATUS WINAPI NtProtectVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T { old = get_win32_prot( vprot, view->protect ); status = set_protection( view, base, size, new_prot ); + + if (simulate_writecopy && status == STATUS_SUCCESS + && ((old == PAGE_WRITECOPY || old == PAGE_EXECUTE_WRITECOPY))) + { + TRACE("Setting VPROT_COPIED.\n"); + + set_page_vprot_bits(base, size, VPROT_COPIED, 0); + vprot |= VPROT_COPIED; + old = get_win32_prot( vprot, view->protect ); + } + else if (status == STATUS_SUCCESS && (view->protect & SEC_IMAGE) && + base == (void*)NtCurrentTeb()->Peb->ImageBaseAddress) + { + /* GTA5 HACK: Mark first page as copied. */ + const WCHAR gta5W[] = { 'g','t','a','5','.','e','x','e',0 }; + WCHAR *name, *p; + + name = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer; + p = wcsrchr(name, '\\'); + p = p ? p+1 : name; + + if(!wcsicmp(p, gta5W)) + { + FIXME("HACK: changing GTA5.exe vprot\n"); + set_page_vprot_bits(base, page_size, VPROT_COPIED, 0); + } + } } else status = STATUS_NOT_COMMITTED; } From e9fe5478552643b8aad885db5bf7422f68b23979 Mon Sep 17 00:00:00 2001 From: Isaac Marovitz Date: Fri, 17 May 2024 15:51:25 -0400 Subject: [PATCH 2/3] Define VPROT_COPIED --- dlls/ntdll/unix/virtual.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 24083571ca50..bd02e106f82f 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -120,6 +120,7 @@ struct file_view #define VPROT_GUARD 0x10 #define VPROT_COMMITTED 0x20 #define VPROT_WRITEWATCH 0x40 +#define VPROT_COPIED 0x80 /* per-mapping protection flags */ #define VPROT_SYSTEM 0x0200 /* system view (underlying mmap not under our control) */ From 56c8f4b26b0b8ebb2fafe14ffda74181b8c174e2 Mon Sep 17 00:00:00 2001 From: Isaac Marovitz Date: Fri, 17 May 2024 15:52:59 -0400 Subject: [PATCH 3/3] Remove Proton Hack --- dlls/ntdll/unix/virtual.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index bd02e106f82f..a8345548d801 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -4145,23 +4145,6 @@ NTSTATUS WINAPI NtProtectVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T vprot |= VPROT_COPIED; old = get_win32_prot( vprot, view->protect ); } - else if (status == STATUS_SUCCESS && (view->protect & SEC_IMAGE) && - base == (void*)NtCurrentTeb()->Peb->ImageBaseAddress) - { - /* GTA5 HACK: Mark first page as copied. */ - const WCHAR gta5W[] = { 'g','t','a','5','.','e','x','e',0 }; - WCHAR *name, *p; - - name = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer; - p = wcsrchr(name, '\\'); - p = p ? p+1 : name; - - if(!wcsicmp(p, gta5W)) - { - FIXME("HACK: changing GTA5.exe vprot\n"); - set_page_vprot_bits(base, page_size, VPROT_COPIED, 0); - } - } } else status = STATUS_NOT_COMMITTED; }