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; PcodeOp *op = *curNode.iter;
++curNode.iter; ++curNode.iter;
Varnode *outVn = op->getOut(); 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()) { switch(op->code()) {
case CPUI_INT_ADD: case CPUI_INT_ADD:
{ {
@ -1045,7 +1045,7 @@ void Heritage::guardLoads(uint4 flags,const Address &addr,int4 size,vector<Varno
iter = loadGuard.begin(); iter = loadGuard.begin();
while(iter!=loadGuard.end()) { while(iter!=loadGuard.end()) {
LoadGuard &guardRec(*iter); LoadGuard &guardRec(*iter);
if (!guardRec.isValid()) { if (!guardRec.isValid(CPUI_LOAD)) {
list<LoadGuard>::iterator copyIter = iter; list<LoadGuard>::iterator copyIter = iter;
++iter; ++iter;
loadGuard.erase(copyIter); loadGuard.erase(copyIter);

View file

@ -126,7 +126,7 @@ public:
uintb getMaximum(void) const { return maximumOffset; } ///< Get maximum offset of the guarded range 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) 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 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 /// \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 /// 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. /// RangeHint, attempting to make use of any data-type or index information.
/// \param guard is the given LoadGuard /// \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 /// \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(); int4 step = guard.getStep();
if (step == 0) return; // No definitive sign of array access if (step == 0) return; // No definitive sign of array access
Datatype *ct = guard.getOp()->getIn(1)->getType(); Datatype *ct = guard.getOp()->getIn(1)->getType();
@ -812,7 +813,11 @@ void MapState::addGuard(const LoadGuard &guard,TypeFactory *typeFactory)
while (ct->getMetatype() == TYPE_ARRAY) while (ct->getMetatype() == TYPE_ARRAY)
ct = ((TypeArray *) ct)->getBase(); 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) { if (outSize != step) {
// LOAD size doesn't match step: field in array of structures or something more unusual // LOAD size doesn't match step: field in array of structures or something more unusual
if (outSize > step || (step % outSize) != 0) if (outSize > step || (step % outSize) != 0)
@ -963,11 +968,11 @@ void MapState::gatherOpen(const Funcdata &fd)
TypeFactory *typeFactory = fd.getArch()->types; TypeFactory *typeFactory = fd.getArch()->types;
const list<LoadGuard> &loadGuard( fd.getLoadGuards() ); const list<LoadGuard> &loadGuard( fd.getLoadGuards() );
for(list<LoadGuard>::const_iterator iter=loadGuard.begin();iter!=loadGuard.end();++iter) 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() ); const list<LoadGuard> &storeGuard( fd.getStoreGuards() );
for(list<LoadGuard>::const_iterator iter=storeGuard.begin();iter!=storeGuard.end();++iter) 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. /// Define stack Symbols based on Varnodes.

View file

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