diff options
| -rw-r--r-- | binaryninjaapi.h | 1 | ||||
| -rw-r--r-- | binaryninjacore.h | 1 | ||||
| -rw-r--r-- | mediumlevelil.cpp | 14 | ||||
| -rw-r--r-- | python/highlevelil.py | 10 | ||||
| -rw-r--r-- | python/lowlevelil.py | 10 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 19 | ||||
| -rw-r--r-- | suite/testcommon.py | 3 |
7 files changed, 55 insertions, 3 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index d0a3bbff..d7911b96 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -4113,6 +4113,7 @@ __attribute__ ((format (printf, 1, 2))) Ref<HighLevelILFunction> GetHighLevelIL() const; size_t GetHighLevelILInstructionIndex(size_t instr) const; size_t GetHighLevelILExprIndex(size_t expr) const; + std::set<size_t> GetHighLevelILExprIndexes(size_t expr) const; Confidence<Ref<Type>> GetExprType(size_t expr); Confidence<Ref<Type>> GetExprType(const MediumLevelILInstruction& expr); diff --git a/binaryninjacore.h b/binaryninjacore.h index 32f1c5b8..f28b6a0a 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -3992,6 +3992,7 @@ __attribute__ ((format (printf, 1, 2))) BINARYNINJACOREAPI BNHighLevelILFunction* BNGetHighLevelILForMediumLevelIL(BNMediumLevelILFunction* func); BINARYNINJACOREAPI size_t BNGetHighLevelILInstructionIndex(BNMediumLevelILFunction* func, size_t instr); BINARYNINJACOREAPI size_t BNGetHighLevelILExprIndex(BNMediumLevelILFunction* func, size_t expr); + BINARYNINJACOREAPI size_t* BNGetHighLevelILExprIndexes(BNMediumLevelILFunction* func, size_t expr, size_t* count); BINARYNINJACOREAPI BNTypeWithConfidence BNGetMediumLevelILExprType(BNMediumLevelILFunction* func, size_t expr); diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index 4e4c926a..e5d9c106 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -811,6 +811,20 @@ size_t MediumLevelILFunction::GetHighLevelILExprIndex(size_t expr) const } +set<size_t> MediumLevelILFunction::GetHighLevelILExprIndexes(size_t expr) const +{ + size_t count; + size_t* exprs = BNGetHighLevelILExprIndexes(m_object, expr, &count); + + set<size_t> result; + for (size_t i = 0; i < count; i++) + result.insert(exprs[i]); + + BNFreeILInstructionList(exprs); + return result; +} + + Confidence<Ref<Type>> MediumLevelILFunction::GetExprType(size_t expr) { BNTypeWithConfidence result = BNGetMediumLevelILExprType(m_object, expr); diff --git a/python/highlevelil.py b/python/highlevelil.py index 164be0e1..1dc8a077 100644 --- a/python/highlevelil.py +++ b/python/highlevelil.py @@ -531,7 +531,7 @@ class HighLevelILInstruction(object): @property def mlils(self): - exprs = self.function.get_medium_level_il_expr_indexes(self._expr_index) + exprs = self._function.get_medium_level_il_expr_indexes(self._expr_index) result = [] for expr in exprs: result.append(mediumlevelil.MediumLevelILInstruction(self._function.medium_level_il.ssa_form, expr)) @@ -550,6 +550,14 @@ class HighLevelILInstruction(object): return self.low_level_il @property + def llils(self): + result = set() + for mlil_expr in self.mlils: + for llil_expr in mlil_expr.llils: + result.add(llil_expr) + return list(result) + + @property def il_basic_block(self): """ IL basic block object containing this expression (read-only) (only available on finalized functions). diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 1ef13fa4..310d9d79 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -1017,7 +1017,7 @@ class LowLevelILInstruction(object): @property def mlils(self): - exprs = self.function.get_medium_level_il_expr_indexes(self.expr_index) + exprs = self._function.get_medium_level_il_expr_indexes(self.expr_index) result = [] for expr in exprs: result.append(binaryninja.mediumlevelil.MediumLevelILInstruction(self._function.medium_level_il, expr)) @@ -1047,6 +1047,14 @@ class LowLevelILInstruction(object): return self.high_level_il @property + def hlils(self): + result = set() + for mlil_expr in self.mlils: + for hlil_expr in mlil_expr.hlils: + result.add(hlil_expr) + return list(result) + + @property def value(self): """Value of expression if constant or a known value (read-only)""" value = core.BNGetLowLevelILExprValue(self._function.handle, self.expr_index) diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index ac11db96..65b90177 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -471,7 +471,7 @@ class MediumLevelILInstruction(object): @property def llils(self): - exprs = self.function.get_low_level_il_expr_indexes(self.expr_index) + exprs = self._function.get_low_level_il_expr_indexes(self.expr_index) result = [] for expr in exprs: result.append(lowlevelil.LowLevelILInstruction(self._function.low_level_il.ssa_form, expr)) @@ -491,6 +491,14 @@ class MediumLevelILInstruction(object): return self.high_level_il @property + def hlils(self): + exprs = self._function.get_high_level_il_expr_indexes(self.expr_index) + result = [] + for expr in exprs: + result.append(binaryninja.highlevelil.HighLevelILInstruction(self._function.high_level_il, expr)) + return result + + @property def ssa_memory_version(self): """Version of active memory contents in SSA form for this instruction""" return core.BNGetMediumLevelILSSAMemoryVersionAtILInstruction(self._function.handle, self._instr_index) @@ -1197,6 +1205,15 @@ class MediumLevelILFunction(object): return None return result + def get_high_level_il_expr_indexes(self, expr): + count = ctypes.c_ulonglong() + exprs = core.BNGetHighLevelILExprIndexes(self.handle, expr, count) + result = [] + for i in range(0, count.value): + result.append(exprs[i]) + core.BNFreeILInstructionList(exprs) + return result + def create_graph(self, settings = None): if settings is not None: settings_obj = settings.handle diff --git a/suite/testcommon.py b/suite/testcommon.py index 9ab24e7b..6763d8ae 100644 --- a/suite/testcommon.py +++ b/suite/testcommon.py @@ -195,6 +195,7 @@ class BinaryViewTestBuilder(Builder): retinfo.append("Function: {:x} Instruction: {:x} LLIL->MLIL: {}".format(func.start, ins.address, str(ins.mlil))) retinfo.append("Function: {:x} Instruction: {:x} LLIL->MLILS: {}".format(func.start, ins.address, str(sorted(list(map(str, ins.mlils)))))) retinfo.append("Function: {:x} Instruction: {:x} LLIL->HLIL: {}".format(func.start, ins.address, str(ins.hlil))) + retinfo.append("Function: {:x} Instruction: {:x} LLIL->HLILS: {}".format(func.start, ins.address, str(sorted(list(map(str, ins.hlils)))))) retinfo.append("Function: {:x} Instruction: {:x} Mapped MLIL: {}".format(func.start, ins.address, str(ins.mapped_medium_level_il))) retinfo.append("Function: {:x} Instruction: {:x} Value: {}".format(func.start, ins.address, str(ins.value))) retinfo.append("Function: {:x} Instruction: {:x} Possible Values: {}".format(func.start, ins.address, str(ins.possible_values))) @@ -249,6 +250,7 @@ class BinaryViewTestBuilder(Builder): retinfo.append("Function: {:x} Instruction: {:x} LLIL_SSA->MLIL: {}".format(func.source_function.start, ins.address, str(ins.mlil))) retinfo.append("Function: {:x} Instruction: {:x} LLIL_SSA->MLILS: {}".format(func.source_function.start, ins.address, str(sorted(list(map(str, ins.mlils)))))) retinfo.append("Function: {:x} Instruction: {:x} LLIL_SSA->HLIL: {}".format(func.source_function.start, ins.address, str(ins.hlil))) + retinfo.append("Function: {:x} Instruction: {:x} LLIL_SSA->HLILS: {}".format(func.source_function.start, ins.address, str(sorted(list(map(str, ins.hlils)))))) return fixOutput(retinfo) def test_med_il_instructions(self): @@ -261,6 +263,7 @@ class BinaryViewTestBuilder(Builder): retinfo.append("Function: {:x} Instruction: {:x} MLIL->LLIL: {}".format(func.start, ins.address, str(ins.llil))) retinfo.append("Function: {:x} Instruction: {:x} MLIL->LLILS: {}".format(func.start, ins.address, str(sorted(list(map(str, ins.llils)))))) retinfo.append("Function: {:x} Instruction: {:x} MLIL->HLIL: {}".format(func.start, ins.address, str(ins.hlil))) + retinfo.append("Function: {:x} Instruction: {:x} MLIL->HLILS: {}".format(func.start, ins.address, str(sorted(list(map(str, ins.hlils)))))) retinfo.append("Function: {:x} Instruction: {:x} Value: {}".format(func.start, ins.address, str(ins.value))) retinfo.append("Function: {:x} Instruction: {:x} Possible values: {}".format(func.start, ins.address, str(ins.possible_values))) retinfo.append("Function: {:x} Instruction: {:x} Branch dependence: {}".format(func.start, ins.address, str(sorted(ins.branch_dependence.items())))) |
