[PATCH v4 0/1] MR11547: ntdll: Map high-entropy ASLR executables at a high address.
Only DLLs were given an address from the shared image address ranges, so executables were left to be mapped at their preferred ImageBase. Windows relocates executables that opt into ASLR like any other image, and places the ones with IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA high in the address space. Assign such executables an address from a separate range at 0x7ff600000000, leaving the ranges used for DLLs unchanged. -- v4: ntdll: Map high-entropy ASLR executables at a high address. https://gitlab.winehq.org/wine/wine/-/merge_requests/11547
From: xeralin <myal1n@icloud.com> Executables were mapped at their preferred ImageBase, since only DLLs are relocated by default. Windows relocates executables that opt into ASLR like any other image, and maps the ones with IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA in the 0x7ff6...-0x7ff8... range. --- dlls/ntdll/unix/unix_private.h | 4 ++++ dlls/ntdll/unix/virtual.c | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index c8ca97d21a0..237089b7798 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -57,6 +57,10 @@ static const BOOL is_win64 = (sizeof(void *) > sizeof(int)); static const ULONG_PTR limit_2g = (ULONG_PTR)1 << 31; static const ULONG_PTR limit_4g = (ULONG_PTR)((ULONGLONG)1 << 32); +/* range used on Windows for executables with high-entropy ASLR */ +static const ULONG_PTR high_entropy_low = (ULONG_PTR)((ULONGLONG)0x7ff6 << 32); +static const ULONG_PTR high_entropy_high = (ULONG_PTR)((ULONGLONG)0x7ff8 << 32); + static inline BOOL is_machine_64bit( WORD machine ) { return (machine == IMAGE_FILE_MACHINE_AMD64 || machine == IMAGE_FILE_MACHINE_ARM64); diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index db820a89525..8bcf0ce358e 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -3351,6 +3351,21 @@ static NTSTATUS map_image_view( struct file_view **view_ret, struct pe_image_inf limit_low = max( limit_low, (ULONG_PTR)address_space_start ); /* make sure the DOS area remains free */ if (!limit_high) limit_high = (ULONG_PTR)user_space_limit; + /* executables that opt into high-entropy ASLR are mapped high, like on Windows */ + + if (is_win64 && !(image_info->image_charact & IMAGE_FILE_DLL) && + (image_info->image_flags & IMAGE_FLAGS_ImageDynamicallyRelocated) && + (image_info->dll_charact & IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA)) + { + start = max( limit_low, high_entropy_low ); + end = min( limit_high, high_entropy_high ); + if (start < end) + { + status = map_view( view_ret, NULL, size, 0, vprot, start, end, 0 ); + if (!status) return status; + } + } + /* first try the specified base */ if (image_info->map_addr) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11547
Updated. The placement is now limited to the 0x7ff6...-0x7ff8... range Windows uses for executables. Without the upper bound the image ended up at the very top of the address space, which is where DLLs are mapped instead. Verified with a minimal executable linked with `--dynamicbase --high-entropy-va` and the same preferred base as the game: it maps at 0x140000000 on master and at 0x7ff600000000 with this change. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11547#note_147552
This is causing test failures on new wow64: ``` tools/runtest -q -P wine -T . -M ntdll.dll -p dlls/ntdll/tests/x86_64-windows/ntdll_test.exe wow64 && touch dlls/ntdll/tests/x86_64-windows/wow64.ok wow64.c:316: Test failed: current: wrong entry 000000014003A470 / 00007FF60003A470 wow64.c:316: Test failed: system32: wrong entry 00000001400222C0 / 00007FF6000222C0 wow64.c:316: Test failed: current: wrong entry 000000014003A470 / 00007FF60003A470 wow64.c:316: Test failed: system32: wrong entry 00000001400222C0 / 00007FF6000222C0 wow64.c:1361: Tests skipped: NtSetLdtEntries not supported make: *** [Makefile:166609: dlls/ntdll/tests/x86_64-windows/wow64.ok] Error 4 ``` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11547#note_149148
participants (3)
-
Alexandre Julliard (@julliard) -
Xera (@xeralin2) -
xeralin