mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
New guardStore
This commit is contained in:
parent
cb39d39a23
commit
171602e1ce
6 changed files with 42 additions and 16 deletions
|
@ -234,6 +234,7 @@ public:
|
|||
|
||||
const list<LoadGuard> &getLoadGuards(void) const { return heritage.getLoadGuards(); } ///< Get the list of guarded LOADs
|
||||
const list<LoadGuard> &getStoreGuards(void) const { return heritage.getStoreGuards(); } ///< Get the list of guarded STOREs
|
||||
const LoadGuard *getStoreGuard(PcodeOp *op) const { return heritage.getStoreGuard(op); } ///< Get LoadGuard associated with STORE op
|
||||
|
||||
// Function prototype and call specification routines
|
||||
int4 numCalls(void) const { return qlst.size(); } ///< Get the number of calls made by \b this function
|
||||
|
@ -420,6 +421,7 @@ public:
|
|||
void opMarkNoCollapse(PcodeOp *op) { op->setFlag(PcodeOp::nocollapse); } ///< Mark PcodeOp as not collapsible
|
||||
void opMarkCpoolTransformed(PcodeOp *op) { op->setFlag(PcodeOp::is_cpool_transformed); } ///< Mark cpool record was visited
|
||||
void opMarkCalculatedBool(PcodeOp *op) { op->setFlag(PcodeOp::calculated_bool); } ///< Mark PcodeOp as having boolean output
|
||||
void opMarkSpacebaseStore(PcodeOp *op) { op->setFlag(PcodeOp::spacebase_ptr); } ///< Mark PcodeOp as STOREing from spacebase ptr
|
||||
void opFlipCondition(PcodeOp *op) { op->flipFlag(PcodeOp::boolean_flip); } ///< Flip output condition of given CBRANCH
|
||||
PcodeOp *target(const Address &addr) const { return obank.target(addr); } ///< Look up a PcodeOp by an instruction Address
|
||||
Varnode *createStackRef(AddrSpace *spc,uintb off,PcodeOp *op,Varnode *stackptr,bool insertafter);
|
||||
|
|
|
@ -653,6 +653,18 @@ void LoadGuard::finalizeRange(const ValueSetRead &valueSet)
|
|||
maximumOffset = spc->getHighest();
|
||||
}
|
||||
|
||||
/// Check if the address falls within the range defined by \b this
|
||||
/// \param addr is the given address
|
||||
/// \return \b true if the address is contained
|
||||
bool LoadGuard::isGuarded(const Address &addr) const
|
||||
|
||||
{
|
||||
if (addr.getSpace() != spc) return false;
|
||||
if (addr.getOffset() < minimumOffset) return false;
|
||||
if (addr.getOffset() > maximumOffset) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Heritage::analyzeNewLoadGuards(void)
|
||||
|
||||
{
|
||||
|
@ -747,6 +759,7 @@ void Heritage::generateStoreGuard(StackNode &node,PcodeOp *op,AddrSpace *spc)
|
|||
{
|
||||
storeGuard.push_back(LoadGuard());
|
||||
storeGuard.back().set(op,spc,node.offset);
|
||||
fd->opMarkSpacebaseStore(op);
|
||||
}
|
||||
|
||||
/// \brief Trace input stackpointer to any indexed loads
|
||||
|
@ -1012,12 +1025,16 @@ void Heritage::guardStores(const Address &addr,int4 size,vector<Varnode *> &writ
|
|||
{
|
||||
list<PcodeOp *>::const_iterator iter,iterend;
|
||||
PcodeOp *op,*indop;
|
||||
AddrSpace *spc = addr.getSpace();
|
||||
AddrSpace *container = spc->getContain();
|
||||
|
||||
iterend = fd->endOp(CPUI_STORE);
|
||||
for(iter=fd->beginOp(CPUI_STORE);iter!=iterend;++iter) {
|
||||
op = *iter;
|
||||
if (op->isDead()) continue;
|
||||
if (addr.getSpace()->contain(Address::getSpaceFromConst(op->getIn(0)->getAddr()))) { // Does store affect same space
|
||||
AddrSpace *storeSpace = Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||
if ((container == storeSpace && op->usesSpacebasePtr()) ||
|
||||
(spc == storeSpace)) {
|
||||
indop = fd->newIndirectOp(op,addr,size);
|
||||
indop->getIn(0)->setActiveHeritage();
|
||||
indop->getOut()->setActiveHeritage();
|
||||
|
@ -2149,6 +2166,19 @@ void Heritage::heritage(void)
|
|||
pass += 1;
|
||||
}
|
||||
|
||||
/// \param op is the given PcodeOp
|
||||
/// \return the associated LoadGuard or NULL
|
||||
const LoadGuard *Heritage::getStoreGuard(PcodeOp *op) const
|
||||
|
||||
{
|
||||
list<LoadGuard>::const_iterator iter;
|
||||
for(iter=storeGuard.begin();iter!=storeGuard.end();++iter) {
|
||||
if ((*iter).op == op)
|
||||
return &(*iter);
|
||||
}
|
||||
return (const LoadGuard *)0;
|
||||
}
|
||||
|
||||
/// \brief Get the number times heritage was performed for the given address space
|
||||
///
|
||||
/// A negative number indicates the number of passes to be wait before the first
|
||||
|
|
|
@ -125,6 +125,7 @@ public:
|
|||
uintb getMinimum(void) const { return minimumOffset; } ///< Get minimum 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)
|
||||
bool isGuarded(const Address &addr) const; ///< Does \b this guard apply to the given address
|
||||
bool isRangeLocked(void) const { return (analysisState == 2); } ///< Return \b true if the range is fully determined
|
||||
bool isValid(OpCode opc) const { return (!op->isDead() && op->code() == opc); } ///< Return \b true if the record still describes an active LOAD
|
||||
};
|
||||
|
@ -273,6 +274,7 @@ public:
|
|||
void heritage(void); ///< Perform one pass of heritage
|
||||
const list<LoadGuard> &getLoadGuards(void) const { return loadGuard; } ///< Get list of LOAD ops that are guarded
|
||||
const list<LoadGuard> &getStoreGuards(void) const { return storeGuard; } ///< Get list of STORE ops that are guarded
|
||||
const LoadGuard *getStoreGuard(PcodeOp *op) const; ///< Get LoadGuard record associated with given PcodeOp
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2805,6 +2805,13 @@ int4 RuleIndirectCollapse::applyOp(PcodeOp *op,Funcdata &data)
|
|||
if (!op->getOut()->hasNoLocalAlias())
|
||||
return 0;
|
||||
}
|
||||
else if (indop->usesSpacebasePtr()) {
|
||||
const LoadGuard *guard = data.getStoreGuard(indop);
|
||||
if (guard != (const LoadGuard *)0) {
|
||||
if (guard->isGuarded(op->getOut()->getAddr()))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -112,20 +112,6 @@ void AddrSpace::truncateSpace(uint4 newsize)
|
|||
calcScaleMask();
|
||||
}
|
||||
|
||||
/// Check if this space contains \b id2.
|
||||
/// \param id2 is the space to check
|
||||
/// \return \b true if \b id2 is contained
|
||||
bool AddrSpace::contain(AddrSpace *id2) const
|
||||
|
||||
{
|
||||
while(this != id2) {
|
||||
id2 = id2->getContain();
|
||||
if (id2 == (AddrSpace *)0)
|
||||
return false; // No containment
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Write the main XML attributes for an address within this space
|
||||
/// The caller provides only the \e offset, and this routine fills
|
||||
/// in other details pertaining to this particular space.
|
||||
|
|
|
@ -121,7 +121,6 @@ public:
|
|||
uintb getHighest(void) const; ///< Get the highest byte-scaled address
|
||||
uintb wrapOffset(uintb off) const; ///< Wrap -off- to the offset that fits into this space
|
||||
char getShortcut(void) const; ///< Get the shortcut character
|
||||
bool contain(AddrSpace *id2) const; ///< Determine if this space contains another
|
||||
bool isHeritaged(void) const; ///< Return \b true if dataflow has been traced
|
||||
bool doesDeadcode(void) const; ///< Return \b true if dead code analysis should be done on this space
|
||||
bool hasPhysical(void) const; ///< Return \b true if data is physically stored in this
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue