mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Subvariable flow into switch
This commit is contained in:
parent
e6f09b141b
commit
936f541e64
7 changed files with 164 additions and 67 deletions
|
@ -340,6 +340,28 @@ bool SubvariableFlow::tryCallReturnPull(PcodeOp *op,ReplaceVarnode *rvn)
|
|||
return true;
|
||||
}
|
||||
|
||||
/// \brief Determine if the subgraph variable can act as a switch variable for the given BRANCHIND
|
||||
///
|
||||
/// We query the JumpTable associated with the BRANCHIND to see if its switch variable
|
||||
/// can be trimmed as indicated by the logical flow.
|
||||
/// \param op is the given BRANCHIND op
|
||||
/// \param rvn is the subgraph variable flowing to the BRANCHIND
|
||||
/// \return \b true if the switch variable can be successfully trimmed to its logical size
|
||||
bool SubvariableFlow::trySwitchPull(PcodeOp *op,ReplaceVarnode *rvn)
|
||||
|
||||
{
|
||||
if ((rvn->mask & 1) == 0) return false; // Logical value must be justified
|
||||
if ((rvn->vn->getConsume()&~rvn->mask)!=0) // If there's something outside the mask being consumed
|
||||
return false; // we can't trim
|
||||
patchlist.push_back(PatchRecord());
|
||||
patchlist.back().type = 2;
|
||||
patchlist.back().pullop = op;
|
||||
patchlist.back().in1 = rvn;
|
||||
patchlist.back().slot = 0;
|
||||
pullcount += 1; // A true terminal modification
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Try to trace the logical variable through descendant Varnodes
|
||||
/// creating new nodes in the logical subgraph and updating the worklist.
|
||||
/// \param rvn is the given subgraph variable to trace
|
||||
|
@ -573,6 +595,10 @@ bool SubvariableFlow::traceForward(ReplaceVarnode *rvn)
|
|||
if (!tryReturnPull(op,rvn,slot)) return false;
|
||||
hcount += 1;
|
||||
break;
|
||||
case CPUI_BRANCHIND:
|
||||
if (!trySwitchPull(op, rvn)) return false;
|
||||
hcount += 1;
|
||||
break;
|
||||
case CPUI_BOOL_NEGATE:
|
||||
case CPUI_BOOL_AND:
|
||||
case CPUI_BOOL_OR:
|
||||
|
@ -850,6 +876,10 @@ bool SubvariableFlow::traceForwardSext(ReplaceVarnode *rvn)
|
|||
if (!tryReturnPull(op,rvn,slot)) return false;
|
||||
hcount += 1;
|
||||
break;
|
||||
case CPUI_BRANCHIND:
|
||||
if (!trySwitchPull(op,rvn)) return false;
|
||||
hcount += 1;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -1331,7 +1361,7 @@ void SubvariableFlow::doReplacement(void)
|
|||
fd->opSetInput(pullop,getReplaceVarnode((*piter).in1),0);
|
||||
fd->opSetInput(pullop,getReplaceVarnode((*piter).in2),1);
|
||||
}
|
||||
else if (type == 2) { // A call parameter or return value
|
||||
else if (type == 2) { // A call parameter, return value, or switch variable
|
||||
fd->opSetInput(pullop,getReplaceVarnode((*piter).in1),(*piter).slot);
|
||||
}
|
||||
else if (type == 3) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue