Alexandre Julliard : wow64: Add support for jumping to 32-bit code in Wow64LdrpInitialize().

Alexandre Julliard julliard at winehq.org
Wed Aug 4 16:41:37 CDT 2021


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Aug  4 12:25:52 2021 +0200

wow64: Add support for jumping to 32-bit code in Wow64LdrpInitialize().

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

---

 dlls/wow64/process.c | 15 ++++++++++++
 dlls/wow64/sync.c    |  9 ++++++++
 dlls/wow64/syscall.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++------
 dlls/wow64/syscall.h |  2 ++
 4 files changed, 83 insertions(+), 7 deletions(-)

diff --git a/dlls/wow64/process.c b/dlls/wow64/process.c
index 44380535d9c..764a2ba46ca 100644
--- a/dlls/wow64/process.c
+++ b/dlls/wow64/process.c
@@ -309,6 +309,21 @@ NTSTATUS WINAPI wow64_NtAssignProcessToJobObject( UINT *args )
 }
 
 
+/**********************************************************************
+ *           wow64_NtContinue
+ */
+NTSTATUS WINAPI wow64_NtContinue( UINT *args )
+{
+    void *context = get_ptr( &args );
+    BOOLEAN alertable = get_ulong( &args );
+
+    NtSetInformationThread( GetCurrentThread(), ThreadWow64Context,
+                            context, get_machine_context_size( current_machine ));
+    if (alertable) NtTestAlert();
+    return STATUS_SUCCESS;
+}
+
+
 /**********************************************************************
  *           wow64_NtCreateThread
  */
diff --git a/dlls/wow64/sync.c b/dlls/wow64/sync.c
index 1b4c3c864c3..400deeb8422 100644
--- a/dlls/wow64/sync.c
+++ b/dlls/wow64/sync.c
@@ -1461,6 +1461,15 @@ NTSTATUS WINAPI wow64_NtTerminateJobObject( UINT *args )
 }
 
 
+/**********************************************************************
+ *           wow64_NtTestAlert
+ */
+NTSTATUS WINAPI wow64_NtTestAlert( UINT *args )
+{
+    return NtTestAlert();
+}
+
+
 /**********************************************************************
  *           wow64_NtWaitForDebugEvent
  */
diff --git a/dlls/wow64/syscall.c b/dlls/wow64/syscall.c
index e120ed022cd..6f443557e16 100644
--- a/dlls/wow64/syscall.c
+++ b/dlls/wow64/syscall.c
@@ -393,7 +393,7 @@ static HMODULE load_cpu_dll(void)
 /**********************************************************************
  *           process_init
  */
-static void process_init(void)
+static DWORD WINAPI process_init( RTL_RUN_ONCE *once, void *param, void **context )
 {
     HMODULE module;
     UNICODE_STRING str;
@@ -421,11 +421,63 @@ static void process_init(void)
     *pWow64Transition = *p__wine_syscall_dispatcher = pBTCpuGetBopCode();
 
     init_file_redirects();
+    return TRUE;
 
 #undef GET_PTR
 }
 
 
+/**********************************************************************
+ *           thread_init
+ */
+static void thread_init(void)
+{
+    /* update initial context to jump to 32-bit LdrInitializeThunk (cf. 32-bit call_init_thunk) */
+    switch (current_machine)
+    {
+    case IMAGE_FILE_MACHINE_I386:
+        {
+            I386_CONTEXT *ctx_ptr, ctx = { CONTEXT_I386_ALL };
+            ULONG *stack;
+
+            NtQueryInformationThread( GetCurrentThread(), ThreadWow64Context, &ctx, sizeof(ctx), NULL );
+            ctx_ptr = (I386_CONTEXT *)ULongToPtr( ctx.Esp ) - 1;
+            *ctx_ptr = ctx;
+
+            stack = (ULONG *)ctx_ptr;
+            *(--stack) = 0;
+            *(--stack) = 0;
+            *(--stack) = 0;
+            *(--stack) = PtrToUlong( ctx_ptr );
+            *(--stack) = 0xdeadbabe;
+            ctx.Esp = PtrToUlong( stack );
+            ctx.Eip = pLdrSystemDllInitBlock->pLdrInitializeThunk;
+            NtSetInformationThread( GetCurrentThread(), ThreadWow64Context, &ctx, sizeof(ctx) );
+        }
+        break;
+
+    case IMAGE_FILE_MACHINE_ARMNT:
+        {
+            ARM_CONTEXT *ctx_ptr, ctx = { CONTEXT_ARM_ALL };
+
+            NtQueryInformationThread( GetCurrentThread(), ThreadWow64Context, &ctx, sizeof(ctx), NULL );
+            ctx_ptr = (ARM_CONTEXT *)ULongToPtr( ctx.Sp & ~15 ) - 1;
+            *ctx_ptr = ctx;
+
+            ctx.R0 = PtrToUlong( ctx_ptr );
+            ctx.Sp = PtrToUlong( ctx_ptr );
+            ctx.Pc = pLdrSystemDllInitBlock->pLdrInitializeThunk;
+            NtSetInformationThread( GetCurrentThread(), ThreadWow64Context, &ctx, sizeof(ctx) );
+        }
+        break;
+
+    default:
+        ERR( "not supported machine %x\n", current_machine );
+        NtTerminateProcess( GetCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT );
+    }
+}
+
+
 /**********************************************************************
  *           free_temp_data
  */
@@ -500,11 +552,9 @@ void WINAPI Wow64ApcRoutine( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, CON
  */
 void WINAPI Wow64LdrpInitialize( CONTEXT *context )
 {
-    static BOOL init_done;
+    static RTL_RUN_ONCE init_done;
 
-    if (!init_done)
-    {
-        init_done = TRUE;
-        process_init();
-    }
+    RtlRunOnceExecuteOnce( &init_done, process_init, NULL, NULL );
+    thread_init();
+    pBTCpuSimulate();
 }
diff --git a/dlls/wow64/syscall.h b/dlls/wow64/syscall.h
index 782a7a78c18..f794d35cee4 100644
--- a/dlls/wow64/syscall.h
+++ b/dlls/wow64/syscall.h
@@ -43,6 +43,7 @@
     SYSCALL_ENTRY( NtClose ) \
     SYSCALL_ENTRY( NtCompleteConnectPort ) \
     SYSCALL_ENTRY( NtConnectPort ) \
+    SYSCALL_ENTRY( NtContinue ) \
     SYSCALL_ENTRY( NtCreateDebugObject ) \
     SYSCALL_ENTRY( NtCreateDirectoryObject ) \
     SYSCALL_ENTRY( NtCreateEvent ) \
@@ -217,6 +218,7 @@
     SYSCALL_ENTRY( NtTerminateJobObject ) \
     SYSCALL_ENTRY( NtTerminateProcess ) \
     SYSCALL_ENTRY( NtTerminateThread ) \
+    SYSCALL_ENTRY( NtTestAlert ) \
     SYSCALL_ENTRY( NtUnloadDriver ) \
     SYSCALL_ENTRY( NtUnloadKey ) \
     SYSCALL_ENTRY( NtUnlockFile ) \




More information about the wine-cvs mailing list