http://bugs.winehq.org/show_bug.cgi?id=11121
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |obfuscation CC| |focht@gmx.net Component|directx-d3d |ntdll Summary|crash in/after |Night Watch crashes on |IWineD3DDeviceImpl_BeginSce |startup (StarForce v3, |ne |loader: section | |SizeOfRawData vs. | |FileAlignment violation, | |zero padding of section | |remainder wipes out code | |executed at runtime)
--- Comment #18 from Anastasius Focht focht@gmx.net --- Hello folks,
confirming, the game is protected with StarForce v3 and needs 'no-CD' patch to be useful at all. The initial crash (attachment from comment #14) is already covered by StarForce bug(s).
I'm making this bug about the crash of no-CD version which highlights a valid problem with Wine.
(msvcr71 and msvcp71 were forced to 'builtin' to give a bit more context)
--- snip --- $ pwd /home/focht/.wine/drive_c/Program Files/NightWatch/Run
$ WINEDEBUG=+tid,+seh,+relay,+msvcrt,+msvcp wine ./NWatch.exe >>log.txt 2>&1 ...
0031:Call KERNEL32.OutputDebugStringA(00ab0bd8 "<color=grey>scenario tracker: scenario zone has 0 item slots and 0 person slots\n") ret=00496b93 0031:Ret KERNEL32.OutputDebugStringA() retval=00000000 ret=00496b93 ... 0031:Call KERNEL32.CreateFileW(0793dc90 L"temp\197_5467.sav",80000000,00000003,0033f5c0,00000003,00000080,00000000) ret=7e72c10d 0031:Ret KERNEL32.CreateFileW() retval=ffffffff ret=7e72c10d ... 0031:Call msvcrt._CxxThrowException(0033f7d4,00a080fc) ret=0045baf2 0031:Call KERNEL32.RaiseException(e06d7363,00000001,00000003,0033f764) ret=7e71a3a1 0031:trace:seh:raise_exception code=e06d7363 flags=1 addr=0x7b83a8ef ip=7b83a8ef tid=0031 0031:trace:seh:raise_exception info[0]=19930520 0031:trace:seh:raise_exception info[1]=0033f7d4 0031:trace:seh:raise_exception info[2]=00a080fc 0031:trace:seh:raise_exception eax=7b826921 ebx=7b8ba000 ecx=19930520 edx=0033f6b4 esi=0033f760 edi=0033f720 0031:trace:seh:raise_exception ebp=0033f6f8 esp=0033f694 cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00000283 ... 0031:Call KERNEL32.OutputDebugStringA(00ab0bd8 "WARNING: Can't load zone197_5467.sav\n") ret=00496b93 0031:Ret KERNEL32.OutputDebugStringA() retval=00000000 ret=00496b93 ... 0031:trace:seh:call_catch_block done, continuing at 0x4e6a08 ... 0031:Call KERNEL32.OutputDebugStringA(00ab0bd8 "WORLD VALID: no ADRESS 0\n") ret=00496b93 0031:Ret KERNEL32.OutputDebugStringA() retval=00000000 ret=00496b93 ... 0031:trace:seh:call_catch_block done, continuing at 0x4e6a08 ... 0031:Call KERNEL32.OutputDebugStringA(00ab0bd8 "WORLD VALID: no ADRESS 0\n") ret=00496b93 0031:Ret KERNEL32.OutputDebugStringA() retval=00000000 ret=00496b93 0031:trace:seh:raise_exception code=c0000005 flags=0 addr=0x90a810 ip=0090a810 tid=0031 0031:trace:seh:raise_exception info[0]=00000001 0031:trace:seh:raise_exception info[1]=00000000 0031:trace:seh:raise_exception eax=00000000 ebx=7b3f24c8 ecx=7b3f24c8 edx=0000005f esi=7b3f24c8 edi=00000000 0031:trace:seh:raise_exception ebp=00000000 esp=0033f860 cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00010246 0031:trace:seh:call_stack_handlers calling handler at 0x964e18 code=c0000005 flags=0 0031:trace:seh:call_stack_handlers handler at 0x964e18 returned 1 ... 0031:trace:seh:cxx_frame_handler handling C exception code c0000005 rec 0x33f808 frame 0x33fd6c trylevel 67 descr 0xa0413c nested_frame (nil) ... 0031:Call msvcrt._except_handler3(0033f808,0033fe10,0033f53c,0033f3cc) ret=7bc85e4d 0031:trace:seh:_except_handler3 exception c0000005 flags=0 at 0x90a810 handler=0x58649c 0x33f53c 0x33f3cc semi-stub 0031:trace:seh:_except_handler3 level 0 prev -1 filter 0x5860c8 0031:Call msvcrt._XcptFilter(c0000005,0033f2a4) ret=005860d9 0031:trace:seh:_XcptFilter (c0000005,0x33f2a4) 0031:Ret msvcrt._XcptFilter() retval=00000000 ret=005860d9 0031:trace:seh:_except_handler3 filter returned CONTINUE_SEARCH 0031:trace:seh:_except_handler3 reached TRYLEVEL_END, returning ExceptionContinueSearch 0031:Ret msvcrt._except_handler3() retval=00000001 ret=7bc85e4d 0031:trace:seh:call_stack_handlers handler at 0x58649c returned 1 0031:trace:seh:call_stack_handlers calling handler at 0x7bc9dc4f code=c0000005 flags=0 0031:Call KERNEL32.UnhandledExceptionFilter(0033f334) ret=7bc9dc89 ... wine: Unhandled page fault on write access to 0x00000000 at address 0x90a810 (thread 0031), starting debugger... --- snip ---
The game tries to load a (non-existing) savegame on startup and throws a C++ exception for handling the error. The catch block is found and executed (dumps error message).
Next, some validation on the game state is done which fails because the savegame didn't restore a valid 'world' state. During that (failing) check the execution flow reaches an area which is zero-filled - hence the page fault at address 0x90a810.
I did an off-line analysis of the StarForce v3 protected binary (disassembly) and to my surprise I found valid opcodes at the location where the fault occurred. The code is located in '.idata' section of PE binary. Someone played dirty here and partially wiped out the section contents.
After firing up a debugger I quickly nailed it down ... at the time when the entry point was reached the opcodes were already wiped out. Code in '.sforce3' section had the same problem - wipe out at the end.
WINEDEBUG=+module,+virtual to the help ;-)
--- snip --- ... 0039:trace:process:__wine_kernel_init starting process name=L"C:\Program Files\NightWatch\Run\NWatch.exe" argv[0]=L"C:\Program Files\NightWatch\Run\NWatch.exe" ... 0039:trace:module:load_native_dll Trying native dll L"C:\Program Files\NightWatch\Run\NWatch.exe" 0039:trace:virtual:NtMapViewOfSection handle=0x1c process=0xffffffff addr=(nil) off=000000000 size=0 access=20 0039:trace:virtual:VIRTUAL_DumpView View: 0x400000 - 0xafbfff (anonymous) 0039:trace:virtual:VIRTUAL_DumpView 0x400000 - 0xafbfff c-rWx
0039:trace:module:map_image mapped PE file at 0x400000-0xafc000
0039:trace:module:map_image mapping section .sforce3 at 0x401000 off 1000 size 508ba0 virt 509000 flags 60000040 0039:trace:module:map_image clearing 0x909c00 - 0x90a000
0039:trace:module:map_image mapping section .idata at 0x90a000 off 50a000 size 224 virt 1000 flags e0000040 0039:trace:module:map_image clearing 0x90a400 - 0x90b000
0039:trace:module:map_image mapping section .brick at 0x90b000 off 50b000 size 89000 virt 89000 flags e0000040
0039:trace:module:map_image mapping section .RDATA at 0x994000 off 594000 size 1000 virt 1000 flags e0000040
0039:trace:module:map_image mapping section .brick at 0x995000 off 595000 size b6000 virt b6000 flags e0000040
0039:trace:module:map_image mapping section .RDATA at 0xa4b000 off 64b000 size c62 virt 1000 flags e0000040 0039:trace:module:map_image clearing 0xa4be00 - 0xa4c000
0039:trace:module:map_image mapping section .brick at 0xa4c000 off 64c000 size ab000 virt ab000 flags e0000040
0039:trace:module:map_image mapping section .tls at 0xaf7000 off 6f7000 size 9 virt 1000 flags e0000040 0039:trace:module:map_image clearing 0xaf7200 - 0xaf8000
0039:trace:module:map_image mapping section .rsrc at 0xaf8000 off 6f8000 size 1f90 virt 1f90 flags e0000040
0039:trace:module:map_image mapping section .start at 0xafa000 off 6fa000 size 2000 virt 2000 flags e0000060
0039:trace:virtual:VIRTUAL_SetProt 0x400000-0x400fff c-r-- 0039:trace:virtual:VIRTUAL_DumpView View: 0x400000 - 0xafbfff (anonymous) 0039:trace:virtual:VIRTUAL_DumpView 0x400000 - 0x400fff c-r-- 0039:trace:virtual:VIRTUAL_DumpView 0x401000 - 0xafbfff c-rW- 0039:trace:virtual:VIRTUAL_SetProt 0x401000-0x909fff c-r-x 0039:trace:virtual:VIRTUAL_DumpView View: 0x400000 - 0xafbfff (anonymous) 0039:trace:virtual:VIRTUAL_DumpView 0x400000 - 0x400fff c-r-- 0039:trace:virtual:VIRTUAL_DumpView 0x401000 - 0x909fff c-r-x 0039:trace:virtual:VIRTUAL_DumpView 0x90a000 - 0xafbfff c-rW- 0039:trace:virtual:VIRTUAL_SetProt 0x90a000-0x90afff c-rWx 0039:trace:virtual:VIRTUAL_DumpView View: 0x400000 - 0xafbfff (anonymous) 0039:trace:virtual:VIRTUAL_DumpView 0x400000 - 0x400fff c-r-- 0039:trace:virtual:VIRTUAL_DumpView 0x401000 - 0x909fff c-r-x 0039:trace:virtual:VIRTUAL_DumpView 0x90a000 - 0x90afff c-rWx 0039:trace:virtual:VIRTUAL_DumpView 0x90b000 - 0xafbfff c-rW- 0039:trace:virtual:VIRTUAL_SetProt 0x90b000-0x993fff c-rWx 0039:trace:virtual:VIRTUAL_DumpView View: 0x400000 - 0xafbfff (anonymous) 0039:trace:virtual:VIRTUAL_DumpView 0x400000 - 0x400fff c-r-- 0039:trace:virtual:VIRTUAL_DumpView 0x401000 - 0x909fff c-r-x 0039:trace:virtual:VIRTUAL_DumpView 0x90a000 - 0x993fff c-rWx 0039:trace:virtual:VIRTUAL_DumpView 0x994000 - 0xafbfff c-rW- 0039:trace:virtual:VIRTUAL_SetProt 0x994000-0x994fff c-rWx 0039:trace:virtual:VIRTUAL_DumpView View: 0x400000 - 0xafbfff (anonymous) 0039:trace:virtual:VIRTUAL_DumpView 0x400000 - 0x400fff c-r-- 0039:trace:virtual:VIRTUAL_DumpView 0x401000 - 0x909fff c-r-x 0039:trace:virtual:VIRTUAL_DumpView 0x90a000 - 0x994fff c-rWx 0039:trace:virtual:VIRTUAL_DumpView 0x995000 - 0xafbfff c-rW- 0039:trace:virtual:VIRTUAL_SetProt 0x995000-0xa4afff c-rWx 0039:trace:virtual:VIRTUAL_DumpView View: 0x400000 - 0xafbfff (anonymous) 0039:trace:virtual:VIRTUAL_DumpView 0x400000 - 0x400fff c-r-- 0039:trace:virtual:VIRTUAL_DumpView 0x401000 - 0x909fff c-r-x 0039:trace:virtual:VIRTUAL_DumpView 0x90a000 - 0xa4afff c-rWx 0039:trace:virtual:VIRTUAL_DumpView 0xa4b000 - 0xafbfff c-rW- 0039:trace:virtual:VIRTUAL_SetProt 0xa4b000-0xa4bfff c-rWx 0039:trace:virtual:VIRTUAL_DumpView View: 0x400000 - 0xafbfff (anonymous) 0039:trace:virtual:VIRTUAL_DumpView 0x400000 - 0x400fff c-r-- 0039:trace:virtual:VIRTUAL_DumpView 0x401000 - 0x909fff c-r-x 0039:trace:virtual:VIRTUAL_DumpView 0x90a000 - 0xa4bfff c-rWx 0039:trace:virtual:VIRTUAL_DumpView 0xa4c000 - 0xafbfff c-rW- 0039:trace:virtual:VIRTUAL_SetProt 0xa4c000-0xaf6fff c-rWx 0039:trace:virtual:VIRTUAL_DumpView View: 0x400000 - 0xafbfff (anonymous) 0039:trace:virtual:VIRTUAL_DumpView 0x400000 - 0x400fff c-r-- 0039:trace:virtual:VIRTUAL_DumpView 0x401000 - 0x909fff c-r-x 0039:trace:virtual:VIRTUAL_DumpView 0x90a000 - 0xaf6fff c-rWx 0039:trace:virtual:VIRTUAL_DumpView 0xaf7000 - 0xafbfff c-rW- 0039:trace:virtual:VIRTUAL_SetProt 0xaf7000-0xaf7fff c-rWx 0039:trace:virtual:VIRTUAL_DumpView View: 0x400000 - 0xafbfff (anonymous) 0039:trace:virtual:VIRTUAL_DumpView 0x400000 - 0x400fff c-r-- 0039:trace:virtual:VIRTUAL_DumpView 0x401000 - 0x909fff c-r-x 0039:trace:virtual:VIRTUAL_DumpView 0x90a000 - 0xaf7fff c-rWx 0039:trace:virtual:VIRTUAL_DumpView 0xaf8000 - 0xafbfff c-rW- 0039:trace:virtual:VIRTUAL_SetProt 0xaf8000-0xaf9fff c-rWx 0039:trace:virtual:VIRTUAL_DumpView View: 0x400000 - 0xafbfff (anonymous) 0039:trace:virtual:VIRTUAL_DumpView 0x400000 - 0x400fff c-r-- 0039:trace:virtual:VIRTUAL_DumpView 0x401000 - 0x909fff c-r-x 0039:trace:virtual:VIRTUAL_DumpView 0x90a000 - 0xaf9fff c-rWx 0039:trace:virtual:VIRTUAL_DumpView 0xafa000 - 0xafbfff c-rW- 0039:trace:virtual:VIRTUAL_SetProt 0xafa000-0xafbfff c-rWx 0039:trace:virtual:VIRTUAL_DumpView View: 0x400000 - 0xafbfff (anonymous) 0039:trace:virtual:VIRTUAL_DumpView 0x400000 - 0x400fff c-r-- 0039:trace:virtual:VIRTUAL_DumpView 0x401000 - 0x909fff c-r-x 0039:trace:virtual:VIRTUAL_DumpView 0x90a000 - 0xafbfff c-rWx 0039:warn:module:alloc_module disabling no-exec because of L"NWatch.exe" --- snip ---
'clearing 0x909c00 - 0x90a000' -> zero-init until page boundary of '.sforce3' section
'clearing 0x90a400 - 0x90b000' -> zero-init until page boundary of '.idata' section
Remember the page fault address? 0x90a810 -> bingo ;-)
MSDN/PE-COFF spec:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms680341%28v=vs.85%2...
--- quote --- IMAGE_SECTION_HEADER structure
...
SizeOfRawData
The size of the initialized data on disk, in bytes. This value must be a multiple of the FileAlignment member of the IMAGE_OPTIONAL_HEADER structure. If this value is less than the VirtualSize member, the remainder of the section is filled with zeroes. If the section contains only uninitialized data, the member is zero. --- quote ---
'.idata at 0x90a000 off 50a000 size 224 virt 1000 flags e0000040'
VirtualSize = 0x1000 SizeOfRawData = 0x224
Dumping the optional PE header with 'LordPE' gives some insight...
--- snip --- ->Optional Header Magic: 0x010B (HDR32_MAGIC) MajorLinkerVersion: 0x4B MinorLinkerVersion: 0x18 -> 75.24 SizeOfCode: 0x0057D000 SizeOfInitializedData: 0x001DD800 SizeOfUninitializedData: 0x00000000 AddressOfEntryPoint: 0x00185F02 BaseOfCode: 0x00001000 BaseOfData: 0x0057E000 ImageBase: 0x00400000 SectionAlignment: 0x00001000 FileAlignment: 0x00001000 ... --- snip ---
The requirement 'SizeOfRawData = multiple of the FileAlignment' seems to be violated here. Maybe this is the reason why the Windows loader treats the section remainder differently in this case.
For testing I disabled the zero-padding of section remainder to next boundary when this requirement was not met:
http://source.winehq.org/git/wine.git/blob/e8eb781327457b39c3578f8f651671499...
It made the game work ;-)
* intro movie/cutscenes. * main menu * gameplay (I played a bit - no crash)
$ sha1sum Night_Watch_DEMO_english.exe du -sh 826a6318a016d86fab6172eab23b4a15b2b92f54 Night_Watch_DEMO_english.exe
$ du -sh Night_Watch_DEMO_english.exe 458M Night_Watch_DEMO_english.exe
$ wine --version wine-1.7.8-232-g3bad812
Regards