https://git.reactos.org/?p=reactos.git;a=commitdiff;h=90d2e12dfab8f6aa8473d2...
commit 90d2e12dfab8f6aa8473d2d88a404ba1bb6c1ecd Author: Timo Kreuzer timo.kreuzer@reactos.org AuthorDate: Mon Aug 8 09:31:08 2022 +0200 Commit: Timo Kreuzer timo.kreuzer@reactos.org CommitDate: Thu Nov 24 21:17:58 2022 +0200
[RTL] Fix RtlpCaptureNonVolatileContextPointers --- sdk/lib/rtl/amd64/unwind.c | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-)
diff --git a/sdk/lib/rtl/amd64/unwind.c b/sdk/lib/rtl/amd64/unwind.c index 619d31b6bb9..33a7e71c857 100644 --- a/sdk/lib/rtl/amd64/unwind.c +++ b/sdk/lib/rtl/amd64/unwind.c @@ -1053,29 +1053,37 @@ RtlpCaptureNonVolatileContextPointers(
do { - /* Look up the function entry */ - FunctionEntry = RtlLookupFunctionEntry(Context.Rip, &ImageBase, NULL); - ASSERT(FunctionEntry != NULL); - - /* Do a virtual unwind to the caller and capture saved non-volatiles */ - RtlVirtualUnwind(UNW_FLAG_EHANDLER, - ImageBase, - Context.Rip, - FunctionEntry, - &Context, - &HandlerData, - &EstablisherFrame, - NonvolatileContextPointers); - /* Make sure nothing fishy is going on. Currently this is for kernel mode only. */ - ASSERT(EstablisherFrame != 0); ASSERT((LONG64)Context.Rip < 0); + ASSERT((LONG64)Context.Rsp < 0); + + /* Look up the function entry */ + FunctionEntry = RtlLookupFunctionEntry(Context.Rip, &ImageBase, NULL); + if (FunctionEntry != NULL) + { + /* Do a virtual unwind to the caller and capture saved non-volatiles */ + RtlVirtualUnwind(UNW_FLAG_EHANDLER, + ImageBase, + Context.Rip, + FunctionEntry, + &Context, + &HandlerData, + &EstablisherFrame, + NonvolatileContextPointers); + + ASSERT(EstablisherFrame != 0); + } + else + { + Context.Rip = *(PULONG64)Context.Rsp; + Context.Rsp += 8; + }
- /* Continue until we reached the target frame or user mode */ - } while (EstablisherFrame < TargetFrame); + /* Continue until we reach user mode */ + } while ((LONG64)Context.Rip < 0);
- /* If the caller did the right thing, we should get exactly the target frame */ - ASSERT(EstablisherFrame == TargetFrame); + /* If the caller did the right thing, we should get past the target frame */ + ASSERT(EstablisherFrame >= TargetFrame); }
VOID