decompiler
1.0.0
|
The basic switch model. More...
#include <jumptable.hh>
Public Member Functions | |
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 | findUnnormalized (uint4 maxaddsub, uint4 maxleftright, uint4 maxext) |
Recover the unnormalized switch variable. 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 Varnode * | foldInNormalization (Funcdata *fd, PcodeOp *indop) |
Do normalization of the given switch specific to this model. 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) |
Protected Member Functions | |
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... | |
virtual bool | foldInOneGuard (Funcdata *fd, GuardRecord &guard, JumpTable *jump) |
Eliminate the given guard to this switch. More... | |
Static Protected Member Functions | |
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... | |
Protected Attributes | |
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. | |
![]() | |
JumpTable * | jumptable |
The jump-table that is building this model. | |
The basic switch model.
This is the most common model:
|
protected |
Analyze CBRANCHs leading up to the given basic-block as a potential switch guard.
In general there is only one path to the switch, and the given basic-block will hold the BRANCHIND. In some models, there is more than one path to the switch block, and a path must be specified. In this case, the given basic-block will be a block that flows into the switch block, and the pathout parameter describes which path leads to the switch block.
For each CBRANCH, range restrictions on the various variables which allow control flow to pass through the CBRANCH to the switch are analyzed. A GuardRecord is created for each of these restrictions.
bl | is the given basic-block |
pathout | is an optional path from the basic-block to the switch or -1 |
References CPUI_BRANCHIND, CPUI_CBRANCH, PcodeOp::isBooleanFlip(), JumpModel::jumptable, CircleRange::pullBack(), and selectguards.
Referenced by findNormalized().
|
staticprotected |
Back up the constant value in the output Varnode to the value in the input Varnode.
This does the work of going from a normalized switch value to the unnormalized value. PcodeOps between the output and input Varnodes must be reversible or an exception is thrown.
fd | is the function containing the switch |
output | is the constant value to back up |
outvn | is the output Varnode of the data-flow |
invn | is the input Varnode to back up to |
References PcodeOp::binary, PcodeOp::getEvalType(), Address::getOffset(), Address::getSpace(), MemoryBank::getValue(), Address::isConstant(), TypeOp::recoverInputBinary(), TypeOp::recoverInputUnary(), and PcodeOp::unary.
Referenced by buildLabels(), and JumpBasicOverride::buildLabels().
|
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 |
Implements JumpModel.
Reimplemented in JumpBasicOverride.
References AddrSpace::addressToByte(), EmulateFunction::collectLoadPoints(), EmulateFunction::emulatePath(), JumpValuesRange::getStartOp(), JumpValuesRange::getStartVarnode(), JumpValuesRange::getValue(), AddrSpace::getWordSize(), JumpValuesRange::initializeForReading(), jrange, JumpValuesRange::next(), and pathMeld.
|
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 |
Implements JumpModel.
Reimplemented in JumpBasicOverride.
References backup2Switch(), JumpValuesRange::contains(), JumpValuesRange::getValue(), JumpValuesRange::initializeForReading(), JumpValuesRange::isReversible(), jrange, JumpValuesRange::next(), normalvn, switchvn, and Funcdata::warning().
|
protected |
Calculate the range of values in the given Varnode that direct control-flow to the switch.
The Varnode is evaluated against each GuardRecord to determine if its range of values can be restricted. Multiple guards may provide different restrictions.
vn | is the given Varnode |
rng | will hold resulting range of values the Varnode can hold at the switch |
References calc_mask(), coveringmask(), CPUI_INT_AND, CircleRange::getSize(), getStride(), CircleRange::intersect(), GuardRecord::quasiCopy(), selectguards, and GuardRecord::valueMatch().
Referenced by findSmallestNormal().
|
protected |
Calculate the initial set of Varnodes that might be switch variables.
Paths that terminate at the given PcodeOp are calculated and organized in a PathMeld object that determines Varnodes that are common to all the paths.
References ispoint(), isprune(), PathMeld::meld(), pathMeld, and PathMeld::set().
Referenced by recoverModel(), JumpBasic2::recoverModel(), and JumpBasicOverride::recoverModel().
|
protected |
Do all the work necessary to recover the normalized switch variable.
The switch can be specified as the basic-block containing the BRANCHIND, or as a block that flows to the BRANCHIND block by following the specified path out.
fd | is the function containing the switch |
rootbl | is the basic-block |
pathout | is the (optional) path to the BRANCHIND or -1 |
matchsize | is an (optional) size to expect for the normalized switch variable range |
maxtablesize | is the maximum size expected for the normalized switch variable range |
References analyzeGuards(), findSmallestNormal(), JumpValuesRange::getSize(), MemoryBank::getValue(), jrange, Architecture::loader, pathMeld, and varnodeIndex.
Referenced by recoverModel(), and JumpBasic2::recoverModel().
|
protected |
Find the putative switch variable with the smallest range of values reaching the switch.
The Varnode with the smallest range and closest to the BRANCHIND is assumed to be the normalized switch variable. If an expected range size is provided, it is used to prefer a particular Varnode as the switch variable. Whatever Varnode is selected, the JumpValue object is set up to iterator over its range.
matchsize | optionally gives an expected size of the range, or it can be 0 |
References calcRange(), PathMeld::getEarliestOp(), CircleRange::getSize(), jrange, pathMeld, and varnodeIndex.
Referenced by findNormalized().
|
virtual |
Recover the unnormalized switch variable.
The normalized switch variable must already be recovered. The amount of normalization between the two switch variables can be restricted.
maxaddsub | is a restriction on arithmetic operations |
maxleftright | is a restriction on shift operations |
maxext | is a restriction on extension operations |
Implements JumpModel.
Reimplemented in JumpBasic2.
References CPUI_INT_ADD, CPUI_INT_SEXT, CPUI_INT_SUB, CPUI_INT_ZEXT, flowsOnlyToModel(), markModel(), normalvn, pathMeld, switchvn, and varnodeIndex.
Referenced by JumpBasic2::findUnnormalized().
Check if the given Varnode flows to anything other than this model.
The PcodeOps in this model must have been previously marked with markModel(). Run through the descendants of the given Varnode and look for this mark.
Referenced by findUnnormalized().
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. |
Implements JumpModel.
Reimplemented in JumpBasicOverride.
References foldInOneGuard(), and selectguards.
Do normalization of the given switch specific to this model.
The PcodeOp machinery is removed so it looks like the CPUI_BRANCHIND simply takes the switch variable as an input Varnode and automatically interprets its values to reach the correct destination.
fd | is the function containing the switch |
indop | is the given switch as a CPUI_BRANCHIND |
Implements JumpModel.
References Funcdata::opSetInput(), and switchvn.
|
protectedvirtual |
Eliminate the given guard to this switch.
We disarm the guard instructions by making the guard condition always false. If the simplification removes the unusable branches, we are left with only one path through the switch.
fd | is the function containing the switch |
guard | is a description of the particular guard mechanism |
jump | is the JumpTable owning this model |
Reimplemented in JumpBasic2.
References JumpTable::addBlockToSwitch(), PcodeOp::isBooleanFlip(), Funcdata::newConstant(), BlockBasic::noInterveningStatement(), Funcdata::opSetInput(), Funcdata::pushBranch(), and JumpTable::setLastAsMostCommon().
Referenced by foldInGuards().
|
staticprotected |
Get the step/stride associated with the Varnode.
If the some of the least significant bits of the given Varnode are known to be zero, translate this into a stride for the jumptable range.
vn | is the given Varnode |
Referenced by calcRange().
|
staticprotected |
Is it possible for the given Varnode to be a switch variable?
vn | is the given Varnode to test |
Referenced by findDeterminingVarnodes().
|
staticprotected |
Do we prune in here in our depth-first search for the normalized switch variable.
vn | is the Varnode we are testing for pruning |
Referenced by findDeterminingVarnodes().
|
protected |
Mark the guard CBRANCHs that are truly part of the model.
These CBRANCHs will be removed from the active control-flow graph, their function folded into the action of the model, as represented by BRANCHIND.
References pathMeld, GuardRecord::quasiCopy(), selectguards, and varnodeIndex.
Referenced by recoverModel().
|
protected |
Mark (or unmark) all PcodeOps involved in the model.
val | is true to set marks, false to clear marks |
References PathMeld::markPaths(), pathMeld, selectguards, and varnodeIndex.
Referenced by findUnnormalized().
|
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 |
Implements JumpModel.
Reimplemented in JumpBasicOverride, and JumpBasic2.
References findDeterminingVarnodes(), findNormalized(), JumpValuesRange::getSize(), jrange, and markFoldableGuards().
|
virtual |
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 |
Implements JumpModel.
Reimplemented in JumpBasicOverride.
References Address::getOffset(), jrange, LoadImage::loadFill(), and JumpValuesRange::truncate().