mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
Merge remote-tracking branch 'origin/GP-1405_ThisPointerPrep'
This commit is contained in:
commit
7e4df39fe5
7 changed files with 64 additions and 1 deletions
|
@ -4059,6 +4059,8 @@ int4 ActionPrototypeTypes::apply(Funcdata &data)
|
|||
evalfp = data.getArch()->defaultfp;
|
||||
if ((!data.getFuncProto().isModelLocked())&&(!data.getFuncProto().hasMatchingModel(evalfp)))
|
||||
data.getFuncProto().setModel(evalfp);
|
||||
if (data.getFuncProto().hasThisPointer())
|
||||
data.prepareThisPointer();
|
||||
|
||||
iterend = data.endOp(CPUI_RETURN);
|
||||
|
||||
|
|
|
@ -4198,6 +4198,28 @@ bool FuncProto::getBiggestContainedOutput(const Address &loc,int4 size,VarnodeDa
|
|||
return model->getBiggestContainedOutput(loc,size,res);
|
||||
}
|
||||
|
||||
/// A likely pointer data-type for "this" pointer is passed in, which can be pointer to void. As the
|
||||
/// storage of "this" may depend on the full prototype, if the prototype is not already locked in, we
|
||||
/// assume the prototype returns void and takes the given data-type as the single input parameter.
|
||||
/// \param dt is the given input data-type
|
||||
/// \return the starting address of storage for the "this" pointer
|
||||
Address FuncProto::getThisPointerStorage(Datatype *dt)
|
||||
|
||||
{
|
||||
if (!model->hasThisPointer())
|
||||
return Address();
|
||||
vector<Datatype *> typelist;
|
||||
typelist.push_back(getOutputType());
|
||||
typelist.push_back(dt);
|
||||
vector<ParameterPieces> res;
|
||||
model->assignParameterStorage(typelist, res, true);
|
||||
for(int4 i=1;i<res.size();++i) {
|
||||
if ((res[i].flags & ParameterPieces::hiddenretparm) != 0) continue;
|
||||
return res[i].addr;
|
||||
}
|
||||
return Address();
|
||||
}
|
||||
|
||||
/// \brief Decide if \b this can be safely restricted to match another prototype
|
||||
///
|
||||
/// Do \b this and another given function prototype share enough of
|
||||
|
|
|
@ -1524,6 +1524,8 @@ public:
|
|||
/// \brief Pass-back the biggest potential output storage location contained within the given range
|
||||
bool getBiggestContainedOutput(const Address &loc,int4 size,VarnodeData &res) const;
|
||||
|
||||
Address getThisPointerStorage(Datatype *dt); ///< Get the storage location associated with the "this" pointer
|
||||
|
||||
bool isCompatible(const FuncProto &op2) const;
|
||||
AddrSpace *getSpacebase(void) const { return model->getSpacebase(); } ///< Get the \e stack address space
|
||||
void printRaw(const string &funcname,ostream &s) const;
|
||||
|
|
|
@ -374,6 +374,7 @@ public:
|
|||
|
||||
HighVariable *findHigh(const string &nm) const; ///< Find a high-level variable by name
|
||||
void mapGlobals(void); ///< Make sure there is a Symbol entry for all global Varnodes
|
||||
void prepareThisPointer(void); ///< Prepare for recovery of the "this" pointer
|
||||
bool checkCallDoubleUse(const PcodeOp *opmatch,const PcodeOp *op,const Varnode *vn,uint4 fl,const ParamTrial &trial) const;
|
||||
bool onlyOpUse(const Varnode *invn,const PcodeOp *opmatch,const ParamTrial &trial,uint4 mainFlags) const;
|
||||
bool ancestorOpUse(int4 maxlevel,const Varnode *invn,const PcodeOp *op,ParamTrial &trial,int4 offset,uint4 mainFlags) const;
|
||||
|
|
|
@ -1549,6 +1549,30 @@ void Funcdata::mapGlobals(void)
|
|||
warningHeader("Globals starting with '_' overlap smaller symbols at the same address");
|
||||
}
|
||||
|
||||
/// Make sure that if a Varnode exists representing the "this" pointer for the function, that it
|
||||
/// is treated as pointer data-type.
|
||||
void Funcdata::prepareThisPointer(void)
|
||||
|
||||
{
|
||||
int4 numInputs = funcp.numParams();
|
||||
for(int4 i=0;i<numInputs;++i) {
|
||||
ProtoParameter *param = funcp.getParam(i);
|
||||
if (param->isThisPointer() && param->isTypeLocked())
|
||||
return; // Data-type will be obtained directly from symbol
|
||||
}
|
||||
|
||||
// Its possible that a recommendation for the "this" pointer has already been been collected.
|
||||
// Currently the only type recommendations are for the "this" pointer. If there any, it is for "this"
|
||||
if (localmap->hasTypeRecommendations())
|
||||
return;
|
||||
|
||||
Datatype *dt = glb->types->getTypeVoid();
|
||||
AddrSpace *spc = glb->getDefaultDataSpace();
|
||||
dt = glb->types->getTypePointer(spc->getAddrSize(),dt,spc->getWordSize());
|
||||
Address addr = funcp.getThisPointerStorage(dt);
|
||||
localmap->addTypeRecommendation(addr, dt);
|
||||
}
|
||||
|
||||
/// \brief Test for legitimate double use of a parameter trial
|
||||
///
|
||||
/// The given trial is a \e putative input to first CALL, but can also trace its data-flow
|
||||
|
|
|
@ -302,7 +302,7 @@ void ScopeLocal::collectNameRecs(void)
|
|||
// If the "this" pointer points to a class, try to preserve the data-type
|
||||
// even though the symbol is not preserved.
|
||||
SymbolEntry *entry = sym->getFirstWholeMap();
|
||||
typeRecommend.push_back(TypeRecommend(entry->getAddr(),dt));
|
||||
addTypeRecommendation(entry->getAddr(), dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1385,6 +1385,16 @@ void ScopeLocal::applyTypeRecommendations(void)
|
|||
}
|
||||
}
|
||||
|
||||
/// Associate a data-type with a particular storage address. If we see an input Varnode at this address,
|
||||
/// if no other info is available, the given data-type is applied.
|
||||
/// \param addr is the storage address
|
||||
/// \param dt is the given data-type
|
||||
void ScopeLocal::addTypeRecommendation(const Address &addr,Datatype *dt)
|
||||
|
||||
{
|
||||
typeRecommend.push_back(TypeRecommend(addr,dt));
|
||||
}
|
||||
|
||||
/// The symbol is stored as a name recommendation and then removed from the scope.
|
||||
/// Name recommendations are associated either with a storage address and usepoint, or a dynamic hash.
|
||||
/// The name may be reattached to a Symbol after decompilation.
|
||||
|
|
|
@ -243,6 +243,8 @@ public:
|
|||
SymbolEntry *remapSymbolDynamic(Symbol *sym,uint8 hash,const Address &usepoint);
|
||||
void recoverNameRecommendationsForSymbols(void);
|
||||
void applyTypeRecommendations(void); ///< Try to apply recommended data-type information
|
||||
bool hasTypeRecommendations(void) const { return !typeRecommend.empty(); } ///< Are there data-type recommendations
|
||||
void addTypeRecommendation(const Address &addr,Datatype *dt); ///< Add a new data-type recommendation
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue