https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3cf2bea0def78939382f0a...
commit 3cf2bea0def78939382f0aa4045c6d7cef2b3ef2 Author: Timo Kreuzer timo.kreuzer@reactos.org AuthorDate: Wed Mar 7 15:38:24 2018 +0100 Commit: Timo Kreuzer timo.kreuzer@reactos.org CommitDate: Sat Jun 5 13:52:42 2021 +0200
[RTL] Fix RtlWalkFrameChain and wrap it in SEH --- sdk/lib/rtl/amd64/unwind.c | 100 +++++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 39 deletions(-)
diff --git a/sdk/lib/rtl/amd64/unwind.c b/sdk/lib/rtl/amd64/unwind.c index 859ef783043..87e370ed89f 100644 --- a/sdk/lib/rtl/amd64/unwind.c +++ b/sdk/lib/rtl/amd64/unwind.c @@ -956,53 +956,75 @@ RtlWalkFrameChain(OUT PVOID *Callers, { }
- /* Loop the frames */ - for (i = 0; i < FramesToSkip + Count; i++) + _SEH2_TRY { - /* Lookup the FunctionEntry for the current ControlPc */ - FunctionEntry = RtlLookupFunctionEntry(ControlPc, &ImageBase, NULL); - - /* Is this a leaf function? */ - if (!FunctionEntry) + /* Loop the frames */ + for (i = 0; i < FramesToSkip + Count; i++) { - Context.Rip = *(DWORD64*)Context.Rsp; - Context.Rsp += sizeof(DWORD64); - DPRINT("leaf funtion, new Rip = %p, new Rsp = %p\n", (PVOID)Context.Rip, (PVOID)Context.Rsp); - } - else - { - RtlVirtualUnwind(0, - ImageBase, - ControlPc, - FunctionEntry, - &Context, - &HandlerData, - &EstablisherFrame, - NULL); - DPRINT("normal funtion, new Rip = %p, new Rsp = %p\n", (PVOID)Context.Rip, (PVOID)Context.Rsp); - } + /* Lookup the FunctionEntry for the current ControlPc */ + FunctionEntry = RtlLookupFunctionEntry(ControlPc, &ImageBase, NULL);
- /* Check if new Rip is valid */ - if (!Context.Rip) - { - break; - } + /* Is this a leaf function? */ + if (!FunctionEntry) + { + Context.Rip = *(DWORD64*)Context.Rsp; + Context.Rsp += sizeof(DWORD64); + DPRINT("leaf funtion, new Rip = %p, new Rsp = %p\n", (PVOID)Context.Rip, (PVOID)Context.Rsp); + } + else + { + RtlVirtualUnwind(UNW_FLAG_NHANDLER, + ImageBase, + ControlPc, + FunctionEntry, + &Context, + &HandlerData, + &EstablisherFrame, + NULL); + DPRINT("normal funtion, new Rip = %p, new Rsp = %p\n", (PVOID)Context.Rip, (PVOID)Context.Rsp); + }
- /* Check, if we have left our stack */ - if ((Context.Rsp < StackLow) || (Context.Rsp > StackHigh)) - { - break; - } + /* Check if we are in kernel mode */ + if (RtlpGetMode() == KernelMode) + { + /* Check if we left the kernel range */ + if (!(Flags & 1) && (Context.Rip < 0xFFFF800000000000ULL)) + { + break; + } + } + else + { + /* Check if we left the user range */ + if ((Context.Rip < 0x10000) || + (Context.Rip > 0x000007FFFFFEFFFFULL)) + { + break; + } + }
- /* Continue with new Rip */ - ControlPc = Context.Rip; + /* Check, if we have left our stack */ + if ((Context.Rsp < StackLow) || (Context.Rsp > StackHigh)) + { + break; + }
- /* Save value, if we are past the frames to skip */ - if (i >= FramesToSkip) - { - Callers[i - FramesToSkip] = (PVOID)ControlPc; + /* Continue with new Rip */ + ControlPc = Context.Rip; + + /* Save value, if we are past the frames to skip */ + if (i >= FramesToSkip) + { + Callers[i - FramesToSkip] = (PVOID)ControlPc; + } } } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + DPRINT1("Exception while getting callers!\n"); + i = 0; + } + _SEH2_END;
DPRINT("RtlWalkFrameChain returns %ld\n", i); return i;