GP-1642 Display formats for data-types

This commit is contained in:
caheckman 2022-01-05 19:32:44 -05:00
parent 9c04807c8c
commit 955838cd62
12 changed files with 266 additions and 99 deletions

View file

@ -37,7 +37,6 @@ void IfaceDecompCapability::registerCommands(IfaceStatus *status)
status->registerCom(new IfcComment(),"%"); //Note: A space must follow this when used.
status->registerCom(new IfcQuit(),"quit");
status->registerCom(new IfcHistory(),"history");
status->registerCom(new IfcOpenfile(),"openfile");
status->registerCom(new IfcOpenfile(),"openfile", "write");
status->registerCom(new IfcOpenfileAppend(),"openfile","append");
status->registerCom(new IfcClosefile(),"closefile");
@ -63,8 +62,8 @@ void IfaceDecompCapability::registerCommands(IfaceStatus *status)
status->registerCom(new IfcDump(),"dump");
status->registerCom(new IfcDumpbinary(),"binary");
status->registerCom(new IfcForcegoto(),"force","goto");
status->registerCom(new IfcForceHex(),"force","hex");
status->registerCom(new IfcForceDec(),"force","dec");
status->registerCom(new IfcForceFormat(),"force","varnode");
status->registerCom(new IfcForceDatatypeFormat(),"force","datatype");
status->registerCom(new IfcProtooverride(),"override","prototype");
status->registerCom(new IfcJumpOverride(),"override","jumptable");
status->registerCom(new IfcFlowOverride(),"override","flow");
@ -1254,10 +1253,7 @@ void IfcRename::execute(istream &s)
Symbol *sym;
vector<Symbol *> symList;
if (dcp->fd != (Funcdata *)0)
dcp->fd->getScopeLocal()->queryByName(oldname,symList);
else
dcp->conf->symboltab->getGlobalScope()->queryByName(oldname,symList);
dcp->readSymbol(oldname,symList);
if (symList.empty())
throw IfaceExecutionError("No symbol named: "+oldname);
@ -1273,7 +1269,7 @@ void IfcRename::execute(istream &s)
}
/// \class IfcRemove
/// \brief Remove a symbol by name: `remove <varname>`
/// \brief Remove a symbol by name: `remove <symbolname>`
///
/// The symbol is searched for starting in the current function's scope.
/// The resulting symbol is removed completely from the symbol table.
@ -1287,10 +1283,7 @@ void IfcRemove::execute(istream &s)
throw IfaceParseError("Missing symbol name");
vector<Symbol *> symList;
if (dcp->fd != (Funcdata *)0)
dcp->fd->getScopeLocal()->queryByName(name,symList);
else
dcp->conf->symboltab->getGlobalScope()->queryByName(name,symList);
dcp->readSymbol(name,symList);
if (symList.empty())
throw IfaceExecutionError("No symbol named: "+name);
@ -1300,7 +1293,7 @@ void IfcRemove::execute(istream &s)
}
/// \class IfcRetype
/// \brief Change the data-type of a symbol: `retype <varname> <typedeclaration>`
/// \brief Change the data-type of a symbol: `retype <symbolname> <typedeclaration>`
///
/// The symbol is searched for by name starting in the current function's scope.
/// If the type declaration includes a new name for the variable, the
@ -1318,10 +1311,7 @@ void IfcRetype::execute(istream &s)
Symbol *sym;
vector<Symbol *> symList;
if (dcp->fd != (Funcdata *)0)
dcp->fd->getScopeLocal()->queryByName(name,symList);
else
dcp->conf->symboltab->getGlobalScope()->queryByName(name,symList);
dcp->readSymbol(name,symList);
if (symList.empty())
throw IfaceExecutionError("No symbol named: "+name);
@ -1414,6 +1404,21 @@ Varnode *IfaceDecompData::readVarnode(istream &s)
return vn;
}
/// Find any symbols matching the given name in the current scope. Scope is either the
/// current function scope if a function is active, otherwise the global scope.
/// \param name is the given name, either absolute or partial
/// \param res will hold any matching symbols
void IfaceDecompData::readSymbol(const string &name,vector<Symbol *> &res)
{
Scope *scope = (fd == (Funcdata *)0) ? conf->symboltab->getGlobalScope() : fd->getScopeLocal();
string basename;
scope = conf->symboltab->resolveScopeFromSymbolName(name, "::", basename, scope);
if (scope == (Scope *)0)
throw IfaceParseError("Bad namespace for symbol: " + name);
scope->queryByName(basename,res);
}
/// \class IfcPrintVarnode
/// \brief Print information about a Varnode: `print varnode <varnode>`
///
@ -1644,56 +1649,51 @@ void IfcTypeVarnode::execute(istream &s)
*status->fileoptr << " to scope " << scope->getFullName() << endl;
}
/// \class IfcForceHex
/// \brief Mark a constant to be printed in hex format: `force hex <varnode>`
/// \class IfcForceFormat
/// \brief Mark a constant to be printed in a specific format: `force varnode <varnode> [hex|dec|oct|bin|char]`
///
/// A selected constant Varnode in the \e current function is marked so
/// that it will be printed in hexadecimal format in decompiler output.
void IfcForceHex::execute(istream &s)
/// A constant Varnode in the \e current function is marked so that is forced
/// to print in one of the formats: \b hex, \b dec, \b oct, \b bin, \b char.
void IfcForceFormat::execute(istream &s)
{
if (dcp->fd == (Funcdata *)0)
throw IfaceExecutionError("No function selected");
Varnode *vn = dcp->readVarnode(s);
if (!vn->isConstant())
throw IfaceExecutionError("Can only force hex on a constant");
throw IfaceExecutionError("Can only force format on a constant");
type_metatype mt = vn->getType()->getMetatype();
if ((mt!=TYPE_INT)&&(mt!=TYPE_UINT)&&(mt!=TYPE_UNKNOWN))
throw IfaceExecutionError("Can only force hex on integer type constant");
throw IfaceExecutionError("Can only force format on integer type constant");
dcp->fd->buildDynamicSymbol(vn);
Symbol *sym = vn->getHigh()->getSymbol();
if (sym == (Symbol *)0)
throw IfaceExecutionError("Unable to create symbol");
sym->getScope()->setDisplayFormat(sym,Symbol::force_hex);
string formatString;
s >> ws >> formatString;
uint4 format = Datatype::encodeIntegerFormat(formatString);
sym->getScope()->setDisplayFormat(sym,format);
sym->getScope()->setAttribute(sym,Varnode::typelock);
*status->optr << "Successfully forced hex display" << endl;
*status->optr << "Successfully forced format display" << endl;
}
/// \class IfcForceDec
/// \brief Mark a constant to be printed in decimal format: `force dec <varnode>`
/// \class IfcForceDatatypeFormat
/// \brief Mark constants of a data-type to be printed in a specific format: `force datatype <datatype> [hex|dec|oct|bin|char]`
///
/// A selected constant Varnode in the \e current function is marked so
/// that it will be printed in decimal format in decompiler output.
void IfcForceDec::execute(istream &s)
/// A display format attribute is set on the indicated data-type.
void IfcForceDatatypeFormat::execute(istream &s)
{
if (dcp->fd == (Funcdata *)0)
throw IfaceExecutionError("No function selected");
Datatype *dt;
Varnode *vn = dcp->readVarnode(s);
if (!vn->isConstant())
throw IfaceExecutionError("Can only force hex on a constant");
type_metatype mt = vn->getType()->getMetatype();
if ((mt!=TYPE_INT)&&(mt!=TYPE_UINT)&&(mt!=TYPE_UNKNOWN))
throw IfaceExecutionError("Can only force dec on integer type constant");
dcp->fd->buildDynamicSymbol(vn);
Symbol *sym = vn->getHigh()->getSymbol();
if (sym == (Symbol *)0)
throw IfaceExecutionError("Unable to create symbol");
sym->getScope()->setDisplayFormat(sym,Symbol::force_dec);
sym->getScope()->setAttribute(sym,Varnode::typelock);
*status->optr << "Successfully forced dec display" << endl;
string typeName;
s >> ws >> typeName;
dt = dcp->conf->types->findByName(typeName);
if (dt == (Datatype *)0)
throw IfaceExecutionError("Unknown data-type: " + typeName);
string formatString;
s >> ws >> formatString;
uint4 format = Datatype::encodeIntegerFormat(formatString);
dcp->conf->types->setDisplayFormat(dt, format);
*status->optr << "Successfully forced data-type display" << endl;
}
/// \class IfcForcegoto