Under Wow64, disabling no-exec (done at the bottom of `alloc_module`) was failing.
Fixes crashes in games using older Steam DRM (where the EXE entry point is in a '.bind' section which is not marked executable)
From: Brendan Shanks bshanks@codeweavers.com
--- dlls/ntdll/unix/process.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c index 078ad75099d..83888717a5c 100644 --- a/dlls/ntdll/unix/process.c +++ b/dlls/ntdll/unix/process.c @@ -73,9 +73,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(process);
-static ULONG execute_flags = MEM_EXECUTE_OPTION_DISABLE | (sizeof(void *) > sizeof(int) ? - MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION | - MEM_EXECUTE_OPTION_PERMANENT : 0); +static ULONG execute_flags = MEM_EXECUTE_OPTION_DISABLE;
static UINT process_error_mode;
@@ -1434,8 +1432,14 @@ NTSTATUS WINAPI NtQueryInformationProcess( HANDLE handle, PROCESSINFOCLASS class
case ProcessExecuteFlags: len = sizeof(ULONG); - if (size == len) *(ULONG *)info = execute_flags; - else ret = STATUS_INFO_LENGTH_MISMATCH; + if (size != len) + ret = STATUS_INFO_LENGTH_MISMATCH; + else if (is_win64 && !NtCurrentTeb()->WowTebOffset) + *(ULONG *)info = MEM_EXECUTE_OPTION_DISABLE | + MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION | + MEM_EXECUTE_OPTION_PERMANENT; + else + *(ULONG *)info = execute_flags; break;
case ProcessPriorityClass: @@ -1560,7 +1564,7 @@ NTSTATUS WINAPI NtSetInformationProcess( HANDLE handle, PROCESSINFOCLASS class, break;
case ProcessExecuteFlags: - if (is_win64 || size != sizeof(ULONG)) return STATUS_INVALID_PARAMETER; + if ((is_win64 && !NtCurrentTeb()->WowTebOffset) || size != sizeof(ULONG)) return STATUS_INVALID_PARAMETER; if (execute_flags & MEM_EXECUTE_OPTION_PERMANENT) return STATUS_ACCESS_DENIED; else {
This doesn't seem to match the Windows behavior, according to the ntdll:info tests. Maybe we need to bring back 08c2555dd86969c157037b7850667175aa102f16, which was reverted in d2e35b04fb21ac51a02edd6d21ece1d3ac248f27? It would need more tests.
But d2e35b04fb21ac51a02edd6d21ece1d3ac248f27 had a test which showed that adding exec for a section with EP is not the case on Windows, at least in a generic case. And an older behaviour was breaking Halo Infinite DRM. Maybe IMAGE_DLLCHARACTERISTICS_NX_COMPAT flag should be handled there? Or something has changed in Windows and old apps might be getting some compatibility handling on Windows?
It seems like the test is failing under wow64 because the thunk for setting `ProcessExecuteFlags` always returns access denied: https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/wow64/process.c#L1088. After passing it through to `NtSetInformationProcess`, the tests pass. I can commit this.