krnl386: detect and warn about Win16 stack corruption when doing a +relay trace
Damjan Jovanovic
damjan.jov at gmail.com
Wed Apr 20 14:48:42 CDT 2011
Changelog:
* krnl386: detect and warn about Win16 stack corruption when doing a
+relay trace
Wine currently easily corrupts the Win16 stack because 32 bit
structures are usually bigger and some parts (eg. mmsystem.dll16)
don't convert 32->16 properly, so at least provide a warning that this
has probably happened in +relay traces to make debugging easier.
Damjan Jovanovic
-------------- next part --------------
diff --git a/dlls/krnl386.exe16/relay.c b/dlls/krnl386.exe16/relay.c
index dcafe17..cc98e91 100644
--- a/dlls/krnl386.exe16/relay.c
+++ b/dlls/krnl386.exe16/relay.c
@@ -36,6 +36,7 @@
#include "wine/unicode.h"
#include "wine/library.h"
#include "wine/debug.h"
+#include "wine/exception.h"
WINE_DEFAULT_DEBUG_CHANNEL(relay);
@@ -427,6 +428,20 @@ static int relay_call_from_16_no_debug( void *entry_point, unsigned char *args16
}
+static DWORD safely_read(volatile DWORD *p)
+{
+ DWORD ret = 0;
+ __TRY
+ {
+ ret = *p;
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ }
+ __ENDTRY
+ return ret;
+}
+
/***********************************************************************
* relay_call_from_16
*
@@ -440,6 +455,8 @@ int relay_call_from_16( void *entry_point, unsigned char *args16, CONTEXT *conte
int ret_val, args32[20];
char module[10], func[64];
const CALLFROM16 *call;
+ volatile DWORD *ssbp;
+ DWORD bpBefore, bpAfter;
frame = CURRENT_STACK16;
call = get_entry_point( frame, module, func, &ordinal );
@@ -568,12 +585,19 @@ int relay_call_from_16( void *entry_point, unsigned char *args16, CONTEXT *conte
(WORD)context->SegEs, context->EFlags );
}
+ ssbp = (DWORD*)MapSL(MAKESEGPTR(SELECTOROF(NtCurrentTeb()->WOW32Reserved), frame->bp));
+ bpBefore = safely_read(ssbp);
+
SYSLEVEL_CheckNotLevel( 2 );
ret_val = call_entry_point( entry_point, nb_args, args32 );
SYSLEVEL_CheckNotLevel( 2 );
+ bpAfter = safely_read(ssbp);
+ if (bpBefore != bpAfter)
+ DPRINTF("***POSSIBLE WIN16 STACK CORRUPTION DETECTED***\n");
+
DPRINTF( "%04x:Ret %s.%d: %s() ",GetCurrentThreadId(), module, ordinal, func );
if (!j) /* register function */
{
diff --git a/dlls/mmsystem.dll16/mci16.c b/dlls/mmsystem.dll16/mci16.c
More information about the wine-patches
mailing list