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