mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Added patch to implement support for additional ATL thunks.
This commit is contained in:
parent
971d304a1f
commit
500d83235b
1
debian/changelog
vendored
1
debian/changelog
vendored
@ -8,6 +8,7 @@ wine-compholio (1.7.29) UNRELEASED; urgency=low
|
||||
* Added patch to implement ID3DXSkinInfoImpl_UpdateSkinnedMesh.
|
||||
* Added patch for implementation of D3DXGetShaderInputSemantics.
|
||||
* Added patch to ensure tests check exact return value of ParseURLFromOutsideSourceX.
|
||||
* Added patch for additional ATL thunks.
|
||||
* Removed patch to fix issues with drag image in ImageLists (accepted upstream).
|
||||
* Removed patch to set ldr.EntryPoint for main executable (accepted upstream).
|
||||
* Removed patch to implement stubs for [Get|Set]SystemFileCacheSize (accepted upstream).
|
||||
|
@ -41,6 +41,7 @@ PATCHLIST := \
|
||||
kernel32-UTF7_Support.ok \
|
||||
libs-Unicode_Collation.ok \
|
||||
msvcp90-basic_string_wchar_dtor.ok \
|
||||
ntdll-ATL_Thunk.ok \
|
||||
ntdll-DOS_Attributes.ok \
|
||||
ntdll-Dynamic_DST.ok \
|
||||
ntdll-Exception.ok \
|
||||
@ -578,6 +579,25 @@ msvcp90-basic_string_wchar_dtor.ok:
|
||||
echo '+ { "msvcp90-basic_string_wchar_dtor", "Michael Müller", "basic_string_wchar_dtor needs to return NULL." },'; \
|
||||
) > msvcp90-basic_string_wchar_dtor.ok
|
||||
|
||||
# Patchset ntdll-ATL_Thunk
|
||||
# |
|
||||
# | Included patches:
|
||||
# | * Implement additional ATL Thunks. [by Sebastian Lackner]
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#29903] Support for additional ATL Thunks
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/kernel32/tests/virtual.c, dlls/ntdll/signal_i386.c
|
||||
# |
|
||||
.INTERMEDIATE: ntdll-ATL_Thunk.ok
|
||||
ntdll-ATL_Thunk.ok:
|
||||
$(call APPLY_FILE,ntdll-ATL_Thunk/0001-kernel32-tests-Add-tests-for-additional-ATL-thunks-e.patch)
|
||||
$(call APPLY_FILE,ntdll-ATL_Thunk/0002-ntdll-Add-support-for-additional-ATL-thunks.patch)
|
||||
@( \
|
||||
echo '+ { "ntdll-ATL_Thunk", "Sebastian Lackner", "Implement additional ATL Thunks." },'; \
|
||||
) > ntdll-ATL_Thunk.ok
|
||||
|
||||
# Patchset ntdll-DOS_Attributes
|
||||
# |
|
||||
# | Included patches:
|
||||
|
@ -0,0 +1,171 @@
|
||||
From bec1fa5d3b8ccd21ec4be39980a06f37ab2a6bdc Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 18 Oct 2014 03:15:57 +0200
|
||||
Subject: kernel32/tests: Add tests for additional ATL thunks emulated on
|
||||
Windows.
|
||||
|
||||
---
|
||||
dlls/kernel32/tests/virtual.c | 113 ++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 108 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c
|
||||
index 73b753e..6971144 100644
|
||||
--- a/dlls/kernel32/tests/virtual.c
|
||||
+++ b/dlls/kernel32/tests/virtual.c
|
||||
@@ -1882,7 +1882,24 @@ static inline DWORD send_message_excpt( HWND hWnd, UINT uMsg, WPARAM wParam, LPA
|
||||
pNtCurrentTeb()->Tib.ExceptionList = &frame;
|
||||
|
||||
num_guard_page_calls = num_execute_fault_calls = 0;
|
||||
- ret = SendMessageA( hWnd, WM_USER, 0, 0 );
|
||||
+ ret = SendMessageA( hWnd, uMsg, wParam, lParam );
|
||||
+
|
||||
+ pNtCurrentTeb()->Tib.ExceptionList = frame.Prev;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static inline DWORD call_proc_excpt( DWORD (CALLBACK *code)(void *), void *arg )
|
||||
+{
|
||||
+ EXCEPTION_REGISTRATION_RECORD frame;
|
||||
+ DWORD ret;
|
||||
+
|
||||
+ frame.Handler = execute_fault_seh_handler;
|
||||
+ frame.Prev = pNtCurrentTeb()->Tib.ExceptionList;
|
||||
+ pNtCurrentTeb()->Tib.ExceptionList = &frame;
|
||||
+
|
||||
+ num_guard_page_calls = num_execute_fault_calls = 0;
|
||||
+ ret = code( arg );
|
||||
|
||||
pNtCurrentTeb()->Tib.ExceptionList = frame.Prev;
|
||||
|
||||
@@ -1900,14 +1917,26 @@ static LRESULT CALLBACK jmp_test_func( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
|
||||
static LRESULT CALLBACK atl_test_func( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
DWORD arg = (DWORD)hWnd;
|
||||
- ok( arg == 0x11223344, "arg is 0x%08x instead of 0x11223344\n", arg );
|
||||
+ if (uMsg == WM_USER)
|
||||
+ ok( arg == 0x11223344, "arg is 0x%08x instead of 0x11223344\n", arg );
|
||||
+ else
|
||||
+ ok( arg != 0x11223344, "arg is unexpectedly 0x11223344\n" );
|
||||
return 43;
|
||||
}
|
||||
|
||||
+static DWORD CALLBACK atl5_test_func( void )
|
||||
+{
|
||||
+ return 44;
|
||||
+}
|
||||
+
|
||||
static void test_atl_thunk_emulation( ULONG dep_flags )
|
||||
{
|
||||
static const char code_jmp[] = {0xE9, 0x00, 0x00, 0x00, 0x00};
|
||||
- static const char code_atl[] = {0xC7, 0x44, 0x24, 0x04, 0x44, 0x33, 0x22, 0x11, 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 code_atl4[] = {0xB9, 0x44, 0x33, 0x22, 0x11, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0};
|
||||
+ static const char code_atl5[] = {0x59, 0x58, 0x51, 0xFF, 0x60, 0x04};
|
||||
static const char cls_name[] = "atl_thunk_class";
|
||||
DWORD ret, size, old_prot;
|
||||
ULONG old_flags = MEM_EXECUTE_OPTION_ENABLE;
|
||||
@@ -2008,7 +2037,7 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
|
||||
|
||||
/* Now test with a proper ATL thunk instruction. */
|
||||
|
||||
- memcpy( base, code_atl, sizeof(code_atl) );
|
||||
+ memcpy( base, code_atl1, sizeof(code_atl1) );
|
||||
*(DWORD *)(base + 9) = (DWORD_PTR)atl_test_func - (DWORD_PTR)(base + 13);
|
||||
|
||||
success = VirtualProtect( base, size, PAGE_EXECUTE_READWRITE, &old_prot );
|
||||
@@ -2077,6 +2106,80 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
|
||||
win_skip( "RtlAddVectoredExceptionHandler or RtlRemoveVectoredExceptionHandler not found\n" );
|
||||
}
|
||||
|
||||
+ /* Test alternative ATL thunk instructions. */
|
||||
+
|
||||
+ memcpy( base, code_atl2, sizeof(code_atl2) );
|
||||
+ *(DWORD *)(base + 6) = (DWORD_PTR)atl_test_func - (DWORD_PTR)(base + 10);
|
||||
+
|
||||
+ 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 register ECX 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 if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
|
||||
+ todo_wine
|
||||
+ ok( num_execute_fault_calls == 0, "expected no 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 );
|
||||
+
|
||||
+ 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 if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
|
||||
+ todo_wine
|
||||
+ ok( num_execute_fault_calls == 0, "expected no 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 );
|
||||
+
|
||||
+ memcpy( base, code_atl4, sizeof(code_atl4) );
|
||||
+ *(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 EAX/ECX 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 if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
|
||||
+ todo_wine
|
||||
+ ok( num_execute_fault_calls == 0, "expected no 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 );
|
||||
+
|
||||
+ memcpy( base, code_atl5, sizeof(code_atl5) );
|
||||
+
|
||||
+ success = VirtualProtect( base, size, PAGE_READWRITE, &old_prot );
|
||||
+ ok( success, "VirtualProtect failed %u\n", GetLastError() );
|
||||
+
|
||||
+ ret = (DWORD_PTR)atl5_test_func;
|
||||
+ ret = call_proc_excpt( (void *)base, &ret - 1 );
|
||||
+ /* FIXME: We don't check the content of the registers EAX/ECX yet */
|
||||
+ ok( ret == 44, "call returned wrong result, expected 44, 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 if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
|
||||
+ todo_wine
|
||||
+ ok( num_execute_fault_calls == 0, "expected no 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) );
|
||||
@@ -2194,7 +2297,7 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
|
||||
|
||||
/* Now test with a proper ATL thunk instruction. */
|
||||
|
||||
- memcpy( base, code_atl, sizeof(code_atl) );
|
||||
+ memcpy( base, code_atl1, sizeof(code_atl1) );
|
||||
*(DWORD *)(base + 9) = (DWORD_PTR)atl_test_func - (DWORD_PTR)(base + 13);
|
||||
|
||||
count = 64;
|
||||
--
|
||||
2.1.2
|
||||
|
@ -0,0 +1,204 @@
|
||||
From 31046c5a489a1b646b6dfb94c8156b96bb40bd2e Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 18 Oct 2014 04:32:27 +0200
|
||||
Subject: ntdll: Add support for additional ATL thunks.
|
||||
|
||||
---
|
||||
dlls/kernel32/tests/virtual.c | 12 -----
|
||||
dlls/ntdll/signal_i386.c | 120 ++++++++++++++++++++++++++++++++++++------
|
||||
2 files changed, 103 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c
|
||||
index 6971144..3be2977 100644
|
||||
--- a/dlls/kernel32/tests/virtual.c
|
||||
+++ b/dlls/kernel32/tests/virtual.c
|
||||
@@ -2120,9 +2120,6 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
|
||||
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 if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
|
||||
- todo_wine
|
||||
- ok( num_execute_fault_calls == 0, "expected no 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 );
|
||||
|
||||
@@ -2138,9 +2135,6 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
|
||||
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 if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
|
||||
- todo_wine
|
||||
- ok( num_execute_fault_calls == 0, "expected no 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 );
|
||||
|
||||
@@ -2156,9 +2150,6 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
|
||||
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 if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
|
||||
- todo_wine
|
||||
- ok( num_execute_fault_calls == 0, "expected no 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 );
|
||||
|
||||
@@ -2174,9 +2165,6 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
|
||||
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 if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
|
||||
- todo_wine
|
||||
- ok( num_execute_fault_calls == 0, "expected no 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 );
|
||||
|
||||
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
|
||||
index f97799c..b2a9cb0 100644
|
||||
--- a/dlls/ntdll/signal_i386.c
|
||||
+++ b/dlls/ntdll/signal_i386.c
|
||||
@@ -1616,12 +1616,46 @@ static inline BOOL check_invalid_gs( CONTEXT *context )
|
||||
|
||||
|
||||
#include "pshpack1.h"
|
||||
-struct atl_thunk
|
||||
+union atl_thunk
|
||||
{
|
||||
- DWORD movl; /* movl this,4(%esp) */
|
||||
- DWORD this;
|
||||
- BYTE jmp; /* jmp func */
|
||||
- int func;
|
||||
+ struct
|
||||
+ {
|
||||
+ DWORD movl; /* movl this,4(%esp) */
|
||||
+ DWORD this;
|
||||
+ BYTE jmp; /* jmp func */
|
||||
+ int func;
|
||||
+ } t1;
|
||||
+ struct
|
||||
+ {
|
||||
+ BYTE movl; /* movl this,ecx */
|
||||
+ DWORD this;
|
||||
+ 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;
|
||||
+ struct
|
||||
+ {
|
||||
+ BYTE movl1; /* movl this,ecx */
|
||||
+ DWORD this;
|
||||
+ BYTE movl2; /* movl func,eax */
|
||||
+ DWORD func;
|
||||
+ WORD jmp; /* jmp eax */
|
||||
+ } t4;
|
||||
+ struct
|
||||
+ {
|
||||
+ DWORD inst1; /* pop ecx
|
||||
+ * pop eax
|
||||
+ * push ecx
|
||||
+ * jmp 4(%eax) */
|
||||
+ WORD inst2;
|
||||
+ } t5;
|
||||
};
|
||||
#include "poppack.h"
|
||||
|
||||
@@ -1632,26 +1666,78 @@ struct atl_thunk
|
||||
*/
|
||||
static BOOL check_atl_thunk( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||
{
|
||||
- const struct atl_thunk *thunk = (const struct atl_thunk *)rec->ExceptionInformation[1];
|
||||
- struct atl_thunk thunk_copy;
|
||||
- BOOL ret = FALSE;
|
||||
+ const union atl_thunk *thunk = (const union atl_thunk *)rec->ExceptionInformation[1];
|
||||
+ union atl_thunk thunk_copy;
|
||||
+ SIZE_T thunk_len;
|
||||
|
||||
- if (virtual_uninterrupted_read_memory( thunk, &thunk_copy, sizeof(*thunk) ) != sizeof(*thunk))
|
||||
- return FALSE;
|
||||
+ thunk_len = virtual_uninterrupted_read_memory( thunk, &thunk_copy, sizeof(*thunk) );
|
||||
+ if (!thunk_len) return FALSE;
|
||||
|
||||
- if (thunk_copy.movl == 0x042444c7 && thunk_copy.jmp == 0xe9)
|
||||
+ if (thunk_len >= sizeof(thunk_copy.t1) && thunk_copy.t1.movl == 0x042444c7 &&
|
||||
+ thunk_copy.t1.jmp == 0xe9)
|
||||
{
|
||||
if (virtual_uninterrupted_write_memory( (DWORD *)context->Esp + 1,
|
||||
- &thunk_copy.this, sizeof(DWORD) ) == sizeof(DWORD))
|
||||
+ &thunk_copy.t1.this, sizeof(DWORD) ) == sizeof(DWORD))
|
||||
+ {
|
||||
+ context->Eip = (DWORD_PTR)(&thunk->t1.func + 1) + thunk_copy.t1.func;
|
||||
+ TRACE( "emulating ATL thunk type 1 at %p, func=%08x arg=%08x\n",
|
||||
+ thunk, context->Eip, thunk_copy.t1.this );
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ }
|
||||
+ else if (thunk_len >= sizeof(thunk_copy.t2) && thunk_copy.t2.movl == 0xb9 &&
|
||||
+ thunk_copy.t2.jmp == 0xe9)
|
||||
+ {
|
||||
+ context->Ecx = thunk_copy.t2.this;
|
||||
+ context->Eip = (DWORD_PTR)(&thunk->t2.func + 1) + thunk_copy.t2.func;
|
||||
+ TRACE( "emulating ATL thunk type 2 at %p, func=%08x ecx=%08x\n",
|
||||
+ 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;
|
||||
+ }
|
||||
+ else if (thunk_len >= sizeof(thunk_copy.t4) && thunk_copy.t4.movl1 == 0xb9 &&
|
||||
+ thunk_copy.t4.movl2 == 0xb8 &&
|
||||
+ thunk_copy.t4.jmp == 0xe0ff)
|
||||
+ {
|
||||
+ context->Ecx = thunk_copy.t4.this;
|
||||
+ context->Eax = thunk_copy.t4.func;
|
||||
+ context->Eip = thunk_copy.t4.func;
|
||||
+ TRACE( "emulating ATL thunk type 4 at %p, func=%08x eax=%08x ecx=%08x\n",
|
||||
+ thunk, context->Eip, context->Eax, context->Ecx );
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ else if (thunk_len >= sizeof(thunk_copy.t5) && thunk_copy.t5.inst1 == 0xff515859 &&
|
||||
+ thunk_copy.t5.inst2 == 0x0460)
|
||||
+ {
|
||||
+ DWORD func, stack[2];
|
||||
+ if (virtual_uninterrupted_read_memory( context->Esp,
|
||||
+ stack, sizeof(stack) ) == sizeof(stack) &&
|
||||
+ virtual_uninterrupted_read_memory( (DWORD *)stack[1] + 1,
|
||||
+ &func, sizeof(DWORD) ) == sizeof(DWORD) &&
|
||||
+ virtual_uninterrupted_write_memory( (DWORD *)context->Esp + 1,
|
||||
+ &stack[0], sizeof(stack[0]) ) == sizeof(stack[0]))
|
||||
{
|
||||
- context->Eip = (DWORD_PTR)(&thunk->func + 1) + thunk_copy.func;
|
||||
- TRACE( "emulating ATL thunk at %p, func=%08x arg=%08x\n",
|
||||
- thunk, context->Eip, thunk_copy.this );
|
||||
- ret = TRUE;
|
||||
+ context->Ecx = stack[0];
|
||||
+ context->Eax = stack[1];
|
||||
+ context->Esp = context->Esp + sizeof(DWORD);
|
||||
+ context->Eip = func;
|
||||
+ TRACE( "emulating ATL thunk type 5 at %p, func=%08x eax=%08x ecx=%08x esp=%08x\n",
|
||||
+ thunk, context->Eip, context->Eax, context->Ecx, context->Esp );
|
||||
+ return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
- return ret;
|
||||
+ return FALSE;
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
2.1.2
|
||||
|
4
patches/ntdll-ATL_Thunk/definition
Normal file
4
patches/ntdll-ATL_Thunk/definition
Normal file
@ -0,0 +1,4 @@
|
||||
Author: Sebastian Lackner
|
||||
Subject: Implement additional ATL Thunks.
|
||||
Revision: 1
|
||||
Fixes: [29903] Support for additional ATL Thunks
|
Loading…
Reference in New Issue
Block a user