mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
Overlapping input fixes
This commit is contained in:
parent
a8f9d4f7ac
commit
2df81f803b
4 changed files with 33 additions and 9 deletions
|
@ -1649,6 +1649,12 @@ int4 AncestorRealistic::enterNode(State &state)
|
|||
multiDepth += 1;
|
||||
stateStack.push_back(State(op,0));
|
||||
return enter_node; // Nothing to check, start traversing inputs of MULTIEQUAL
|
||||
case CPUI_PIECE:
|
||||
// If the trial is getting pieced together and then truncated in a register,
|
||||
// this is evidence of artificial data-flow.
|
||||
if (state.vn->getSize() > trial->getSize() && state.vn->getSpace()->getType() != IPTR_SPACEBASE)
|
||||
return pop_fail;
|
||||
return pop_solid;
|
||||
default:
|
||||
return pop_solid; // Any other LOAD or arithmetic/logical operation is viewed as solid movement
|
||||
}
|
||||
|
|
|
@ -7279,7 +7279,7 @@ int4 RuleSubvarAnd::applyOp(PcodeOp *op,Funcdata &data)
|
|||
// if ((vn->getConsume() & 0xff)==0xff) return 0;
|
||||
// if (op->getIn(1)->getOffset() != (uintb)1) return 0;
|
||||
if (op->getOut()->hasNoDescend()) return 0;
|
||||
SubvariableFlow subflow(&data,vn,cmask,false,false);
|
||||
SubvariableFlow subflow(&data,vn,cmask,false,false,false);
|
||||
if (!subflow.doTrace()) return 0;
|
||||
subflow.doReplacement();
|
||||
return 1;
|
||||
|
@ -7298,14 +7298,24 @@ int4 RuleSubvarSubpiece::applyOp(PcodeOp *op,Funcdata &data)
|
|||
{
|
||||
Varnode *vn = op->getIn(0);
|
||||
Varnode *outvn = op->getOut();
|
||||
uintb mask = calc_mask( outvn->getSize() );
|
||||
int4 flowsize = outvn->getSize();
|
||||
uintb mask = calc_mask( flowsize );
|
||||
mask <<= 8*((int4)op->getIn(1)->getOffset());
|
||||
bool aggressive = outvn->isPtrFlow();
|
||||
if (!aggressive) {
|
||||
if ((vn->getConsume() & mask) != vn->getConsume()) return 0;
|
||||
if (op->getOut()->hasNoDescend()) return 0;
|
||||
}
|
||||
SubvariableFlow subflow(&data,vn,mask,aggressive,false);
|
||||
bool big = false;
|
||||
if (flowsize >= 8 && vn->isInput()) {
|
||||
// Vector register inputs getting truncated to what actually gets used
|
||||
// happens occasionally. We let SubvariableFlow deal with this special case
|
||||
// to avoid overlapping inputs
|
||||
// TODO: ActionLaneDivide should be handling this
|
||||
if (vn->loneDescend() == op)
|
||||
big = true;
|
||||
}
|
||||
SubvariableFlow subflow(&data,vn,mask,aggressive,false,big);
|
||||
if (!subflow.doTrace()) return 0;
|
||||
subflow.doReplacement();
|
||||
return 1;
|
||||
|
@ -7624,7 +7634,7 @@ int4 RuleSubvarCompZero::applyOp(PcodeOp *op,Funcdata &data)
|
|||
}
|
||||
}
|
||||
|
||||
SubvariableFlow subflow(&data,vn,mask,false,false);
|
||||
SubvariableFlow subflow(&data,vn,mask,false,false,false);
|
||||
if (!subflow.doTrace()) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -7656,7 +7666,7 @@ int4 RuleSubvarShift::applyOp(PcodeOp *op,Funcdata &data)
|
|||
mask = (mask >> sa) << sa;
|
||||
if (op->getOut()->hasNoDescend()) return 0;
|
||||
|
||||
SubvariableFlow subflow(&data,vn,mask,false,false);
|
||||
SubvariableFlow subflow(&data,vn,mask,false,false,false);
|
||||
if (!subflow.doTrace()) return 0;
|
||||
subflow.doReplacement();
|
||||
return 1;
|
||||
|
@ -7677,7 +7687,7 @@ int4 RuleSubvarZext::applyOp(PcodeOp *op,Funcdata &data)
|
|||
Varnode *invn = op->getIn(0);
|
||||
uintb mask = calc_mask(invn->getSize());
|
||||
|
||||
SubvariableFlow subflow(&data,vn,mask,invn->isPtrFlow(),false);
|
||||
SubvariableFlow subflow(&data,vn,mask,invn->isPtrFlow(),false,false);
|
||||
if (!subflow.doTrace()) return 0;
|
||||
subflow.doReplacement();
|
||||
return 1;
|
||||
|
@ -7698,7 +7708,7 @@ int4 RuleSubvarSext::applyOp(PcodeOp *op,Funcdata &data)
|
|||
Varnode *invn = op->getIn(0);
|
||||
uintb mask = calc_mask(invn->getSize());
|
||||
|
||||
SubvariableFlow subflow(&data,vn,mask,isaggressive,true);
|
||||
SubvariableFlow subflow(&data,vn,mask,isaggressive,true,false);
|
||||
if (!subflow.doTrace()) return 0;
|
||||
subflow.doReplacement();
|
||||
return 1;
|
||||
|
|
|
@ -1260,7 +1260,8 @@ bool SubvariableFlow::processNextWork(void)
|
|||
/// \param mask is a mask where 1 bits indicate the position of the logical value within the \e root Varnode
|
||||
/// \param aggr is \b true if we should use aggressive (less restrictive) tests during the trace
|
||||
/// \param sext is \b true if we should assume sign extensions from the logical value into its container
|
||||
SubvariableFlow::SubvariableFlow(Funcdata *f,Varnode *root,uintb mask,bool aggr,bool sext)
|
||||
/// \param big is \b true if we look for subvariable flow for \e big (8-byte) logical values
|
||||
SubvariableFlow::SubvariableFlow(Funcdata *f,Varnode *root,uintb mask,bool aggr,bool sext,bool big)
|
||||
|
||||
{
|
||||
fd = f;
|
||||
|
@ -1280,6 +1281,13 @@ SubvariableFlow::SubvariableFlow(Funcdata *f,Varnode *root,uintb mask,bool aggr,
|
|||
flowsize = 3;
|
||||
else if (bitsize <= 32)
|
||||
flowsize = 4;
|
||||
else if (bitsize <= 64) {
|
||||
if (!big) {
|
||||
fd = (Funcdata *)0;
|
||||
return;
|
||||
}
|
||||
flowsize = 8;
|
||||
}
|
||||
else {
|
||||
fd = (Funcdata *)0;
|
||||
return;
|
||||
|
|
|
@ -118,7 +118,7 @@ class SubvariableFlow {
|
|||
Varnode *getReplaceVarnode(ReplaceVarnode *rvn);
|
||||
bool processNextWork(void); ///< Extend the subgraph from the next node in the worklist
|
||||
public:
|
||||
SubvariableFlow(Funcdata *f,Varnode *root,uintb mask,bool aggr,bool sext); ///< Constructor
|
||||
SubvariableFlow(Funcdata *f,Varnode *root,uintb mask,bool aggr,bool sext,bool big); ///< Constructor
|
||||
bool doTrace(void); ///< Trace logical value through data-flow, constructing transform
|
||||
void doReplacement(void); ///< Perform the discovered transform, making logical values explicit
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue