summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2017-03-10 19:21:10 -0500
committerRusty Wagner <rusty@vector35.com>2017-03-10 19:21:10 -0500
commit29be664b3c91d135b54ed34976357bb7d3413e94 (patch)
tree18f94e81f34feac3791f6f4387290e76983c4434
parenta51f7666462341f77e3223ff2b6ab218688dfa8c (diff)
Mappings between low level IL and medium level IL
-rw-r--r--binaryninjaapi.h14
-rw-r--r--binaryninjacore.h26
-rw-r--r--lowlevelil.cpp36
-rw-r--r--mediumlevelil.cpp39
-rw-r--r--python/lowlevelil.py45
-rw-r--r--python/mediumlevelil.py51
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):