GP-4226 Detect BRANCHIND used as a RETURN

This commit is contained in:
caheckman 2024-01-12 20:48:09 +00:00
parent dffb5fd859
commit e655ab3cb3
8 changed files with 115 additions and 37 deletions

View file

@ -1282,6 +1282,40 @@ bool Funcdata::attemptDynamicMappingLate(SymbolEntry *entry,DynamicHash &dhash)
return true;
}
/// Follow the Varnode back to see if it comes from the return address for \b this function.
/// If so, return \b true. The return address can flow through COPY, INDIRECT, and AND operations.
/// If there are any other operations in the flow path, or if a standard storage location for the
/// return address was not defined, return \b false.
/// \param vn is the given Varnode to trace
/// \return \b true if flow is from the return address
bool Funcdata::testForReturnAddress(Varnode *vn)
{
VarnodeData &retaddr(glb->defaultReturnAddr);
if (retaddr.space == (AddrSpace *)0)
return false; // No standard storage location to compare to
while(vn->isWritten()) {
PcodeOp *op = vn->getDef();
OpCode opc = op->code();
if (opc == CPUI_INDIRECT || opc == CPUI_COPY) {
vn = op->getIn(0);
}
else if (opc == CPUI_INT_AND) {
// We only want to allow "alignment" style masking
if (!op->getIn(1)->isConstant())
return false;
vn = op->getIn(0);
}
else
return false;
}
if (vn->getSpace() != retaddr.space || vn->getOffset() != retaddr.offset || vn->getSize() != retaddr.size)
return false;
if (!vn->isInput())
return false;
return true;
}
/// \brief Replace all read references to the first Varnode with a second Varnode
///
/// \param vn is the first Varnode (being replaced)