mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GP-3014 - Add deduping to DynamicHash gatherFirstLevelVars
This commit is contained in:
parent
f1dc157f04
commit
4b2a78b1fb
3 changed files with 46 additions and 9 deletions
|
@ -364,7 +364,7 @@ void DynamicHash::pieceTogetherHash(const Varnode *root,uint4 method)
|
|||
hash <<= 4;
|
||||
hash |= method; // 4-bits
|
||||
hash <<= 7;
|
||||
hash |= (uint8)op->code(); // 7-bits
|
||||
hash |= (uint8)transtable[op->code()]; // 7-bits
|
||||
hash <<= 5;
|
||||
hash |= (uint8)(slot & 0x1f); // 5-bits
|
||||
|
||||
|
@ -607,6 +607,25 @@ PcodeOp *DynamicHash::findOp(const Funcdata *fd,const Address &addr,uint8 h)
|
|||
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
|
||||
///
|
||||
/// 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)
|
||||
|
||||
{
|
||||
OpCode opc = getOpCodeFromHash(h);
|
||||
uint4 opcVal = getOpCodeFromHash(h);
|
||||
int4 slot = getSlotFromHash(h);
|
||||
bool isnotattached = getIsNotAttached(h);
|
||||
PcodeOpTree::const_iterator iter = fd->beginOp(addr);
|
||||
|
@ -629,7 +648,7 @@ void DynamicHash::gatherFirstLevelVars(vector<Varnode *> &varlist,const Funcdata
|
|||
PcodeOp *op = (*iter).second;
|
||||
++iter;
|
||||
if (op->isDead()) continue;
|
||||
if (op->code() != opc) continue;
|
||||
if (transtable[op->code()] != opcVal) continue;
|
||||
if (slot <0) {
|
||||
Varnode *vn = op->getOut();
|
||||
if (vn != (Varnode *)0) {
|
||||
|
@ -655,6 +674,7 @@ void DynamicHash::gatherFirstLevelVars(vector<Varnode *> &varlist,const Funcdata
|
|||
varlist.push_back(vn);
|
||||
}
|
||||
}
|
||||
dedupVarnodes(varlist);
|
||||
}
|
||||
|
||||
/// \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
|
||||
/// \param h is the hash value
|
||||
/// \return the op-code
|
||||
OpCode DynamicHash::getOpCodeFromHash(uint8 h)
|
||||
/// \return the op-code as an integer
|
||||
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
|
||||
|
|
|
@ -77,6 +77,7 @@ class DynamicHash {
|
|||
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
|
||||
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:
|
||||
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
|
||||
|
@ -92,7 +93,7 @@ public:
|
|||
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 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 getTotalFromHash(uint8 h); ///< Retrieve the encoded collision total from a hash
|
||||
static bool getIsNotAttached(uint8 h); ///< Retrieve the attachment boolean from a hash
|
||||
|
|
|
@ -415,7 +415,7 @@ public class DynamicHash {
|
|||
hash <<= 4;
|
||||
hash |= method; // 4-bits
|
||||
hash <<= 7;
|
||||
hash |= op.getOpcode(); // 7-bits
|
||||
hash |= transtable[op.getOpcode()]; // 7-bits
|
||||
hash <<= 5;
|
||||
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,
|
||||
Address addr, long h) {
|
||||
int opc = getOpCodeFromHash(h);
|
||||
|
@ -714,7 +729,7 @@ public class DynamicHash {
|
|||
|
||||
while (iter.hasNext()) {
|
||||
PcodeOp op = iter.next();
|
||||
if (op.getOpcode() != opc) {
|
||||
if (transtable[op.getOpcode()] != opc) {
|
||||
continue;
|
||||
}
|
||||
if (slot < 0) {
|
||||
|
@ -745,6 +760,7 @@ public class DynamicHash {
|
|||
varlist.add(vn);
|
||||
}
|
||||
}
|
||||
dedupVarnodes(varlist);
|
||||
}
|
||||
|
||||
public static int getSlotFromHash(long h) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue