fixes for STORE range analysis

This commit is contained in:
caheckman 2019-06-18 18:29:00 -04:00
parent ec9bfa86a7
commit b9b26275f5
4 changed files with 14 additions and 9 deletions

View file

@ -777,7 +777,7 @@ void Heritage::discoverIndexedStackPointers(AddrSpace *spc)
PcodeOp *op = *curNode.iter;
++curNode.iter;
Varnode *outVn = op->getOut();
if (outVn == (Varnode *)0 || outVn->isMark()) continue; // Don't revisit Varnodes
if (outVn != (Varnode *)0 && outVn->isMark()) continue; // Don't revisit Varnodes
switch(op->code()) {
case CPUI_INT_ADD:
{
@ -1045,7 +1045,7 @@ void Heritage::guardLoads(uint4 flags,const Address &addr,int4 size,vector<Varno
iter = loadGuard.begin();
while(iter!=loadGuard.end()) {
LoadGuard &guardRec(*iter);
if (!guardRec.isValid()) {
if (!guardRec.isValid(CPUI_LOAD)) {
list<LoadGuard>::iterator copyIter = iter;
++iter;
loadGuard.erase(copyIter);

View file

@ -126,7 +126,7 @@ public:
uintb getMaximum(void) const { return maximumOffset; } ///< Get maximum offset of the guarded range
int4 getStep(void) const { return step; } ///< Get the calculated step associated with the range (or 0)
bool isRangeLocked(void) const { return (analysisState == 2); } ///< Return \b true if the range is fully determined
bool isValid(void) const { return (!op->isDead() && op->code() == CPUI_LOAD); } ///< Return \b true if the record still describes an active LOAD
bool isValid(OpCode opc) const { return (!op->isDead() && op->code() == opc); } ///< Return \b true if the record still describes an active LOAD
};
/// \brief Manage the construction of Static Single Assignment (SSA) form

View file

@ -799,11 +799,12 @@ void MapState::addRange(uintb st,Datatype *ct,uint4 fl,RangeHint::RangeType rt,i
/// The given LoadGuard, which may be a LOAD or STORE is converted into an appropriate
/// RangeHint, attempting to make use of any data-type or index information.
/// \param guard is the given LoadGuard
/// \param opc is the expected op-code (CPUI_LOAD or CPUI_STORE)
/// \param typeFactory is used to manufacture a data-type for the hint if necessary
void MapState::addGuard(const LoadGuard &guard,TypeFactory *typeFactory)
void MapState::addGuard(const LoadGuard &guard,OpCode opc,TypeFactory *typeFactory)
{
if (!guard.isValid()) return;
if (!guard.isValid(opc)) return;
int4 step = guard.getStep();
if (step == 0) return; // No definitive sign of array access
Datatype *ct = guard.getOp()->getIn(1)->getType();
@ -812,7 +813,11 @@ void MapState::addGuard(const LoadGuard &guard,TypeFactory *typeFactory)
while (ct->getMetatype() == TYPE_ARRAY)
ct = ((TypeArray *) ct)->getBase();
}
int4 outSize = guard.getOp()->getOut()->getSize();
int4 outSize;
if (opc == CPUI_STORE)
outSize = guard.getOp()->getIn(2)->getSize(); // The Varnode being stored
else
outSize = guard.getOp()->getOut()->getSize(); // The Varnode being loaded
if (outSize != step) {
// LOAD size doesn't match step: field in array of structures or something more unusual
if (outSize > step || (step % outSize) != 0)
@ -963,11 +968,11 @@ void MapState::gatherOpen(const Funcdata &fd)
TypeFactory *typeFactory = fd.getArch()->types;
const list<LoadGuard> &loadGuard( fd.getLoadGuards() );
for(list<LoadGuard>::const_iterator iter=loadGuard.begin();iter!=loadGuard.end();++iter)
addGuard(*iter,typeFactory);
addGuard(*iter,CPUI_LOAD,typeFactory);
const list<LoadGuard> &storeGuard( fd.getStoreGuards() );
for(list<LoadGuard>::const_iterator iter=storeGuard.begin();iter!=storeGuard.end();++iter)
addGuard(*iter,typeFactory);
addGuard(*iter,CPUI_STORE,typeFactory);
}
/// Define stack Symbols based on Varnodes.

View file

@ -127,7 +127,7 @@ class MapState {
vector<RangeHint *>::iterator iter; ///< The current iterator into the RangeHints
Datatype *defaultType; ///< The default data-type to use for RangeHints
AliasChecker checker; ///< A collection of pointer Varnodes into our address space
void addGuard(const LoadGuard &guard,TypeFactory *typeFactory); ///< Add LoadGuard record as a hint to the collection
void addGuard(const LoadGuard &guard,OpCode opc,TypeFactory *typeFactory); ///< Add LoadGuard record as a hint to the collection
void addRange(uintb st,Datatype *ct,uint4 fl,RangeHint::RangeType rt,int4 hi); ///< Add a hint to the collection
public:
#ifdef OPACTION_DEBUG