}
}
- /* 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;
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);
}
}
- /* Process the left Ops */
+ /* Process the remaining unwind ops */
while (i < UnwindInfo->CountOfCodes)
{
UnwindCode = UnwindInfo->UnwindCode[i];