[Bug 46949] New: DDraw games using older windowed mode wrappers such as DirectX Windower Embedded v2.3 /D3D Windower v1.x crash (ddraw_palette_vtbl and ddraw_surface{1,2,3,4, 7}_vtbl need to be writable)
wine-bugs at winehq.org
wine-bugs at winehq.org
Tue Apr 2 17:48:35 CDT 2019
https://bugs.winehq.org/show_bug.cgi?id=46949
Bug ID: 46949
Summary: DDraw games using older windowed mode wrappers such as
DirectX Windower Embedded v2.3/D3D Windower v1.x crash
(ddraw_palette_vtbl and ddraw_surface{1,2,3,4,7}_vtbl
need to be writable)
Product: Wine
Version: 4.5
Hardware: x86-64
OS: Linux
Status: NEW
Severity: normal
Priority: P2
Component: directx-d3d
Assignee: wine-bugs at winehq.org
Reporter: focht at gmx.net
Distribution: ---
Hello folks,
encountered while investigating bug 44803 ("Age of Empires II Forgotten Empires
crashes "Unhandled privileged instruction").
There are various community installers that claim to add windowed mode support
for old DDraw-based games. The presence of older windowed mode wrappers causes
the games to crash. These old wrappers (over)write function pointers directly
to vtables without changing the page protection.
--- snip ---
-=[ ProtectionID v0.6.9.0 DECEMBER]=-
(c) 2003-2017 CDKiLLER & TippeX
Build 24/12/17-21:05:42
Ready...
Scanning -> C:\Program Files (x86)\Microsoft Games\Age of Empires
II\age2_x1\wndmode.dll
File Type : 32-Bit Dll (Subsystem : Win GUI / 2), Size : 778752 (0BE200h)
Byte(s) | Machine: 0x14C (I386)
Compilation TimeStamp : 0x413D41E7 -> Tue 07th Sep 2004 05:06:47 (GMT)
[TimeStamp] 0x413D41E7 -> Tue 07th Sep 2004 05:06:47 (GMT) | PE Header | - |
Offset: 0x00000208 | VA: 0x00400208 | -
[File Heuristics] -> Flag #1 : 00000000000000001000000000100000 (0x00008020)
[Entrypoint Section Entropy] : 6.54 (section #0) ".text " | Size : 0x98400
(623616) byte(s)
[DllCharacteristics] -> Flag : (0x0000) -> NONE
[SectionCount] 7 (0x7) | ImageSize 0xC8000 (819200) byte(s)
[VersionInfo] Product Name : DirectX Windower Embedded v2.3 (based on D3D
Windower v1.88)
[VersionInfo] File Description : DirectX Windower Embedded
[VersionInfo] File Version : 2.3.0.12
[VersionInfo] Original FileName : wndmode.dll
[VersionInfo] Legal Copyrights : (C) 2008 VEG <veg at tut.by>. (C) 2004 menopem
<menopem at yahoo.co.jp>
[ModuleReport] [IAT] Modules -> KERNEL32.DLL | ADVAPI32.DLL | COMCTL32.DLL |
GDI32.DLL | OLE32.DLL | OLEAUT32.DLL | USER32.DLL | VERSION.DLL | WINMM.DLL
[CdKeySerial] found "Invalid code" @ VA: 0x00096E24 / Offset: 0x00096424
[CompilerDetect] -> Borland C/C++
[!] File appears to have no protection or is using an unknown protection
- Scan Took : 0.410 Second(s) [00000019Ah (410) tick(s)] [246 of 580 scan(s)
done]
--- snip ---
--- snip ---
$ winedbg --gdb ./age2_x2.exe
Wine-gdb> bt
#0 ddraw1_CreatePalette (iface=0x192a7c, flags=68, entries=0x32c048,
palette=0x9261fc, outer_unknown=0x0) at
/home/focht/projects/wine/mainline-src/dlls/ddraw/ddraw.c:3521
#1 0x00b21274 in ?? ()
#2 0x005a1019 in ?? ()
#3 0x00000000 in ?? ()
...
Wine-gdb> x/10i $eip
=> 0xb21291: movl $0xb212a0,0x18(%edx)
0xb21298: pop %ebx
0xb21299: pop %ebp
0xb2129a: ret $0x14
Wine-gdb> x/10x $edx
0x1c0588: 0x7e0e21c8 0x00000001 0x001c0748 0x00192a70
0x1c0598: 0x00000000 0x00000044 0x00000000 0x001c0580
0x1c05a8: 0x00000080 0x00455355
Wine-gdb> x/10x 0x7e0e21c8
0x7e0e21c8 <ddraw_palette_vtbl>: 0x7e09f667 0x7e09f74d 0x7e09f7fc
0x7e09f9a7
0x7e0e21d8 <ddraw_palette_vtbl+16>: 0x7e09fb32 0x7e09f92c 0x7e09fa42
0x00000000
0x7e0e21e8: 0x00000000 0x00000000
--- snip ---
Obviously can't work because the vtable is const data:
https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ddraw/palette.c#l221
--- snip ---
221 static const struct IDirectDrawPaletteVtbl ddraw_palette_vtbl =
222 {
223 /*** IUnknown ***/
224 ddraw_palette_QueryInterface,
225 ddraw_palette_AddRef,
226 ddraw_palette_Release,
227 /*** IDirectDrawPalette ***/
228 ddraw_palette_GetCaps,
229 ddraw_palette_GetEntries,
230 ddraw_palette_Initialize,
231 ddraw_palette_SetEntries
232 };
--- snip ---
--- snip ---
Thread 1 received signal SIGSEGV, Segmentation fault.
0x00b2b130 in ?? ()
Wine-gdb> bt
#0 0x00b2b130 in ?? ()
#1 0x00b2163c in ?? ()
#2 0x005a14c4 in ?? ()
#3 0x001c0fc8 in ?? ()
#4 0x00192a7c in ?? ()
Wine-gdb> x/10i 0x00b2b130
=> 0xb2b130: rep movsl %ds:(%esi),%es:(%edi)
0xb2b132: pop %edi
0xb2b133: pop %esi
0xb2b134: mov -0x44(%ebp),%ecx
0xb2b137: push %ecx
0xb2b138: mov -0x44(%ebp),%edx
0xb2b13b: test %edx,%edx
0xb2b13d: jne 0xb2b143
0xb2b13f: xor %ecx,%ecx
Wine-gdb> info reg
eax 0x7e070500 2114389248
ecx 0x24 36
edx 0x7e070500 2114389248
ebx 0x1c03c8 1835976
esp 0x32ba7c 0x32ba7c
ebp 0x32bb14 0x32bb14
esi 0xbbeae4 12315364
edi 0x7e070500 2114389248
eip 0xb2b130 0xb2b130
eflags 0x210246 [ PF ZF IF RF ID ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x63 99
gs 0x6b 107
Wine-gdb> x/10x 0x7e070500
0x7e070500 <ddraw_surface1_vtbl>: 0x7e02f169 0x7e02f7fb 0x7e03030f
0x7e0341b1
0x7e070510 <ddraw_surface1_vtbl+16>: 0x7e034a8f 0x7e033a73 0x7e03648a
0x7e03aa33
0x7e070520 <ddraw_surface1_vtbl+32>: 0x7e034784 0x7e036a03
--- snip ---
https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ddraw/surface.c#l5600
--- snip ---
5600 static const struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl =
5601 {
5602 /* IUnknown */
5603 ddraw_surface1_QueryInterface,
5604 ddraw_surface1_AddRef,
5605 ddraw_surface1_Release,
...
--- snip ---
--- snip ---
Wine-gdb> bt
#0 0x00b2b1d6 in ?? ()
#1 0x00b2163c in ?? ()
#2 0x005a14c4 in ?? ()
#3 0x001c0fc8 in ?? ()
#4 0x00192a7c in ?? ()
Wine-gdb> x/10i 0x00b2b1d6
=> 0xb2b1d6: rep movsl %ds:(%esi),%es:(%edi)
0xb2b1d8: pop %edi
0xb2b1d9: pop %esi
0xb2b1da: mov -0x48(%ebp),%ecx
0xb2b1dd: push %ecx
0xb2b1de: mov -0x48(%ebp),%edx
0xb2b1e1: test %edx,%edx
0xb2b1e3: jne 0xb2b1e9
0xb2b1e5: xor %ecx,%ecx
0xb2b1e7: jmp 0xb2b238
ine-gdb> info reg
eax 0x7e0704e0 2114389216
ecx 0x27 39
edx 0x7e0704e0 2114389216
ebx 0x1c03c8 1835976
esp 0x32ba7c 0x32ba7c
ebp 0x32bb14 0x32bb14
esi 0xbbeb74 12315508
edi 0x7e0704e0 2114389216
eip 0xb2b1d6 0xb2b1d6
eflags 0x210246 [ PF ZF IF RF ID ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x63 99
gs 0x6b 107
Wine-gdb> x/10x 0x7e0704e0
0x7e0704e0 <ddraw_surface2_vtbl>: 0x7e02f0c4 0x7e02f737 0x7e03024b
0x7e0340b3
0x7e0704f0 <ddraw_surface2_vtbl+16>: 0x7e0349f0 0x7e033977 0x7e0363de
0x7e03a947
0x7e070500 <ddraw_surface2_vtbl+32>: 0x7e0346db 0x7e036959
--- snip ---
https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ddraw/surface.c#l5554
--- snip ---
5554 static const struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl =
5555 {
5556 /* IUnknown */
5557 ddraw_surface2_QueryInterface,
5558 ddraw_surface2_AddRef,
5559 ddraw_surface2_Release,
5560 /* IDirectDrawSurface */
...
--- snip ---
--- snip ---
Wine-gdb> bt
#0 0x00b2b27c in ?? ()
#1 0x00b2163c in ?? ()
#2 0x005a14c4 in ?? ()
#3 0x001c0fc8 in ?? ()
#4 0x00192a7c in ?? ()
Wine-gdb> x/10i 0x00b2b27c
=> 0xb2b27c: rep movsl %ds:(%esi),%es:(%edi)
0xb2b27e: pop %edi
0xb2b27f: pop %esi
0xb2b280: mov -0x4c(%ebp),%ecx
0xb2b283: push %ecx
0xb2b284: mov -0x4c(%ebp),%edx
0xb2b287: test %edx,%edx
0xb2b289: jne 0xb2b28f
0xb2b28b: xor %ecx,%ecx
0xb2b28d: jmp 0xb2b2de
Wine-gdb> info reg
eax 0x7e0704e0 2114389216
ecx 0x28 40
edx 0x7e0704e0 2114389216
ebx 0x1c03c8 1835976
esp 0x32ba7c 0x32ba7c
ebp 0x32bb14 0x32bb14
esi 0xbbec10 12315664
edi 0x7e0704e0 2114389216
eip 0xb2b27c 0xb2b27c
eflags 0x210246 [ PF ZF IF RF ID ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x63 99
gs 0x6b 107
Wine-gdb> x/10x 0x7e0704e0
0x7e0704e0 <ddraw_surface3_vtbl>: 0x7e02f01f 0x7e02f673 0x7e030187
0x7e033fb5
0x7e0704f0 <ddraw_surface3_vtbl+16>: 0x7e034951 0x7e03387b 0x7e036332
0x7e03a85b
0x7e070500 <ddraw_surface3_vtbl+32>: 0x7e034632 0x7e0368af
--- snip ---
https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ddraw/surface.c#l5506
--- snip ---
5506 static const struct IDirectDrawSurface3Vtbl ddraw_surface3_vtbl =
5507 {
5508 /* IUnknown */
5509 ddraw_surface3_QueryInterface,
5510 ddraw_surface3_AddRef,
5511 ddraw_surface3_Release,
5512 /* IDirectDrawSurface */
...
--- snip ---
--- snip ---
Wine-gdb> bt
#0 0x00b2b322 in ?? ()
#1 0x00b2163c in ?? ()
#2 0x005a14c4 in ?? ()
#3 0x001c0fc8 in ?? ()
#4 0x00192a7c in ?? ()
Wine-gdb> x/10i 0x00b2b322
=> 0xb2b322: rep movsl %ds:(%esi),%es:(%edi)
0xb2b324: pop %edi
0xb2b325: pop %esi
0xb2b326: mov -0x50(%ebp),%ecx
0xb2b329: push %ecx
0xb2b32a: mov -0x50(%ebp),%edx
0xb2b32d: test %edx,%edx
0xb2b32f: jne 0xb2b335
0xb2b331: xor %ecx,%ecx
0xb2b333: jmp 0xb2b384
Wine-gdb> info reg
eax 0x7e0704e0 2114389216
ecx 0x2d 45
edx 0x7e0704e0 2114389216
ebx 0x1c03c8 1835976
esp 0x32ba7c 0x32ba7c
ebp 0x32bb14 0x32bb14
esi 0xbbecb0 12315824
edi 0x7e0704e0 2114389216
eip 0xb2b322 0xb2b322
eflags 0x210246 [ PF ZF IF RF ID ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x63 99
gs 0x6b 107
Wine-gdb> x/10x 0x7e0704e0
0x7e0704e0 <ddraw_surface4_vtbl>: 0x7e02ef7a 0x7e02f5af 0x7e0300c3
0x7e033dd2
0x7e0704f0 <ddraw_surface4_vtbl+16>: 0x7e0348b2 0x7e03377f 0x7e036286
0x7e03a76f
0x7e070500 <ddraw_surface4_vtbl+32>: 0x7e034589 0x7e036805
--- snip ---
https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ddraw/surface.c#l5452
--- snip ---
5452 static const struct IDirectDrawSurface4Vtbl ddraw_surface4_vtbl =
5453 {
5454 /* IUnknown */
5455 ddraw_surface4_QueryInterface,
5456 ddraw_surface4_AddRef,
5457 ddraw_surface4_Release,
5458 /* IDirectDrawSurface */
...
--- snip ---
--- snip ---
Wine-gdb> bt
#0 0x00b2b3c8 in ?? ()
#1 0x00b2163c in ?? ()
#2 0x005a14c4 in ?? ()
#3 0x001c0fc8 in ?? ()
#4 0x00192a7c in ?? ()
Wine-gdb> x/10i 0x00b2b3c8
=> 0xb2b3c8: rep movsl %ds:(%esi),%es:(%edi)
0xb2b3ca: pop %edi
0xb2b3cb: pop %esi
0xb2b3cc: mov -0x54(%ebp),%ecx
0xb2b3cf: push %ecx
0xb2b3d0: mov -0x54(%ebp),%edx
0xb2b3d3: test %edx,%edx
0xb2b3d5: jne 0xb2b3db
0xb2b3d7: xor %ecx,%ecx
0xb2b3d9: jmp 0xb2b42a
Wine-gdb> info reg
eax 0x7e0704c0 2114389184
ecx 0x31 49
edx 0x7e0704c0 2114389184
ebx 0x1c03c8 1835976
esp 0x32ba7c 0x32ba7c
ebp 0x32bb14 0x32bb14
esi 0xbbed64 12316004
edi 0x7e0704c0 2114389184
eip 0xb2b3c8 0xb2b3c8
eflags 0x210246 [ PF ZF IF RF ID ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x63 99
gs 0x6b 107
Wine-gdb> x/10x 0x7e0704c0
0x7e0704c0 <ddraw_surface7_vtbl>: 0x7e02e8a8 0x7e02f4eb 0x7e02ffff
0x7e033c96
0x7e0704d0 <ddraw_surface7_vtbl+16>: 0x7e03482d 0x7e032e03 0x7e0361f5
0x7e03a442
0x7e0704e0 <ddraw_surface7_vtbl+32>: 0x7e0344e0 0x7e036526
--- snip ---
https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ddraw/surface.c#l5393
--- snip ---
5393 static const struct IDirectDrawSurface7Vtbl ddraw_surface7_vtbl =
5394 {
5395 /* IUnknown */
5396 ddraw_surface7_QueryInterface,
5397 ddraw_surface7_AddRef,
5398 ddraw_surface7_Release,
5399 /* IDirectDrawSurface */
--- snip ---
If you remove the 'const' the old games start successfully in windowed mode.
Tested with AoE2 + expansions. NOTE: I'm not talking about the newer AoE2HD
which supports windowed mode out of the box, it's the older versions that
didn't support windowed mode at all.
Newer windowed mode wrapper projects such as 'DxWnd'
(https://github.com/DxWnd/DxWnd.reloaded) use more safe mechanisms
(VirtualProtect) to make sure the vtables are actually writable.
But again, it seems native DDraw has writable vtables.
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