https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3cf2bea0def78939382f0…
commit 3cf2bea0def78939382f0aa4045c6d7cef2b3ef2
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Wed Mar 7 15:38:24 2018 +0100
Commit: Timo Kreuzer <timo.kreuzer(a)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;