[RTL/x64] Fix logic in RtlpTryToUnwindEpilog

svn path=/trunk/; revision=76020
This commit is contained in:
Timo Kreuzer 2017-10-01 14:36:21 +00:00
parent 555300d680
commit 87fcad8440

View file

@ -295,9 +295,9 @@ RtlpTryToUnwindEpilog(
} }
} }
/* Loop the following instructions */ /* Loop the following instructions before the ret */
EndAddress = FunctionEntry->EndAddress + ImageBase; EndAddress = FunctionEntry->EndAddress + ImageBase - 1;
while((DWORD64)InstrPtr < EndAddress) while ((DWORD64)InstrPtr < EndAddress)
{ {
Instr = *(DWORD*)InstrPtr; Instr = *(DWORD*)InstrPtr;
@ -315,23 +315,31 @@ RtlpTryToUnwindEpilog(
if ( (Instr & 0xf8fb) == 0x5841 ) if ( (Instr & 0xf8fb) == 0x5841 )
{ {
/* Opcode is pop r8 .. r15 */ /* Opcode is pop r8 .. r15 */
Reg = (Instr & 0x7) + 8; Reg = ((Instr >> 8) & 0x7) + 8;
PopReg(&LocalContext, Reg); PopReg(&LocalContext, Reg);
InstrPtr += 2; InstrPtr += 2;
continue; continue;
} }
/* Check for retn / retf */
if ( (Instr & 0xf7) == 0xc3 )
{
/* We are finished */
break;
}
/* Opcode not allowed for Epilog */ /* Opcode not allowed for Epilog */
return FALSE; 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 */ /* Unwind is finished, pop new Rip from Stack */
LocalContext.Rip = *(DWORD64*)LocalContext.Rsp; LocalContext.Rip = *(DWORD64*)LocalContext.Rsp;
LocalContext.Rsp += sizeof(DWORD64); LocalContext.Rsp += sizeof(DWORD64);
@ -414,7 +422,7 @@ RtlVirtualUnwind(
} }
} }
/* Process the left Ops */ /* Process the remaining unwind ops */
while (i < UnwindInfo->CountOfCodes) while (i < UnwindInfo->CountOfCodes)
{ {
UnwindCode = UnwindInfo->UnwindCode[i]; UnwindCode = UnwindInfo->UnwindCode[i];