https://bugs.winehq.org/show_bug.cgi?id=48423
Bug ID: 48423 Summary: Add support of address space layout randomization (ASLR) for PE images with DLLCHARACTERISTICS_DYNAMIC_BASE Product: Wine Version: 5.0-rc4 Hardware: x86-64 OS: Linux Status: NEW Severity: normal Priority: P2 Component: ntdll Assignee: wine-bugs@winehq.org Reporter: focht@gmx.net Distribution: ---
Hello folks,
split out from bug 48417
Partial copy/pasta of https://bugs.winehq.org/show_bug.cgi?id=48417#c4
llvm project lld supports option '--dynamicbase' which is used for ASLR.
https://github.com/llvm/llvm-project/blob/b11386f9be9b2dc7276a758d64f66833da...
--- snip --- if (config->dynamicBase) pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE; --- snip ---
Using Martin's https://github.com/mstorsjo/llvm-mingw I've injected '-Wl,--dynamicbase' into 'CROSSLDFLAGS'.
--- snip --- $ winedump $(winepath -u "c:\windows\syswow64\kernelbase.dll") Contents of /home/focht/.wine/dosdevices/c:/windows/syswow64/kernelbase.dll: 1802240 bytes
*** This is a Wine builtin DLL ***
File Header Machine: 014C (i386) Number of Sections: 13 TimeDateStamp: 5E11DCBC (Sun Jan 5 13:55:24 2020) offset 128 PointerToSymbolTable: 001B7E00 NumberOfSymbols: 00000000 SizeOfOptionalHeader: 00E0 Characteristics: 2102 EXECUTABLE_IMAGE 32BIT_MACHINE DLL
Optional Header (32bit) Magic 0x10B 267 linker version 14.00 size of code 0x46800 288768 size of initialized data 0x171200 1511936 size of uninitialized data 0x0 0 entrypoint RVA 0x20850 133200 base of code 0x1000 4096 base of data 0x0 0 image base 0x10000000 268435456 section align 0x1000 4096 file align 0x200 512 required OS version 6.00 image version 0.00 subsystem version 6.00 Win32 Version 0x0 0 size of image 0x1c1000 1839104 size of headers 0x400 1024 checksum 0x0 0 Subsystem 0x2 (Windows GUI) DLL characteristics: 0x140 DYNAMIC_BASE NX_COMPAT stack reserve size 0x100000 1048576 stack commit size 0x1000 4096 heap reserve size 0x100000 1048576 heap commit size 0x1000 4096 loader flags 0x0 0 RVAs & sizes 0x10 16
Data Directory EXPORT rva: 0x72468 size: 0xa8e3 IMPORT rva: 0x7cd4b size: 0x28 RESOURCE rva: 0x0 size: 0x0 EXCEPTION rva: 0x0 size: 0x0 SECURITY rva: 0x0 size: 0x0 BASERELOC rva: 0x85000 size: 0x4158 DEBUG rva: 0x80000 size: 0x1c ARCHITECTURE rva: 0x0 size: 0x0 GLOBALPTR rva: 0x0 size: 0x0 TLS rva: 0x0 size: 0x0 LOAD_CONFIG rva: 0x0 size: 0x0 Bound IAT rva: 0x0 size: 0x0 IAT rva: 0x7d324 size: 0x5b0 Delay IAT rva: 0x0 size: 0x0 CLR Header rva: 0x0 size: 0x0 rva: 0x0 size: 0x0
Done dumping /home/focht/.wine/dosdevices/c:/windows/syswow64/kernelbase.dll --- snip ---
'DLL characteristics' -> 'DYNAMIC_BASE'
Dlls will still have the default image base set though:
https://github.com/llvm/llvm-project/blob/d3fec7fb456138c83b84e38ce785ea6bfa...
--- snip --- static uint64_t getDefaultImageBase() { if (config->is64()) return config->dll ? 0x180000000 : 0x140000000; return config->dll ? 0x10000000 : 0x400000; } --- snip ---
https://github.com/llvm/llvm-project/blob/d3fec7fb456138c83b84e38ce785ea6bfa...
--- snip --- // Set default image base if /base is not given. if (config->imageBase == uint64_t(-1)) config->imageBase = getDefaultImageBase(); --- snip ---
The problem: ASLR isn't supported in Wine loader yet.
--- snip --- $ grep -Hrn DYNAMIC_BASE
dlls/kernel32/tests/loader.c:462: if (!(nt_header->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE)) dlls/kernel32/tests/loader.c:1123: nt_header.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE; dlls/kernel32/tests/loader.c:1297: nt64.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE; dlls/kernel32/tests/loader.c:1408: nt32.OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE;
dlls/fusion/tests/asmcache.c:328: IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE |
tools/winedump/pe.c:218: X(IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE, "DYNAMIC_BASE");
server/mapping.c:651: if ((nt.opt.hdr32.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) && server/mapping.c:691: if ((nt.opt.hdr64.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) &&
include/winnt.h:2986:#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040 --- snip ---
--- snip --- $ grep -Hrni DynamicallyRelocated
dlls/kernel32/tests/loader.c:387: (S(U(image)).ImageDynamicallyRelocated && LOWORD(image.TransferAddress) == LOWORD(entry_point)), dlls/kernel32/tests/loader.c:463: ok( !S(U(image)).ImageDynamicallyRelocated || broken( S(U(image)).ComPlusILOnly ), /* <= win7 */ dlls/kernel32/tests/loader.c:464: "%u: wrong ImageDynamicallyRelocated flags %02x\n", id, U(image).ImageFlags ); dlls/kernel32/tests/loader.c:466: ok( S(U(image)).ImageDynamicallyRelocated || broken(is_winxp), dlls/kernel32/tests/loader.c:467: "%u: wrong ImageDynamicallyRelocated flags %02x\n", id, U(image).ImageFlags ); dlls/kernel32/tests/loader.c:469: ok( !S(U(image)).ImageDynamicallyRelocated || broken(TRUE), /* <= win8 */ dlls/kernel32/tests/loader.c:470: "%u: wrong ImageDynamicallyRelocated flags %02x\n", id, U(image).ImageFlags );
server/protocol.def:767:#define IMAGE_FLAGS_ImageDynamicallyRelocated 0x04
server/mapping.c:653: mapping->image.image_flags |= IMAGE_FLAGS_ImageDynamicallyRelocated; server/mapping.c:693: mapping->image.image_flags |= IMAGE_FLAGS_ImageDynamicallyRelocated;
include/winternl.h:2028: UCHAR ImageDynamicallyRelocated : 1;
include/wine/server_protocol.h:751:#define IMAGE_FLAGS_ImageDynamicallyRelocated 0x04 --- snip ---
Supporting ASLR in Wine loader would bring the PE binaries created with mingw cross-toolchain in line with what's produced by Microsoft's toolchains by default -> https://web.archive.org/web/20200105131452/https://devblogs.microsoft.com/cp...
Tidbit: https://insights.sei.cmu.edu/cert/2018/08/when-aslr-is-not-really-aslr---the...
$ wine --version wine-5.0-rc4
Regards