http://bugs.winehq.org/show_bug.cgi?id=12179
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net
--- Comment #1 from Anastasius Focht focht@gmx.net 2008-03-24 06:06:05 --- Hello,
first: it would actually help if you fill out each bug reports properly, at least specifying the exact version of app used (7.0) and the download location. Thanks.
This is an interesting and nasty bug - AJ might like this ;-) The app crashes in wine loader while try to load shdocvw.dll. Actually the crash is the result of earlier heap corruption. The wine loader lists get corrupted by app.
What makes this pretty worse is that the location of corruption is highly dependent on wine snapshot and configured version. The loader module list corruption was actually a big hit which helped me to track this quickly down.
MSN messenger app uses richedit CreateTextServices/TextServices. Unfortunately it seems to directly access data structures in a way wine has no knowledge - highly implementation specific area. This looks like another example of apps not consistently using public API/interfaces. I hate them...
Following is the memory dump and the code snippet to show where/how the corruption happens, annotated for easier understanding.
$-8 = wine CreateTextServices (dlls/riched20/txtsrv.c) allocated block $+0 = [esi+0A0h] ; ITextServicesImpl+0 -> wine riched20.textservices_Vtbl $+50 = wine loader allocated block $+60 = loader list entry which gets corrupted (high byte, see code snippet "or byte ptr [eax+3], 8")
--- snip memory dump --- $-8 000000xx ; heapblock->size $-4 00455355 ; heapblock->magic = ARENA_INUSE_MAGIC $+0 60E12560 ; ITextServicesImpl->lpVtbl $+4 00BCA278 ; ITextServicesImpl->pMyHost; $+8 00000001 ; ITextServicesImpl->ref $+C 0015EAB0 ; ITextServicesImpl->csTxtSrv.DebugInfo -> $+30 $+10 FFFFFFFF ; ITextServicesImpl->csTxtSrv.LockCount $+14 00000000 ; ITextServicesImpl->csTxtSrv.RecursionCount $+18 00000000 ; ITextServicesImpl->csTxtSrv.OwningThread $+1C 00000000 ; ITextServicesImpl->csTxtSrv.LockSemaphore $+20 00000000 ; ITextServicesImpl->csTxtSrv.SpinCount $+24 00650074 ; ITextServicesImpl->csTxtSrv.SpinCount
$+28 00000020 ; heapblock->size $+2C 00455355 ; heapblock->magic = ARENA_INUSE_MAGIC $+30 00000000 ; DebugInfo->Type/CreatorBackTraceIndex $+34 0015EA8C ; DebugInfo->CriticalSection $+38 0015EAB8 ; DebugInfo->ProcessLocksList.entry->next $+3C 0015EAB8 ; DebugInfo->ProcessLocksList.entry->prev $+40 00000000 ; DebugInfo->EntryCount $+44 00000000 ; DebugInfo->ContentionCount $+48 60E0D280 ; DebugInfo->Spare[0] -> ASCII ptr "txtsrv.c: ITextServicesImpl.csTxtSrv" $+4C 00000000 ; DebugInfo->Spare[1]
$+50 00000058 ; heapblock->size $+54 04455355 ; heapblock->magic = ARENA_INUSE_MAGIC $+58 00162548 ; loader InLoadOrderModuleList: entry->next $+5C 00158868 ; loader InLoadOrderModuleList: entry->prev $+60 00162550 ; loader InMemoryOrderModuleList: entry->next $+64 001534E0 ; loader InMemoryOrderModuleList: entry->prev $+68 00162558 ; loader InInitializationOrderModuleList: entry->next $+6C 00158878 ; loader InInitializationOrderModuleList: entry->prev $+70 60DE0000 $+74 60E06D60 ; riched20.__wine_spec_dll_entry $+78 00039000 $+7C 00420040 $+80 0015EB38 ; UNICODE ptr "C:\windows\system32\riched20.dll" $+84 001A0018 $+88 0015EB60 ; UNICODE ptr "riched20.dll" --- snip memory dump ---
Relevant app code which corrupts the loader data by chance, annotated for easier reading:
--- snip app code --- .. ; esi = pThis of some vtbl mov eax, [esi+0A0h] ; wine riched20.textservices_Vtbl .. add eax, 60h ; offset into real IText(Services)Impl+0x60 ? .. or byte ptr [eax+3], 8 ; *eek* this will corrupt heap !!! .. mov ecx, [esi+0A0h] ; wine riched20.textservices_Vtbl .. mov edx, [ecx] push ebx mov eax, 1000h push eax push eax push 4CCh call dword ptr [edx+0Ch] ; textservices_Vtbl->fnTextSrv_TxSendMessage .. --- snip app code ---
What happens? Because the app relies on internal data structures (CreateTextServices/ITextServicesImpl) - with a layout chosen by implementors - it corrupts data from next heap block. Unfortunately the next heap block contains loader data - by chance.
By adding some spare area in ITextServicesImpl I worked around this problem. Hopefully the app will not peek/use data beyond.
--- dlls/riched20/txtsrv.c ---
diff --git a/dlls/riched20/txtsrv.c b/dlls/riched20/txtsrv.c index 95d6f7c..d4679f7 100644 --- a/dlls/riched20/txtsrv.c +++ b/dlls/riched20/txtsrv.c @@ -57,6 +57,7 @@ typedef struct ITextServicesImpl { ITextHost *pMyHost; LONG ref; CRITICAL_SECTION csTxtSrv; + char spare[256]; } ITextServicesImpl;
static const ITextServicesVtbl textservices_Vtbl;
--- dlls/riched20/txtsrv.c ---
And yes, the app crashes again after the fix. Thats another bug (CredUI insufficiencies) which has nothing to do with this problem.
http://bugs.winehq.org/show_bug.cgi?id=10073 seems to be the same problem. As described earlier, the memory corruption highly depends on wine snapshot/config. If you mark it as duplicate, please make bug 10073 a duplicate of this, because I gave all the info/fix here.
This incidence made me think of how easily wine's "precious" data structures (loader lists, ...) can get corrupted because blocks are allocated from same process heap. Richedit and wine loader blocks were adjacent in this case - by chance.
Regards