[RTL/x64] Do not overwrite the original context during exception handling

This fixes ExceptionContinueExecution cases, where we want to continue execution on the original context (or as modified by the handler), not on some halfway unwinded one.
This commit is contained in:
Timo Kreuzer 2024-09-07 22:10:28 +03:00
parent 402bc38ba7
commit 5eab2ddb2e

View file

@ -679,7 +679,7 @@ RtlpUnwindInternal(
ULONG64 ImageBase, EstablisherFrame; ULONG64 ImageBase, EstablisherFrame;
CONTEXT UnwindContext; CONTEXT UnwindContext;
/* Get the current stack limits and registration frame */ /* Get the current stack limits */
RtlpGetStackLimits(&StackLow, &StackHigh); RtlpGetStackLimits(&StackLow, &StackHigh);
/* If we have a target frame, then this is our high limit */ /* If we have a target frame, then this is our high limit */
@ -708,8 +708,11 @@ RtlpUnwindInternal(
UnwindContext.Rip = *(DWORD64*)UnwindContext.Rsp; UnwindContext.Rip = *(DWORD64*)UnwindContext.Rsp;
UnwindContext.Rsp += sizeof(DWORD64); UnwindContext.Rsp += sizeof(DWORD64);
if (HandlerType == UNW_FLAG_UHANDLER)
{
/* Copy the context back for the next iteration */ /* Copy the context back for the next iteration */
*ContextRecord = UnwindContext; *ContextRecord = UnwindContext;
}
continue; continue;
} }
@ -756,7 +759,7 @@ RtlpUnwindInternal(
/* Log the exception if it's enabled */ /* Log the exception if it's enabled */
RtlpCheckLogException(ExceptionRecord, RtlpCheckLogException(ExceptionRecord,
ContextRecord, &UnwindContext,
&DispatcherContext, &DispatcherContext,
sizeof(DispatcherContext)); sizeof(DispatcherContext));
@ -844,9 +847,12 @@ RtlpUnwindInternal(
break; break;
} }
if (HandlerType == UNW_FLAG_UHANDLER)
{
/* We have successfully unwound a frame. Copy the unwind context back. */ /* We have successfully unwound a frame. Copy the unwind context back. */
*ContextRecord = UnwindContext; *ContextRecord = UnwindContext;
} }
}
if (ExceptionRecord->ExceptionCode != STATUS_UNWIND_CONSOLIDATE) if (ExceptionRecord->ExceptionCode != STATUS_UNWIND_CONSOLIDATE)
{ {