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
8b24139f
Commit
8b24139f
authored
Nov 30, 2023
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Add a machine frame to the KiUserApcDispatcher stack on x86-64.
parent
061c612b
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
142 additions
and
42 deletions
+142
-42
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+33
-23
exception.c
dlls/ntdll/tests/exception.c
+91
-0
signal_x86_64.c
dlls/ntdll/unix/signal_x86_64.c
+18
-19
No files found.
dlls/ntdll/signal_x86_64.c
View file @
8b24139f
...
...
@@ -652,30 +652,40 @@ __ASM_GLOBAL_FUNC( KiUserExceptionDispatcher,
/*******************************************************************
* KiUserApcDispatcher (NTDLL.@)
*/
void
WINAPI
dispatch_apc
(
CONTEXT
*
context
,
ULONG_PTR
arg1
,
ULONG_PTR
arg2
,
ULONG_PTR
arg3
,
void
(
CALLBACK
*
func
)(
ULONG_PTR
,
ULONG_PTR
,
ULONG_PTR
,
CONTEXT
*
)
)
{
func
(
arg1
,
arg2
,
arg3
,
context
);
NtContinue
(
context
,
TRUE
);
}
__ASM_GLOBAL_FUNC
(
KiUserApcDispatcher
,
"addq $0x8,%rsp
\n\t
"
"mov 0x98(%rcx),%r10
\n\t
"
/* context->Rsp */
"mov 0xf8(%rcx),%r11
\n\t
"
/* context->Rip */
"mov %r11,-0x8(%r10)
\n\t
"
"mov %rbp,-0x10(%r10)
\n\t
"
"lea -0x10(%r10),%rbp
\n\t
"
__ASM_SEH
(
".seh_pushreg %rbp
\n\t
"
)
__ASM_SEH
(
".seh_setframe %rbp,0
\n\t
"
)
__ASM_SEH
(
".seh_endprologue
\n\t
"
)
__ASM_CFI
(
".cfi_signal_frame
\n\t
"
)
__ASM_CFI
(
".cfi_adjust_cfa_offset 0x10
\n\t
"
)
__ASM_CFI
(
".cfi_def_cfa %rbp,0x10
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %rip,0x8
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %rbp,0
\n\t
"
)
"call "
__ASM_NAME
(
"dispatch_apc"
)
"
\n\t
"
"int3"
)
__ASM_SEH
(
".seh_pushframe
\n\t
"
)
__ASM_SEH
(
".seh_stackalloc 0x4d0
\n\t
"
)
/* sizeof(CONTEXT) */
__ASM_SEH
(
".seh_savereg %rbx,0x90
\n\t
"
)
__ASM_SEH
(
".seh_savereg %rbp,0xa0
\n\t
"
)
__ASM_SEH
(
".seh_savereg %rsi,0xa8
\n\t
"
)
__ASM_SEH
(
".seh_savereg %rdi,0xb0
\n\t
"
)
__ASM_SEH
(
".seh_savereg %r12,0xd8
\n\t
"
)
__ASM_SEH
(
".seh_savereg %r13,0xe0
\n\t
"
)
__ASM_SEH
(
".seh_savereg %r14,0xe8
\n\t
"
)
__ASM_SEH
(
".seh_savereg %r15,0xf0
\n\t
"
)
__ASM_SEH
(
".seh_endprologue
\n\t
"
)
__ASM_CFI
(
".cfi_signal_frame
\n\t
"
)
__ASM_CFI
(
".cfi_def_cfa_offset 0
\n\t
"
)
__ASM_CFI
(
".cfi_offset %rbx,0x90
\n\t
"
)
__ASM_CFI
(
".cfi_offset %rbp,0xa0
\n\t
"
)
__ASM_CFI
(
".cfi_offset %rsi,0xa8
\n\t
"
)
__ASM_CFI
(
".cfi_offset %rdi,0xb0
\n\t
"
)
__ASM_CFI
(
".cfi_offset %r12,0xd8
\n\t
"
)
__ASM_CFI
(
".cfi_offset %r13,0xe0
\n\t
"
)
__ASM_CFI
(
".cfi_offset %r14,0xe8
\n\t
"
)
__ASM_CFI
(
".cfi_offset %r15,0xf0
\n\t
"
)
__ASM_CFI
(
".cfi_offset %rip,0x4d0
\n\t
"
)
__ASM_CFI
(
".cfi_offset %rsp,0x4e8
\n\t
"
)
"movq 0x00(%rsp),%rcx
\n\t
"
/* context->P1Home = arg1 */
"movq 0x08(%rsp),%rdx
\n\t
"
/* context->P2Home = arg2 */
"movq 0x10(%rsp),%r8
\n\t
"
/* context->P3Home = arg3 */
"movq 0x18(%rsp),%rax
\n\t
"
/* context->P4Home = func */
"movq %rsp,%r9
\n\t
"
/* context */
"callq *%rax
\n\t
"
"movq %rsp,%rcx
\n\t
"
/* context */
"movl $1,%edx
\n\t
"
/* alertable */
"call "
__ASM_NAME
(
"NtContinue"
)
"
\n\t
"
"int3"
)
/*******************************************************************
...
...
dlls/ntdll/tests/exception.c
View file @
8b24139f
...
...
@@ -79,6 +79,7 @@ static BOOL (WINAPI *pSetXStateFeaturesMask)(CONTEXT *context, DWORD64 feat
static
BOOL
(
WINAPI
*
pGetXStateFeaturesMask
)(
CONTEXT
*
context
,
DWORD64
*
feature_mask
);
static
BOOL
(
WINAPI
*
pWaitForDebugEventEx
)(
DEBUG_EVENT
*
,
DWORD
);
static
void
*
pKiUserApcDispatcher
;
static
void
*
pKiUserExceptionDispatcher
;
#define RTL_UNLOAD_EVENT_TRACE_NUMBER 64
...
...
@@ -4930,6 +4931,94 @@ static void test_KiUserExceptionDispatcher(void)
ok
(
ret
,
"Got unexpected ret %#x, GetLastError() %lu.
\n
"
,
ret
,
GetLastError
());
}
static
BYTE
saved_KiUserApcDispatcher
[
12
];
static
BOOL
apc_called
;
static
void
CALLBACK
apc_func
(
ULONG_PTR
arg1
,
ULONG_PTR
arg2
,
ULONG_PTR
arg3
)
{
ok
(
arg1
==
0x1234
,
"wrong arg1 %Ix
\n
"
,
arg1
);
ok
(
arg2
==
0x5678
,
"wrong arg2 %Ix
\n
"
,
arg2
);
ok
(
arg3
==
0xdeadbeef
,
"wrong arg3 %Ix
\n
"
,
arg3
);
apc_called
=
TRUE
;
}
static
void
*
WINAPI
hook_KiUserApcDispatcher
(
CONTEXT
*
context
)
{
struct
machine_frame
*
frame
=
(
struct
machine_frame
*
)(
context
+
1
);
UINT
i
;
trace
(
"context %p, context->Rip %#Ix, context->Rsp %#Ix (%#Ix), ContextFlags %#lx.
\n
"
,
context
,
context
->
Rip
,
context
->
Rsp
,
(
char
*
)
context
->
Rsp
-
(
char
*
)
context
,
context
->
ContextFlags
);
ok
(
context
->
P1Home
==
0x1234
,
"wrong p1 %#Ix
\n
"
,
context
->
P1Home
);
ok
(
context
->
P2Home
==
0x5678
,
"wrong p2 %#Ix
\n
"
,
context
->
P2Home
);
ok
(
context
->
P3Home
==
0xdeadbeef
,
"wrong p3 %#Ix
\n
"
,
context
->
P3Home
);
ok
(
context
->
P4Home
==
(
ULONG_PTR
)
apc_func
,
"wrong p4 %#Ix / %p
\n
"
,
context
->
P4Home
,
apc_func
);
/* machine frame offset varies between Windows versions */
for
(
i
=
0
;
i
<
16
;
i
++
)
{
if
(
frame
->
rip
==
context
->
Rip
)
break
;
frame
=
(
struct
machine_frame
*
)((
ULONG64
*
)
frame
+
2
);
}
trace
(
"machine frame %p (%#Ix): rip=%#Ix cs=%#Ix eflags=%#Ix rsp=%#Ix ss=%#Ix
\n
"
,
frame
,
(
char
*
)
frame
-
(
char
*
)
context
,
frame
->
rip
,
frame
->
cs
,
frame
->
eflags
,
frame
->
rsp
,
frame
->
ss
);
ok
(
frame
->
rip
==
context
->
Rip
,
"wrong rip %#Ix / %#Ix
\n
"
,
frame
->
rip
,
context
->
Rip
);
ok
(
frame
->
rsp
==
context
->
Rsp
,
"wrong rsp %#Ix / %#Ix
\n
"
,
frame
->
rsp
,
context
->
Rsp
);
hook_called
=
TRUE
;
memcpy
(
pKiUserApcDispatcher
,
saved_KiUserApcDispatcher
,
sizeof
(
saved_KiUserApcDispatcher
));
return
pKiUserApcDispatcher
;
}
static
void
test_KiUserApcDispatcher
(
void
)
{
BYTE
hook_trampoline
[]
=
{
0x48
,
0x89
,
0xe1
,
/* mov %rsp,%rcx */
0x48
,
0xb8
,
/* movabs hook_KiUserApcDispatcher,%rax */
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
/* offset 5 */
0xff
,
0xd0
,
/* callq *rax */
0xff
,
0xe0
,
/* jmpq *rax */
};
BYTE
patched_KiUserApcDispatcher
[
12
];
DWORD
old_protect
;
BYTE
*
ptr
;
BOOL
ret
;
*
(
ULONG_PTR
*
)(
hook_trampoline
+
5
)
=
(
ULONG_PTR
)
hook_KiUserApcDispatcher
;
memcpy
(
code_mem
,
hook_trampoline
,
sizeof
(
hook_trampoline
));
ret
=
VirtualProtect
(
pKiUserApcDispatcher
,
sizeof
(
saved_KiUserApcDispatcher
),
PAGE_EXECUTE_READWRITE
,
&
old_protect
);
ok
(
ret
,
"Got unexpected ret %#x, GetLastError() %lu.
\n
"
,
ret
,
GetLastError
()
);
memcpy
(
saved_KiUserApcDispatcher
,
pKiUserApcDispatcher
,
sizeof
(
saved_KiUserApcDispatcher
)
);
ptr
=
patched_KiUserApcDispatcher
;
/* mov $code_mem, %rax */
*
ptr
++
=
0x48
;
*
ptr
++
=
0xb8
;
*
(
void
**
)
ptr
=
code_mem
;
ptr
+=
sizeof
(
ULONG64
);
/* jmp *rax */
*
ptr
++
=
0xff
;
*
ptr
++
=
0xe0
;
memcpy
(
pKiUserApcDispatcher
,
patched_KiUserApcDispatcher
,
sizeof
(
patched_KiUserApcDispatcher
)
);
hook_called
=
FALSE
;
apc_called
=
FALSE
;
pNtQueueApcThread
(
GetCurrentThread
(),
apc_func
,
0x1234
,
0x5678
,
0xdeadbeef
);
SleepEx
(
0
,
TRUE
);
ok
(
apc_called
,
"APC was not called
\n
"
);
ok
(
hook_called
,
"hook was not called
\n
"
);
VirtualProtect
(
pKiUserApcDispatcher
,
sizeof
(
saved_KiUserApcDispatcher
),
old_protect
,
&
old_protect
);
}
static
BOOL
got_nested_exception
,
got_prev_frame_exception
;
static
void
*
nested_exception_initial_frame
;
...
...
@@ -11476,6 +11565,7 @@ START_TEST(exception)
X
(
RtlGetExtendedFeaturesMask
);
X
(
RtlCopyContext
);
X
(
RtlCopyExtendedContext
);
X
(
KiUserApcDispatcher
);
X
(
KiUserExceptionDispatcher
);
#undef X
...
...
@@ -11637,6 +11727,7 @@ START_TEST(exception)
test_dpe_exceptions
();
test_wow64_context
();
test_KiUserExceptionDispatcher
();
test_KiUserApcDispatcher
();
test_nested_exception
();
test_collided_unwind
();
...
...
dlls/ntdll/unix/signal_x86_64.c
View file @
8b24139f
...
...
@@ -365,6 +365,16 @@ C_ASSERT( offsetof(struct exc_stack_layout, rec) == 0x4f0 );
C_ASSERT
(
offsetof
(
struct
exc_stack_layout
,
machine_frame
)
==
0x590
);
C_ASSERT
(
sizeof
(
struct
exc_stack_layout
)
==
0x700
);
/* stack layout when calling KiUserApcDispatcher */
struct
apc_stack_layout
{
CONTEXT
context
;
/* 000 */
struct
machine_frame
machine_frame
;
/* 4d0 */
ULONG64
align
;
/* 4f8 */
};
C_ASSERT
(
offsetof
(
struct
apc_stack_layout
,
machine_frame
)
==
0x4d0
);
C_ASSERT
(
sizeof
(
struct
apc_stack_layout
)
==
0x500
);
/* flags to control the behavior of the syscall dispatcher */
#define SYSCALL_HAVE_XSAVE 1
#define SYSCALL_HAVE_XSAVEC 2
...
...
@@ -373,18 +383,6 @@ C_ASSERT( sizeof(struct exc_stack_layout) == 0x700 );
static
unsigned
int
syscall_flags
;
/* stack layout when calling an user apc function.
* FIXME: match Windows ABI. */
struct
apc_stack_layout
{
ULONG64
save_regs
[
4
];
void
*
func
;
ULONG64
align
;
CONTEXT
context
;
ULONG64
rbp
;
ULONG64
rip
;
};
struct
syscall_frame
{
ULONG64
rax
;
/* 0000 */
...
...
@@ -1492,15 +1490,16 @@ NTSTATUS call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR a
NtGetContextThread
(
GetCurrentThread
(),
&
stack
->
context
);
stack
->
context
.
Rax
=
status
;
}
stack
->
context
.
P1Home
=
arg1
;
stack
->
context
.
P2Home
=
arg2
;
stack
->
context
.
P3Home
=
arg3
;
stack
->
context
.
P4Home
=
(
ULONG64
)
func
;
stack
->
machine_frame
.
rip
=
stack
->
context
.
Rip
;
stack
->
machine_frame
.
rsp
=
stack
->
context
.
Rsp
;
frame
->
rbp
=
stack
->
context
.
Rbp
;
frame
->
rsp
=
(
ULONG64
)
stack
-
8
;
frame
->
rsp
=
(
ULONG64
)
stack
;
frame
->
rip
=
(
ULONG64
)
pKiUserApcDispatcher
;
frame
->
rcx
=
(
ULONG64
)
&
stack
->
context
;
frame
->
rdx
=
arg1
;
frame
->
r8
=
arg2
;
frame
->
r9
=
arg3
;
stack
->
func
=
func
;
frame
->
restore_flags
|=
CONTEXT_CONTROL
|
CONTEXT_INTEGER
;
frame
->
restore_flags
|=
CONTEXT_CONTROL
;
return
status
;
}
...
...
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