mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
New indirect_store flag
This commit is contained in:
parent
b7608adcf2
commit
a4856b9af0
6 changed files with 12 additions and 9 deletions
|
@ -1144,7 +1144,8 @@ int4 ActionDirectWrite::apply(Funcdata &data)
|
||||||
dvn = op->getOut();
|
dvn = op->getOut();
|
||||||
if (!dvn->isDirectWrite()) {
|
if (!dvn->isDirectWrite()) {
|
||||||
dvn->setDirectWrite();
|
dvn->setDirectWrite();
|
||||||
if (propagateIndirect || op->code() != CPUI_INDIRECT) // If INDIRECT, output is marked, but does not propagate
|
// For call based INDIRECTs, output is marked, but does not propagate depending on setting
|
||||||
|
if (propagateIndirect || op->code() != CPUI_INDIRECT || op->isIndirectStore())
|
||||||
worklist.push_back(dvn);
|
worklist.push_back(dvn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -384,7 +384,7 @@ public:
|
||||||
PcodeOp *newOpBefore(PcodeOp *follow,OpCode opc,Varnode *in1,Varnode *in2,Varnode *in3=(Varnode *)0);
|
PcodeOp *newOpBefore(PcodeOp *follow,OpCode opc,Varnode *in1,Varnode *in2,Varnode *in3=(Varnode *)0);
|
||||||
PcodeOp *cloneOp(const PcodeOp *op,const SeqNum &seq); /// Clone a PcodeOp into \b this function
|
PcodeOp *cloneOp(const PcodeOp *op,const SeqNum &seq); /// Clone a PcodeOp into \b this function
|
||||||
PcodeOp *canonicalReturnOp(void) const; /// Find a representative CPUI_RETURN op for \b this function
|
PcodeOp *canonicalReturnOp(void) const; /// Find a representative CPUI_RETURN op for \b this function
|
||||||
PcodeOp *newIndirectOp(PcodeOp *indeffect,const Address &addr,int4 size);
|
PcodeOp *newIndirectOp(PcodeOp *indeffect,const Address &addr,int4 size,uint4 extraFlags);
|
||||||
void setIndirectCreation(PcodeOp *op,PcodeOp *indeffect,Varnode *outvn,bool possibleout);
|
void setIndirectCreation(PcodeOp *op,PcodeOp *indeffect,Varnode *outvn,bool possibleout);
|
||||||
PcodeOp *newIndirectCreation(PcodeOp *indeffect,const Address &addr,int4 size,bool possibleout);
|
PcodeOp *newIndirectCreation(PcodeOp *indeffect,const Address &addr,int4 size,bool possibleout);
|
||||||
void truncateIndirect(PcodeOp *indop); ///< Convert CPUI_INDIRECT into an \e indirect \e creation
|
void truncateIndirect(PcodeOp *indop); ///< Convert CPUI_INDIRECT into an \e indirect \e creation
|
||||||
|
|
|
@ -608,8 +608,9 @@ PcodeOp *Funcdata::newOpBefore(PcodeOp *follow,OpCode opc,Varnode *in1,Varnode *
|
||||||
/// \param indeffect is the PcodeOp with the indirect effect
|
/// \param indeffect is the PcodeOp with the indirect effect
|
||||||
/// \param addr is the starting address of the storage range to protect
|
/// \param addr is the starting address of the storage range to protect
|
||||||
/// \param size is the number of bytes in the storage range
|
/// \param size is the number of bytes in the storage range
|
||||||
|
/// \param extraFlags are extra boolean properties to put on the INDIRECT
|
||||||
/// \return the new CPUI_INDIRECT op
|
/// \return the new CPUI_INDIRECT op
|
||||||
PcodeOp *Funcdata::newIndirectOp(PcodeOp *indeffect,const Address &addr,int4 size)
|
PcodeOp *Funcdata::newIndirectOp(PcodeOp *indeffect,const Address &addr,int4 size,uint4 extraFlags)
|
||||||
|
|
||||||
{
|
{
|
||||||
Varnode *newin;
|
Varnode *newin;
|
||||||
|
@ -617,6 +618,7 @@ PcodeOp *Funcdata::newIndirectOp(PcodeOp *indeffect,const Address &addr,int4 siz
|
||||||
|
|
||||||
newin = newVarnode(size,addr);
|
newin = newVarnode(size,addr);
|
||||||
newop = newOp(2,indeffect->getAddr());
|
newop = newOp(2,indeffect->getAddr());
|
||||||
|
newop->flags |= extraFlags;
|
||||||
newVarnodeOut(size,addr,newop);
|
newVarnodeOut(size,addr,newop);
|
||||||
opSetOpcode(newop,CPUI_INDIRECT);
|
opSetOpcode(newop,CPUI_INDIRECT);
|
||||||
opSetInput(newop,newin,0);
|
opSetInput(newop,newin,0);
|
||||||
|
|
|
@ -1402,7 +1402,6 @@ bool AncestorRealistic::checkConditionalExe(State &state)
|
||||||
int4 AncestorRealistic::enterNode(State &state)
|
int4 AncestorRealistic::enterNode(State &state)
|
||||||
|
|
||||||
{
|
{
|
||||||
PcodeOp *indop;
|
|
||||||
// If the node has already been visited, we truncate the traversal to prevent cycles.
|
// If the node has already been visited, we truncate the traversal to prevent cycles.
|
||||||
// We always return success assuming the proper result will get returned along the first path
|
// We always return success assuming the proper result will get returned along the first path
|
||||||
if (state.vn->isMark()) return pop_success;
|
if (state.vn->isMark()) return pop_success;
|
||||||
|
@ -1424,8 +1423,7 @@ int4 AncestorRealistic::enterNode(State &state)
|
||||||
return pop_failkill; // Truncate this path, indicating killedbycall
|
return pop_failkill; // Truncate this path, indicating killedbycall
|
||||||
return pop_success; // otherwise it could be valid
|
return pop_success; // otherwise it could be valid
|
||||||
}
|
}
|
||||||
indop = PcodeOp::getOpFromConst(op->getIn(1)->getAddr());
|
if (!op->isIndirectStore()) { // If flow goes THROUGH a call
|
||||||
if (indop->isCall()) { // If flow goes THROUGH a call
|
|
||||||
if (op->getOut()->isReturnAddress()) return pop_fail; // Storage address location is completely invalid
|
if (op->getOut()->isReturnAddress()) return pop_fail; // Storage address location is completely invalid
|
||||||
if (trial->isKilledByCall()) return pop_fail; // "Likely" killedbycall is invalid
|
if (trial->isKilledByCall()) return pop_fail; // "Likely" killedbycall is invalid
|
||||||
}
|
}
|
||||||
|
|
|
@ -1088,7 +1088,7 @@ void Heritage::guardCalls(uint4 flags,const Address &addr,int4 size,vector<Varno
|
||||||
}
|
}
|
||||||
// We do not guard the call if the effect is "unaffected" or "reload"
|
// We do not guard the call if the effect is "unaffected" or "reload"
|
||||||
if ((effecttype == EffectRecord::unknown_effect)||(effecttype == EffectRecord::return_address)) {
|
if ((effecttype == EffectRecord::unknown_effect)||(effecttype == EffectRecord::return_address)) {
|
||||||
indop = fd->newIndirectOp(fc->getOp(),addr,size);
|
indop = fd->newIndirectOp(fc->getOp(),addr,size,0);
|
||||||
indop->getIn(0)->setActiveHeritage();
|
indop->getIn(0)->setActiveHeritage();
|
||||||
indop->getOut()->setActiveHeritage();
|
indop->getOut()->setActiveHeritage();
|
||||||
write.push_back(indop->getOut());
|
write.push_back(indop->getOut());
|
||||||
|
@ -1129,7 +1129,7 @@ void Heritage::guardStores(const Address &addr,int4 size,vector<Varnode *> &writ
|
||||||
AddrSpace *storeSpace = Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
AddrSpace *storeSpace = Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||||
if ((container == storeSpace && op->usesSpacebasePtr()) ||
|
if ((container == storeSpace && op->usesSpacebasePtr()) ||
|
||||||
(spc == storeSpace)) {
|
(spc == storeSpace)) {
|
||||||
indop = fd->newIndirectOp(op,addr,size);
|
indop = fd->newIndirectOp(op,addr,size,PcodeOp::indirect_store);
|
||||||
indop->getIn(0)->setActiveHeritage();
|
indop->getIn(0)->setActiveHeritage();
|
||||||
indop->getOut()->setActiveHeritage();
|
indop->getOut()->setActiveHeritage();
|
||||||
write.push_back(indop->getOut());
|
write.push_back(indop->getOut());
|
||||||
|
|
|
@ -96,7 +96,8 @@ public:
|
||||||
indirect_creation = 0x8000000, ///< Output varnode is created by indirect effect
|
indirect_creation = 0x8000000, ///< Output varnode is created by indirect effect
|
||||||
calculated_bool = 0x10000000, ///< Output has been determined to be a 1-bit boolean value
|
calculated_bool = 0x10000000, ///< Output has been determined to be a 1-bit boolean value
|
||||||
is_cpool_transformed = 0x20000000, ///< Have we checked for cpool transforms
|
is_cpool_transformed = 0x20000000, ///< Have we checked for cpool transforms
|
||||||
ptrflow = 0x40000000 ///< Op consumes or produces a ptr
|
ptrflow = 0x40000000, ///< Op consumes or produces a ptr
|
||||||
|
indirect_store = 0x80000000 ///< CPUI_INDIRECT is caused by CPUI_STORE
|
||||||
};
|
};
|
||||||
enum {
|
enum {
|
||||||
has_thisptr = 0x1, ///< First parameter ( getIn(1) ) is a this pointer
|
has_thisptr = 0x1, ///< First parameter ( getIn(1) ) is a this pointer
|
||||||
|
@ -163,6 +164,7 @@ public:
|
||||||
bool isCall(void) const { return ((flags&PcodeOp::call)!=0); } ///< Return \b true if this op indicates call semantics
|
bool isCall(void) const { return ((flags&PcodeOp::call)!=0); } ///< Return \b true if this op indicates call semantics
|
||||||
bool isMarker(void) const { return ((flags&PcodeOp::marker)!=0); } ///< Return \b true is a special SSA form op
|
bool isMarker(void) const { return ((flags&PcodeOp::marker)!=0); } ///< Return \b true is a special SSA form op
|
||||||
bool isIndirectCreation(void) const { return ((flags&PcodeOp::indirect_creation)!=0); } ///< Return \b true if op creates a varnode indirectly
|
bool isIndirectCreation(void) const { return ((flags&PcodeOp::indirect_creation)!=0); } ///< Return \b true if op creates a varnode indirectly
|
||||||
|
bool isIndirectStore(void) const { return ((flags&PcodeOp::indirect_store)!=0); } ///< Return \b true if \b this INDIRECT is caused by STORE
|
||||||
/// \brief Return \b true if this op is not directly represented in C output
|
/// \brief Return \b true if this op is not directly represented in C output
|
||||||
bool notPrinted(void) const { return ((flags&(PcodeOp::marker|PcodeOp::nonprinting|PcodeOp::noreturn))!=0); }
|
bool notPrinted(void) const { return ((flags&(PcodeOp::marker|PcodeOp::nonprinting|PcodeOp::noreturn))!=0); }
|
||||||
/// \brief Return \b true if this op produces a boolean output
|
/// \brief Return \b true if this op produces a boolean output
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue