[Bug 48423] New: Add support of address space layout randomization (ASLR) for PE images with DLLCHARACTERISTICS_DYNAMIC_BASE

WineHQ Bugzilla wine-bugs at winehq.org
Sun Jan 5 14:08:59 CST 2020


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 at winehq.org
          Reporter: focht at 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/b11386f9be9b2dc7276a758d64f66833da10bdea/lld/COFF/Writer.cpp#L1359

--- 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/d3fec7fb456138c83b84e38ce785ea6bfa59c30b/lld/COFF/Driver.cpp#L599

--- 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/d3fec7fb456138c83b84e38ce785ea6bfa59c30b/lld/COFF/Driver.cpp#L1788

--- 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/cppblog/dynamicbase-and-nxcompat/

Tidbit:
https://insights.sei.cmu.edu/cert/2018/08/when-aslr-is-not-really-aslr---the-case-of-incorrect-assumptions-and-bad-defaults.html

$ wine --version
wine-5.0-rc4

Regards

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list