Add dynamic symbols to recommend mechanism

This commit is contained in:
caheckman 2019-09-16 13:36:47 -04:00
parent cf0f981c7f
commit b2a422329c
2 changed files with 66 additions and 10 deletions

View file

@ -312,23 +312,26 @@ ScopeLocal::ScopeLocal(AddrSpace *spc,Funcdata *fd,Architecture *g) : ScopeInter
void ScopeLocal::collectNameRecs(void)
{
SymbolNameTree::iterator iter;
nameRecommend.clear(); // Clear out any old name recommendations
dynRecommend.clear();
iter = nametree.begin();
SymbolNameTree::iterator iter = nametree.begin();
while(iter!=nametree.end()) {
Symbol *sym = *iter++;
if (sym->isNameLocked()&&(!sym->isTypeLocked())) {
SymbolEntry *entry = sym->getFirstWholeMap();
if (entry != (SymbolEntry *)0) {
if (entry->isDynamic()) continue; // Don't collect names for dynamic mappings
Address usepoint;
if (!entry->getUseLimit().empty()) {
const Range *range = entry->getUseLimit().getFirstRange();
usepoint = Address(range->getSpace(),range->getFirst());
if (entry->isDynamic()) {
addDynamicRecommend(entry->getFirstUseAddress(), entry->getHash(), sym->getName());
}
else {
Address usepoint;
if (!entry->getUseLimit().empty()) {
const Range *range = entry->getUseLimit().getFirstRange();
usepoint = Address(range->getSpace(),range->getFirst());
}
addRecommendName( entry->getAddr(), usepoint, sym->getName(), entry->getSize() );
}
addRecommendName( entry->getAddr(), usepoint, sym->getName(), entry->getSize() );
if (sym->getCategory()<0)
removeSymbol(sym);
}
@ -1218,6 +1221,25 @@ void ScopeLocal::makeNameRecommendationsForSymbols(vector<string> &resname,vecto
++biter;
}
}
if (dynRecommend.empty()) return;
list<DynamicRecommend>::const_iterator dyniter;
DynamicHash dhash;
for(dyniter=dynRecommend.begin();dyniter!=dynRecommend.end();++dyniter) {
dhash.clear();
const DynamicRecommend &dynEntry(*dyniter);
Varnode *vn = dhash.findVarnode(fd, dynEntry.getAddress(), dynEntry.getHash());
if (vn == (Varnode *)0) continue;
if (vn->isAnnotation()) continue;
Symbol *sym = vn->getHigh()->getSymbol();
if (sym != (Symbol *)0) {
if (sym->isNameUndefined()) {
resname.push_back( dynEntry.getName() );
ressym.push_back(sym);
}
}
}
}
/// \brief Add a new recommended name to the list
@ -1233,3 +1255,16 @@ void ScopeLocal::addRecommendName(const Address &addr,const Address &usepoint,co
{
nameRecommend[ AddressUsePointPair(addr,usepoint,sz) ] = nm;
}
/// \brief Add a new recommended name for a dynamic storage location to the list
///
/// This recommended name is assigned a storage location via the DynamicHash mechanism.
/// The name may be reattached to a Symbol after decompilation.
/// \param addr is the address of the code use point
/// \param hash is the hash encoding context for identifying the storage location
/// \param nm is the recommended name
void ScopeLocal::addDynamicRecommend(const Address &usepoint,uint8 hash,const string &nm)
{
dynRecommend.push_back(DynamicRecommend(usepoint,hash,nm));
}

View file

@ -40,6 +40,25 @@ public:
bool operator==(const AddressUsePointPair &op2) const; ///< Test for equality
};
/// \brief A name recommendation for a particular dynamic location
///
/// A recommendation for a symbol name whose storage is dynamic. The storage
/// is identified using the DynamicHash mechanism and may or may not exist.
class DynamicRecommend {
Address usePoint; ///< Use point of the Symbol
uint8 hash; ///< Hash encoding the Symbols environment
string name; ///< The local symbol name recommendation
public:
DynamicRecommend(const Address &addr,uint8 h,const string &nm) :
usePoint(addr) {
hash = h;
name = nm;
} ///< Constructor
const Address &getAddress(void) const { return usePoint; } ///< Get the use point address
uint8 getHash(void) const { return hash; } ///< Get the dynamic hash
string getName(void) const { return name; } ///< Get the recommended name
};
/// \brief Partial data-type information mapped to a specific range of bytes
///
/// This object gives a hint about the data-type for a sequence of bytes
@ -160,6 +179,7 @@ class ScopeLocal : public ScopeInternal {
AddrSpace *space; ///< Address space containing the local stack
RangeList localRange; ///< The set of addresses that might hold mapped locals (not parameters)
map<AddressUsePointPair,string> nameRecommend; ///< Symbol name recommendations for specific addresses
list<DynamicRecommend> dynRecommend; ///< Symbol name recommendations for dynamic locations
bool stackGrowsNegative; ///< Marked \b true if the stack is considered to \e grow towards smaller offsets
bool rangeLocked; ///< True if the subset of addresses \e mapped to \b this scope has been locked
bool adjustFit(RangeHint &a) const; ///< Make the given RangeHint fit in the current Symbol map
@ -167,6 +187,8 @@ class ScopeLocal : public ScopeInternal {
bool restructure(MapState &state); ///< Merge hints into a formal Symbol layout of the address space
void markUnaliased(const vector<uintb> &alias); ///< Mark all local symbols for which there are no aliases
void fakeInputSymbols(void); ///< Make sure all stack inputs have an associated Symbol
void addRecommendName(const Address &addr,const Address &usepoint,const string &nm,int4 sz);
void addDynamicRecommend(const Address &usepoint,uint8 hash,const string &nm);
void collectNameRecs(void); ///< Collect names of unlocked Symbols on the stack
public:
ScopeLocal(AddrSpace *spc,Funcdata *fd,Architecture *g); ///< Constructor
@ -193,7 +215,6 @@ public:
void restructureVarnode(bool aliasyes); ///< Layout mapped symbols based on Varnode information
void restructureHigh(void); ///< Layout mapped symbols based on HighVariable information
void makeNameRecommendationsForSymbols(vector<string> &resname,vector<Symbol *> &ressym) const;
void addRecommendName(const Address &addr,const Address &usepoint,const string &nm,int4 sz);
};
#endif