Pass through "this" data-type even if prototype is unlocked

This commit is contained in:
caheckman 2020-07-30 16:44:32 -04:00
parent 004a99bb87
commit fe7fa96113
3 changed files with 42 additions and 0 deletions

View file

@ -4748,6 +4748,7 @@ int4 ActionInferTypes::apply(Funcdata &data)
} }
return 0; return 0;
} }
data.getScopeLocal()->applyTypeRecommendations();
buildLocaltypes(data); // Set up initial types (based on local info) buildLocaltypes(data); // Set up initial types (based on local info)
for(iter=data.beginLoc();iter!=data.endLoc();++iter) { for(iter=data.beginLoc();iter!=data.endLoc();++iter) {
vn = *iter; vn = *iter;

View file

@ -289,6 +289,17 @@ void ScopeLocal::collectNameRecs(void)
Symbol *sym = *iter++; Symbol *sym = *iter++;
if (sym->isNameLocked()&&(!sym->isTypeLocked())) { if (sym->isNameLocked()&&(!sym->isTypeLocked())) {
addRecommendName(sym); addRecommendName(sym);
if (sym->isThisPointer()) { // If there is a "this" pointer
Datatype *dt = sym->getType();
if (dt->getMetatype() == TYPE_PTR) {
if (((TypePointer *)dt)->getPtrTo()->getMetatype() == TYPE_STRUCT) {
// 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));
}
}
}
} }
} }
} }
@ -1302,6 +1313,20 @@ void ScopeLocal::recoverNameRecommendationsForSymbols(void)
} }
} }
/// Run through the recommended list, search for an input Varnode matching the storage address
/// and try to apply the data-type to it. Do not override existing type lock.
void ScopeLocal::applyTypeRecommendations(void)
{
list<TypeRecommend>::const_iterator iter;
for(iter=typeRecommend.begin();iter!=typeRecommend.end();++iter) {
Datatype *dt = (*iter).getType();
Varnode *vn = fd->findVarnodeInput(dt->getSize(), (*iter).getAddress());
if (vn != (Varnode *)0)
vn->updateType(dt, true, false);
}
}
/// The symbol is stored as a name recommendation and then removed from the scope. /// 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. /// 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. /// The name may be reattached to a Symbol after decompilation.

View file

@ -60,6 +60,20 @@ public:
uint8 getSymbolId(void) const { return symbolId; } ///< Get the original Symbol id uint8 getSymbolId(void) const { return symbolId; } ///< Get the original Symbol id
}; };
/// \brief Data-type for a storage location when there is no Symbol (yet)
///
/// Allow a data-type to be fed into a specific storage location. Currently
/// this only applies to input Varnodes.
class TypeRecommend {
Address addr; ///< Storage address of the Varnode
Datatype *dataType; ///< Data-type to assign to the Varnode
public:
TypeRecommend(const Address &ad,Datatype *dt) :
addr(ad), dataType(dt) {} ///< Constructor
const Address &getAddress(void) const { return addr; } ///< Get the storage address
Datatype *getType(void) const { return dataType; } ///< Get the data-type
};
/// \brief Partial data-type information mapped to a specific range of bytes /// \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 /// This object gives a hint about the data-type for a sequence of bytes
@ -184,6 +198,7 @@ class ScopeLocal : public ScopeInternal {
RangeList localRange; ///< The set of addresses that might hold mapped locals (not parameters) RangeList localRange; ///< The set of addresses that might hold mapped locals (not parameters)
list<NameRecommend> nameRecommend; ///< Symbol name recommendations for specific addresses list<NameRecommend> nameRecommend; ///< Symbol name recommendations for specific addresses
list<DynamicRecommend> dynRecommend; ///< Symbol name recommendations for dynamic locations list<DynamicRecommend> dynRecommend; ///< Symbol name recommendations for dynamic locations
list<TypeRecommend> typeRecommend; ///< Data-types for specific storage locations
bool stackGrowsNegative; ///< Marked \b true if the stack is considered to \e grow towards smaller offsets 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 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 bool adjustFit(RangeHint &a) const; ///< Make the given RangeHint fit in the current Symbol map
@ -220,6 +235,7 @@ public:
SymbolEntry *remapSymbol(Symbol *sym,const Address &addr,const Address &usepoint); SymbolEntry *remapSymbol(Symbol *sym,const Address &addr,const Address &usepoint);
SymbolEntry *remapSymbolDynamic(Symbol *sym,uint8 hash,const Address &usepoint); SymbolEntry *remapSymbolDynamic(Symbol *sym,uint8 hash,const Address &usepoint);
void recoverNameRecommendationsForSymbols(void); void recoverNameRecommendationsForSymbols(void);
void applyTypeRecommendations(void); ///< Try to apply recommended data-type information
}; };
#endif #endif