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
e7845fc3
Commit
e7845fc3
authored
May 30, 2023
by
Paul Gofman
Committed by
Alexandre Julliard
Jun 01, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernelbase: Don't modify non-volatile regs in RaiseException() on x64.
parent
1db53cdc
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
145 additions
and
0 deletions
+145
-0
debug.c
dlls/kernelbase/debug.c
+46
-0
exception.c
dlls/ntdll/tests/exception.c
+99
-0
No files found.
dlls/kernelbase/debug.c
View file @
e7845fc3
...
...
@@ -283,6 +283,51 @@ void WINAPI DECLSPEC_HOTPATCH OutputDebugStringW( LPCWSTR str )
/*******************************************************************
* RaiseException (kernelbase.@)
*/
#if defined(__x86_64__)
/* Some DRMs depend on RaiseException not altering non-volatile registers. */
__ASM_GLOBAL_FUNC
(
RaiseException
,
".byte 0x48,0x8d,0xa4,0x24,0x00,0x00,0x00,0x00
\n\t
"
/* hotpatch prolog */
"sub $0xc8,%rsp
\n\t
"
__ASM_SEH
(
".seh_stackalloc 0xc8
\n\t
"
)
__ASM_SEH
(
".seh_endprologue
\n\t
"
)
__ASM_CFI
(
".cfi_adjust_cfa_offset 0xc8
\n\t
"
)
"leaq 0x20(%rsp),%rax
\n\t
"
"movl %ecx,(%rax)
\n\t
"
/* ExceptionCode */
"and $1,%edx
\n\t
"
"movl %edx,4(%rax)
\n\t
"
/* ExceptionFlags */
"movq $0,8(%rax)
\n\t
"
/* ExceptionRecord */
"leaq "
__ASM_NAME
(
"RaiseException"
)
"(%rip),%rcx
\n\t
"
"movq %rcx,0x10(%rax)
\n\t
"
/* ExceptionAddress */
"movq %rax,%rcx
\n\t
"
"movl $0,0x18(%rcx)
\n\t
"
/* NumberParameters */
"testl %r8d,%r8d
\n\t
"
"jz 2f
\n\t
"
"testq %r9,%r9
\n\t
"
"jz 2f
\n\t
"
"movl $15,%edx
\n\t
"
"cmp %edx,%r8d
\n\t
"
"cmovb %r8d,%edx
\n\t
"
"movl %edx,0x18(%rcx)
\n\t
"
/* NumberParameters */
"leaq 0x20(%rcx),%rax
\n
"
/* ExceptionInformation */
"1:
\t
movq (%r9),%r8
\n\t
"
"movq %r8,(%rax)
\n\t
"
"decl %edx
\n\t
"
"jz 2f
\n\t
"
"addq $8,%rax
\n\t
"
"addq $8,%r9
\n\t
"
"jmp 1b
\n
"
"2:
\t
call "
__ASM_NAME
(
"RtlRaiseException"
)
"
\n\t
"
"add $0xc8,%rsp
\n\t
"
__ASM_CFI
(
".cfi_adjust_cfa_offset -0xc8
\n\t
"
)
"ret"
)
C_ASSERT
(
offsetof
(
EXCEPTION_RECORD
,
ExceptionCode
)
==
0
);
C_ASSERT
(
offsetof
(
EXCEPTION_RECORD
,
ExceptionFlags
)
==
4
);
C_ASSERT
(
offsetof
(
EXCEPTION_RECORD
,
ExceptionRecord
)
==
8
);
C_ASSERT
(
offsetof
(
EXCEPTION_RECORD
,
ExceptionAddress
)
==
0x10
);
C_ASSERT
(
offsetof
(
EXCEPTION_RECORD
,
NumberParameters
)
==
0x18
);
C_ASSERT
(
offsetof
(
EXCEPTION_RECORD
,
ExceptionInformation
)
==
0x20
);
#else
void
WINAPI
DECLSPEC_HOTPATCH
RaiseException
(
DWORD
code
,
DWORD
flags
,
DWORD
count
,
const
ULONG_PTR
*
args
)
{
EXCEPTION_RECORD
record
;
...
...
@@ -301,6 +346,7 @@ void WINAPI DECLSPEC_HOTPATCH RaiseException( DWORD code, DWORD flags, DWORD cou
RtlRaiseException
(
&
record
);
}
#endif
__ASM_STDCALL_IMPORT
(
RaiseException
,
16
)
/*******************************************************************
...
...
dlls/ntdll/tests/exception.c
View file @
e7845fc3
...
...
@@ -5031,6 +5031,104 @@ static void test_syscall_clobbered_regs(void)
ok
(
regs
.
r11
==
regs
.
eflags
,
"Expected r11 (%#I64x) to equal EFLAGS (%#x).
\n
"
,
regs
.
r11
,
regs
.
eflags
);
}
static
CONTEXT
test_raiseexception_regs_context
;
static
LONG
CALLBACK
test_raiseexception_regs_handle
(
EXCEPTION_POINTERS
*
exception_info
)
{
EXCEPTION_RECORD
*
rec
=
exception_info
->
ExceptionRecord
;
unsigned
int
i
;
test_raiseexception_regs_context
=
*
exception_info
->
ContextRecord
;
ok
(
rec
->
NumberParameters
==
EXCEPTION_MAXIMUM_PARAMETERS
,
"got %lu.
\n
"
,
rec
->
NumberParameters
);
ok
(
rec
->
ExceptionCode
==
0xdeadbeaf
,
"got %#lx.
\n
"
,
rec
->
ExceptionCode
);
ok
(
!
rec
->
ExceptionRecord
,
"got %p.
\n
"
,
rec
->
ExceptionRecord
);
ok
(
!
rec
->
ExceptionFlags
,
"got %#lx.
\n
"
,
rec
->
ExceptionFlags
);
for
(
i
=
0
;
i
<
rec
->
NumberParameters
;
++
i
)
ok
(
rec
->
ExceptionInformation
[
i
]
==
i
,
"got %Iu, i %u.
\n
"
,
rec
->
ExceptionInformation
[
i
],
i
);
return
EXCEPTION_CONTINUE_EXECUTION
;
}
static
void
test_raiseexception_regs
(
void
)
{
static
const
BYTE
code
[]
=
{
0xb8
,
0x00
,
0xb0
,
0xad
,
0xde
,
/* mov $0xdeadb000,%eax */
0x53
,
/* push %rbx */
0x48
,
0x89
,
0xc3
,
/* mov %rax,%rbx */
0x56
,
/* push %rsi */
0x48
,
0xff
,
0xc0
,
/* inc %rax */
0x48
,
0x89
,
0xc6
,
/* mov %rax,%rsi */
0x57
,
/* push %rdi */
0x48
,
0xff
,
0xc0
,
/* inc %rax */
0x48
,
0x89
,
0xc7
,
/* mov %rax,%rdi */
0x55
,
/* push %rbp */
0x48
,
0xff
,
0xc0
,
/* inc %rax */
0x48
,
0x89
,
0xc5
,
/* mov %rax,%rbp */
0x41
,
0x54
,
/* push %r12 */
0x48
,
0xff
,
0xc0
,
/* inc %rax */
0x49
,
0x89
,
0xc4
,
/* mov %rax,%r12 */
0x41
,
0x55
,
/* push %r13 */
0x48
,
0xff
,
0xc0
,
/* inc %rax */
0x49
,
0x89
,
0xc5
,
/* mov %rax,%r13 */
0x41
,
0x56
,
/* push %r14 */
0x48
,
0xff
,
0xc0
,
/* inc %rax */
0x49
,
0x89
,
0xc6
,
/* mov %rax,%r14 */
0x41
,
0x57
,
/* push %r15 */
0x48
,
0xff
,
0xc0
,
/* inc %rax */
0x49
,
0x89
,
0xc7
,
/* mov %rax,%r15 */
0x50
,
/* push %rax */
/* align stack */
0x48
,
0x89
,
0xc8
,
/* mov %rcx,%rax */
0xb9
,
0xaf
,
0xbe
,
0xad
,
0xde
,
/* mov $0xdeadbeaf,%ecx */
0xff
,
0xd0
,
/* call *%rax */
0x58
,
/* pop %rax */
0x41
,
0x5f
,
/* pop %r15 */
0x41
,
0x5e
,
/* pop %r14 */
0x41
,
0x5d
,
/* pop %r13 */
0x41
,
0x5c
,
/* pop %r12 */
0x5d
,
/* pop %rbp */
0x5f
,
/* pop %rdi */
0x5e
,
/* pop %rsi */
0x5b
,
/* pop %rbx */
0xc3
,
/* ret */
};
void
(
WINAPI
*
pRaiseException
)(
DWORD
code
,
DWORD
flags
,
DWORD
count
,
const
ULONG_PTR
*
args
)
=
RaiseException
;
void
(
WINAPI
*
func
)(
void
*
raise_exception
,
DWORD
flags
,
DWORD
count
,
const
ULONG_PTR
*
args
);
void
*
vectored_handler
;
ULONG_PTR
args
[
20
];
ULONG64
expected
;
unsigned
int
i
;
vectored_handler
=
AddVectoredExceptionHandler
(
TRUE
,
test_raiseexception_regs_handle
);
ok
(
!!
vectored_handler
,
"failed.
\n
"
);
memcpy
(
code_mem
,
code
,
sizeof
(
code
));
func
=
code_mem
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
args
);
++
i
)
args
[
i
]
=
i
;
func
(
pRaiseException
,
0
,
ARRAY_SIZE
(
args
),
args
);
expected
=
0xdeadb000
;
ok
(
test_raiseexception_regs_context
.
Rbx
==
expected
,
"got %#I64x.
\n
"
,
test_raiseexception_regs_context
.
Rbx
);
++
expected
;
ok
(
test_raiseexception_regs_context
.
Rsi
==
expected
,
"got %#I64x.
\n
"
,
test_raiseexception_regs_context
.
Rsi
);
++
expected
;
ok
(
test_raiseexception_regs_context
.
Rdi
==
expected
,
"got %#I64x.
\n
"
,
test_raiseexception_regs_context
.
Rdi
);
++
expected
;
ok
(
test_raiseexception_regs_context
.
Rbp
==
expected
,
"got %#I64x.
\n
"
,
test_raiseexception_regs_context
.
Rbp
);
++
expected
;
ok
(
test_raiseexception_regs_context
.
R12
==
expected
,
"got %#I64x.
\n
"
,
test_raiseexception_regs_context
.
R12
);
++
expected
;
ok
(
test_raiseexception_regs_context
.
R13
==
expected
,
"got %#I64x.
\n
"
,
test_raiseexception_regs_context
.
R13
);
++
expected
;
ok
(
test_raiseexception_regs_context
.
R14
==
expected
,
"got %#I64x.
\n
"
,
test_raiseexception_regs_context
.
R14
);
++
expected
;
ok
(
test_raiseexception_regs_context
.
R15
==
expected
,
"got %#I64x.
\n
"
,
test_raiseexception_regs_context
.
R15
);
RemoveVectoredExceptionHandler
(
vectored_handler
);
}
#elif defined(__arm__)
#define UNW_FLAG_NHANDLER 0
...
...
@@ -10974,6 +11072,7 @@ START_TEST(exception)
test_copy_context
();
test_unwind_from_apc
();
test_syscall_clobbered_regs
();
test_raiseexception_regs
();
#elif defined(__aarch64__)
...
...
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