mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-12-02 00:51:54 +00:00
GP-4369 Adjust switch variable path detection
This commit is contained in:
parent
89c2d55b07
commit
8af47cc7b0
@ -2162,6 +2162,26 @@ int4 ActionLikelyTrash::apply(Funcdata &data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Return \b true if either the Varnode is a constant or if it is the not yet simplified
|
||||
/// INT_ADD of constants.
|
||||
/// \param vn is the given Varnode to test
|
||||
/// \return \b true if the Varnode will be a constant
|
||||
bool ActionRestructureVarnode::isDelayedConstant(Varnode *vn)
|
||||
|
||||
{
|
||||
if (vn->isConstant()) return true;
|
||||
if (!vn->isWritten()) return false;
|
||||
PcodeOp *op = vn->getDef();
|
||||
if (op->code() != CPUI_INT_ADD) return false;
|
||||
if (!op->getIn(1)->isConstant()) return false;
|
||||
Varnode *cvn = op->getIn(0);
|
||||
if (cvn->isConstant()) return true;
|
||||
if (!cvn->isWritten()) return false;
|
||||
PcodeOp *copy = cvn->getDef();
|
||||
if (copy->code() != CPUI_COPY) return false;
|
||||
return copy->getIn(0)->isConstant();
|
||||
}
|
||||
|
||||
/// Test if the path to the given BRANCHIND originates from a constant but passes through INDIRECT operations.
|
||||
/// This indicates that the switch value is produced indirectly, so we mark these INDIRECT
|
||||
/// operations as \e not \e collapsible, to guarantee that the indirect value is not lost during analysis.
|
||||
@ -2176,9 +2196,16 @@ void ActionRestructureVarnode::protectSwitchPathIndirects(PcodeOp *op)
|
||||
uint4 evalType = curOp->getEvalType();
|
||||
if ((evalType & (PcodeOp::binary | PcodeOp::ternary)) != 0) {
|
||||
if (curOp->numInput() > 1) {
|
||||
if (!curOp->getIn(1)->isConstant()) return; // Multiple paths
|
||||
if (isDelayedConstant(curOp->getIn(1)))
|
||||
curVn = curOp->getIn(0);
|
||||
else if (isDelayedConstant(curOp->getIn(0)))
|
||||
curVn = curOp->getIn(1);
|
||||
else
|
||||
return; // Multiple paths
|
||||
}
|
||||
else {
|
||||
curVn = curOp->getIn(0);
|
||||
}
|
||||
curVn = curOp->getIn(0);
|
||||
}
|
||||
else if ((evalType & PcodeOp::unary) != 0)
|
||||
curVn = curOp->getIn(0);
|
||||
|
@ -832,6 +832,7 @@ public:
|
||||
/// This produces on intermediate view of symbols on the stack.
|
||||
class ActionRestructureVarnode : public Action {
|
||||
int4 numpass; ///< Number of passes performed for this function
|
||||
static bool isDelayedConstant(Varnode *vn); ///< Determine if given Varnode is or will be a constant
|
||||
static void protectSwitchPathIndirects(PcodeOp *op); ///< Protect path to the given switch from INDIRECT collapse
|
||||
static void protectSwitchPaths(Funcdata &data); ///< Look for switches and protect path of switch variable
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user