summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binaryninjaapi.h3
-rw-r--r--binaryninjacore.h4
-rw-r--r--mediumlevelil.cpp20
-rw-r--r--python/mediumlevelil.py28
4 files changed, 52 insertions, 3 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index fb735a9d..3f39c827 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -2241,6 +2241,7 @@ namespace BinaryNinja
BNMediumLevelILInstruction operator[](size_t i) const;
size_t GetIndexForInstruction(size_t i) const;
+ size_t GetInstructionForExpr(size_t expr) const;
size_t GetInstructionCount() const;
size_t GetExprCount() const;
@@ -2266,6 +2267,8 @@ namespace BinaryNinja
RegisterValue GetSSAVarValue(const BNILVariable& var, size_t idx);
RegisterValue GetExprValue(size_t expr);
+ RegisterValue GetPossibleSSAVarValues(const BNILVariable& var, size_t idx, size_t instr);
+ RegisterValue GetPossibleExprValues(size_t expr);
size_t GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const;
size_t GetSSAMemoryIndexAtInstruction(size_t instr) const;
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 7cc8b200..4905a73c 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -2221,6 +2221,7 @@ extern "C"
BINARYNINJACOREAPI BNMediumLevelILInstruction BNGetMediumLevelILByIndex(BNMediumLevelILFunction* func, size_t i);
BINARYNINJACOREAPI size_t BNGetMediumLevelILIndexForInstruction(BNMediumLevelILFunction* func, size_t i);
+ BINARYNINJACOREAPI size_t BNGetMediumLevelILInstructionForExpr(BNMediumLevelILFunction* func, size_t expr);
BINARYNINJACOREAPI size_t BNGetMediumLevelILInstructionCount(BNMediumLevelILFunction* func);
BINARYNINJACOREAPI size_t BNGetMediumLevelILExprCount(BNMediumLevelILFunction* func);
@@ -2249,6 +2250,9 @@ extern "C"
BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILSSAVarValue(BNMediumLevelILFunction* func,
const BNILVariable* var, size_t idx);
BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILExprValue(BNMediumLevelILFunction* func, size_t expr);
+ BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleSSAVarValues(BNMediumLevelILFunction* func,
+ const BNILVariable* var, size_t idx, size_t instr);
+ BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILPossibleExprValues(BNMediumLevelILFunction* func, size_t expr);
BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAVarIndexAtILInstruction(BNMediumLevelILFunction* func,
const BNILVariable* var, size_t instr);
diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp
index dcd1fe8e..51dd067d 100644
--- a/mediumlevelil.cpp
+++ b/mediumlevelil.cpp
@@ -262,6 +262,12 @@ size_t MediumLevelILFunction::GetIndexForInstruction(size_t i) const
}
+size_t MediumLevelILFunction::GetInstructionForExpr(size_t expr) const
+{
+ return BNGetMediumLevelILInstructionForExpr(m_object, expr);
+}
+
+
size_t MediumLevelILFunction::GetInstructionCount() const
{
return BNGetMediumLevelILInstructionCount(m_object);
@@ -444,6 +450,20 @@ RegisterValue MediumLevelILFunction::GetExprValue(size_t expr)
}
+RegisterValue MediumLevelILFunction::GetPossibleSSAVarValues(const BNILVariable& var, size_t idx, size_t instr)
+{
+ BNRegisterValue value = BNGetMediumLevelILPossibleSSAVarValues(m_object, &var, idx, instr);
+ return RegisterValue::FromAPIObject(value);
+}
+
+
+RegisterValue MediumLevelILFunction::GetPossibleExprValues(size_t expr)
+{
+ BNRegisterValue value = BNGetMediumLevelILPossibleExprValues(m_object, expr);
+ return RegisterValue::FromAPIObject(value);
+}
+
+
size_t MediumLevelILFunction::GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const
{
return BNGetMediumLevelILSSAVarIndexAtILInstruction(m_object, &var, instr);
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index 8830e738..a63e1b31 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -140,7 +140,10 @@ class MediumLevelILInstruction(object):
instr = core.BNGetMediumLevelILByIndex(func.handle, expr_index)
self.function = func
self.expr_index = expr_index
- self.instr_index = instr_index
+ if instr_index is None:
+ self.instr_index = core.BNGetMediumLevelILInstructionForExpr(func.handle, expr_index)
+ else:
+ self.instr_index = instr_index
self.operation = MediumLevelILOperation(instr.operation)
self.size = instr.size
self.address = instr.address
@@ -218,7 +221,8 @@ class MediumLevelILInstruction(object):
"""MLIL tokens (read-only)"""
count = ctypes.c_ulonglong()
tokens = ctypes.POINTER(core.BNInstructionTextToken)()
- if (self.instr_index is not None) and (self.function.source_function is not None):
+ if ((self.instr_index is not None) and (self.function.source_function is not None) and
+ (self.expr_index == core.BNGetMediumLevelILIndexForInstruction(self.function.handle, self.instr_index))):
if not core.BNGetMediumLevelILInstructionText(self.function.handle, self.function.source_function.handle,
self.function.arch.handle, self.instr_index, tokens, count):
return None
@@ -253,13 +257,21 @@ class MediumLevelILInstruction(object):
@property
def value(self):
- """Value of expression using static data flow analysis (read-only)"""
+ """Value of expression if constant or a known value (read-only)"""
value = core.BNGetMediumLevelILExprValue(self.function.handle, self.expr_index)
result = function.RegisterValue(self.function.arch, value)
core.BNFreeRegisterValue(value)
return result
@property
+ def possible_values(self):
+ """Possible values of expression using path-sensitive static data flow analysis (read-only)"""
+ value = core.BNGetMediumLevelILPossibleExprValues(self.function.handle, self.expr_index)
+ result = function.RegisterValue(self.function.arch, value)
+ 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)
@@ -272,6 +284,16 @@ class MediumLevelILInstruction(object):
return None
return lowlevelil.LowLevelILInstruction(self.function.low_level_il.ssa_form, expr)
+ def get_ssa_var_possible_values(self, var, index):
+ var_data = core.BNILVariable()
+ var_data.type = var.type
+ var_data.index = var.index
+ var_data.identifier = var.identifier
+ value = core.BNGetMediumLevelILPossibleSSAVarValues(self.function.handle, var_data, index, self.instr_index)
+ result = function.RegisterValue(self.function.arch, value)
+ core.BNFreeRegisterValue(value)
+ return result
+
def __setattr__(self, name, value):
try:
object.__setattr__(self, name, value)