decompiler
1.0.0
|
A basic jump-table model incorporating manual override information. More...
#include <jumptable.hh>
Public Member Functions | |
JumpBasicOverride (JumpTable *jt) | |
Constructor. More... | |
void | setAddresses (const vector< Address > &adtable) |
Manually set the address table for this model. More... | |
void | setNorm (const Address &addr, uintb h) |
Set the normalized switch variable. | |
void | setStartingValue (uintb val) |
Set the starting value for the normalized range. | |
virtual bool | isOverride (void) const |
Return true if this model was manually overridden. | |
virtual int4 | getTableSize (void) const |
Return the number of entries in the address table. | |
virtual bool | recoverModel (Funcdata *fd, PcodeOp *indop, uint4 matchsize, uint4 maxtablesize) |
Attempt to recover details of the model, given a specific BRANCHIND. More... | |
virtual void | buildAddresses (Funcdata *fd, PcodeOp *indop, vector< Address > &addresstable, vector< LoadTable > *loadpoints) const |
Construct the explicit list of target addresses (the Address Table) from this model. More... | |
virtual void | buildLabels (Funcdata *fd, vector< Address > &addresstable, vector< uintb > &label, const JumpModel *orig) const |
Recover case labels associated with the Address table. More... | |
virtual bool | foldInGuards (Funcdata *fd, JumpTable *jump) |
Eliminate any guard code involved in computing the switch destination. More... | |
virtual bool | sanityCheck (Funcdata *fd, PcodeOp *indop, vector< Address > &addresstable) |
Perform a sanity check on recovered addresses. More... | |
virtual JumpModel * | clone (JumpTable *jt) const |
Clone this model. | |
virtual void | clear (void) |
Clear any non-permanent aspects of the model. | |
virtual void | encode (Encoder &encoder) const |
Encode this model to a stream. | |
virtual void | decode (Decoder &decoder) |
Decode this model from a stream. | |
Public Member Functions inherited from ghidra::JumpBasic | |
JumpBasic (JumpTable *jt) | |
Construct given a parent JumpTable. | |
const PathMeld & | getPathMeld (void) const |
Get the possible of paths to the switch. | |
const JumpValuesRange * | getValueRange (void) const |
Get the normalized value iterator. | |
virtual void | findUnnormalized (uint4 maxaddsub, uint4 maxleftright, uint4 maxext) |
Recover the unnormalized switch variable. More... | |
virtual Varnode * | foldInNormalization (Funcdata *fd, PcodeOp *indop) |
Do normalization of the given switch specific to this model. More... | |
Public Member Functions inherited from ghidra::JumpModel | |
JumpModel (JumpTable *jt) | |
Construct given a parent jump-table. | |
virtual | ~JumpModel (void) |
Destructor. | |
Private Member Functions | |
int4 | findStartOp (Varnode *vn) |
Return the PcodeOp (within the PathMeld set) that takes the given Varnode as input. More... | |
int4 | trialNorm (Funcdata *fd, Varnode *trialvn, uint4 tolerance) |
Test a given Varnode as a potential normalized switch variable. More... | |
void | setupTrivial (void) |
Convert this to a trivial model. More... | |
Varnode * | findLikelyNorm (void) |
Find a potential normalized switch variable. More... | |
void | clearCopySpecific (void) |
Clear varnodes and ops that are specific to one instance of a function. | |
Private Attributes | |
set< Address > | adset |
Absolute address table (manually specified) | |
vector< uintb > | values |
Normalized switch variable values associated with addresses. | |
vector< Address > | addrtable |
Address associated with each value. | |
uintb | startingvalue |
Possible start for guessing values that match addresses. | |
Address | normaddress |
Dynamic info for recovering normalized switch variable. | |
uint8 | hash |
if (hash==0) there is no normalized switch (use trivial model) | |
bool | istrivial |
true if we use a trivial value model | |
Additional Inherited Members | |
Protected Member Functions inherited from ghidra::JumpBasic | |
void | findDeterminingVarnodes (PcodeOp *op, int4 slot) |
Calculate the initial set of Varnodes that might be switch variables. More... | |
void | analyzeGuards (BlockBasic *bl, int4 pathout) |
Analyze CBRANCHs leading up to the given basic-block as a potential switch guard. More... | |
void | calcRange (Varnode *vn, CircleRange &rng) const |
Calculate the range of values in the given Varnode that direct control-flow to the switch. More... | |
void | findSmallestNormal (uint4 matchsize) |
Find the putative switch variable with the smallest range of values reaching the switch. More... | |
void | findNormalized (Funcdata *fd, BlockBasic *rootbl, int4 pathout, uint4 matchsize, uint4 maxtablesize) |
Do all the work necessary to recover the normalized switch variable. More... | |
void | markFoldableGuards () |
Mark the guard CBRANCHs that are truly part of the model. More... | |
void | markModel (bool val) |
Mark (or unmark) all PcodeOps involved in the model. More... | |
bool | flowsOnlyToModel (Varnode *vn, PcodeOp *trailOp) |
Check if the given Varnode flows to anything other than this model. More... | |
bool | checkCommonCbranch (vector< Varnode *> &varArray, BlockBasic *bl) |
Check that all incoming blocks end with a CBRANCH. More... | |
void | checkUnrolledGuard (BlockBasic *bl, int4 maxpullback, bool usenzmask) |
Check for a guard that has been unrolled across multiple blocks. More... | |
virtual bool | foldInOneGuard (Funcdata *fd, GuardRecord &guard, JumpTable *jump) |
Eliminate the given guard to this switch. More... | |
Static Protected Member Functions inherited from ghidra::JumpBasic | |
static bool | isprune (Varnode *vn) |
Do we prune in here in our depth-first search for the normalized switch variable. More... | |
static bool | ispoint (Varnode *vn) |
Is it possible for the given Varnode to be a switch variable? More... | |
static int4 | getStride (Varnode *vn) |
Get the step/stride associated with the Varnode. More... | |
static uintb | backup2Switch (Funcdata *fd, uintb output, Varnode *outvn, Varnode *invn) |
Back up the constant value in the output Varnode to the value in the input Varnode. More... | |
static uintb | getMaxValue (Varnode *vn) |
Get maximum value associated with the given Varnode. More... | |
Protected Attributes inherited from ghidra::JumpBasic | |
JumpValuesRange * | jrange |
Range of values for the (normalized) switch variable. | |
PathMeld | pathMeld |
Set of PcodeOps and Varnodes producing the final target addresses. | |
vector< GuardRecord > | selectguards |
Any guards associated with model. | |
int4 | varnodeIndex |
Position of the normalized switch Varnode within PathMeld. | |
Varnode * | normalvn |
Normalized switch Varnode. | |
Varnode * | switchvn |
Unnormalized switch Varnode. | |
Protected Attributes inherited from ghidra::JumpModel | |
JumpTable * | jumptable |
The jump-table that is building this model. | |
A basic jump-table model incorporating manual override information.
The list of potential target addresses produced by the BRANCHIND is not recovered by this model, but must provided explicitly via setAddresses(). The model tries to repurpose some of the analysis that JumpBasic does to recover the switch variable. But it will revert to the trivial model if it can't find a suitable switch variable.
ghidra::JumpBasicOverride::JumpBasicOverride | ( | JumpTable * | jt | ) |
Constructor.
jt | is the parent JumpTable |
References hash, istrivial, and startingvalue.
Referenced by clone().
|
virtual |
Construct the explicit list of target addresses (the Address Table) from this model.
The addresses produced all come from the BRANCHIND and may not be deduped. Alternate guard destinations are not yet included.
fd | is the function containing the switch |
indop | is the root BRANCHIND of the switch |
addresstable | will hold the list of Addresses |
loadpoints | if non-null will hold LOAD table information used by the model |
Reimplemented from ghidra::JumpBasic.
References addrtable.
|
virtual |
Recover case labels associated with the Address table.
The unnormalized switch variable must already be recovered. Values that the normalized switch value can hold or walked back to obtain the value that the unnormalized switch variable would hold. Labels are returned in the order provided by normalized switch variable iterator JumpValues.
fd | is the function containing the switch |
addresstable | is the address table (used to label code blocks with bad or missing labels) |
label | will hold recovered labels in JumpValues order |
orig | is the JumpModel to use for the JumpValues iterator |
Reimplemented from ghidra::JumpBasic.
References ghidra::JumpBasic::backup2Switch(), ghidra::JumpBasic::normalvn, ghidra::JumpBasic::switchvn, values, and ghidra::Funcdata::warning().
|
private |
Find a potential normalized switch variable.
This method is called if the normalized switch variable is not explicitly provided. It looks for the normalized Varnode in the most common jump-table constructions, otherwise it returns null.
References ghidra::PcodeOp::code(), ghidra::CPUI_INT_ADD, ghidra::CPUI_INT_MULT, ghidra::CPUI_LOAD, ghidra::PathMeld::getOp(), ghidra::PathMeld::getOpParent(), ghidra::PathMeld::numOps(), and ghidra::JumpBasic::pathMeld.
Referenced by recoverModel().
|
private |
Return the PcodeOp (within the PathMeld set) that takes the given Varnode as input.
If there no PcodeOp in the set reading the Varnode, null is returned
vn | is the given Varnode |
References ghidra::Varnode::beginDescend(), ghidra::Varnode::endDescend(), ghidra::PathMeld::getOp(), ghidra::PcodeOp::isMark(), ghidra::PathMeld::numOps(), and ghidra::JumpBasic::pathMeld.
Referenced by trialNorm().
|
inlinevirtual |
Eliminate any guard code involved in computing the switch destination.
We now think of the BRANCHIND as encompassing any guard function.
fd | is the function containing the switch |
jump | is the JumpTable owning this model. |
Reimplemented from ghidra::JumpBasic.
|
virtual |
Attempt to recover details of the model, given a specific BRANCHIND.
This generally recovers the normalized switch variable and any guards.
fd | is the function containing the switch |
indop | is the given BRANCHIND |
matchsize | is the expected number of address table entries to recover, or 0 for no expectation |
maxtablesize | is maximum number of address table entries to allow in the model |
Reimplemented from ghidra::JumpBasic.
References clearCopySpecific(), ghidra::JumpBasic::findDeterminingVarnodes(), findLikelyNorm(), ghidra::DynamicHash::findVarnode(), hash, istrivial, normaddress, ghidra::JumpBasic::normalvn, setupTrivial(), trialNorm(), values, and ghidra::JumpBasic::varnodeIndex.
|
inlinevirtual |
Perform a sanity check on recovered addresses.
Individual addresses are checked against the function or its program to determine if they are reasonable. This method can optionally remove addresses from the table. If it does so, the underlying model is changed to reflect the removal.
fd | is the function containing the switch |
indop | is the root BRANCHIND of the switch |
addresstable | is the list of recovered Addresses, which may be modified |
Reimplemented from ghidra::JumpBasic.
void ghidra::JumpBasicOverride::setAddresses | ( | const vector< Address > & | adtable | ) |
Manually set the address table for this model.
adtable | is the list of externally provided addresses, which will be deduped |
References adset.
|
private |
Convert this to a trivial model.
Since we have an absolute set of addresses, if all else fails we can use the indirect variable as the normalized switch and the addresses as the values, similar to JumpModelTrivial
References addrtable, adset, ghidra::PathMeld::getVarnode(), istrivial, ghidra::JumpBasic::normalvn, ghidra::JumpBasic::pathMeld, values, and ghidra::JumpBasic::varnodeIndex.
Referenced by recoverModel().
|
private |
Test a given Varnode as a potential normalized switch variable.
This method tries to figure out the set of values for the Varnode that produce the manually provided set of addresses. Starting with startingvalue and simply incrementing by one to obtain new values, the path from the potential variable to the BRANCHIND is emulated to produce addresses in the manual set. Duplicates and misses are allowed. Once we see all addresses in the manual set, the method returns the index of the starting op, otherwise -1 is returned.
fd | is the function containing the switch |
trialvn | is the given trial normalized switch variable |
tolerance | is the number of misses that will be tolerated |
References ghidra::AddrSpace::addressToByte(), addrtable, adset, ghidra::EmulateFunction::emulatePath(), findStartOp(), ghidra::PcodeOp::getAddr(), ghidra::PathMeld::getOp(), ghidra::Address::getSpace(), ghidra::AddrSpace::getWordSize(), ghidra::JumpBasic::pathMeld, startingvalue, and values.
Referenced by recoverModel().