diff --git a/libIRDB/include/util/IBT_Provenance.hpp b/libIRDB/include/util/IBT_Provenance.hpp index 7969904380357052caa648b645e694d60c4d1a54..8467faa543e999385d68db412ad565f71514fbca 100644 --- a/libIRDB/include/util/IBT_Provenance.hpp +++ b/libIRDB/include/util/IBT_Provenance.hpp @@ -6,41 +6,34 @@ class IBTProvenance_t { private: - typedef std::map<const Instruction_t*, Provenance_t> ProvMap_t; + + // types + using InsnProvMap_t = std::map<const Instruction_t*, Provenance_t>; + using ICFSProvMap_t = std::map<const ICFS_t*, Provenance_t>; + + // data + InsnProvMap_t prov_map; + static Provenance_t empty; + + // methods + void Init() {}; + void AddProvs(const Provenance_t& p, const InstructionSet_t& after) ; public: IBTProvenance_t(const FileIR_t* f=NULL) {Init(); if(f) AddFile(f);} - virtual ~IBTProvenance_t() {;} - virtual void AddFile(const FileIR_t* ); + virtual ~IBTProvenance_t() {} // default destructor not OK for some reason? + void AddFile(const FileIR_t* ); - /*Provenance_t getProvenance(const Instruction_t* insn) const - { - return ((ProvMap_t) prov_map)[insn]; - }*/ - - Provenance_t& operator[] (const Instruction_t* i) - { - return prov_map[i]; - } const Provenance_t& operator[] (const Instruction_t* i) const { - ProvMap_t::const_iterator it=prov_map.find(i); + const auto it=prov_map.find(i); if (it!= prov_map.end()) return it->second; - static Provenance_t empty; return empty; } - protected: - virtual void Init() {}; - - private: - - virtual void AddProvs(const Instruction_t* before, const InstructionSet_t& after); - - ProvMap_t prov_map; }; #endif diff --git a/libIRDB/include/util/Provenance.hpp b/libIRDB/include/util/Provenance.hpp index c3d205055be6be4c9262f9c3d2d559861511b9f3..73a14041a09d185cf973c8d43e5a4d47bfe5ef5d 100644 --- a/libIRDB/include/util/Provenance.hpp +++ b/libIRDB/include/util/Provenance.hpp @@ -28,10 +28,16 @@ class Provenance_t prov.set((size_t) ProvType::IndCall); } + void addProv(const Provenance_t& other) + { + prov |= other.prov; + } + bool hasReturn() const { return prov.test((size_t) ProvType::Ret); } + bool hasIndirectJump() const { diff --git a/libIRDB/src/util/IBT_Provenance.cpp b/libIRDB/src/util/IBT_Provenance.cpp index 429455f1d766abb574e5cae4bc84a79cfb0c87b1..9956da0bd03697c51417395a5ad79f3ba4ef9a41 100644 --- a/libIRDB/src/util/IBT_Provenance.cpp +++ b/libIRDB/src/util/IBT_Provenance.cpp @@ -8,47 +8,57 @@ using namespace libIRDB; using namespace std; +Provenance_t IBTProvenance_t::empty; -void IBTProvenance_t::AddProvs(const Instruction_t* before, const InstructionSet_t& afterset) + +void IBTProvenance_t::AddFile(const FileIR_t* firp) { - // Determine type of IB - const auto IndBranchAsm=DecodedInstruction_t(before); - - bool isIndJmp = IndBranchAsm.isUnconditionalBranch() && !IndBranchAsm.getOperand(0).isConstant(); - bool isIndCall = IndBranchAsm.isCall() && !IndBranchAsm.getOperand(0).isConstant(); - bool isRet = IndBranchAsm.isReturn(); - - // Set the provenance info of targets depending on the type of IB - for(auto insn : afterset) + + using ICFSProvMap_t = std::map<const ICFS_t*, Provenance_t>; + + auto icfs_prov_map = ICFSProvMap_t(); + + // collect before info for each icfs into icfs_prov_map + for(auto insn : firp->GetInstructions()) { + const auto &ibTargets=insn->GetIBTargets(); + if(!ibTargets) + continue; + + auto this_prov=Provenance_t(); + const auto IndBranchAsm=DecodedInstruction_t(insn); + const auto isIndJmp = IndBranchAsm.isUnconditionalBranch() && !IndBranchAsm.getOperand(0).isConstant(); + const auto isIndCall = IndBranchAsm.isCall() && !IndBranchAsm.getOperand(0).isConstant(); + const auto isRet = IndBranchAsm.isReturn(); + if(isIndJmp) { - prov_map[insn].addIndirectJump(); + this_prov.addIndirectJump(); } else if(isIndCall) { - prov_map[insn].addIndirectCall(); + this_prov.addIndirectCall(); } else if(isRet) { - prov_map[insn].addReturn(); + this_prov.addReturn(); } else { assert(0); } + + icfs_prov_map[ibTargets].addProv(this_prov); } -} -void IBTProvenance_t::AddFile(const FileIR_t* firp2) -{ - FileIR_t* firp=(FileIR_t*)firp2; // discarding const qualifier because we know we won't change the set - firp->AssembleRegistry(); // Takes time but I'm paranoid - for(auto insn : firp->GetInstructions()) + // deploy info for each target of the icfs + for(const auto &icfs : firp->GetAllICFS()) { - // If insn is an IB, add the type of IB to the targets' provenance info - if(insn->GetIBTargets()) - AddProvs(insn, *insn->GetIBTargets()); + assert(icfs); + for(const auto &insn : *icfs) + { + prov_map[insn].addProv(icfs_prov_map[icfs]); + } } }