mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
commit
4172e448dd
4 changed files with 42 additions and 13 deletions
|
@ -2169,8 +2169,19 @@ int4 ActionLikelyTrash::apply(Funcdata &data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/// \param vn is the given Varnode
|
||||
/// \return \b true if it is a constant or a COPY of a constant
|
||||
bool ActionRestructureVarnode::isCopyConstant(Varnode *vn)
|
||||
|
||||
{
|
||||
if (vn->isConstant()) return true;
|
||||
if (!vn->isWritten()) return false;
|
||||
if (vn->getDef()->code() != CPUI_COPY) return false;
|
||||
return vn->getDef()->getIn(0)->isConstant();
|
||||
}
|
||||
|
||||
/// Return \b true if either the Varnode is a constant or if it is the not yet simplified
|
||||
/// INT_ADD of constants.
|
||||
/// COPY or 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)
|
||||
|
@ -2179,14 +2190,13 @@ 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();
|
||||
OpCode opc = op->code();
|
||||
if (opc == CPUI_COPY)
|
||||
return op->getIn(0)->isConstant();
|
||||
if (opc != CPUI_INT_ADD) return false;
|
||||
if (!isCopyConstant(op->getIn(1))) return false;
|
||||
if (!isCopyConstant(op->getIn(0))) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Test if the path to the given BRANCHIND originates from a constant but passes through INDIRECT operations.
|
||||
|
@ -5374,7 +5384,7 @@ void ActionDatabase::buildDefaultGroups(void)
|
|||
setGroup("decompile",members);
|
||||
|
||||
const char *jumptab[] = { "base", "noproto", "localrecovery", "deadcode", "stackptrflow",
|
||||
"stackvars", "analysis", "segment", "subvar", "conditionalexe", "" };
|
||||
"stackvars", "analysis", "segment", "subvar", "normalizebranches", "conditionalexe", "" };
|
||||
setGroup("jumptable",jumptab);
|
||||
|
||||
const char *normali[] = { "base", "protorecovery", "protorecovery_b", "deindirect", "localrecovery",
|
||||
|
|
|
@ -831,6 +831,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 isCopyConstant(Varnode *vn); ///< Is the given Varnode a constant or a COPY of a constant
|
||||
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
|
||||
|
|
|
@ -1284,6 +1284,18 @@ bool JumpBasic::flowsOnlyToModel(Varnode *vn,PcodeOp *trailOp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/// \param arr is the array of Varnodes
|
||||
/// \return \b true if all elements are the same
|
||||
bool JumpBasic::duplicateVarnodes(const vector<Varnode *> &arr)
|
||||
|
||||
{
|
||||
Varnode *vn = arr[0];
|
||||
for(int4 i=1;i<arr.size();++i) {
|
||||
if (arr[i] != vn) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// All CBRANCHs in addition to flowing to the given block, must also flow to another common block,
|
||||
/// and each boolean value must select between the given block and the common block in the same way.
|
||||
/// If this flow exists, \b true is returned and the boolean Varnode inputs to each CBRANCH are passed back.
|
||||
|
@ -1338,9 +1350,14 @@ void JumpBasic::checkUnrolledGuard(BlockBasic *bl,int4 maxpullback,bool usenzmas
|
|||
int4 indpathstore = bl->getIn(0)->getFlipPath() ? 1-indpath : indpath;
|
||||
PcodeOp *readOp = cbranch;
|
||||
for(int4 j=0;j<maxpullback;++j) {
|
||||
PcodeOp *multiOp = bl->findMultiequal(varArray);
|
||||
if (multiOp != (PcodeOp *)0) {
|
||||
selectguards.push_back(GuardRecord(cbranch,readOp,indpathstore,rng,multiOp->getOut(),true));
|
||||
if (duplicateVarnodes(varArray)) {
|
||||
selectguards.push_back(GuardRecord(cbranch,readOp,indpathstore,rng,varArray[0],true));
|
||||
}
|
||||
else {
|
||||
PcodeOp *multiOp = bl->findMultiequal(varArray);
|
||||
if (multiOp != (PcodeOp *)0) {
|
||||
selectguards.push_back(GuardRecord(cbranch,readOp,indpathstore,rng,multiOp->getOut(),true));
|
||||
}
|
||||
}
|
||||
Varnode *markup; // Throw away markup information
|
||||
Varnode *vn = varArray[0];
|
||||
|
|
|
@ -382,6 +382,7 @@ protected:
|
|||
static int4 getStride(Varnode *vn); ///< Get the step/stride associated with the Varnode
|
||||
static uintb backup2Switch(Funcdata *fd,uintb output,Varnode *outvn,Varnode *invn);
|
||||
static uintb getMaxValue(Varnode *vn); ///< Get maximum value associated with the given Varnode
|
||||
static bool duplicateVarnodes(const vector<Varnode *> &arr); ///< Return \b true if all array elements are the same Varnode
|
||||
void findDeterminingVarnodes(PcodeOp *op,int4 slot);
|
||||
void analyzeGuards(BlockBasic *bl,int4 pathout);
|
||||
void calcRange(Varnode *vn,CircleRange &rng) const;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue