diff options
| author | Rusty Wagner <rusty@vector35.com> | 2017-03-10 19:21:10 -0500 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2017-03-10 19:21:10 -0500 |
| commit | 29be664b3c91d135b54ed34976357bb7d3413e94 (patch) | |
| tree | 18f94e81f34feac3791f6f4387290e76983c4434 | |
| parent | a51f7666462341f77e3223ff2b6ab218688dfa8c (diff) | |
Mappings between low level IL and medium level IL
| -rw-r--r-- | binaryninjaapi.h | 14 | ||||
| -rw-r--r-- | binaryninjacore.h | 26 | ||||
| -rw-r--r-- | lowlevelil.cpp | 36 | ||||
| -rw-r--r-- | mediumlevelil.cpp | 39 | ||||
| -rw-r--r-- | python/lowlevelil.py | 45 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 51 |
6 files changed, 208 insertions, 3 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index f63deee1..ee342851 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2149,6 +2149,7 @@ namespace BinaryNinja BNLowLevelILInstruction operator[](size_t i) const; size_t GetIndexForInstruction(size_t i) const; size_t GetInstructionCount() const; + size_t GetExprCount() const; void AddLabelForAddress(Architecture* arch, ExprId addr); BNLowLevelILLabel* GetLabelForAddress(Architecture* arch, ExprId addr); @@ -2182,6 +2183,11 @@ namespace BinaryNinja RegisterValue GetSSAFlagValue(uint32_t flag, size_t idx); RegisterValue GetExprValue(size_t expr); + + Ref<MediumLevelILFunction> GetMediumLevelIL() const; + Ref<MediumLevelILFunction> GetMappedMediumLevelIL() const; + size_t GetMappedMediumLevelILInstructionIndex(size_t instr) const; + size_t GetMappedMediumLevelILExprIndex(size_t expr) const; }; struct MediumLevelILLabel: public BNMediumLevelILLabel @@ -2236,6 +2242,7 @@ namespace BinaryNinja BNMediumLevelILInstruction operator[](size_t i) const; size_t GetIndexForInstruction(size_t i) const; size_t GetInstructionCount() const; + size_t GetExprCount() const; void Finalize(); @@ -2259,6 +2266,13 @@ namespace BinaryNinja RegisterValue GetSSAVarValue(const BNILVariable& var, size_t idx); RegisterValue GetExprValue(size_t expr); + + size_t GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const; + size_t GetSSAMemoryIndexAtInstruction(size_t instr) const; + + Ref<LowLevelILFunction> GetLowLevelIL() const; + size_t GetLowLevelILInstructionIndex(size_t instr) const; + size_t GetLowLevelILExprIndex(size_t expr) const; }; class FunctionRecognizer diff --git a/binaryninjacore.h b/binaryninjacore.h index 1d5e10d8..66d5f010 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -60,6 +60,8 @@ #define BN_INVALID_OPERAND 0xffffffff +#define BN_INVALID_EXPR ((size_t)-1) + #define BN_DEFAULT_MIN_STRING_LENGTH 4 #define BN_MAX_STRING_LENGTH 128 @@ -366,7 +368,9 @@ extern "C" LiftedILFunctionGraph = 2, LowLevelILSSAFormFunctionGraph = 3, MediumLevelILFunctionGraph = 4, - MediumLevelILSSAFormFunctionGraph = 5 + MediumLevelILSSAFormFunctionGraph = 5, + MappedMediumLevelILFunctionGraph = 6, + MappedMediumLevelILSSAFormFunctionGraph = 7 }; enum BNDisassemblyOption @@ -727,8 +731,8 @@ extern "C" MLIL_CALL_UNTYPED_SSA, MLIL_SYSCALL_SSA, MLIL_SYSCALL_UNTYPED_SSA, - MLIL_CALL_PARAM_SSA, // Only valid within the LLIL_CALL_SSA, LLIL_SYSCALL_SSA family instructions - MLIL_CALL_OUTPUT_SSA, // Only valid within the LLIL_CALL_SSA or LLIL_SYSCALL_SSA family instructions + MLIL_CALL_PARAM_SSA, // Only valid within the MLIL_CALL_SSA, MLIL_SYSCALL_SSA family instructions + MLIL_CALL_OUTPUT_SSA, // Only valid within the MLIL_CALL_SSA or MLIL_SYSCALL_SSA family instructions MLIL_LOAD_SSA, MLIL_STORE_SSA, MLIL_VAR_PHI, @@ -2131,6 +2135,7 @@ extern "C" BINARYNINJACOREAPI BNLowLevelILInstruction BNGetLowLevelILByIndex(BNLowLevelILFunction* func, size_t i); BINARYNINJACOREAPI size_t BNGetLowLevelILIndexForInstruction(BNLowLevelILFunction* func, size_t i); BINARYNINJACOREAPI size_t BNGetLowLevelILInstructionCount(BNLowLevelILFunction* func); + BINARYNINJACOREAPI size_t BNGetLowLevelILExprCount(BNLowLevelILFunction* func); BINARYNINJACOREAPI void BNAddLowLevelILLabelForAddress(BNLowLevelILFunction* func, BNArchitecture* arch, uint64_t addr); BINARYNINJACOREAPI BNLowLevelILLabel* BNGetLowLevelILLabelForAddress(BNLowLevelILFunction* func, @@ -2169,6 +2174,11 @@ extern "C" BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILExprValue(BNLowLevelILFunction* func, size_t expr); + BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetMediumLevelILForLowLevelIL(BNLowLevelILFunction* func); + BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetMappedMediumLevelIL(BNLowLevelILFunction* func); + BINARYNINJACOREAPI size_t BNGetMappedMediumLevelILInstructionIndex(BNLowLevelILFunction* func, size_t instr); + BINARYNINJACOREAPI size_t BNGetMappedMediumLevelILExprIndex(BNLowLevelILFunction* func, size_t expr); + // Medium-level IL BINARYNINJACOREAPI BNMediumLevelILFunction* BNCreateMediumLevelILFunction(BNArchitecture* arch, BNFunction* func); BINARYNINJACOREAPI BNMediumLevelILFunction* BNNewMediumLevelILFunctionReference(BNMediumLevelILFunction* func); @@ -2199,6 +2209,7 @@ extern "C" BINARYNINJACOREAPI BNMediumLevelILInstruction BNGetMediumLevelILByIndex(BNMediumLevelILFunction* func, size_t i); BINARYNINJACOREAPI size_t BNGetMediumLevelILIndexForInstruction(BNMediumLevelILFunction* func, size_t i); BINARYNINJACOREAPI size_t BNGetMediumLevelILInstructionCount(BNMediumLevelILFunction* func); + BINARYNINJACOREAPI size_t BNGetMediumLevelILExprCount(BNMediumLevelILFunction* func); BINARYNINJACOREAPI bool BNGetMediumLevelILExprText(BNMediumLevelILFunction* func, BNArchitecture* arch, size_t i, BNInstructionTextToken** tokens, size_t* count); @@ -2226,6 +2237,15 @@ extern "C" const BNILVariable* var, size_t idx); BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILExprValue(BNMediumLevelILFunction* func, size_t expr); + BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAVarIndexAtILInstruction(BNMediumLevelILFunction* func, + const BNILVariable* var, size_t instr); + BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAMemoryIndexAtILInstruction(BNMediumLevelILFunction* func, + size_t instr); + + BINARYNINJACOREAPI BNLowLevelILFunction* BNGetLowLevelILForMediumLevelIL(BNMediumLevelILFunction* func); + BINARYNINJACOREAPI size_t BNGetLowLevelILInstructionIndex(BNMediumLevelILFunction* func, size_t instr); + BINARYNINJACOREAPI size_t BNGetLowLevelILExprIndex(BNMediumLevelILFunction* func, size_t expr); + // Types BINARYNINJACOREAPI BNType* BNCreateVoidType(void); BINARYNINJACOREAPI BNType* BNCreateBoolType(void); diff --git a/lowlevelil.cpp b/lowlevelil.cpp index 342effea..bd038b6e 100644 --- a/lowlevelil.cpp +++ b/lowlevelil.cpp @@ -553,6 +553,12 @@ size_t LowLevelILFunction::GetInstructionCount() const } +size_t LowLevelILFunction::GetExprCount() const +{ + return BNGetLowLevelILExprCount(m_object); +} + + void LowLevelILFunction::AddLabelForAddress(Architecture* arch, ExprId addr) { BNAddLowLevelILLabelForAddress(m_object, arch->GetObject(), addr); @@ -772,3 +778,33 @@ RegisterValue LowLevelILFunction::GetExprValue(size_t expr) BNRegisterValue value = BNGetLowLevelILExprValue(m_object, expr); return RegisterValue::FromAPIObject(value); } + + +Ref<MediumLevelILFunction> LowLevelILFunction::GetMediumLevelIL() const +{ + BNMediumLevelILFunction* func = BNGetMediumLevelILForLowLevelIL(m_object); + if (!func) + return nullptr; + return new MediumLevelILFunction(func); +} + + +Ref<MediumLevelILFunction> LowLevelILFunction::GetMappedMediumLevelIL() const +{ + BNMediumLevelILFunction* func = BNGetMappedMediumLevelIL(m_object); + if (!func) + return nullptr; + return new MediumLevelILFunction(func); +} + + +size_t LowLevelILFunction::GetMappedMediumLevelILInstructionIndex(size_t instr) const +{ + return BNGetMappedMediumLevelILInstructionIndex(m_object, instr); +} + + +size_t LowLevelILFunction::GetMappedMediumLevelILExprIndex(size_t expr) const +{ + return BNGetMappedMediumLevelILExprIndex(m_object, expr); +} diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index f1f0bdd2..04b1cffd 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -268,6 +268,12 @@ size_t MediumLevelILFunction::GetInstructionCount() const } +size_t MediumLevelILFunction::GetExprCount() const +{ + return BNGetMediumLevelILExprCount(m_object); +} + + void MediumLevelILFunction::Finalize() { BNFinalizeMediumLevelILFunction(m_object); @@ -436,3 +442,36 @@ RegisterValue MediumLevelILFunction::GetExprValue(size_t expr) BNRegisterValue value = BNGetMediumLevelILExprValue(m_object, expr); return RegisterValue::FromAPIObject(value); } + + +size_t MediumLevelILFunction::GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const +{ + return BNGetMediumLevelILSSAVarIndexAtILInstruction(m_object, &var, instr); +} + + +size_t MediumLevelILFunction::GetSSAMemoryIndexAtInstruction(size_t instr) const +{ + return BNGetMediumLevelILSSAMemoryIndexAtILInstruction(m_object, instr); +} + + +Ref<LowLevelILFunction> MediumLevelILFunction::GetLowLevelIL() const +{ + BNLowLevelILFunction* func = BNGetLowLevelILForMediumLevelIL(m_object); + if (!func) + return nullptr; + return new LowLevelILFunction(func); +} + + +size_t MediumLevelILFunction::GetLowLevelILInstructionIndex(size_t instr) const +{ + return BNGetLowLevelILInstructionIndex(m_object, instr); +} + + +size_t MediumLevelILFunction::GetLowLevelILExprIndex(size_t expr) const +{ + return BNGetLowLevelILExprIndex(m_object, expr); +} diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 40cb964c..462d4ade 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -25,6 +25,7 @@ import _binaryninjacore as core from .enums import LowLevelILOperation, LowLevelILFlagCondition, InstructionTextTokenType import function import basicblock +import mediumlevelil class LowLevelILLabel(object): @@ -250,6 +251,14 @@ class LowLevelILInstruction(object): core.BNGetLowLevelILNonSSAExprIndex(self.function.handle, self.expr_index)) @property + def mapped_medium_level_il(self): + """Gets the medium level IL expression corresponding to this expression""" + expr = self.function.get_mapped_medium_level_il_expr_index(self.expr_index) + if expr is None: + return None + return mediumlevelil.MediumLevelILInstruction(self.function.mapped_medium_level_il, expr) + + @property def value(self): """Value of expression using static data flow analysis (read-only)""" value = core.BNGetLowLevelILExprValue(self.function.handle, self.expr_index) @@ -381,6 +390,24 @@ class LowLevelILFunction(object): return None return LowLevelILFunction(self.arch, result, self.source_function) + @property + def medium_level_il(self): + """Medium level IL for this low level IL.""" + result = core.BNGetMediumLevelILForLowLevelIL(self.handle) + if not result: + return None + return mediumlevelil.MediumLevelILFunction(self.arch, result, self.source_function) + + @property + def mapped_medium_level_il(self): + """Medium level IL with mappings between low level IL and medium level IL. Unused stores are not removed. + Typically, this should only be used to answer queries on assembly or low level IL where the query is + easier to perform on medium level IL.""" + result = core.BNGetMappedMediumLevelIL(self.handle) + if not result: + return None + return mediumlevelil.MediumLevelILFunction(self.arch, result, self.source_function) + def __setattr__(self, name, value): try: object.__setattr__(self, name, value) @@ -1422,6 +1449,24 @@ class LowLevelILFunction(object): core.BNFreeRegisterValue(value) return result + def get_mapped_medium_level_il_instruction_index(self, instr): + med_il = self.mapped_medium_level_il + if med_il is None: + return None + result = core.BNGetMappedMediumLevelILInstructionIndex(self.handle, instr) + if result >= core.BNGetMediumLevelILInstructionCount(med_il.handle): + return None + return result + + def get_mapped_medium_level_il_expr_index(self, expr): + med_il = self.mapped_medium_level_il + if med_il is None: + return None + result = core.BNGetMappedMediumLevelILExprIndex(self.handle, expr) + if result >= core.BNGetMediumLevelILExprCount(med_il.handle): + return None + return result + class LowLevelILBasicBlock(basicblock.BasicBlock): def __init__(self, view, handle, owner): diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 9f25ee97..00d7215f 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -25,6 +25,7 @@ import _binaryninjacore as core from .enums import MediumLevelILOperation, InstructionTextTokenType, ILVariableSourceType import function import basicblock +import lowlevelil class MediumLevelILLabel(object): @@ -258,6 +259,14 @@ class MediumLevelILInstruction(object): core.BNFreeRegisterValue(value) return result + @property + def low_level_il(self): + """Low level IL form of this expression""" + expr = self.function.get_low_level_il_expr_index(self.expr_index) + if expr is None: + return None + return lowlevelil.LowLevelILInstruction(self.function.low_level_il.ssa_form, expr) + def __setattr__(self, name, value): try: object.__setattr__(self, name, value) @@ -350,6 +359,14 @@ class MediumLevelILFunction(object): return None return MediumLevelILFunction(self.arch, result, self.source_function) + @property + def low_level_il(self): + """Low level IL for this function""" + result = core.BNGetLowLevelILForMediumLevelIL(self.handle) + if not result: + return None + return lowlevelil.LowLevelILFunction(self.arch, result, self.source_function) + def __setattr__(self, name, value): try: object.__setattr__(self, name, value) @@ -540,6 +557,40 @@ class MediumLevelILFunction(object): core.BNFreeRegisterValue(value) return result + def get_ssa_var_index_at_instruction(self, var, instr): + var_data = core.BNILVariable() + var_data.type = var.type + var_data.index = var.index + var_data.identifier = var.identifier + return core.BNGetMediumLevelILSSAVarIndexAtILInstruction(self.handle, var_data, instr) + + def get_ssa_memory_index_at_instruction(self, instr): + return core.BNGetMediumLevelILSSAMemoryIndexAtILInstruction(self.handle, instr) + + def get_low_level_il_instruction_index(self, instr): + low_il = self.low_level_il + if low_il is None: + return None + low_il = low_il.ssa_form + if low_il is None: + return None + result = core.BNGetLowLevelILInstructionIndex(self.handle, instr) + if result >= core.BNGetLowLevelILInstructionCount(low_il.handle): + return None + return result + + def get_low_level_il_expr_index(self, expr): + low_il = self.low_level_il + if low_il is None: + return None + low_il = low_il.ssa_form + if low_il is None: + return None + result = core.BNGetLowLevelILExprIndex(self.handle, expr) + if result >= core.BNGetLowLevelILExprCount(low_il.handle): + return None + return result + class MediumLevelILBasicBlock(basicblock.BasicBlock): def __init__(self, view, handle, owner): |
