Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
1c1e7ed0
Commit
1c1e7ed0
authored
Oct 21, 2014
by
Sebastian Lackner
Committed by
Alexandre Julliard
Oct 21, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Add support for ATL thunk 'POP ecx; POP eax; PUSH ecx; JMP 4(%eax)'.
parent
dcd2b0a3
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
69 additions
and
0 deletions
+69
-0
virtual.c
dlls/kernel32/tests/virtual.c
+41
-0
signal_i386.c
dlls/ntdll/signal_i386.c
+28
-0
No files found.
dlls/kernel32/tests/virtual.c
View file @
1c1e7ed0
...
...
@@ -1889,6 +1889,23 @@ static inline DWORD send_message_excpt( HWND hWnd, UINT uMsg, WPARAM wParam, LPA
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
;
return
ret
;
}
static
LRESULT
CALLBACK
jmp_test_func
(
HWND
hWnd
,
UINT
uMsg
,
WPARAM
wParam
,
LPARAM
lParam
)
{
if
(
uMsg
==
WM_USER
)
...
...
@@ -1907,6 +1924,11 @@ static LRESULT CALLBACK atl_test_func( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
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
};
...
...
@@ -1914,6 +1936,7 @@ static void test_atl_thunk_emulation( ULONG dep_flags )
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
;
...
...
@@ -2133,6 +2156,24 @@ 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_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
)
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 */
memcpy
(
base
,
code_jmp
,
sizeof
(
code_jmp
)
);
...
...
dlls/ntdll/signal_i386.c
View file @
1c1e7ed0
...
...
@@ -1648,6 +1648,14 @@ union atl_thunk
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"
...
...
@@ -1708,6 +1716,26 @@ static BOOL check_atl_thunk( EXCEPTION_RECORD *rec, CONTEXT *context )
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
(
(
DWORD
*
)
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
->
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
FALSE
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment