Alexandre Julliard : ntdll: Call NtContinue() from LdrInitializeThunk() instead of returning.

Alexandre Julliard julliard at winehq.org
Thu Aug 20 16:03:35 CDT 2020


Module: wine
Branch: master
Commit: 4a7cd0f492affbc0eb347b97426b8c23f9a4f976
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=4a7cd0f492affbc0eb347b97426b8c23f9a4f976

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Aug 20 15:27:30 2020 +0200

ntdll: Call NtContinue() from LdrInitializeThunk() instead of returning.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/loader.c        |  3 ++-
 dlls/ntdll/ntdll_misc.h    |  1 +
 dlls/ntdll/signal_arm.c    | 11 +++++++++++
 dlls/ntdll/signal_arm64.c  | 11 +++++++++++
 dlls/ntdll/signal_i386.c   | 16 ++++++++++++++++
 dlls/ntdll/signal_x86_64.c | 14 ++++++++++++++
 dlls/ntdll/virtual.c       | 16 ++++++++++++++++
 7 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 6290cbcb4e..54d56f4e14 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -3416,7 +3416,7 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, void **entry, ULONG_PTR unknow
     WINE_MODREF *wm;
     LPCWSTR load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
 
-    if (process_detaching) return;
+    if (process_detaching) NtTerminateThread( GetCurrentThread(), 0 );
 
     RtlEnterCriticalSection( &loader_section );
 
@@ -3486,6 +3486,7 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, void **entry, ULONG_PTR unknow
     }
 
     RtlLeaveCriticalSection( &loader_section );
+    signal_start_thread( context );
 }
 
 
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index a97dadb2a5..63ceac42e9 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -65,6 +65,7 @@ extern void init_unix_codepage(void) DECLSPEC_HIDDEN;
 extern void init_locale( HMODULE module ) DECLSPEC_HIDDEN;
 extern void init_user_process_params(void) DECLSPEC_HIDDEN;
 extern NTSTATUS restart_process( RTL_USER_PROCESS_PARAMETERS *params, NTSTATUS status ) DECLSPEC_HIDDEN;
+extern void CDECL DECLSPEC_NORETURN signal_start_thread( CONTEXT *ctx ) DECLSPEC_HIDDEN;
 
 /* server support */
 extern BOOL is_wow64 DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c
index ba455ea71e..1041dadf86 100644
--- a/dlls/ntdll/signal_arm.c
+++ b/dlls/ntdll/signal_arm.c
@@ -263,6 +263,17 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer,
     return 0;
 }
 
+/***********************************************************************
+ *           signal_start_thread
+ */
+__ASM_GLOBAL_FUNC( signal_start_thread,
+                   "mov sp, r0\n\t"  /* context */
+                   "and r0, #~0xff0\n\t"  /* round down to page size */
+                   "bl " __ASM_NAME("virtual_clear_thread_stack") "\n\t"
+                   "mov r1, #1\n\t"
+                   "mov r0, sp\n\t"
+                   "b " __ASM_NAME("NtContinue") )
+
 /**********************************************************************
  *              DbgBreakPoint   (NTDLL.@)
  */
diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c
index a35e48c1d6..e3102f7bdf 100644
--- a/dlls/ntdll/signal_arm64.c
+++ b/dlls/ntdll/signal_arm64.c
@@ -1188,6 +1188,17 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer,
     return 0;
 }
 
+/***********************************************************************
+ *           signal_start_thread
+ */
+__ASM_GLOBAL_FUNC( signal_start_thread,
+                   "mov sp, x0\n\t"  /* context */
+                   "and x0, x0, #~0xfff\n\t"  /* round down to page size */
+                   "bl " __ASM_NAME("virtual_clear_thread_stack") "\n\t"
+                   "mov x0, sp\n\t"
+                   "mov x1, #1\n\t"
+                   "b " __ASM_NAME("NtContinue") )
+
 /**********************************************************************
  *              DbgBreakPoint   (NTDLL.@)
  */
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index b65beb7215..8cdce3384a 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -498,6 +498,22 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer,
 }
 
 
+/***********************************************************************
+ *           signal_start_thread
+ */
+__ASM_GLOBAL_FUNC( signal_start_thread,
+                   "movl 4(%esp),%esi\n\t"   /* context */
+                   "leal -12(%esi),%eax\n\t"
+                   "movl %eax,%esp\n\t"
+                   /* clear the stack */
+                   "andl $~0xfff,%eax\n\t"  /* round down to page size */
+                   "movl %eax,(%esp)\n\t"
+                   "call " __ASM_NAME("virtual_clear_thread_stack") "\n\t"
+                   /* switch to the initial context */
+                   "movl $1,4(%esp)\n\t"
+                   "movl %esi,(%esp)\n\t"
+                   "call " __ASM_STDCALL("NtContinue", 8) )
+
 /**********************************************************************
  *		DbgBreakPoint   (NTDLL.@)
  */
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 40ed53c10d..e1cf7f3e01 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -1477,6 +1477,20 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer,
 }
 
 
+/***********************************************************************
+ *           signal_start_thread
+ */
+__ASM_GLOBAL_FUNC( signal_start_thread,
+                   "movq %rcx,%rbx\n\t"     /* context */
+                   "leaq -32(%rcx),%rcx\n\t"
+                   "movq %rcx,%rsp\n\t"
+                   "andq $~0xfff,%rcx\n\t"  /* round down to page size */
+                   "call " __ASM_NAME("virtual_clear_thread_stack") "\n\t"
+                   "movl $1,%edx\n\t"
+                   "movq %rbx,%rcx\n\t"
+                   "call " __ASM_NAME("NtContinue") )
+
+
 /**********************************************************************
  *		DbgBreakPoint   (NTDLL.@)
  */
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 3ba4b8afbc..64eef6aa84 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -106,6 +106,22 @@ void WINAPI RtlFreeUserStack( void *stack )
     NtFreeVirtualMemory( NtCurrentProcess(), &stack, &size, MEM_RELEASE );
 }
 
+
+/***********************************************************************
+ *           virtual_clear_thread_stack
+ *
+ * Clear the stack contents before calling the main entry point, some broken apps need that.
+ */
+void CDECL virtual_clear_thread_stack( void *stack_end )
+{
+    void *stack = NtCurrentTeb()->Tib.StackLimit;
+    SIZE_T size = (char *)stack_end - (char *)stack;
+
+    NtFreeVirtualMemory( GetCurrentProcess(), &stack, &size, MEM_DECOMMIT );
+    NtAllocateVirtualMemory( GetCurrentProcess(), &stack, 0, &size, MEM_COMMIT, PAGE_READWRITE );
+}
+
+
 /***********************************************************************
  *           __wine_locked_recvmsg
  */




More information about the wine-cvs mailing list