Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
3774b00f
Commit
3774b00f
authored
Nov 30, 2023
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Fix stack layout for KiUserApcDispatcher on i386.
parent
58a00854
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
164 additions
and
38 deletions
+164
-38
signal_i386.c
dlls/ntdll/signal_i386.c
+8
-6
exception.c
dlls/ntdll/tests/exception.c
+106
-0
signal_i386.c
dlls/ntdll/unix/signal_i386.c
+22
-17
syscall.c
dlls/wow64/syscall.c
+28
-15
No files found.
dlls/ntdll/signal_i386.c
View file @
3774b00f
...
...
@@ -255,12 +255,14 @@ __ASM_STDCALL_FUNC( KiUserExceptionDispatcher, 8,
/*******************************************************************
* KiUserApcDispatcher (NTDLL.@)
*/
void
WINAPI
KiUserApcDispatcher
(
CONTEXT
*
context
,
ULONG_PTR
ctx
,
ULONG_PTR
arg1
,
ULONG_PTR
arg2
,
PNTAPCFUNC
func
)
{
func
(
ctx
,
arg1
,
arg2
);
NtContinue
(
context
,
TRUE
);
}
__ASM_STDCALL_FUNC
(
KiUserApcDispatcher
,
20
,
"leal 0x14(%esp),%ebx
\n\t
"
/* context */
"pop %eax
\n\t
"
/* func */
"call *%eax
\n\t
"
"pushl -4(%ebx)
\n\t
"
/* alertable */
"pushl %ebx
\n\t
"
/* context */
"call "
__ASM_STDCALL
(
"NtContinue"
,
8
)
"
\n\t
"
"int3"
)
/*******************************************************************
...
...
dlls/ntdll/tests/exception.c
View file @
3774b00f
...
...
@@ -2070,6 +2070,111 @@ static void test_KiUserExceptionDispatcher(void)
ok
(
ret
,
"Got unexpected ret %#x, GetLastError() %lu.
\n
"
,
ret
,
GetLastError
());
}
static
BYTE
saved_KiUserApcDispatcher
[
7
];
static
UINT
apc_count
;
static
void
CALLBACK
apc_func
(
ULONG_PTR
arg1
,
ULONG_PTR
arg2
,
ULONG_PTR
arg3
)
{
ok
(
arg1
==
0x1234
+
apc_count
,
"wrong arg1 %Ix
\n
"
,
arg1
);
ok
(
arg2
==
0x5678
,
"wrong arg2 %Ix
\n
"
,
arg2
);
ok
(
arg3
==
0xdeadbeef
,
"wrong arg3 %Ix
\n
"
,
arg3
);
apc_count
++
;
}
static
void
*
CDECL
hook_KiUserApcDispatcher
(
void
*
func
,
ULONG_PTR
arg1
,
ULONG_PTR
arg2
,
ULONG_PTR
arg3
)
{
CONTEXT
*
context
=
(
CONTEXT
*
)((
ULONG_PTR
)
&
arg3
+
sizeof
(
ULONG
));
ok
(
func
==
apc_func
,
"wrong function %p / %p
\n
"
,
func
,
apc_func
);
ok
(
arg1
==
0x1234
+
apc_count
,
"wrong arg1 %Ix
\n
"
,
arg1
);
ok
(
arg2
==
0x5678
,
"wrong arg2 %Ix
\n
"
,
arg2
);
ok
(
arg3
==
0xdeadbeef
,
"wrong arg3 %Ix
\n
"
,
arg3
);
if
(
context
->
ContextFlags
!=
1
)
{
trace
(
"context %p eip %lx ebp %lx esp %lx (%x)
\n
"
,
context
,
context
->
Eip
,
context
->
Ebp
,
context
->
Esp
,
(
char
*
)
context
->
Esp
-
(
char
*
)
&
func
);
}
else
/* new style with alertable arg and CONTEXT_EX */
{
CONTEXT_EX
*
xctx
;
ULONG
*
alertable
=
(
ULONG
*
)
context
;
context
=
(
CONTEXT
*
)(
alertable
+
1
);
xctx
=
(
CONTEXT_EX
*
)(
context
+
1
);
trace
(
"alertable %lx context %p eip %lx ebp %lx esp %lx (%x)
\n
"
,
*
alertable
,
context
,
context
->
Eip
,
context
->
Ebp
,
context
->
Esp
,
(
char
*
)
context
->
Esp
-
(
char
*
)
&
func
);
if
((
void
*
)(
xctx
+
1
)
<
(
void
*
)
context
->
Esp
)
{
ok
(
xctx
->
All
.
Offset
==
-
sizeof
(
CONTEXT
),
"wrong All.Offset %lx
\n
"
,
xctx
->
All
.
Offset
);
ok
(
xctx
->
All
.
Length
>=
sizeof
(
CONTEXT
)
+
sizeof
(
CONTEXT_EX
),
"wrong All.Length %lx
\n
"
,
xctx
->
All
.
Length
);
ok
(
xctx
->
Legacy
.
Offset
==
-
sizeof
(
CONTEXT
),
"wrong Legacy.Offset %lx
\n
"
,
xctx
->
All
.
Offset
);
ok
(
xctx
->
Legacy
.
Length
==
sizeof
(
CONTEXT
),
"wrong Legacy.Length %lx
\n
"
,
xctx
->
All
.
Length
);
}
if
(
apc_count
)
*
alertable
=
0
;
pNtQueueApcThread
(
GetCurrentThread
(),
apc_func
,
0x1234
+
apc_count
+
1
,
0x5678
,
0xdeadbeef
);
}
hook_called
=
TRUE
;
memcpy
(
pKiUserApcDispatcher
,
saved_KiUserApcDispatcher
,
sizeof
(
saved_KiUserApcDispatcher
));
return
pKiUserApcDispatcher
;
}
static
void
test_KiUserApcDispatcher
(
void
)
{
BYTE
hook_trampoline
[]
=
{
0xff
,
0x15
,
/* offset: 2 bytes */
0x00
,
0x00
,
0x00
,
0x00
,
/* call *addr */
/* call hook implementation. */
0xff
,
0xe0
,
/* jmp *%eax */
};
BYTE
patched_KiUserApcDispatcher
[
7
];
void
*
phook_KiUserApcDispatcher
=
hook_KiUserApcDispatcher
;
DWORD
old_protect
;
BYTE
*
ptr
;
BOOL
ret
;
*
(
ULONG_PTR
*
)(
hook_trampoline
+
2
)
=
(
ULONG_PTR
)
&
phook_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 $hook_trampoline, %eax */
*
ptr
++
=
0xb8
;
*
(
void
**
)
ptr
=
code_mem
;
ptr
+=
sizeof
(
void
*
);
/* jmp *eax */
*
ptr
++
=
0xff
;
*
ptr
++
=
0xe0
;
memcpy
(
pKiUserApcDispatcher
,
patched_KiUserApcDispatcher
,
sizeof
(
patched_KiUserApcDispatcher
)
);
apc_count
=
0
;
hook_called
=
FALSE
;
pNtQueueApcThread
(
GetCurrentThread
(),
apc_func
,
0x1234
,
0x5678
,
0xdeadbeef
);
SleepEx
(
0
,
TRUE
);
ok
(
apc_count
==
1
||
apc_count
==
2
,
"APC count %u
\n
"
,
apc_count
);
ok
(
hook_called
,
"hook was not called
\n
"
);
if
(
apc_count
==
2
)
{
memcpy
(
pKiUserApcDispatcher
,
patched_KiUserApcDispatcher
,
sizeof
(
patched_KiUserApcDispatcher
)
);
pNtQueueApcThread
(
GetCurrentThread
(),
apc_func
,
0x1234
+
apc_count
,
0x5678
,
0xdeadbeef
);
SleepEx
(
0
,
TRUE
);
ok
(
apc_count
==
3
,
"APC count %u
\n
"
,
apc_count
);
SleepEx
(
0
,
TRUE
);
ok
(
apc_count
==
4
,
"APC count %u
\n
"
,
apc_count
);
}
VirtualProtect
(
pKiUserApcDispatcher
,
sizeof
(
saved_KiUserApcDispatcher
),
old_protect
,
&
old_protect
);
}
#elif defined(__x86_64__)
#define UNW_FLAG_NHANDLER 0
...
...
@@ -12015,6 +12120,7 @@ START_TEST(exception)
test_dpe_exceptions
();
test_prot_fault
();
test_KiUserExceptionDispatcher
();
test_KiUserApcDispatcher
();
test_extended_context
();
test_copy_context
();
test_set_live_context
();
...
...
dlls/ntdll/unix/signal_i386.c
View file @
3774b00f
...
...
@@ -450,6 +450,21 @@ C_ASSERT( offsetof(struct exc_stack_layout, context) == 0x58 );
C_ASSERT
(
offsetof
(
struct
exc_stack_layout
,
xstate
)
==
0x33c
);
C_ASSERT
(
sizeof
(
struct
exc_stack_layout
)
==
0x4c0
);
/* stack layout when calling KiUserApcDispatcher */
struct
apc_stack_layout
{
PNTAPCFUNC
func
;
/* 000 */
UINT
arg1
;
/* 004 */
UINT
arg2
;
/* 008 */
UINT
arg3
;
/* 00c */
UINT
alertable
;
/* 010 */
CONTEXT
context
;
/* 014 */
CONTEXT_EX
xctx
;
/* 2e0 */
UINT
unk2
[
4
];
/* 2f8 */
};
C_ASSERT
(
offsetof
(
struct
apc_stack_layout
,
context
)
==
0x14
);
C_ASSERT
(
sizeof
(
struct
apc_stack_layout
)
==
0x308
);
struct
syscall_frame
{
WORD
syscall_flags
;
/* 000 */
...
...
@@ -1495,17 +1510,6 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
setup_raise_exception
(
sigcontext
,
stack
,
rec
,
&
xcontext
);
}
/* stack layout when calling an user apc function.
* FIXME: match Windows ABI. */
struct
apc_stack_layout
{
CONTEXT
*
context_ptr
;
ULONG_PTR
arg1
;
ULONG_PTR
arg2
;
ULONG_PTR
arg3
;
PNTAPCFUNC
func
;
CONTEXT
context
;
};
/***********************************************************************
* call_user_apc_dispatcher
...
...
@@ -1525,13 +1529,14 @@ NTSTATUS call_user_apc_dispatcher( CONTEXT *context, ULONG_PTR arg1, ULONG_PTR a
}
else
memmove
(
&
stack
->
context
,
context
,
sizeof
(
stack
->
context
)
);
stack
->
context_ptr
=
&
stack
->
context
;
stack
->
arg1
=
arg1
;
stack
->
arg2
=
arg2
;
stack
->
arg3
=
arg3
;
stack
->
func
=
func
;
context_init_xstate
(
&
stack
->
context
,
NULL
);
stack
->
func
=
func
;
stack
->
arg1
=
arg1
;
stack
->
arg2
=
arg2
;
stack
->
arg3
=
arg3
;
stack
->
alertable
=
TRUE
;
frame
->
ebp
=
stack
->
context
.
Ebp
;
frame
->
esp
=
(
ULONG
)
stack
-
4
;
frame
->
esp
=
(
ULONG
)
stack
;
frame
->
eip
=
(
ULONG
)
pKiUserApcDispatcher
;
return
status
;
}
...
...
dlls/wow64/syscall.c
View file @
3774b00f
...
...
@@ -1000,26 +1000,39 @@ void WINAPI Wow64ApcRoutine( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, CON
{
case
IMAGE_FILE_MACHINE_I386
:
{
struct
apc_stack_layout
/* stack layout when calling 32-bit KiUserApcDispatcher */
struct
apc_stack_layout32
{
ULONG
ret
;
ULONG
context_ptr
;
ULONG
arg1
;
ULONG
arg2
;
ULONG
arg3
;
ULONG
func
;
I386_CONTEXT
context
;
ULONG
func
;
/* 000 */
UINT
arg1
;
/* 004 */
UINT
arg2
;
/* 008 */
UINT
arg3
;
/* 00c */
UINT
alertable
;
/* 010 */
I386_CONTEXT
context
;
/* 014 */
CONTEXT_EX32
xctx
;
/* 2e0 */
UINT
unk2
[
4
];
/* 2f8 */
}
*
stack
;
I386_CONTEXT
ctx
=
{
CONTEXT_I386_FULL
};
C_ASSERT
(
offsetof
(
struct
apc_stack_layout32
,
context
)
==
0x14
);
C_ASSERT
(
sizeof
(
struct
apc_stack_layout32
)
==
0x308
);
pBTCpuGetContext
(
GetCurrentThread
(),
GetCurrentProcess
(),
NULL
,
&
ctx
);
stack
=
(
struct
apc_stack_layout
*
)
ULongToPtr
(
ctx
.
Esp
&
~
3
)
-
1
;
stack
->
context_ptr
=
PtrToUlong
(
&
stack
->
context
);
stack
->
func
=
arg1
>>
32
;
stack
->
arg1
=
arg1
;
stack
->
arg2
=
arg2
;
stack
->
arg3
=
arg3
;
stack
->
context
=
ctx
;
stack
=
(
struct
apc_stack_layout32
*
)
ULongToPtr
(
ctx
.
Esp
&
~
3
)
-
1
;
stack
->
func
=
arg1
>>
32
;
stack
->
arg1
=
arg1
;
stack
->
arg2
=
arg2
;
stack
->
arg3
=
arg3
;
stack
->
alertable
=
TRUE
;
stack
->
context
=
ctx
;
stack
->
xctx
.
Legacy
.
Offset
=
-
(
LONG
)
sizeof
(
stack
->
context
);
stack
->
xctx
.
Legacy
.
Length
=
sizeof
(
stack
->
context
);
stack
->
xctx
.
All
.
Offset
=
-
(
LONG
)
sizeof
(
stack
->
context
);
stack
->
xctx
.
All
.
Length
=
sizeof
(
stack
->
context
)
+
sizeof
(
stack
->
xctx
);
stack
->
xctx
.
XState
.
Offset
=
25
;
stack
->
xctx
.
XState
.
Length
=
0
;
ctx
.
Esp
=
PtrToUlong
(
stack
);
ctx
.
Eip
=
pLdrSystemDllInitBlock
->
pKiUserApcDispatcher
;
frame
.
wow_context
=
&
stack
->
context
;
...
...
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