Sebastian Lackner : ntdll: Add support for ATL thunk 'MOV this,edx; MOV func,ecx; JMP ecx'.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Oct 21 09:49:44 CDT 2014
Module: wine
Branch: master
Commit: 40472cd3a7e440386a125760a42ea175bed8176e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=40472cd3a7e440386a125760a42ea175bed8176e
Author: Sebastian Lackner <sebastian at fds-team.de>
Date: Tue Oct 21 06:00:20 2014 +0200
ntdll: Add support for ATL thunk 'MOV this,edx; MOV func,ecx; JMP ecx'.
---
dlls/kernel32/tests/virtual.c | 16 ++++++++++++++++
dlls/ntdll/signal_i386.c | 19 +++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c
index 5f83ead..a89f1e3 100644
--- a/dlls/kernel32/tests/virtual.c
+++ b/dlls/kernel32/tests/virtual.c
@@ -1912,6 +1912,7 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
static const char code_jmp[] = {0xE9, 0x00, 0x00, 0x00, 0x00};
static const char code_atl1[] = {0xC7, 0x44, 0x24, 0x04, 0x44, 0x33, 0x22, 0x11, 0xE9, 0x00, 0x00, 0x00, 0x00};
static const char code_atl2[] = {0xB9, 0x44, 0x33, 0x22, 0x11, 0xE9, 0x00, 0x00, 0x00, 0x00};
+ static const char code_atl3[] = {0xBA, 0x44, 0x33, 0x22, 0x11, 0xB9, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE1};
static const char cls_name[] = "atl_thunk_class";
DWORD ret, size, old_prot;
ULONG old_flags = MEM_EXECUTE_OPTION_ENABLE;
@@ -2098,6 +2099,21 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
else
ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls );
+ memcpy( base, code_atl3, sizeof(code_atl3) );
+ *(DWORD *)(base + 6) = (DWORD_PTR)atl_test_func;
+
+ success = VirtualProtect( base, size, PAGE_READWRITE, &old_prot );
+ ok( success, "VirtualProtect failed %u\n", GetLastError() );
+
+ ret = send_message_excpt( hWnd, WM_USER + 1, 0, 0 );
+ /* FIXME: we don't check the content of the registers ECX/EDX yet */
+ ok( ret == 43, "call returned wrong result, expected 43, got %d\n", ret );
+ ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls );
+ if ((dep_flags & MEM_EXECUTE_OPTION_DISABLE) && (dep_flags & MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION))
+ ok( num_execute_fault_calls == 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls );
+ else
+ ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls );
+
/* Restore the JMP instruction, set to executable, and then destroy the Window */
memcpy( base, code_jmp, sizeof(code_jmp) );
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index dde4e2d..e8c6a77 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -1632,6 +1632,14 @@ union atl_thunk
BYTE jmp; /* jmp func */
int func;
} t2;
+ struct
+ {
+ BYTE movl1; /* movl this,edx */
+ DWORD this;
+ BYTE movl2; /* movl func,ecx */
+ DWORD func;
+ WORD jmp; /* jmp ecx */
+ } t3;
};
#include "poppack.h"
@@ -1670,6 +1678,17 @@ static BOOL check_atl_thunk( EXCEPTION_RECORD *rec, CONTEXT *context )
thunk, context->Eip, context->Ecx );
return TRUE;
}
+ else if (thunk_len >= sizeof(thunk_copy.t3) && thunk_copy.t3.movl1 == 0xba &&
+ thunk_copy.t3.movl2 == 0xb9 &&
+ thunk_copy.t3.jmp == 0xe1ff)
+ {
+ context->Edx = thunk_copy.t3.this;
+ context->Ecx = thunk_copy.t3.func;
+ context->Eip = thunk_copy.t3.func;
+ TRACE( "emulating ATL thunk type 3 at %p, func=%08x ecx=%08x edx=%08x\n",
+ thunk, context->Eip, context->Ecx, context->Edx );
+ return TRUE;
+ }
return FALSE;
}
More information about the wine-cvs
mailing list