decompiler
1.0.0
|
A basic jump-table model with an added default address path. More...
#include <jumptable.hh>
Public Member Functions | |
JumpBasic2 (JumpTable *jt) | |
Constructor. | |
void | initializeStart (const PathMeld &pMeld) |
Pass in the prior PathMeld calculation. | |
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 | findUnnormalized (uint4 maxaddsub, uint4 maxleftright, uint4 maxext) |
Recover the unnormalized switch variable. More... | |
virtual JumpModel * | clone (JumpTable *jt) const |
Clone this model. | |
virtual void | clear (void) |
Clear any non-permanent aspects of the model. | |
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 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 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 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... | |
Public Member Functions inherited from ghidra::JumpModel | |
JumpModel (JumpTable *jt) | |
Construct given a parent jump-table. | |
virtual | ~JumpModel (void) |
Destructor. | |
virtual void | encode (Encoder &encoder) const |
Encode this model to a stream. | |
virtual void | decode (Decoder &decoder) |
Decode this model from a stream. | |
Private Member Functions | |
bool | checkNormalDominance (void) const |
Check if the block that defines the normalized switch variable dominates the block containing the switch. More... | |
virtual bool | foldInOneGuard (Funcdata *fd, GuardRecord &guard, JumpTable *jump) |
Eliminate the given guard to this switch. More... | |
Private Attributes | |
Varnode * | extravn |
The extra Varnode holding the default value. | |
PathMeld | origPathMeld |
The set of paths that produce non-default addresses. | |
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... | |
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 with an added default address path.
This model expects two paths to the switch, 1 from a default value, 1 from the other values that hit the switch If A is the guarding control-flow block, C is the block setting the default value, and S the switch block itself, We expect one of the following situations:
This builds on the analysis performed for JumpBasic, which fails because there are too many paths to the BRANCHIND, preventing the guards from being interpreted properly. This class expects to reuse the PathMeld calculation from JumpBasic.
|
private |
Check if the block that defines the normalized switch variable dominates the block containing the switch.
References ghidra::FlowBlock::getImmedDom(), and ghidra::FlowBlock::getParent().
|
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 |
Reimplemented from ghidra::JumpBasic.
References ghidra::JumpBasic::findUnnormalized(), and ghidra::PcodeOp::getIn().
|
privatevirtual |
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 from ghidra::JumpBasic.
References ghidra::GuardRecord::clear(), and ghidra::JumpTable::setLastAsMostCommon().
|
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 ghidra::PcodeOp::code(), ghidra::CPUI_COPY, ghidra::CPUI_MULTIEQUAL, ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::FlowBlock::getIn(), ghidra::FlowBlock::getInRevIndex(), ghidra::Varnode::getOffset(), ghidra::PcodeOp::getParent(), ghidra::Varnode::isConstant(), ghidra::Varnode::isWritten(), ghidra::PcodeOp::numInput(), ghidra::JumpValuesRangeDefault::setDefaultOp(), ghidra::JumpValuesRangeDefault::setDefaultVn(), and ghidra::JumpValuesRangeDefault::setExtraValue().