Merge remote-tracking branch 'origin/patch'

This commit is contained in:
Ryan Kurtz 2023-01-13 12:32:34 -05:00
commit 539d5b2aad
4 changed files with 50 additions and 12 deletions

View file

@ -364,7 +364,7 @@ void DynamicHash::pieceTogetherHash(const Varnode *root,uint4 method)
hash <<= 4; hash <<= 4;
hash |= method; // 4-bits hash |= method; // 4-bits
hash <<= 7; hash <<= 7;
hash |= (uint8)op->code(); // 7-bits hash |= (uint8)transtable[op->code()]; // 7-bits
hash <<= 5; hash <<= 5;
hash |= (uint8)(slot & 0x1f); // 5-bits hash |= (uint8)(slot & 0x1f); // 5-bits
@ -607,6 +607,25 @@ PcodeOp *DynamicHash::findOp(const Funcdata *fd,const Address &addr,uint8 h)
return oplist2[pos]; return oplist2[pos];
} }
/// Otherwise preserve the order of the list.
/// \param varlist is the given list of Varnodes to check
void DynamicHash::dedupVarnodes(vector<Varnode *> &varlist)
{
if (varlist.size() < 2) return;
vector<Varnode *> resList;
for(int4 i=0;i<varlist.size();++i) {
Varnode *vn = varlist[i];
if (!vn->isMark()) {
vn->setMark();
resList.push_back(vn);
}
}
for(int4 i=0;i<resList.size();++i)
resList[i]->clearMark();
varlist.swap(resList);
}
/// \brief Get the Varnodes immediately attached to PcodeOps at the given address /// \brief Get the Varnodes immediately attached to PcodeOps at the given address
/// ///
/// Varnodes can be either inputs or outputs to the PcodeOps. The op-code, slot, and /// Varnodes can be either inputs or outputs to the PcodeOps. The op-code, slot, and
@ -619,7 +638,7 @@ PcodeOp *DynamicHash::findOp(const Funcdata *fd,const Address &addr,uint8 h)
void DynamicHash::gatherFirstLevelVars(vector<Varnode *> &varlist,const Funcdata *fd,const Address &addr,uint8 h) void DynamicHash::gatherFirstLevelVars(vector<Varnode *> &varlist,const Funcdata *fd,const Address &addr,uint8 h)
{ {
OpCode opc = getOpCodeFromHash(h); uint4 opcVal = getOpCodeFromHash(h);
int4 slot = getSlotFromHash(h); int4 slot = getSlotFromHash(h);
bool isnotattached = getIsNotAttached(h); bool isnotattached = getIsNotAttached(h);
PcodeOpTree::const_iterator iter = fd->beginOp(addr); PcodeOpTree::const_iterator iter = fd->beginOp(addr);
@ -629,7 +648,7 @@ void DynamicHash::gatherFirstLevelVars(vector<Varnode *> &varlist,const Funcdata
PcodeOp *op = (*iter).second; PcodeOp *op = (*iter).second;
++iter; ++iter;
if (op->isDead()) continue; if (op->isDead()) continue;
if (op->code() != opc) continue; if (transtable[op->code()] != opcVal) continue;
if (slot <0) { if (slot <0) {
Varnode *vn = op->getOut(); Varnode *vn = op->getOut();
if (vn != (Varnode *)0) { if (vn != (Varnode *)0) {
@ -655,6 +674,7 @@ void DynamicHash::gatherFirstLevelVars(vector<Varnode *> &varlist,const Funcdata
varlist.push_back(vn); varlist.push_back(vn);
} }
} }
dedupVarnodes(varlist);
} }
/// \brief Place all PcodeOps at the given address in the provided container /// \brief Place all PcodeOps at the given address in the provided container
@ -697,11 +717,11 @@ uint4 DynamicHash::getMethodFromHash(uint8 h)
/// The hash encodes the op-code of the p-code op attached to the root Varnode /// The hash encodes the op-code of the p-code op attached to the root Varnode
/// \param h is the hash value /// \param h is the hash value
/// \return the op-code /// \return the op-code as an integer
OpCode DynamicHash::getOpCodeFromHash(uint8 h) uint4 DynamicHash::getOpCodeFromHash(uint8 h)
{ {
return (OpCode)((h>>37)&0x7f); return (h>>37)&0x7f;
} }
/// The hash encodes the position of the root Varnode within the list of hash collisions /// The hash encodes the position of the root Varnode within the list of hash collisions

View file

@ -77,6 +77,7 @@ class DynamicHash {
void gatherUnmarkedOp(void); ///< Mark any new PcodeOps in the sub-graph void gatherUnmarkedOp(void); ///< Mark any new PcodeOps in the sub-graph
void pieceTogetherHash(const Varnode *root,uint4 method); ///< Clean-up and piece together formal hash value void pieceTogetherHash(const Varnode *root,uint4 method); ///< Clean-up and piece together formal hash value
static void moveOffSkip(const PcodeOp *&op,int4 &slot); ///< Convert given PcodeOp to a non-skip op by following data-flow static void moveOffSkip(const PcodeOp *&op,int4 &slot); ///< Convert given PcodeOp to a non-skip op by following data-flow
static void dedupVarnodes(vector<Varnode *> &varlist); ///< Remove any duplicate Varnodes in given list
public: public:
void clear(void); ///< Called for each additional hash (after the first) void clear(void); ///< Called for each additional hash (after the first)
void calcHash(const Varnode *root,uint4 method); ///< Calculate the hash for given Varnode and method void calcHash(const Varnode *root,uint4 method); ///< Calculate the hash for given Varnode and method
@ -92,7 +93,7 @@ public:
static void gatherOpsAtAddress(vector<PcodeOp *> &opList,const Funcdata *fd,const Address &addr); static void gatherOpsAtAddress(vector<PcodeOp *> &opList,const Funcdata *fd,const Address &addr);
static int4 getSlotFromHash(uint8 h); ///< Retrieve the encoded slot from a hash static int4 getSlotFromHash(uint8 h); ///< Retrieve the encoded slot from a hash
static uint4 getMethodFromHash(uint8 h); ///< Retrieve the encoded method from a hash static uint4 getMethodFromHash(uint8 h); ///< Retrieve the encoded method from a hash
static OpCode getOpCodeFromHash(uint8 h); ///< Retrieve the encoded op-code from a hash static uint4 getOpCodeFromHash(uint8 h); ///< Retrieve the encoded op-code from a hash
static uint4 getPositionFromHash(uint8 h); ///< Retrieve the encoded position from a hash static uint4 getPositionFromHash(uint8 h); ///< Retrieve the encoded position from a hash
static uint4 getTotalFromHash(uint8 h); ///< Retrieve the encoded collision total from a hash static uint4 getTotalFromHash(uint8 h); ///< Retrieve the encoded collision total from a hash
static bool getIsNotAttached(uint8 h); ///< Retrieve the attachment boolean from a hash static bool getIsNotAttached(uint8 h); ///< Retrieve the attachment boolean from a hash

View file

@ -570,10 +570,11 @@ bool Funcdata::earlyJumpTableFail(PcodeOp *op)
OpCode opc = op->code(); OpCode opc = op->code();
if (opc == CPUI_CALLOTHER) { if (opc == CPUI_CALLOTHER) {
int4 id = (int4)op->getIn(0)->getOffset(); int4 id = (int4)op->getIn(0)->getOffset();
InjectedUserOp *userOp = dynamic_cast<InjectedUserOp *>(glb->userops.getOp(id)); UserPcodeOp *userOp = glb->userops.getOp(id);
if (userOp != (InjectedUserOp *)0) { if (dynamic_cast<InjectedUserOp *>(userOp) != (InjectedUserOp *)0)
return false; // Don't try to back track through injection return false; // Don't try to back track through injection
} if (dynamic_cast<JumpAssistOp *>(userOp) != (JumpAssistOp *)0)
return false;
if (outhit) if (outhit)
return true; // Address formed via uninjected CALLOTHER, analysis will fail return true; // Address formed via uninjected CALLOTHER, analysis will fail
// Assume CALLOTHER will not interfere with address and continue backtracking // Assume CALLOTHER will not interfere with address and continue backtracking

View file

@ -415,7 +415,7 @@ public class DynamicHash {
hash <<= 4; hash <<= 4;
hash |= method; // 4-bits hash |= method; // 4-bits
hash <<= 7; hash <<= 7;
hash |= op.getOpcode(); // 7-bits hash |= transtable[op.getOpcode()]; // 7-bits
hash <<= 5; hash <<= 5;
hash |= slot & 0x1f; // 5-bits hash |= slot & 0x1f; // 5-bits
@ -705,6 +705,21 @@ public class DynamicHash {
} }
} }
private static void dedupVarnodes(ArrayList<Varnode> varlist) {
if (varlist.size() < 2) {
return;
}
ArrayList<Varnode> resList = new ArrayList<>();
HashSet<Varnode> hashSet = new HashSet<>();
for (Varnode vn : varlist) {
if (hashSet.add(vn)) {
resList.add(vn);
}
}
varlist.clear();
varlist.addAll(resList);
}
public static void gatherFirstLevelVars(ArrayList<Varnode> varlist, PcodeSyntaxTree fd, public static void gatherFirstLevelVars(ArrayList<Varnode> varlist, PcodeSyntaxTree fd,
Address addr, long h) { Address addr, long h) {
int opc = getOpCodeFromHash(h); int opc = getOpCodeFromHash(h);
@ -714,7 +729,7 @@ public class DynamicHash {
while (iter.hasNext()) { while (iter.hasNext()) {
PcodeOp op = iter.next(); PcodeOp op = iter.next();
if (op.getOpcode() != opc) { if (transtable[op.getOpcode()] != opc) {
continue; continue;
} }
if (slot < 0) { if (slot < 0) {
@ -745,6 +760,7 @@ public class DynamicHash {
varlist.add(vn); varlist.add(vn);
} }
} }
dedupVarnodes(varlist);
} }
public static int getSlotFromHash(long h) { public static int getSlotFromHash(long h) {