ntdll: Add support for ATL thunk 'MOV this,ecx; MOV func,eax; JMP eax'.
This commit is contained in:
parent
40472cd3a7
commit
dcd2b0a366
|
@ -1913,6 +1913,7 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
|
||||||
static const char code_atl1[] = {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_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_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 cls_name[] = "atl_thunk_class";
|
static const char cls_name[] = "atl_thunk_class";
|
||||||
DWORD ret, size, old_prot;
|
DWORD ret, size, old_prot;
|
||||||
ULONG old_flags = MEM_EXECUTE_OPTION_ENABLE;
|
ULONG old_flags = MEM_EXECUTE_OPTION_ENABLE;
|
||||||
|
@ -2114,6 +2115,24 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
|
||||||
else
|
else
|
||||||
ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls );
|
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)
|
||||||
|
ok( num_execute_fault_calls == 0 || broken(num_execute_fault_calls == 1) /* Windows XP */,
|
||||||
|
"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 */
|
/* Restore the JMP instruction, set to executable, and then destroy the Window */
|
||||||
|
|
||||||
memcpy( base, code_jmp, sizeof(code_jmp) );
|
memcpy( base, code_jmp, sizeof(code_jmp) );
|
||||||
|
|
|
@ -1640,6 +1640,14 @@ union atl_thunk
|
||||||
DWORD func;
|
DWORD func;
|
||||||
WORD jmp; /* jmp ecx */
|
WORD jmp; /* jmp ecx */
|
||||||
} t3;
|
} t3;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
BYTE movl1; /* movl this,ecx */
|
||||||
|
DWORD this;
|
||||||
|
BYTE movl2; /* movl func,eax */
|
||||||
|
DWORD func;
|
||||||
|
WORD jmp; /* jmp eax */
|
||||||
|
} t4;
|
||||||
};
|
};
|
||||||
#include "poppack.h"
|
#include "poppack.h"
|
||||||
|
|
||||||
|
@ -1689,6 +1697,17 @@ static BOOL check_atl_thunk( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||||
thunk, context->Eip, context->Ecx, context->Edx );
|
thunk, context->Eip, context->Ecx, context->Edx );
|
||||||
return TRUE;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue