https://git.reactos.org/?p=reactos.git;a=commitdiff;h=90d2e12dfab8f6aa8473d2d88a404ba1bb6c1ecd

commit 90d2e12dfab8f6aa8473d2d88a404ba1bb6c1ecd
Author:     Timo Kreuzer <[email protected]>
AuthorDate: Mon Aug 8 09:31:08 2022 +0200
Commit:     Timo Kreuzer <[email protected]>
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

Reply via email to