[RTL/x64] Fix logic in RtlpTryToUnwindEpilog
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Sun, 1 Oct 2017 14:36:21 +0000 (14:36 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Sun, 1 Oct 2017 14:36:21 +0000 (14:36 +0000)
svn path=/trunk/; revision=76020

reactos/sdk/lib/rtl/amd64/unwind.c

index f9af729..d854b8e 100644 (file)
@@ -295,9 +295,9 @@ RtlpTryToUnwindEpilog(
         }
     }
 
-    /* Loop the following instructions */
-    EndAddress = FunctionEntry->EndAddress + ImageBase;
-    while((DWORD64)InstrPtr < EndAddress)
+    /* Loop the following instructions before the ret */
+    EndAddress = FunctionEntry->EndAddress + ImageBase - 1;
+    while ((DWORD64)InstrPtr < EndAddress)
     {
         Instr = *(DWORD*)InstrPtr;
 
@@ -315,23 +315,31 @@ RtlpTryToUnwindEpilog(
         if ( (Instr & 0xf8fb) == 0x5841 )
         {
             /* Opcode is pop r8 .. r15 */
-            Reg = (Instr & 0x7) + 8;
+            Reg = ((Instr >> 8) & 0x7) + 8;
             PopReg(&LocalContext, Reg);
             InstrPtr += 2;
             continue;
         }
 
-        /* Check for retn / retf */
-        if ( (Instr & 0xf7) == 0xc3 )
-        {
-            /* We are finished */
-            break;
-        }
-
         /* Opcode not allowed for Epilog */
         return FALSE;
     }
 
+    /* Check if we are at the ret instruction */
+    if ((DWORD64)InstrPtr != EndAddress)
+    {
+        /* If we went past the end of the function, something is broken! */
+        ASSERT((DWORD64)InstrPtr <= EndAddress);
+        return FALSE;
+    }
+
+    /* Make sure this is really a ret instruction */
+    if (*InstrPtr != 0xc3)
+    {
+        ASSERT(FALSE);
+        return FALSE;
+    }
+
     /* Unwind is finished, pop new Rip from Stack */
     LocalContext.Rip = *(DWORD64*)LocalContext.Rsp;
     LocalContext.Rsp += sizeof(DWORD64);
@@ -414,7 +422,7 @@ RtlVirtualUnwind(
         }
     }
 
-    /* Process the left Ops */
+    /* Process the remaining unwind ops */
     while (i < UnwindInfo->CountOfCodes)
     {
         UnwindCode = UnwindInfo->UnwindCode[i];