diff options
| -rw-r--r-- | binaryninjaapi.h | 3 | ||||
| -rw-r--r-- | binaryninjacore.h | 4 | ||||
| -rw-r--r-- | mediumlevelil.cpp | 20 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 28 |
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) |
