Author: tkreuzer Date: Sun Oct 1 14:36:21 2017 New Revision: 76020
URL: http://svn.reactos.org/svn/reactos?rev=76020&view=rev Log: [RTL/x64] Fix logic in RtlpTryToUnwindEpilog
Modified: trunk/reactos/sdk/lib/rtl/amd64/unwind.c
Modified: trunk/reactos/sdk/lib/rtl/amd64/unwind.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/rtl/amd64/unwind.c?... ============================================================================== --- trunk/reactos/sdk/lib/rtl/amd64/unwind.c [iso-8859-1] (original) +++ trunk/reactos/sdk/lib/rtl/amd64/unwind.c [iso-8859-1] Sun Oct 1 14:36:21 2017 @@ -295,9 +295,9 @@ } }
- /* 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,20 +315,28 @@ 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; }
@@ -414,7 +422,7 @@ } }
- /* Process the left Ops */ + /* Process the remaining unwind ops */ while (i < UnwindInfo->CountOfCodes) { UnwindCode = UnwindInfo->UnwindCode[i];