[Bug 28296] AceMoney 3.11 and 4.19 crash immediately as soon as you try to print anything (broken app passes hDevMode pointer value in PRINTDLG struct to PrintDlgA/W)

wine-bugs at winehq.org wine-bugs at winehq.org
Sun Apr 6 16:52:49 CDT 2014


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

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |download
             Status|UNCONFIRMED                 |NEW
                URL|                            |http://www.mechcad.net/down
                   |                            |loads/win95/AceMoneySetup.e
                   |                            |xe
                 CC|                            |focht at gmx.net
          Component|-unknown                    |comdlg32
            Summary|AceMoney 4.19 crashes       |AceMoney 3.11 and 4.19
                   |immediately as soon as you  |crash immediately as soon
                   |try to print anything.      |as you try to print
                   |                            |anything (broken app passes
                   |                            |hDevMode pointer value in
                   |                            |PRINTDLG struct to
                   |                            |PrintDlgA/W)
     Ever confirmed|0                           |1

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

confirming, I can reproduce it with a very old AceMoney version.

All newer AceMoney 4.35.x versions seem to work fine (printed example).

Download: http://www.mechcad.net/products/acemoney/download.shtml

The oldest available version from download area:

--- snip ---
AceMoney 4.18.1 - 30 days trial
for Windows 95, 98, Me, NT 4.0, 2000
Release date: May 25, 2011, 1.8 Mb 
--- snip ---

The app reports 'AceMoney 3.11' in 'about' dialog after installation ...
strange.

Anyway, relevant part of trace log (relay exclude modified to show ntdll heap
API usage):

--- snip ---
$ pwd
/home/focht/.wine/drive_c/Program Files/AceMoney

$ WINEDEBUG=+tid,+seh,+relay,+commdlg,+ntdll wine ./AceMoney.exe >>log.txt 2>&1
...
0023:Call KERNEL32.GlobalAlloc(00000042,000000a4) ret=00527967
0023:Call ntdll.RtlAllocateHeap(00110000,00000000,00000008) ret=7b8457c8
0023:Ret  ntdll.RtlAllocateHeap() retval=0017bb90 ret=7b8457c8
0023:Call ntdll.RtlAllocateHeap(00110000,00000008,000000ac) ret=7b8457c8
0023:Ret  ntdll.RtlAllocateHeap() retval=001523c8 ret=7b8457c8
0023:Ret  KERNEL32.GlobalAlloc() retval=0017bb92 ret=00527967
0023:Call KERNEL32.GlobalLock(0017bb92) ret=005279e6
0023:Call ntdll.RtlLockHeap(00110000) ret=7b845c5c
0023:Ret  ntdll.RtlLockHeap() retval=00000001 ret=7b845c5c
0023:Call ntdll.RtlUnlockHeap(00110000) ret=7b845e30
0023:Ret  ntdll.RtlUnlockHeap() retval=00000001 ret=7b845e30
0023:Ret  KERNEL32.GlobalLock() retval=001523d0 ret=005279e6
0023:Call winspool.drv.DocumentPropertiesA(00000000,00000001,006f7ea9
"Xerox_Xerox_WorkCentre_3315",001523d0,001523d0,00000002) ret=00527a13 
...
0023:Ret  winspool.drv.DocumentPropertiesA() retval=00000001 ret=00527a13
0023:Call winspool.drv.DocumentPropertiesA(00000000,00000001,006f7ea9
"Xerox_Xerox_WorkCentre_3315",001523d0,001523d0,0000000a) ret=00527a9f 
...
0023:Ret  winspool.drv.DocumentPropertiesA() retval=00000001 ret=00527a9f
0023:Call gdi32.CreateDCA(006f7ee1 "wineps.drv",006f7ea9
"Xerox_Xerox_WorkCentre_3315",006f7f19
"CUPS:Xerox_Xerox_WorkCentre_3315",001523d0) ret=0052898d 
...
0023:Call comdlg32.PrintDlgA(0033f5ac) ret=00527be6
0023:trace:commdlg:PrintDlgA (0x33f5ac): hwndOwner = (nil), hDevMode =
0x1523d0, hDevNames = (nil)
pp. 0-1, min p 1, max p 1, copies 0, hinst (nil)
flags 00140100 (PD_RETURNDC PD_USEDEVMODECOPIES[ANDCOLLATE] PD_HIDEPRINTTOFILE
) 
...
0023:Call KERNEL32.GlobalLock(001523d0) ret=7e9670d6
0023:Ret  KERNEL32.GlobalLock() retval=001523d0 ret=7e9670d6
0023:Call
winspool.drv.EnumPrintersA(00000002,00000000,00000002,00000000,00000000,0033dedc,0033ded8)
ret=7e96336f
...
0023:Ret  winspool.drv.DocumentPropertiesA() retval=00000001 ret=7e96582c
0023:Call KERNEL32.GlobalUnlock(001523d0) ret=7e965843
0023:Ret  KERNEL32.GlobalUnlock() retval=00000001 ret=7e965843
...
0023:Ret  user32.DialogBoxIndirectParamA() retval=00000001 ret=7e969c47
0023:Call KERNEL32.GlobalReAlloc(001523d0,000000a4,00000002) ret=7e969d40
0023:Call ntdll.RtlLockHeap(00110000) ret=7b84635f
0023:Ret  ntdll.RtlLockHeap() retval=00000001 ret=7b84635f
0023:Call ntdll.RtlReAllocateHeap(00110000,00000000,001523d0,000000a4)
ret=7b845842
0023:Ret  ntdll.RtlReAllocateHeap() retval=00000000 ret=7b845842
0023:Call ntdll.RtlUnlockHeap(00110000) ret=7b8466fe
0023:Ret  ntdll.RtlUnlockHeap() retval=00000001 ret=7b8466fe
0023:Ret  KERNEL32.GlobalReAlloc() retval=00000000 ret=7e969d40
0023:Call KERNEL32.GlobalLock(00000000) ret=7e969d5d
0023:Ret  KERNEL32.GlobalLock() retval=00000000 ret=7e969d5d
0023:trace:seh:raise_exception code=c0000005 flags=0 addr=0xf7569db1
ip=f7569db1 tid=0023
0023:trace:seh:raise_exception  info[0]=00000001
0023:trace:seh:raise_exception  info[1]=00000000
0023:trace:seh:raise_exception  eax=00188db0 ebx=f759ab30 ecx=00000074
edx=00000010 esi=00000000 edi=00000000
0023:trace:seh:raise_exception  ebp=0033f318 esp=0033ee00 cs=0023 ds=002b
es=002b fs=0063 gs=006b flags=00210206 
...
wine: Unhandled page fault on write access to 0x00000000 at address 0xf7569db1
(thread 0023), starting debugger... 
...
Backtrace:
=>0 0xf7569db1 __memcpy_ssse3_rep+0x751() in libc.so.6 (0x0033f318)
  1 0x7e969d8f PrintDlgA+0x933(lppd=<couldn't compute location>)
[/home/focht/projects/wine/wine.repo/src/dlls/comdlg32/printdlg.c:2363] in
comdlg32 (0x0033f318)
  2 0x7bc6e3f2 relay_call+0x39() in ntdll (0x0033f344)
  3 0x7e93ba15 in comdlg32 (+0xba14) (0x0033f61c) 
  4 0x00527be6 in acemoney (+0x127be5) (0x0033f61c)
  5 0x004ead45 in acemoney (+0xead44) (0x0033f69c) 
...
0xf7569db1 __memcpy_ssse3_rep+0x751 in libc.so.6: repe movq    %mm0,0x0(%esi) 
Modules:
Module    Address            Debug info    Name (92 modules)
PE      400000-  6bc000    Export          acemoney 
...
Threads:
process  tid      prio (all id:s are in hex)
...
00000022 (D) C:\Program Files\AceMoney\AceMoney.exe
    00000027    0
    00000026    0
    00000023    0 <== 
--- snip ---

The crash is the result of broken app code.
It passes a pointer instead of handle in 'hDevMode' member.
API functions such as the common PrintDlg() take parameters that are needed to
be handles to global memory (obtained by GlobalAlloc())
'DevMode' was allocated with GMEM_MOVEABLE and GMEM_ZEROINIT.

Since Windows copes with such broken API usage Wine should do too.

GlobalReAlloc() -> RtlReAllocateHeap() can't work with that pointer because
it's actually 'pintern->Pointer' ('pintern->Pointer-HGLOBAL_STORAGE' would work
as it points to original heap block).

One fix could be to avoid GlobalReAlloc() in case of size match of both devmode
data and only do the copy operation.
A real fix might be hard as the app could see a handle instead of (broken)
pointer in 'lppd->hDevMode' or a different pointer value because Wine modifies
the struct member.

Source:
http://source.winehq.org/git/wine.git/blob/be367393c95bd391d7ad3309d3e085d9f4be2237:/dlls/comdlg32/printdlg.c#l2238

--- snip ---
2238 BOOL WINAPI PrintDlgA(LPPRINTDLGA lppd)
2239 {
2240     BOOL bRet = FALSE;
2241     LPVOID ptr;
2242     HINSTANCE hInst;
...
2271     if(lppd->Flags & PD_RETURNDEFAULT) {
2272         PRINTER_INFO_2A *pbuf;
2273         DRIVER_INFO_3A *dbuf;
2274         HANDLE hprn;
2275         DWORD needed;
...
2317     } else {
2318         HGLOBAL hDlgTmpl;
2319         PRINT_PTRA *PrintStructures;
...
2344         bRet = (0<DialogBoxIndirectParamA(hInst, ptr, lppd->hwndOwner,
2345                 PrintDlgProcA,
2346                 (LPARAM)PrintStructures));
2347
2348         if(bRet) {
2349             DEVMODEA *lpdm = PrintStructures->lpDevMode, *lpdmReturn;
2350             PRINTER_INFO_2A *pi = PrintStructures->lpPrinterInfo;
2351             DRIVER_INFO_3A *di = PrintStructures->lpDriverInfo;
2352
2353             if (lppd->hDevMode == 0) {
2354                 TRACE(" No hDevMode yet... Need to create my own\n");
2355                 lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE,
2356                 lpdm->dmSize + lpdm->dmDriverExtra);
2357             } else {
2358                 lppd->hDevMode = GlobalReAlloc(lppd->hDevMode,
2359                 lpdm->dmSize + lpdm->dmDriverExtra,
2360                 GMEM_MOVEABLE);
2361             }
2362             lpdmReturn = GlobalLock(lppd->hDevMode);
2363             memcpy(lpdmReturn, lpdm, lpdm->dmSize + lpdm->dmDriverExtra);
... 
--- snip ---

The code flow is hard to follow if don't have '8 character tabs' editor setting
(strange mixup of tab and whitespace).

$ sha1sum AceMoneySetup.exe 
5d36ab88e80dcbf3980552016c8f6381235ca2d1  AceMoneySetup.exe

$ du -sh AceMoneySetup.exe 
1.9M    AceMoneySetup.exe

$ wine --version
wine-1.7.16-1-gb772260

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