[Bug 44988] Win86emu for Windows RT fails with error 'Can't reserve memory (file is too big or corrupted)' when trying to run x86 apps (PE loader / PE32 executables for ARMv7 require ASLR)

WineHQ Bugzilla wine-bugs at winehq.org
Mon May 25 08:58:41 CDT 2020


https://bugs.winehq.org/show_bug.cgi?id=44988

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
                URL|                            |https://forum.xda-developer
                   |                            |s.com/showthread.php?t=2095
                   |                            |934
          Component|-unknown                    |ntdll
           Keywords|                            |download
                 CC|                            |focht at gmx.net
             Status|UNCONFIRMED                 |NEW
            Summary|win86emu says "unable to    |Win86emu for Windows RT
                   |reserve memory" when i try  |fails with error 'Can't
                   |to run an x86 app on arm    |reserve memory (file is too
                   |                            |big or corrupted)' when
                   |                            |trying to run x86 apps (PE
                   |                            |loader / PE32 executables
                   |                            |for ARMv7 require ASLR)

--- Comment #4 from Anastasius Focht <focht at gmx.net> ---
Hello folks,

confirming. Not that it matters here but the project has been abandoned for
many years:

https://forum.xda-developers.com/showthread.php?t=2095934

The backtrace from comment #3 is invalid. You are not supposed to run
'peloader.exe' standalone. The app expects the environment variable
'EMU_PROGRAM' properly set. If the variable is empty you end up exactly with
that crash due to non-existing error handling. Use the .cmd wrappers or pass
environment/parameters properly.

--- snip ---
hikey960:~/projects/x86node/Windows$ file *.exe

autohook.exe:    PE32 executable (GUI) ARMv7 Thumb, for MS Windows
cmd.86.exe:      PE32 executable (console) Intel 80386, for MS Windows
launcher.exe:    PE32 executable (GUI) ARMv7 Thumb, for MS Windows
peloader.exe:    PE32 executable (GUI) ARMv7 Thumb, for MS Windows
peloaderc.exe:   PE32 executable (console) ARMv7 Thumb, for MS Windows
postinstall.exe: PE32 executable (console) ARMv7 Thumb, for MS Windows
regedit.86.exe:  PE32 executable (GUI) Intel 80386, for MS Windows
regsvr32.86.exe: PE32 executable (GUI) Intel 80386, for MS Windows
rundll32.86.exe: PE32 executable (GUI) Intel 80386, for MS Windows
thunk86.exe:     PE32 executable (GUI) ARMv7 Thumb, for MS Windows
thunk86c.exe:    PE32 executable (console) ARMv7 Thumb, for MS Windows
--- snip ---

Using the provided 'regedit.86.exe' for testing:

--- snip ---
$ WINEDEBUG=+seh,+relay,+process,+loaddll,+ntdll,+server,+virtual,+module
EMU_PROGRAM=regedit.86.exe wine ./thunk86.exe >>log.txt 2>&1
...
0024:trace:process:CreateProcessInternalW app
L"E:\\home\\focht\\projects\\x86node\\Windows\\peloader.exe" cmdline
L"thunk86.exe " 
...
00c4: load_dll( dbg_offset=0, base=00400000, name=7fe30a98, dbg_size=0,
filename=L"E:\\home\\focht\\projects\\x86node\\Windows\\peloader.exe" )
00c4: load_dll() = 0
00c4:trace:loaddll:load_native_dll Loaded
L"E:\\home\\focht\\projects\\x86node\\Windows\\peloader.exe" at 0x400000:
native
...
00c4: init_process_done( gui=1, module=00400000, ldt_copy=00000000,
entry=00401679, usd_handle=001c )
...
0024:trace:process:CreateProcessInternalW started process pid 00c0 tid 00c4
...
00c4:Starting process
L"E:\\home\\focht\\projects\\x86node\\Windows\\peloader.exe"
(entryproc=0x401679) 
...
00c4:Call KERNEL32.CreateFileW(7fe7bc20
L"regedit.86.exe",80000000,00000003,00000000,00000003,00000000,00000000)
ret=004010c3
00c4:Ret  KERNEL32.CreateFileW() retval=00000034 ret=004010c3
00c4:Call KERNEL32.ReadFile(00000034,8011fa98,00000200,8011fa8c,00000000)
ret=004010f5
00c4:Ret  KERNEL32.ReadFile() retval=00000001 ret=004010f5
00c4:Call KERNEL32.SetFilePointer(00000034,00000080,00000000,00000000)
ret=0040112d
00c4:Ret  KERNEL32.SetFilePointer() retval=00000080 ret=0040112d
00c4:Call KERNEL32.ReadFile(00000034,8011fa98,00000200,8011fa8c,00000000)
ret=0040114d
00c4:Ret  KERNEL32.ReadFile() retval=00000001 ret=0040114d
00c4:Call KERNEL32.VirtualAlloc(00400000,000c0000,00003000,00000004)
ret=004011c7
00c4:Call
ntdll.NtAllocateVirtualMemory(ffffffff,8011fa1c,00000000,8011fa14,00003000,00000004)
ret=7fb5c800
00c4:Ret  ntdll.NtAllocateVirtualMemory() retval=c0000018 ret=7fb5c800
00c4:Call ntdll.RtlNtStatusToDosError(c0000018) ret=7fb5c81c
00c4:Ret  ntdll.RtlNtStatusToDosError() retval=000001e7 ret=7fb5c81c
00c4:Ret  KERNEL32.VirtualAlloc() retval=00000000 ret=004011c7 
...
00c4:Call KERNEL32.ExitProcess(bad00000) ret=00401935
00c4: terminate_process( handle=0000, exit_code=-1160773632 )
00c4: terminate_process() = 0 { self=1 }
...
0024:Call KERNEL32.GetExitCodeProcess(00000060,80167b10) ret=00401187
0024:trace:process:NtQueryInformationProcess
(0x60,0x00000000,0x80167a78,0x00000018,(nil))
0024: get_process_info( handle=0060 )
0024: get_process_info() = 0 { pid=00c0, ppid=0020, affinity=000000ff,
peb=7ffcf000, start_time=1d63293fa98231a (-0.5552090), end_time=1d63293faebfeea
(-0.0056330), exit_code=-1160773632, priority=2, cpu=ARM, debugger_present=0,
debug_children=1 }
0024:Ret  KERNEL32.GetExitCodeProcess() retval=00000001 ret=00401187
...
0024:Call KERNEL32.CreateProcessA(80167b80
"E:\\home\\focht\\projects\\x86node\\Windows\\peloader.exe",80167c88
"thunk86.exe
",00000000,00000000,00000001,00000000,00000000,00000000,80167b18,80167b00)
ret=00401135 
...
<retries to start process two times before giving up>
...
0024:Call user32.MessageBoxW(00000000,0040a2e0 L"Can't reserve memory (file is
too big or corrupted)",0040a248 L"Error",00000010) ret=00401231 
--- snip ---

The PE loader/hosting process main executable (armv7) occupies the default load
address 0x400000. The loader reads the PE header of the x86 executable and
tries to reserve the same region in order to map the executable there later
(same load base). This obviously can't work.

Some notes from the developer:

https://forum.xda-developers.com/showthread.php?t=2095934&page=9

--- quote ---
This is exactly what I'm doing now. peloader.exe - is a tiny loader that
reserves the memory at its start. It determines the program image base and
image size and reserves the memory at that address. If the address is already
used - it exits complaining about ASLR. Here I abuse ASLR for my own needs - at
next program start OS would be using different addresses for its data
(environment block and so on), so I usually can reserve needed memory at 1-2
restarts.
There is a bug in peloader. It reserves the memory for the whole EXE file size,
including the overlayed data in its end. So self-extracting archives would
require too much memory to be loaded successfully.
...
--- quote ---

Which implies Windows RT OS loader uses ASLR by default. PE32 executables for
ARMv7 should not be mapped at 0x400000 (default load base from PE header). Does
someone have WinRT device to confirm?

$ sha1sum x86node.zip 
a85eec05496c1abc24ba7f26a8fb368d11449e4a  x86node.zip

$ du -sh x86node.zip 
48M    x86node.zip

$ wine --version
wine-5.9

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