Commit 0702d6b8 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Don't allow single-stepping through syscalls.

parent 5c009c17
...@@ -1753,6 +1753,34 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, void *stack_ptr, ...@@ -1753,6 +1753,34 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, void *stack_ptr,
} }
/***********************************************************************
* handle_syscall_trap
*
* Handle a trap exception during a system call.
*/
static BOOL handle_syscall_trap( ucontext_t *sigcontext )
{
extern void __wine_syscall_dispatcher_prolog_end(void);
struct syscall_frame *frame = x86_thread_data()->syscall_frame;
/* disallow single-stepping through a syscall */
if ((void *)EIP_sig( sigcontext ) != __wine_syscall_dispatcher) return FALSE;
TRACE( "ignoring trap in syscall eip=%08x eflags=%08x\n", EIP_sig(sigcontext), EFL_sig(sigcontext) );
frame->eip = *(ULONG *)ESP_sig( sigcontext );
frame->eflags = EFL_sig(sigcontext);
frame->restore_flags = CONTEXT_CONTROL;
EIP_sig( sigcontext ) = (ULONG)__wine_syscall_dispatcher_prolog_end;
ECX_sig( sigcontext ) = (ULONG)frame;
ESP_sig( sigcontext ) += sizeof(ULONG);
EFL_sig( sigcontext ) &= ~0x100; /* clear single-step flag */
return TRUE;
}
/********************************************************************** /**********************************************************************
* segv_handler * segv_handler
* *
...@@ -1855,6 +1883,8 @@ static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext ) ...@@ -1855,6 +1883,8 @@ static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext )
ucontext_t *ucontext = sigcontext; ucontext_t *ucontext = sigcontext;
void *stack = setup_exception_record( sigcontext, &rec, &xcontext ); void *stack = setup_exception_record( sigcontext, &rec, &xcontext );
if (handle_syscall_trap( ucontext )) return;
switch (TRAP_sig(ucontext)) switch (TRAP_sig(ucontext))
{ {
case TRAP_x86_TRCTRAP: /* Single-step exception */ case TRAP_x86_TRCTRAP: /* Single-step exception */
......
...@@ -2202,6 +2202,35 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, EXCEPTION_RECORD *rec, ...@@ -2202,6 +2202,35 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, EXCEPTION_RECORD *rec,
} }
/***********************************************************************
* handle_syscall_trap
*
* Handle a trap exception during a system call.
*/
static BOOL handle_syscall_trap( ucontext_t *sigcontext )
{
extern void __wine_syscall_dispatcher_prolog_end(void);
struct syscall_frame *frame = amd64_thread_data()->syscall_frame;
/* disallow single-stepping through a syscall */
if ((void *)RIP_sig( sigcontext ) != __wine_syscall_dispatcher) return FALSE;
TRACE( "ignoring trap in syscall rip=%p eflags=%08x\n",
(void *)RIP_sig(sigcontext), (ULONG)EFL_sig(sigcontext) );
frame->rip = *(ULONG64 *)RSP_sig( sigcontext );
frame->eflags = EFL_sig(sigcontext);
frame->restore_flags = CONTEXT_CONTROL;
RIP_sig( sigcontext ) = (ULONG64)__wine_syscall_dispatcher_prolog_end;
RCX_sig( sigcontext ) = (ULONG64)frame;
RSP_sig( sigcontext ) += sizeof(ULONG64);
EFL_sig( sigcontext ) &= ~0x100; /* clear single-step flag */
return TRUE;
}
/********************************************************************** /**********************************************************************
* segv_handler * segv_handler
* *
...@@ -2281,6 +2310,8 @@ static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext ) ...@@ -2281,6 +2310,8 @@ static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext )
struct xcontext context; struct xcontext context;
ucontext_t *ucontext = sigcontext; ucontext_t *ucontext = sigcontext;
if (handle_syscall_trap( sigcontext )) return;
rec.ExceptionAddress = (void *)RIP_sig(ucontext); rec.ExceptionAddress = (void *)RIP_sig(ucontext);
save_context( &context, sigcontext ); save_context( &context, sigcontext );
......
...@@ -1436,9 +1436,10 @@ static void output_syscall_dispatcher(void) ...@@ -1436,9 +1436,10 @@ static void output_syscall_dispatcher(void)
output( "\tmovl %%fs:0x1f8,%%ecx\n" ); /* x86_thread_data()->syscall_frame */ output( "\tmovl %%fs:0x1f8,%%ecx\n" ); /* x86_thread_data()->syscall_frame */
output( "\tmovl $0,0x00(%%ecx)\n" ); /* frame->restore_flags */ output( "\tmovl $0,0x00(%%ecx)\n" ); /* frame->restore_flags */
output( "\tpopl 0x08(%%ecx)\n" ); /* frame->eip */ output( "\tpopl 0x08(%%ecx)\n" ); /* frame->eip */
output( "\tmovl %%esp,0x0c(%%ecx)\n" ); /* frame->esp */
output( "\tpushfl\n" ); output( "\tpushfl\n" );
output( "\tpopl 0x04(%%ecx)\n" ); /* frame->eflags */ output( "\tpopl 0x04(%%ecx)\n" ); /* frame->eflags */
output( "%s\n", asm_globl("__wine_syscall_dispatcher_prolog_end") );
output( "\tmovl %%esp,0x0c(%%ecx)\n" ); /* frame->esp */
output( "\tmovw %%cs,0x10(%%ecx)\n" ); output( "\tmovw %%cs,0x10(%%ecx)\n" );
output( "\tmovw %%ss,0x12(%%ecx)\n" ); output( "\tmovw %%ss,0x12(%%ecx)\n" );
output( "\tmovw %%ds,0x14(%%ecx)\n" ); output( "\tmovw %%ds,0x14(%%ecx)\n" );
...@@ -1553,6 +1554,11 @@ static void output_syscall_dispatcher(void) ...@@ -1553,6 +1554,11 @@ static void output_syscall_dispatcher(void)
case CPU_x86_64: case CPU_x86_64:
output( "\tmovq %%gs:0x30,%%rcx\n" ); output( "\tmovq %%gs:0x30,%%rcx\n" );
output( "\tmovq 0x328(%%rcx),%%rcx\n" ); /* amd64_thread_data()->syscall_frame */ output( "\tmovq 0x328(%%rcx),%%rcx\n" ); /* amd64_thread_data()->syscall_frame */
output( "\tpopq 0x70(%%rcx)\n" ); /* frame->rip */
output( "\tpushfq\n" );
output( "\tpopq 0x80(%%rcx)\n" );
output( "\tmovl $0,0x94(%%rcx)\n" ); /* frame->restore_flags */
output( "%s\n", asm_globl("__wine_syscall_dispatcher_prolog_end") );
output( "\tmovq %%rax,0x00(%%rcx)\n" ); output( "\tmovq %%rax,0x00(%%rcx)\n" );
output( "\tmovq %%rbx,0x08(%%rcx)\n" ); output( "\tmovq %%rbx,0x08(%%rcx)\n" );
output( "\tmovq %%rdx,0x18(%%rcx)\n" ); output( "\tmovq %%rdx,0x18(%%rcx)\n" );
...@@ -1562,7 +1568,6 @@ static void output_syscall_dispatcher(void) ...@@ -1562,7 +1568,6 @@ static void output_syscall_dispatcher(void)
output( "\tmovq %%r13,0x58(%%rcx)\n" ); output( "\tmovq %%r13,0x58(%%rcx)\n" );
output( "\tmovq %%r14,0x60(%%rcx)\n" ); output( "\tmovq %%r14,0x60(%%rcx)\n" );
output( "\tmovq %%r15,0x68(%%rcx)\n" ); output( "\tmovq %%r15,0x68(%%rcx)\n" );
output( "\tpopq 0x70(%%rcx)\n" ); /* frame->rip */
output( "\tmovw %%cs,0x78(%%rcx)\n" ); output( "\tmovw %%cs,0x78(%%rcx)\n" );
output( "\tmovw %%ds,0x7a(%%rcx)\n" ); output( "\tmovw %%ds,0x7a(%%rcx)\n" );
output( "\tmovw %%es,0x7c(%%rcx)\n" ); output( "\tmovw %%es,0x7c(%%rcx)\n" );
...@@ -1570,10 +1575,7 @@ static void output_syscall_dispatcher(void) ...@@ -1570,10 +1575,7 @@ static void output_syscall_dispatcher(void)
output( "\tmovq %%rsp,0x88(%%rcx)\n" ); output( "\tmovq %%rsp,0x88(%%rcx)\n" );
output( "\tmovw %%ss,0x90(%%rcx)\n" ); output( "\tmovw %%ss,0x90(%%rcx)\n" );
output( "\tmovw %%gs,0x92(%%rcx)\n" ); output( "\tmovw %%gs,0x92(%%rcx)\n" );
output( "\tmovl $0,0x94(%%rcx)\n" ); /* frame->restore_flags */
output( "\tmovq %%rbp,0x98(%%rcx)\n" ); output( "\tmovq %%rbp,0x98(%%rcx)\n" );
output( "\tpushfq\n" );
output( "\tpopq 0x80(%%rcx)\n" );
/* Legends of Runeterra hooks the first system call return instruction, and /* Legends of Runeterra hooks the first system call return instruction, and
* depends on us returning to it. Adjust the return address accordingly. */ * depends on us returning to it. Adjust the return address accordingly. */
output( "\tsubq $0xb,0x70(%%rcx)\n" ); output( "\tsubq $0xb,0x70(%%rcx)\n" );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment