GP-3941 New boolean correlation test

This commit is contained in:
caheckman 2024-01-05 22:44:44 +00:00
parent ad532036ab
commit 8f3328856c
2 changed files with 137 additions and 323 deletions

View file

@ -27,41 +27,24 @@ namespace ghidra {
/// This class determines if two CBRANCHs share the same condition. It also determines if the conditions
/// are complements of each other, and/or they are shared along only one path.
///
/// The expression computing the root boolean value for one CBRANCH is marked out
/// by setupInitOp(). For the other CBRANCH, findMatch() tries to find common Varnode
/// in its boolean expression and then maps a critical path from the Varnode to the final boolean.
/// Assuming the common Varnode exists, the method finalJudgement() decides if the two boolean values
/// are the same, uncorrelated, or complements of one another.
class ConditionMarker {
PcodeOp *initop; ///< The root CBRANCH operation to compare against
Varnode *basevn; ///< The boolean Varnode on which the root CBRANCH keys
Varnode *boolvn; ///< If \b basevn is defined by BOOL_NEGATE, this is the unnegated Varnode
Varnode *bool2vn; ///< If the first param to \b binaryop is defined by BOOL_NEGATE, this is the unnegated Varnode
Varnode *bool3vn; ///< If the second param to \b binaryop is defined by BOOL_NEGATE, this is the unnegated Varnode
PcodeOp *binaryop; ///< The binary operator producing the root boolean (if non-null)
/// Traverse (upto a specific depth) the two boolean expressions consisting of BOOL_AND, BOOL_OR, and
/// BOOL_XOR operations. Leaf operators in the expression can be other operators with boolean output (INT_LESS,
/// INT_SLESS, etc.).
class BooleanExpressionMatch {
enum {
same = 1, ///< Pair always hold the same value
complementary = 2, ///< Pair always hold complementary values
uncorrelated = 3 ///< Pair values are uncorrelated
};
static const int4 maxDepth; ///< Maximum depth to trace a boolean expression
bool matchflip; ///< True if the compared CBRANCH keys on the opposite boolean value of the root
int4 state; ///< Depth of critical path
PcodeOp *opstate[2]; ///< p-code operations along the critical path
bool flipstate[2]; ///< Boolean negation along the critical path
int4 slotstate[2]; ///< Input Varnode to follow to stay on critical path
bool multion; ///< True if MULTIEQUAL used in condition
bool binon; ///< True if a binary operator is used in condition
int4 multislot; ///< Input slot of MULTIEQUAL on critical path, -1 if no MULTIEQUAL
void setupInitOp(PcodeOp *op); ///< Map out the root boolean expression
Varnode *findMatch(PcodeOp *op); ///< Find a matching Varnode in the root expression producing the given CBRANCH boolean
bool sameOpComplement(PcodeOp *bin1op, PcodeOp *bin2op);
bool andOrComplement(PcodeOp *bin1op, PcodeOp *bin2op);
bool finalJudgement(Varnode *vn);
public:
ConditionMarker(void); ///< Constructor
~ConditionMarker(void); ///< Destructor
bool verifyCondition(PcodeOp *op, PcodeOp *iop); ///< Perform the correlation test on two CBRANCH operations
int4 getMultiSlot(void) const { return multislot; } ///< Get the MULTIEQUAL slot in the critical path
bool getFlip(void) const { return matchflip; } ///< Return \b true is the expressions are anti-correlated
static bool sameOpComplement(PcodeOp *bin1op, PcodeOp *bin2op);
static bool varnodeSame(Varnode *a,Varnode *b);
static bool varnodeComplement(Varnode *a,Varnode *b);
static int4 evaluate(Varnode *vn1,Varnode *vn2,int4 depth);
public:
bool verifyCondition(PcodeOp *op, PcodeOp *iop); ///< Perform the correlation test on two CBRANCH operations
int4 getMultiSlot(void) const { return -1; } ///< Get the MULTIEQUAL slot in the critical path
bool getFlip(void) const { return matchflip; } ///< Return \b true if the expressions are anti-correlated
};
/// \brief A class for simplifying a series of conditionally executed statements.