From 42cb99079d4ff0a5aa49e7730bb73500d13f35dd Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Mon, 13 Mar 2017 23:03:41 -0400 Subject: Branch dependence APIs for path sensitive analysis --- binaryninjaapi.h | 3 +++ binaryninjacore.h | 19 +++++++++++++++++++ mediumlevelil.cpp | 20 ++++++++++++++++++++ python/mediumlevelil.py | 19 ++++++++++++++++++- 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/binaryninjaapi.h b/binaryninjaapi.h index ee342851..fb735a9d 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2270,6 +2270,9 @@ namespace BinaryNinja size_t GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const; size_t GetSSAMemoryIndexAtInstruction(size_t instr) const; + BNILBranchDependence GetBranchDependenceAtInstruction(size_t curInstr, size_t branchInstr) const; + std::map GetAllBranchDependenceAtInstruction(size_t instr) const; + Ref GetLowLevelIL() const; size_t GetLowLevelILInstructionIndex(size_t instr) const; size_t GetLowLevelILExprIndex(size_t expr) const; diff --git a/binaryninjacore.h b/binaryninjacore.h index 66d5f010..7cc8b200 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1379,6 +1379,19 @@ extern "C" BNType* type; }; + enum BNILBranchDependence + { + NotBranchDependent, + TrueBranchDependent, + FalseBranchDependent + }; + + struct BNILBranchInstructionAndDependence + { + size_t branch; + BNILBranchDependence dependence; + }; + BINARYNINJACOREAPI char* BNAllocString(const char* contents); BINARYNINJACOREAPI void BNFreeString(char* str); BINARYNINJACOREAPI void BNFreeStringList(char** strs, size_t count); @@ -2242,6 +2255,12 @@ extern "C" BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAMemoryIndexAtILInstruction(BNMediumLevelILFunction* func, size_t instr); + BINARYNINJACOREAPI BNILBranchDependence BNGetMediumLevelILBranchDependence(BNMediumLevelILFunction* func, + size_t curInstr, size_t branchInstr); + BINARYNINJACOREAPI BNILBranchInstructionAndDependence* BNGetAllMediumLevelILBranchDependence( + BNMediumLevelILFunction* func, size_t instr, size_t* count); + BINARYNINJACOREAPI void BNFreeILBranchDependenceList(BNILBranchInstructionAndDependence* branches); + BINARYNINJACOREAPI BNLowLevelILFunction* BNGetLowLevelILForMediumLevelIL(BNMediumLevelILFunction* func); BINARYNINJACOREAPI size_t BNGetLowLevelILInstructionIndex(BNMediumLevelILFunction* func, size_t instr); BINARYNINJACOREAPI size_t BNGetLowLevelILExprIndex(BNMediumLevelILFunction* func, size_t expr); diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index 04b1cffd..dcd1fe8e 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -456,6 +456,26 @@ size_t MediumLevelILFunction::GetSSAMemoryIndexAtInstruction(size_t instr) const } +BNILBranchDependence MediumLevelILFunction::GetBranchDependenceAtInstruction(size_t curInstr, size_t branchInstr) const +{ + return BNGetMediumLevelILBranchDependence(m_object, curInstr, branchInstr); +} + + +map MediumLevelILFunction::GetAllBranchDependenceAtInstruction(size_t instr) const +{ + size_t count; + BNILBranchInstructionAndDependence* deps = BNGetAllMediumLevelILBranchDependence(m_object, instr, &count); + + map result; + for (size_t i = 0; i < count; i++) + result[deps[i].branch] = deps[i].dependence; + + BNFreeILBranchDependenceList(deps); + return result; +} + + Ref MediumLevelILFunction::GetLowLevelIL() const { BNLowLevelILFunction* func = BNGetLowLevelILForMediumLevelIL(m_object); diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 00d7215f..8830e738 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -22,7 +22,7 @@ import ctypes # Binary Ninja components import _binaryninjacore as core -from .enums import MediumLevelILOperation, InstructionTextTokenType, ILVariableSourceType +from .enums import MediumLevelILOperation, InstructionTextTokenType, ILVariableSourceType, ILBranchDependence import function import basicblock import lowlevelil @@ -259,6 +259,11 @@ class MediumLevelILInstruction(object): core.BNFreeRegisterValue(value) return result + @property + def branch_dependence(self): + """Set of branching instructions that must take the true or false path to reach this instruction""" + return self.function.get_all_branch_dependence_at_instruction(self.instr_index) + @property def low_level_il(self): """Low level IL form of this expression""" @@ -567,6 +572,18 @@ class MediumLevelILFunction(object): def get_ssa_memory_index_at_instruction(self, instr): return core.BNGetMediumLevelILSSAMemoryIndexAtILInstruction(self.handle, instr) + def get_branch_dependence_at_instruction(self, cur_instr, branch_instr): + return ILBranchDependence(core.BNGetMediumLevelILBranchDependence(self.handle, cur_instr, branch_instr)) + + def get_all_branch_dependence_at_instruction(self, instr): + count = ctypes.c_ulonglong() + deps = core.BNGetAllMediumLevelILBranchDependence(self.handle, instr, count) + result = {} + for i in xrange(0, count.value): + result[deps[i].branch] = ILBranchDependence(deps[i].dependence) + core.BNFreeILBranchDependenceList(deps) + return result + def get_low_level_il_instruction_index(self, instr): low_il = self.low_level_il if low_il is None: -- cgit v1.3.1