summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binaryninjaapi.h1
-rw-r--r--binaryninjacore.h1
-rw-r--r--mediumlevelil.cpp14
-rw-r--r--python/highlevelil.py10
-rw-r--r--python/lowlevelil.py10
-rw-r--r--python/mediumlevelil.py19
-rw-r--r--suite/testcommon.py3
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()))))