summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binaryninjaapi.h32
-rw-r--r--binaryninjacore.h36
-rw-r--r--lowlevelil.cpp32
-rw-r--r--mediumlevelil.cpp32
-rw-r--r--python/architecture.py14
-rw-r--r--python/function.py12
-rw-r--r--python/lowlevelil.py229
-rw-r--r--python/mediumlevelil.py220
8 files changed, 396 insertions, 211 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 8812e7c9..41beb852 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -2206,15 +2206,15 @@ namespace BinaryNinja
size_t GetSSAExprIndex(size_t instr) const;
size_t GetNonSSAExprIndex(size_t instr) const;
- size_t GetSSARegisterDefinition(uint32_t reg, size_t idx) const;
- size_t GetSSAFlagDefinition(uint32_t flag, size_t idx) const;
- size_t GetSSAMemoryDefinition(size_t idx) const;
- std::set<size_t> GetSSARegisterUses(uint32_t reg, size_t idx) const;
- std::set<size_t> GetSSAFlagUses(uint32_t flag, size_t idx) const;
- std::set<size_t> GetSSAMemoryUses(size_t idx) const;
+ size_t GetSSARegisterDefinition(uint32_t reg, size_t version) const;
+ size_t GetSSAFlagDefinition(uint32_t flag, size_t version) const;
+ size_t GetSSAMemoryDefinition(size_t version) const;
+ std::set<size_t> GetSSARegisterUses(uint32_t reg, size_t version) const;
+ std::set<size_t> GetSSAFlagUses(uint32_t flag, size_t version) const;
+ std::set<size_t> GetSSAMemoryUses(size_t version) const;
- RegisterValue GetSSARegisterValue(uint32_t reg, size_t idx);
- RegisterValue GetSSAFlagValue(uint32_t flag, size_t idx);
+ RegisterValue GetSSARegisterValue(uint32_t reg, size_t version);
+ RegisterValue GetSSAFlagValue(uint32_t flag, size_t version);
RegisterValue GetExprValue(size_t expr);
PossibleValueSet GetPossibleExprValues(size_t expr);
@@ -2287,18 +2287,18 @@ namespace BinaryNinja
size_t GetSSAExprIndex(size_t instr) const;
size_t GetNonSSAExprIndex(size_t instr) const;
- size_t GetSSAVarDefinition(const Variable& var, size_t idx) const;
- size_t GetSSAMemoryDefinition(size_t idx) const;
- std::set<size_t> GetSSAVarUses(const Variable& var, size_t idx) const;
- std::set<size_t> GetSSAMemoryUses(size_t idx) const;
+ size_t GetSSAVarDefinition(const Variable& var, size_t version) const;
+ size_t GetSSAMemoryDefinition(size_t version) const;
+ std::set<size_t> GetSSAVarUses(const Variable& var, size_t version) const;
+ std::set<size_t> GetSSAMemoryUses(size_t version) const;
- RegisterValue GetSSAVarValue(const Variable& var, size_t idx);
+ RegisterValue GetSSAVarValue(const Variable& var, size_t version);
RegisterValue GetExprValue(size_t expr);
- PossibleValueSet GetPossibleSSAVarValues(const Variable& var, size_t idx, size_t instr);
+ PossibleValueSet GetPossibleSSAVarValues(const Variable& var, size_t version, size_t instr);
PossibleValueSet GetPossibleExprValues(size_t expr);
- size_t GetSSAVarIndexAtInstruction(const Variable& var, size_t instr) const;
- size_t GetSSAMemoryIndexAtInstruction(size_t instr) const;
+ size_t GetSSAVarVersionAtInstruction(const Variable& var, size_t instr) const;
+ size_t GetSSAMemoryVersionAtInstruction(size_t instr) const;
Variable GetVariableForRegisterAtInstruction(uint32_t reg, size_t instr) const;
Variable GetVariableForFlagAtInstruction(uint32_t flag, size_t instr) const;
Variable GetVariableForStackLocationAtInstruction(int64_t offset, size_t instr) const;
diff --git a/binaryninjacore.h b/binaryninjacore.h
index dcd9941c..730cbe8d 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -2257,19 +2257,21 @@ extern "C"
BINARYNINJACOREAPI size_t BNGetLowLevelILSSAExprIndex(BNLowLevelILFunction* func, size_t expr);
BINARYNINJACOREAPI size_t BNGetLowLevelILNonSSAExprIndex(BNLowLevelILFunction* func, size_t expr);
- BINARYNINJACOREAPI size_t BNGetLowLevelILSSARegisterDefinition(BNLowLevelILFunction* func, uint32_t reg, size_t idx);
- BINARYNINJACOREAPI size_t BNGetLowLevelILSSAFlagDefinition(BNLowLevelILFunction* func, uint32_t reg, size_t idx);
- BINARYNINJACOREAPI size_t BNGetLowLevelILSSAMemoryDefinition(BNLowLevelILFunction* func, size_t idx);
- BINARYNINJACOREAPI size_t* BNGetLowLevelILSSARegisterUses(BNLowLevelILFunction* func, uint32_t reg, size_t idx,
+ BINARYNINJACOREAPI size_t BNGetLowLevelILSSARegisterDefinition(BNLowLevelILFunction* func,
+ uint32_t reg, size_t version);
+ BINARYNINJACOREAPI size_t BNGetLowLevelILSSAFlagDefinition(BNLowLevelILFunction* func,
+ uint32_t reg, size_t version);
+ BINARYNINJACOREAPI size_t BNGetLowLevelILSSAMemoryDefinition(BNLowLevelILFunction* func, size_t version);
+ BINARYNINJACOREAPI size_t* BNGetLowLevelILSSARegisterUses(BNLowLevelILFunction* func,
+ uint32_t reg, size_t version, size_t* count);
+ BINARYNINJACOREAPI size_t* BNGetLowLevelILSSAFlagUses(BNLowLevelILFunction* func, uint32_t reg, size_t version,
size_t* count);
- BINARYNINJACOREAPI size_t* BNGetLowLevelILSSAFlagUses(BNLowLevelILFunction* func, uint32_t reg, size_t idx,
- size_t* count);
- BINARYNINJACOREAPI size_t* BNGetLowLevelILSSAMemoryUses(BNLowLevelILFunction* func, size_t idx, size_t* count);
+ BINARYNINJACOREAPI size_t* BNGetLowLevelILSSAMemoryUses(BNLowLevelILFunction* func, size_t version, size_t* count);
BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILSSARegisterValue(BNLowLevelILFunction* func,
- uint32_t reg, size_t idx);
+ uint32_t reg, size_t version);
BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILSSAFlagValue(BNLowLevelILFunction* func,
- uint32_t flag, size_t idx);
+ uint32_t flag, size_t version);
BINARYNINJACOREAPI BNRegisterValue BNGetLowLevelILExprValue(BNLowLevelILFunction* func, size_t expr);
BINARYNINJACOREAPI BNPossibleValueSet BNGetLowLevelILPossibleExprValues(BNLowLevelILFunction* func, size_t expr);
@@ -2352,23 +2354,23 @@ extern "C"
BINARYNINJACOREAPI size_t BNGetMediumLevelILNonSSAExprIndex(BNMediumLevelILFunction* func, size_t expr);
BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAVarDefinition(BNMediumLevelILFunction* func,
- const BNVariable* var, size_t idx);
- BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAMemoryDefinition(BNMediumLevelILFunction* func, size_t idx);
+ const BNVariable* var, size_t version);
+ BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAMemoryDefinition(BNMediumLevelILFunction* func, size_t version);
BINARYNINJACOREAPI size_t* BNGetMediumLevelILSSAVarUses(BNMediumLevelILFunction* func, const BNVariable* var,
- size_t idx, size_t* count);
+ size_t version, size_t* count);
BINARYNINJACOREAPI size_t* BNGetMediumLevelILSSAMemoryUses(BNMediumLevelILFunction* func,
- size_t idx, size_t* count);
+ size_t version, size_t* count);
BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILSSAVarValue(BNMediumLevelILFunction* func,
- const BNVariable* var, size_t idx);
+ const BNVariable* var, size_t version);
BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILExprValue(BNMediumLevelILFunction* func, size_t expr);
BINARYNINJACOREAPI BNPossibleValueSet BNGetMediumLevelILPossibleSSAVarValues(BNMediumLevelILFunction* func,
- const BNVariable* var, size_t idx, size_t instr);
+ const BNVariable* var, size_t version, size_t instr);
BINARYNINJACOREAPI BNPossibleValueSet BNGetMediumLevelILPossibleExprValues(BNMediumLevelILFunction* func, size_t expr);
- BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAVarIndexAtILInstruction(BNMediumLevelILFunction* func,
+ BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAVarVersionAtILInstruction(BNMediumLevelILFunction* func,
const BNVariable* var, size_t instr);
- BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAMemoryIndexAtILInstruction(BNMediumLevelILFunction* func,
+ BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAMemoryVersionAtILInstruction(BNMediumLevelILFunction* func,
size_t instr);
BINARYNINJACOREAPI BNVariable BNGetMediumLevelILVariableForRegisterAtInstruction(BNMediumLevelILFunction* func,
uint32_t reg, size_t instr);
diff --git a/lowlevelil.cpp b/lowlevelil.cpp
index 9764445e..d266c2c9 100644
--- a/lowlevelil.cpp
+++ b/lowlevelil.cpp
@@ -699,28 +699,28 @@ size_t LowLevelILFunction::GetNonSSAExprIndex(size_t expr) const
}
-size_t LowLevelILFunction::GetSSARegisterDefinition(uint32_t reg, size_t idx) const
+size_t LowLevelILFunction::GetSSARegisterDefinition(uint32_t reg, size_t version) const
{
- return BNGetLowLevelILSSARegisterDefinition(m_object, reg, idx);
+ return BNGetLowLevelILSSARegisterDefinition(m_object, reg, version);
}
-size_t LowLevelILFunction::GetSSAFlagDefinition(uint32_t flag, size_t idx) const
+size_t LowLevelILFunction::GetSSAFlagDefinition(uint32_t flag, size_t version) const
{
- return BNGetLowLevelILSSAFlagDefinition(m_object, flag, idx);
+ return BNGetLowLevelILSSAFlagDefinition(m_object, flag, version);
}
-size_t LowLevelILFunction::GetSSAMemoryDefinition(size_t idx) const
+size_t LowLevelILFunction::GetSSAMemoryDefinition(size_t version) const
{
- return BNGetLowLevelILSSAMemoryDefinition(m_object, idx);
+ return BNGetLowLevelILSSAMemoryDefinition(m_object, version);
}
-set<size_t> LowLevelILFunction::GetSSARegisterUses(uint32_t reg, size_t idx) const
+set<size_t> LowLevelILFunction::GetSSARegisterUses(uint32_t reg, size_t version) const
{
size_t count;
- size_t* instrs = BNGetLowLevelILSSARegisterUses(m_object, reg, idx, &count);
+ size_t* instrs = BNGetLowLevelILSSARegisterUses(m_object, reg, version, &count);
set<size_t> result;
for (size_t i = 0; i < count; i++)
@@ -731,10 +731,10 @@ set<size_t> LowLevelILFunction::GetSSARegisterUses(uint32_t reg, size_t idx) con
}
-set<size_t> LowLevelILFunction::GetSSAFlagUses(uint32_t flag, size_t idx) const
+set<size_t> LowLevelILFunction::GetSSAFlagUses(uint32_t flag, size_t version) const
{
size_t count;
- size_t* instrs = BNGetLowLevelILSSAFlagUses(m_object, flag, idx, &count);
+ size_t* instrs = BNGetLowLevelILSSAFlagUses(m_object, flag, version, &count);
set<size_t> result;
for (size_t i = 0; i < count; i++)
@@ -745,10 +745,10 @@ set<size_t> LowLevelILFunction::GetSSAFlagUses(uint32_t flag, size_t idx) const
}
-set<size_t> LowLevelILFunction::GetSSAMemoryUses(size_t idx) const
+set<size_t> LowLevelILFunction::GetSSAMemoryUses(size_t version) const
{
size_t count;
- size_t* instrs = BNGetLowLevelILSSAMemoryUses(m_object, idx, &count);
+ size_t* instrs = BNGetLowLevelILSSAMemoryUses(m_object, version, &count);
set<size_t> result;
for (size_t i = 0; i < count; i++)
@@ -759,16 +759,16 @@ set<size_t> LowLevelILFunction::GetSSAMemoryUses(size_t idx) const
}
-RegisterValue LowLevelILFunction::GetSSARegisterValue(uint32_t reg, size_t idx)
+RegisterValue LowLevelILFunction::GetSSARegisterValue(uint32_t reg, size_t version)
{
- BNRegisterValue value = BNGetLowLevelILSSARegisterValue(m_object, reg, idx);
+ BNRegisterValue value = BNGetLowLevelILSSARegisterValue(m_object, reg, version);
return RegisterValue::FromAPIObject(value);
}
-RegisterValue LowLevelILFunction::GetSSAFlagValue(uint32_t flag, size_t idx)
+RegisterValue LowLevelILFunction::GetSSAFlagValue(uint32_t flag, size_t version)
{
- BNRegisterValue value = BNGetLowLevelILSSAFlagValue(m_object, flag, idx);
+ BNRegisterValue value = BNGetLowLevelILSSAFlagValue(m_object, flag, version);
return RegisterValue::FromAPIObject(value);
}
diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp
index 868f3f75..75c99a54 100644
--- a/mediumlevelil.cpp
+++ b/mediumlevelil.cpp
@@ -271,22 +271,22 @@ size_t MediumLevelILFunction::GetNonSSAExprIndex(size_t expr) const
}
-size_t MediumLevelILFunction::GetSSAVarDefinition(const Variable& var, size_t idx) const
+size_t MediumLevelILFunction::GetSSAVarDefinition(const Variable& var, size_t version) const
{
- return BNGetMediumLevelILSSAVarDefinition(m_object, &var, idx);
+ return BNGetMediumLevelILSSAVarDefinition(m_object, &var, version);
}
-size_t MediumLevelILFunction::GetSSAMemoryDefinition(size_t idx) const
+size_t MediumLevelILFunction::GetSSAMemoryDefinition(size_t version) const
{
- return BNGetMediumLevelILSSAMemoryDefinition(m_object, idx);
+ return BNGetMediumLevelILSSAMemoryDefinition(m_object, version);
}
-set<size_t> MediumLevelILFunction::GetSSAVarUses(const Variable& var, size_t idx) const
+set<size_t> MediumLevelILFunction::GetSSAVarUses(const Variable& var, size_t version) const
{
size_t count;
- size_t* instrs = BNGetMediumLevelILSSAVarUses(m_object, &var, idx, &count);
+ size_t* instrs = BNGetMediumLevelILSSAVarUses(m_object, &var, version, &count);
set<size_t> result;
for (size_t i = 0; i < count; i++)
@@ -297,10 +297,10 @@ set<size_t> MediumLevelILFunction::GetSSAVarUses(const Variable& var, size_t idx
}
-set<size_t> MediumLevelILFunction::GetSSAMemoryUses(size_t idx) const
+set<size_t> MediumLevelILFunction::GetSSAMemoryUses(size_t version) const
{
size_t count;
- size_t* instrs = BNGetMediumLevelILSSAMemoryUses(m_object, idx, &count);
+ size_t* instrs = BNGetMediumLevelILSSAMemoryUses(m_object, version, &count);
set<size_t> result;
for (size_t i = 0; i < count; i++)
@@ -311,9 +311,9 @@ set<size_t> MediumLevelILFunction::GetSSAMemoryUses(size_t idx) const
}
-RegisterValue MediumLevelILFunction::GetSSAVarValue(const Variable& var, size_t idx)
+RegisterValue MediumLevelILFunction::GetSSAVarValue(const Variable& var, size_t version)
{
- BNRegisterValue value = BNGetMediumLevelILSSAVarValue(m_object, &var, idx);
+ BNRegisterValue value = BNGetMediumLevelILSSAVarValue(m_object, &var, version);
return RegisterValue::FromAPIObject(value);
}
@@ -325,9 +325,9 @@ RegisterValue MediumLevelILFunction::GetExprValue(size_t expr)
}
-PossibleValueSet MediumLevelILFunction::GetPossibleSSAVarValues(const Variable& var, size_t idx, size_t instr)
+PossibleValueSet MediumLevelILFunction::GetPossibleSSAVarValues(const Variable& var, size_t version, size_t instr)
{
- BNPossibleValueSet value = BNGetMediumLevelILPossibleSSAVarValues(m_object, &var, idx, instr);
+ BNPossibleValueSet value = BNGetMediumLevelILPossibleSSAVarValues(m_object, &var, version, instr);
return PossibleValueSet::FromAPIObject(value);
}
@@ -339,15 +339,15 @@ PossibleValueSet MediumLevelILFunction::GetPossibleExprValues(size_t expr)
}
-size_t MediumLevelILFunction::GetSSAVarIndexAtInstruction(const Variable& var, size_t instr) const
+size_t MediumLevelILFunction::GetSSAVarVersionAtInstruction(const Variable& var, size_t instr) const
{
- return BNGetMediumLevelILSSAVarIndexAtILInstruction(m_object, &var, instr);
+ return BNGetMediumLevelILSSAVarVersionAtILInstruction(m_object, &var, instr);
}
-size_t MediumLevelILFunction::GetSSAMemoryIndexAtInstruction(size_t instr) const
+size_t MediumLevelILFunction::GetSSAMemoryVersionAtInstruction(size_t instr) const
{
- return BNGetMediumLevelILSSAMemoryIndexAtILInstruction(m_object, instr);
+ return BNGetMediumLevelILSSAMemoryVersionAtILInstruction(m_object, instr);
}
diff --git a/python/architecture.py b/python/architecture.py
index d3778613..60c8a1dd 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -1232,6 +1232,20 @@ class Architecture(object):
"""
return core.BNGetArchitectureFlagName(self.handle, flag)
+ def get_reg_index(self, reg):
+ if isinstance(reg, str):
+ return self.regs[reg].index
+ elif isinstance(reg, lowlevelil.ILRegister):
+ return reg.index
+ return reg
+
+ def get_flag_index(self, flag):
+ if isinstance(flag, str):
+ return self._flags[flag]
+ elif isinstance(flag, lowlevelil.ILFlag):
+ return flag.index
+ return flag
+
def get_flag_write_type_name(self, write_type):
"""
``get_flag_write_type_name`` gets the flag write type name for the given flag.
diff --git a/python/function.py b/python/function.py
index 2a0176c9..509d9b3b 100644
--- a/python/function.py
+++ b/python/function.py
@@ -510,8 +510,7 @@ class Function(object):
"""
if arch is None:
arch = self.arch
- if isinstance(reg, str):
- reg = arch.regs[reg].index
+ reg = arch.get_reg_index(reg)
value = core.BNGetRegisterValueAtInstruction(self.handle, arch.handle, addr, reg)
result = RegisterValue(arch, value)
return result
@@ -531,8 +530,7 @@ class Function(object):
"""
if arch is None:
arch = self.arch
- if isinstance(reg, str):
- reg = arch.regs[reg].index
+ reg = arch.get_reg_index(reg)
value = core.BNGetRegisterValueAfterInstruction(self.handle, arch.handle, addr, reg)
result = RegisterValue(arch, value)
return result
@@ -638,8 +636,7 @@ class Function(object):
return self.lifted_il[core.BNGetLiftedILForInstruction(self.handle, arch.handle, addr)]
def get_lifted_il_flag_uses_for_definition(self, i, flag):
- if isinstance(flag, str):
- flag = self.arch._flags[flag]
+ flag = self.arch.get_flag_index(flag)
count = ctypes.c_ulonglong()
instrs = core.BNGetLiftedILFlagUsesForDefinition(self.handle, i, flag, count)
result = []
@@ -649,8 +646,7 @@ class Function(object):
return result
def get_lifted_il_flag_definitions_for_use(self, i, flag):
- if isinstance(flag, str):
- flag = self.arch._flags[flag]
+ flag = self.arch.get_flag_index(flag)
count = ctypes.c_ulonglong()
instrs = core.BNGetLiftedILFlagDefinitionsForUse(self.handle, i, flag, count)
result = []
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index 3634cca2..21f43db3 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -37,6 +37,73 @@ class LowLevelILLabel(object):
self.handle = handle
+class ILRegister(object):
+ def __init__(self, arch, reg):
+ self.arch = arch
+ self.index = reg
+ self.temp = (self.index & 0x80000000) != 0
+ if self.temp:
+ self.name = "temp%d" % (self.index & 0x7fffffff)
+ else:
+ self.name = self.arch.get_reg_name(self.index)
+
+ @property
+ def info(self):
+ return self.arch.regs[self.name]
+
+ def __str__(self):
+ return self.name
+
+ def __repr__(self):
+ return self.name
+
+
+class ILFlag(object):
+ def __init__(self, arch, flag):
+ self.arch = arch
+ self.index = flag
+ self.temp = (self.index & 0x80000000) != 0
+ if self.temp:
+ self.name = "cond:%d" % (self.index & 0x7fffffff)
+ else:
+ self.name = self.arch.get_flag_name(self.index)
+
+ def __str__(self):
+ return self.name
+
+ def __repr__(self):
+ return self.name
+
+
+class SSARegister(object):
+ def __init__(self, reg, version):
+ self.reg = reg
+ self.version = version
+
+ def __repr__(self):
+ return "<ssa %s version %d>" % (repr(self.reg), self.version)
+
+
+class SSAFlag(object):
+ def __init__(self, flag, version):
+ self.flag = flag
+ self.version = version
+
+ def __repr__(self):
+ return "<ssa %s version %d>" % (repr(self.flag), self.version)
+
+
+class LowLevelILOperationAndSize(object):
+ def __init__(self, operation, size):
+ self.operation = operation
+ self.size = size
+
+ def __repr__(self):
+ if self.size == 0:
+ return "<%s>" % self.operation.name
+ return "<%s %d>" % (self.operation.name, self.size)
+
+
class LowLevelILInstruction(object):
"""
``class LowLevelILInstruction`` Low Level Intermediate Language Instructions are infinite length tree-based
@@ -112,24 +179,24 @@ class LowLevelILInstruction(object):
LowLevelILOperation.LLIL_UNDEF: [],
LowLevelILOperation.LLIL_UNIMPL: [],
LowLevelILOperation.LLIL_UNIMPL_MEM: [("src", "expr")],
- LowLevelILOperation.LLIL_SET_REG_SSA: [("dest", "reg"), ("index", "int"), ("src", "expr")],
- LowLevelILOperation.LLIL_SET_REG_SSA_PARTIAL: [("full_reg", "reg"), ("index", "int"), ("dest", "reg"), ("src", "expr")],
+ LowLevelILOperation.LLIL_SET_REG_SSA: [("dest", "reg_ssa"), ("src", "expr")],
+ LowLevelILOperation.LLIL_SET_REG_SSA_PARTIAL: [("full_reg", "reg_ssa"), ("dest", "reg"), ("src", "expr")],
LowLevelILOperation.LLIL_SET_REG_SPLIT_SSA: [("hi", "expr"), ("lo", "expr"), ("src", "expr")],
- LowLevelILOperation.LLIL_REG_SPLIT_DEST_SSA: [("dest", "reg", "index", "int")],
- LowLevelILOperation.LLIL_REG_SSA: [("src", "reg"), ("index", "int")],
- LowLevelILOperation.LLIL_REG_SSA_PARTIAL: [("full_reg", "reg"), ("index", "int"), ("src", "reg")],
- LowLevelILOperation.LLIL_SET_FLAG_SSA: [("dest", "flag"), ("index", "int"), ("src", "expr")],
- LowLevelILOperation.LLIL_FLAG_SSA: [("src", "flag"), ("index", "int")],
- LowLevelILOperation.LLIL_FLAG_BIT_SSA: [("src", "flag"), ("index", "int"), ("bit", "int")],
+ LowLevelILOperation.LLIL_REG_SPLIT_DEST_SSA: [("dest", "reg_ssa")],
+ LowLevelILOperation.LLIL_REG_SSA: [("src", "reg_ssa")],
+ LowLevelILOperation.LLIL_REG_SSA_PARTIAL: [("full_reg", "reg_ssa"), ("src", "reg")],
+ LowLevelILOperation.LLIL_SET_FLAG_SSA: [("dest", "flag_ssa"), ("src", "expr")],
+ LowLevelILOperation.LLIL_FLAG_SSA: [("src", "flag_ssa")],
+ LowLevelILOperation.LLIL_FLAG_BIT_SSA: [("src", "flag_ssa"), ("bit", "int")],
LowLevelILOperation.LLIL_CALL_SSA: [("output", "expr"), ("dest", "expr"), ("stack", "expr"), ("param", "expr")],
LowLevelILOperation.LLIL_SYSCALL_SSA: [("output", "expr"), ("stack", "expr"), ("param", "expr")],
LowLevelILOperation.LLIL_CALL_OUTPUT_SSA: [("dest_memory", "int"), ("dest", "reg_ssa_list")],
- LowLevelILOperation.LLIL_CALL_STACK_SSA: [("src", "reg"), ("index", "int"), ("src_memory", "int")],
+ LowLevelILOperation.LLIL_CALL_STACK_SSA: [("src", "reg_ssa"), ("src_memory", "int")],
LowLevelILOperation.LLIL_CALL_PARAM_SSA: [("src", "reg_ssa_list")],
LowLevelILOperation.LLIL_LOAD_SSA: [("src", "expr"), ("src_memory", "int")],
LowLevelILOperation.LLIL_STORE_SSA: [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")],
- LowLevelILOperation.LLIL_REG_PHI: [("dest", "reg"), ("index", "int"), ("src", "reg_ssa_list")],
- LowLevelILOperation.LLIL_FLAG_PHI: [("dest", "reg"), ("index", "int"), ("src", "flag_ssa_list")],
+ LowLevelILOperation.LLIL_REG_PHI: [("dest", "reg_ssa"), ("src", "reg_ssa_list")],
+ LowLevelILOperation.LLIL_FLAG_PHI: [("dest", "flag_ssa"), ("src", "flag_ssa_list")],
LowLevelILOperation.LLIL_MEM_PHI: [("dest_memory", "int"), ("src_memory", "int_list")]
}
@@ -150,27 +217,31 @@ class LowLevelILInstruction(object):
self.source_operand = None
operands = LowLevelILInstruction.ILOperations[instr.operation]
self.operands = []
- for i in xrange(0, len(operands)):
- name, operand_type = operands[i]
+ i = 0
+ for operand in operands:
+ name, operand_type = operand
if operand_type == "int":
value = instr.operands[i]
elif operand_type == "expr":
value = LowLevelILInstruction(func, instr.operands[i])
elif operand_type == "reg":
- if (instr.operands[i] & 0x80000000) != 0:
- value = instr.operands[i]
- else:
- value = func.arch.get_reg_name(instr.operands[i])
+ value = ILRegister(func.arch, instr.operands[i])
+ elif operand_type == "reg_ssa":
+ reg = ILRegister(func.arch, instr.operands[i])
+ i += 1
+ value = SSARegister(reg, instr.operands[i])
elif operand_type == "flag":
- if (instr.operands[i] & 0x80000000) != 0:
- value = instr.operands[i]
- else:
- value = func.arch.get_flag_name(instr.operands[i])
+ value = ILFlag(func.arch, instr.operands[i])
+ elif operand_type == "flag_ssa":
+ flag = ILFlag(func.arch, instr.operands[i])
+ i += 1
+ value = SSAFlag(flag, instr.operands[i])
elif operand_type == "cond":
value = LowLevelILFlagCondition(instr.operands[i])
elif operand_type == "int_list":
count = ctypes.c_ulonglong()
operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count)
+ i += 1
value = []
for i in xrange(count.value):
value.append(operand_list[i])
@@ -178,27 +249,26 @@ class LowLevelILInstruction(object):
elif operand_type == "reg_ssa_list":
count = ctypes.c_ulonglong()
operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count)
+ i += 1
value = []
for i in xrange(count.value / 2):
reg = operand_list[i * 2]
- reg_index = operand_list[(i * 2) + 1]
- if (reg & 0x80000000) == 0:
- reg = func.arch.get_reg_name(reg)
- value.append((reg, reg_index))
+ reg_version = operand_list[(i * 2) + 1]
+ value.append(SSARegister(ILRegister(func.arch, reg), reg_version))
core.BNLowLevelILFreeOperandList(operand_list)
elif operand_type == "flag_ssa_list":
count = ctypes.c_ulonglong()
operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count)
+ i += 1
value = []
for i in xrange(count.value / 2):
flag = operand_list[i * 2]
- flag_index = operand_list[(i * 2) + 1]
- if (flag & 0x80000000) == 0:
- flag = func.arch.get_flag_name(flag)
- value.append((flag, flag_index))
+ flag_version = operand_list[(i * 2) + 1]
+ value.append(SSAFlag(ILFlag(func.arch, flag), flag_version))
core.BNLowLevelILFreeOperandList(operand_list)
self.operands.append(value)
self.__dict__[name] = value
+ i += 1
def __str__(self):
tokens = self.tokens
@@ -273,61 +343,76 @@ class LowLevelILInstruction(object):
core.BNFreePossibleValueSet(value)
return result
+ @property
+ def prefix_operands(self):
+ """All operands in the expression tree in prefix order"""
+ result = [LowLevelILOperationAndSize(self.operation, self.size)]
+ for operand in self.operands:
+ if isinstance(operand, LowLevelILInstruction):
+ result += operand.prefix_operands
+ else:
+ result.append(operand)
+ return result
+
+ @property
+ def postfix_operands(self):
+ """All operands in the expression tree in postfix order"""
+ result = []
+ for operand in self.operands:
+ if isinstance(operand, LowLevelILInstruction):
+ result += operand.postfix_operands
+ else:
+ result.append(operand)
+ result.append(LowLevelILOperationAndSize(self.operation, self.size))
+ return result
+
def get_reg_value(self, reg):
- if isinstance(reg, str):
- reg = self.function.arch.regs[reg].index
+ reg = self.function.arch.get_reg_index(reg)
value = core.BNGetLowLevelILRegisterValueAtInstruction(self.function.handle, reg, self.instr_index)
result = function.RegisterValue(self.function.arch, value)
return result
def get_reg_value_after(self, reg):
- if isinstance(reg, str):
- reg = self.function.arch.regs[reg].index
+ reg = self.function.arch.get_reg_index(reg)
value = core.BNGetLowLevelILRegisterValueAfterInstruction(self.function.handle, reg, self.instr_index)
result = function.RegisterValue(self.function.arch, value)
return result
def get_possible_reg_values(self, reg):
- if isinstance(reg, str):
- reg = self.function.arch.regs[reg].index
+ reg = self.function.arch.get_reg_index(reg)
value = core.BNGetLowLevelILPossibleRegisterValuesAtInstruction(self.function.handle, reg, self.instr_index)
result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
def get_possible_reg_values_after(self, reg):
- if isinstance(reg, str):
- reg = self.function.arch.regs[reg].index
+ reg = self.function.arch.get_reg_index(reg)
value = core.BNGetLowLevelILPossibleRegisterValuesAfterInstruction(self.function.handle, reg, self.instr_index)
result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
def get_flag_value(self, flag):
- if isinstance(flag, str):
- flag = self.function.arch.flags[flag].index
+ flag = self.function.arch.get_flag_index(flag)
value = core.BNGetLowLevelILFlagValueAtInstruction(self.function.handle, flag, self.instr_index)
result = function.RegisterValue(self.function.arch, value)
return result
def get_flag_value_after(self, flag):
- if isinstance(flag, str):
- flag = self.function.arch.flags[flag].index
+ flag = self.function.arch.get_flag_index(flag)
value = core.BNGetLowLevelILFlagValueAfterInstruction(self.function.handle, flag, self.instr_index)
result = function.RegisterValue(self.function.arch, value)
return result
def get_possible_flag_values(self, flag):
- if isinstance(flag, str):
- flag = self.function.arch.flags[flag].index
+ flag = self.function.arch.get_flag_index(flag)
value = core.BNGetLowLevelILPossibleFlagValuesAtInstruction(self.function.handle, flag, self.instr_index)
result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
def get_possible_flag_values_after(self, flag):
- if isinstance(flag, str):
- flag = self.function.arch.flags[flag].index
+ flag = self.function.arch.get_flag_index(flag)
value = core.BNGetLowLevelILPossibleFlagValuesAfterInstruction(self.function.handle, flag, self.instr_index)
result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
@@ -589,8 +674,7 @@ class LowLevelILFunction(object):
:return: The expression ``reg = value``
:rtype: LowLevelILExpr
"""
- if isinstance(reg, str):
- reg = self.arch.regs[reg].index
+ reg = self.arch.get_reg_index(reg)
return self.expr(LowLevelILOperation.LLIL_SET_REG, reg, value.index, size = size, flags = flags)
def set_reg_split(self, size, hi, lo, value, flags = 0):
@@ -606,10 +690,8 @@ class LowLevelILFunction(object):
:return: The expression ``hi:lo = value``
:rtype: LowLevelILExpr
"""
- if isinstance(hi, str):
- hi = self.arch.regs[hi].index
- if isinstance(lo, str):
- lo = self.arch.regs[lo].index
+ hi = self.arch.get_reg_index(hi)
+ lo = self.arch.get_reg_index(lo)
return self.expr(LowLevelILOperation.LLIL_SET_REG_SPLIT, hi, lo, value.index, size = size, flags = flags)
def set_flag(self, flag, value):
@@ -676,8 +758,7 @@ class LowLevelILFunction(object):
:return: A register expression for the given string
:rtype: LowLevelILExpr
"""
- if isinstance(reg, str):
- reg = self.arch.regs[reg].index
+ reg = self.arch.get_reg_index(reg)
return self.expr(LowLevelILOperation.LLIL_REG, reg, size=size)
def const(self, size, value):
@@ -1477,18 +1558,16 @@ class LowLevelILFunction(object):
def get_non_ssa_instruction_index(self, instr):
return core.BNGetLowLevelILNonSSAInstructionIndex(self.handle, instr)
- def get_ssa_reg_definition(self, reg, index):
- if isinstance(reg, str):
- reg = self.arch.regs[reg].index
- result = core.BNGetLowLevelILSSARegisterDefinition(self.handle, reg, index)
+ def get_ssa_reg_definition(self, reg_ssa):
+ reg = self.arch.get_reg_index(reg_ssa.reg)
+ result = core.BNGetLowLevelILSSARegisterDefinition(self.handle, reg, reg_ssa.version)
if result >= core.BNGetLowLevelILInstructionCount(self.handle):
return None
return result
- def get_ssa_flag_definition(self, flag, index):
- if isinstance(flag, str):
- flag = self.arch.get_flag_by_name(flag)
- result = core.BNGetLowLevelILSSAFlagDefinition(self.handle, flag, index)
+ def get_ssa_flag_definition(self, flag_ssa):
+ flag = self.arch.get_flag_index(flag_ssa.flag)
+ result = core.BNGetLowLevelILSSAFlagDefinition(self.handle, flag, flag_ssa.version)
if result >= core.BNGetLowLevelILInstructionCount(self.handle):
return None
return result
@@ -1499,22 +1578,20 @@ class LowLevelILFunction(object):
return None
return result
- def get_ssa_reg_uses(self, reg, index):
- if isinstance(reg, str):
- reg = self.arch.regs[reg].index
+ def get_ssa_reg_uses(self, reg_ssa):
+ reg = self.arch.get_reg_index(reg_ssa.reg)
count = ctypes.c_ulonglong()
- instrs = core.BNGetLowLevelILSSARegisterUses(self.handle, reg, index, count)
+ instrs = core.BNGetLowLevelILSSARegisterUses(self.handle, reg, reg_ssa.version, count)
result = []
for i in xrange(0, count.value):
result.append(instrs[i])
core.BNFreeILInstructionList(instrs)
return result
- def get_ssa_flag_uses(self, flag, index):
- if isinstance(flag, str):
- flag = self.arch.get_flag_by_name(flag)
+ def get_ssa_flag_uses(self, flag_ssa):
+ flag = self.arch.get_flag_index(flag_ssa.flag)
count = ctypes.c_ulonglong()
- instrs = core.BNGetLowLevelILSSAFlagUses(self.handle, flag, index, count)
+ instrs = core.BNGetLowLevelILSSAFlagUses(self.handle, flag, flag_ssa.version, count)
result = []
for i in xrange(0, count.value):
result.append(instrs[i])
@@ -1530,17 +1607,15 @@ class LowLevelILFunction(object):
core.BNFreeILInstructionList(instrs)
return result
- def get_ssa_reg_value(self, reg, index):
- if isinstance(reg, str):
- reg = self.arch.regs[reg].index
- value = core.BNGetLowLevelILSSARegisterValue(self.handle, reg, index)
+ def get_ssa_reg_value(self, reg_ssa):
+ reg = self.arch.get_reg_index(reg_ssa.reg)
+ value = core.BNGetLowLevelILSSARegisterValue(self.handle, reg, reg_ssa.version)
result = function.RegisterValue(self.arch, value)
return result
- def get_ssa_flag_value(self, flag, index):
- if isinstance(flag, str):
- flag = self.arch.get_flag_by_name(flag)
- value = core.BNGetLowLevelILSSAFlagValue(self.handle, flag, index)
+ def get_ssa_flag_value(self, flag_ssa):
+ flag = self.arch.get_flag_index(flag_ssa.flag)
+ value = core.BNGetLowLevelILSSAFlagValue(self.handle, flag, flag_ssa.version)
result = function.RegisterValue(self.arch, value)
return result
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index f205714e..e8c5b0f3 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -28,6 +28,15 @@ import basicblock
import lowlevelil
+class SSAVariable(object):
+ def __init__(self, var, version):
+ self.var = var
+ self.version = version
+
+ def __repr__(self):
+ return "<ssa %s version %d>" % (repr(self.var), self.version)
+
+
class MediumLevelILLabel(object):
def __init__(self, handle = None):
if handle is None:
@@ -37,6 +46,17 @@ class MediumLevelILLabel(object):
self.handle = handle
+class MediumLevelILOperationAndSize(object):
+ def __init__(self, operation, size):
+ self.operation = operation
+ self.size = size
+
+ def __repr__(self):
+ if self.size == 0:
+ return "<%s>" % self.operation.name
+ return "<%s %d>" % (self.operation.name, self.size)
+
+
class MediumLevelILInstruction(object):
"""
``class MediumLevelILInstruction`` Medium Level Intermediate Language Instructions are infinite length tree-based
@@ -114,15 +134,15 @@ class MediumLevelILInstruction(object):
MediumLevelILOperation.MLIL_UNDEF: [],
MediumLevelILOperation.MLIL_UNIMPL: [],
MediumLevelILOperation.MLIL_UNIMPL_MEM: [("src", "expr")],
- MediumLevelILOperation.MLIL_SET_VAR_SSA: [("dest", "var"), ("index", "int"), ("src", "expr")],
- MediumLevelILOperation.MLIL_SET_VAR_SSA_FIELD: [("dest", "var"), ("dest_index", "int"), ("src_index", "int"), ("offset", "int"), ("src", "expr")],
+ MediumLevelILOperation.MLIL_SET_VAR_SSA: [("dest", "var_ssa"), ("src", "expr")],
+ MediumLevelILOperation.MLIL_SET_VAR_SSA_FIELD: [("prev", "var_ssa_dest_and_src"), ("offset", "int"), ("src", "expr")],
MediumLevelILOperation.MLIL_SET_VAR_SPLIT_SSA: [("high", "expr"), ("low", "expr"), ("src", "expr")],
- MediumLevelILOperation.MLIL_SET_VAR_ALIASED: [("dest", "var"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "exor")],
- MediumLevelILOperation.MLIL_SET_VAR_ALIASED_FIELD: [("dest", "var"), ("dest_memory", "int"), ("src_memory", "int"), ("offset", "int"), ("src", "exor")],
- MediumLevelILOperation.MLIL_VAR_SSA: [("src", "var"), ("index", "int")],
- MediumLevelILOperation.MLIL_VAR_SSA_FIELD: [("src", "var"), ("index", "int"), ("offset", "int")],
- MediumLevelILOperation.MLIL_VAR_ALIASED: [("src", "var"), ("src_memory", "int")],
- MediumLevelILOperation.MLIL_VAR_ALIASED_FIELD: [("src", "var"), ("src_memory", "int"), ("offset", "int")],
+ MediumLevelILOperation.MLIL_SET_VAR_ALIASED: [("prev", "var_ssa_dest_and_src"), ("src", "expr")],
+ MediumLevelILOperation.MLIL_SET_VAR_ALIASED_FIELD: [("prev", "var_ssa_dest_and_src"), ("offset", "int"), ("src", "expr")],
+ MediumLevelILOperation.MLIL_VAR_SSA: [("src", "var_ssa")],
+ MediumLevelILOperation.MLIL_VAR_SSA_FIELD: [("src", "var_ssa"), ("offset", "int")],
+ MediumLevelILOperation.MLIL_VAR_ALIASED: [("src", "var_ssa")],
+ MediumLevelILOperation.MLIL_VAR_ALIASED_FIELD: [("src", "var_ssa"), ("offset", "int")],
MediumLevelILOperation.MLIL_CALL_SSA: [("output", "expr"), ("dest", "expr"), ("params", "expr_list"), ("src_memory", "int")],
MediumLevelILOperation.MLIL_CALL_UNTYPED_SSA: [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")],
MediumLevelILOperation.MLIL_SYSCALL_SSA: [("output", "expr"), ("params", "expr_list"), ("src_memory", "int")],
@@ -131,7 +151,7 @@ class MediumLevelILInstruction(object):
MediumLevelILOperation.MLIL_CALL_PARAM_SSA: [("src_memory", "int"), ("src", "var_ssa_list")],
MediumLevelILOperation.MLIL_LOAD_SSA: [("src", "expr"), ("src_memory", "int")],
MediumLevelILOperation.MLIL_STORE_SSA: [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")],
- MediumLevelILOperation.MLIL_VAR_PHI: [("dest", "var"), ("index", "int"), ("src", "var_ssa_list")],
+ MediumLevelILOperation.MLIL_VAR_PHI: [("dest", "var_ssa"), ("src", "var_ssa_list")],
MediumLevelILOperation.MLIL_MEM_PHI: [("dest_memory", "int"), ("src_memory", "int_list")]
}
@@ -157,6 +177,19 @@ class MediumLevelILInstruction(object):
value = MediumLevelILInstruction(func, instr.operands[i])
elif operand_type == "var":
value = function.Variable.from_identifier(self.function.source_function, instr.operands[i])
+ elif operand_type == "var_ssa":
+ var = function.Variable.from_identifier(self.function.source_function, instr.operands[i])
+ version = instr.operands[i + 1]
+ i += 1
+ value = SSAVariable(var, version)
+ elif operand_type == "var_ssa_dest_and_src":
+ var = function.Variable.from_identifier(self.function.source_function, instr.operands[i])
+ dest_version = instr.operands[i + 1]
+ src_version = instr.operands[i + 2]
+ i += 2
+ self.operands.append(SSAVariable(var, dest_version))
+ self.dest = SSAVariable(var, dest_version)
+ value = SSAVariable(var, src_version)
elif operand_type == "int_list":
count = ctypes.c_ulonglong()
operand_list = core.BNMediumLevelILGetOperandList(func.handle, self.expr_index, i, count)
@@ -179,9 +212,9 @@ class MediumLevelILInstruction(object):
value = []
for j in xrange(count.value / 2):
var_id = operand_list[j * 2]
- var_index = operand_list[(j * 2) + 1]
- value.append((function.Variable.from_identifier(self.function.source_function,
- var_id), var_index))
+ var_version = operand_list[(j * 2) + 1]
+ value.append(SSAVariable(function.Variable.from_identifier(self.function.source_function,
+ var_id), var_version))
core.BNMediumLevelILFreeOperandList(operand_list)
elif operand_type == "expr_list":
count = ctypes.c_ulonglong()
@@ -281,35 +314,108 @@ class MediumLevelILInstruction(object):
return lowlevelil.LowLevelILInstruction(self.function.low_level_il.ssa_form, expr)
@property
- def ssa_memory_index(self):
- """Index of active memory contents in SSA form for this instruction"""
- return core.BNGetMediumLevelILSSAMemoryIndexAtILInstruction(self.function.handle, self.instr_index)
+ 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)
+
+ @property
+ def prefix_operands(self):
+ """All operands in the expression tree in prefix order"""
+ result = [MediumLevelILOperationAndSize(self.operation, self.size)]
+ for operand in self.operands:
+ if isinstance(operand, MediumLevelILInstruction):
+ result += operand.prefix_operands
+ else:
+ result.append(operand)
+ return result
+
+ @property
+ def postfix_operands(self):
+ """All operands in the expression tree in postfix order"""
+ result = []
+ for operand in self.operands:
+ if isinstance(operand, MediumLevelILInstruction):
+ result += operand.postfix_operands
+ else:
+ result.append(operand)
+ result.append(MediumLevelILOperationAndSize(self.operation, self.size))
+ return result
+
+ @property
+ def vars_written(self):
+ """List of variables written by instruction"""
+ if self.operation in [MediumLevelILOperation.MLIL_SET_VAR, MediumLevelILOperation.MLIL_SET_VAR_FIELD,
+ MediumLevelILOperation.MLIL_SET_VAR_SSA, MediumLevelILOperation.MLIL_SET_VAR_SSA_FIELD,
+ MediumLevelILOperation.MLIL_SET_VAR_ALIASED, MediumLevelILOperation.MLIL_SET_VAR_ALIASED_FIELD,
+ MediumLevelILOperation.MLIL_VAR_PHI]:
+ return [self.dest]
+ elif self.operation in [MediumLevelILOperation.MLIL_SET_VAR_SPLIT, MediumLevelILOperation.MLIL_SET_VAR_SPLIT_SSA]:
+ return [self.high, self.low]
+ elif self.operation in [MediumLevelILOperation.MLIL_CALL, MediumLevelILOperation.MLIL_SYSCALL]:
+ return self.output
+ elif self.operation in [MediumLevelILOperation.MLIL_CALL_UNTYPED, MediumLevelILOperation.MLIL_SYSCALL_UNTYPED,
+ MediumLevelILOperation.MLIL_CALL_SSA, MediumLevelILOperation.MLIL_CALL_UNTYPED_SSA,
+ MediumLevelILOperation.MLIL_SYSCALL_SSA, MediumLevelILOperation.MLIL_SYSCALL_UNTYPED_SSA]:
+ return self.output.vars_written
+ elif self.operation in [MediumLevelILOperation.MLIL_CALL_OUTPUT, MediumLevelILOperation.MLIL_CALL_OUTPUT_SSA]:
+ return self.dest
+ return []
+
+ @property
+ def vars_read(self):
+ """List of variables read by instruction"""
+ if self.operation in [MediumLevelILOperation.MLIL_SET_VAR, MediumLevelILOperation.MLIL_SET_VAR_FIELD,
+ MediumLevelILOperation.MLIL_SET_VAR_SPLIT, MediumLevelILOperation.MLIL_SET_VAR_SSA,
+ MediumLevelILOperation.MLIL_SET_VAR_SPLIT_SSA, MediumLevelILOperation.MLIL_SET_VAR_ALIASED]:
+ return self.src.vars_read
+ elif self.operation in [MediumLevelILOperation.MLIL_SET_VAR_SSA_FIELD,
+ MediumLevelILOperation.MLIL_SET_VAR_ALIASED_FIELD]:
+ return [self.prev] + self.src.vars_read
+ elif self.operation in [MediumLevelILOperation.MLIL_CALL, MediumLevelILOperation.MLIL_SYSCALL,
+ MediumLevelILOperation.MLIL_CALL_SSA, MediumLevelILOperation.MLIL_SYSCALL_SSA]:
+ result = []
+ for param in self.params:
+ result += param.vars_read
+ return result
+ elif self.operation in [MediumLevelILOperation.MLIL_CALL_UNTYPED, MediumLevelILOperation.MLIL_SYSCALL_UNTYPED,
+ MediumLevelILOperation.MLIL_CALL_UNTYPED_SSA, MediumLevelILOperation.MLIL_SYSCALL_UNTYPED_SSA]:
+ return self.params.vars_read
+ elif self.operation in [MediumLevelILOperation.MLIL_CALL_PARAM, MediumLevelILOperation.MLIL_CALL_PARAM_SSA,
+ MediumLevelILOperation.MLIL_VAR_PHI]:
+ return self.src
+ elif self.operation in [MediumLevelILOperation.MLIL_CALL_OUTPUT, MediumLevelILOperation.MLIL_CALL_OUTPUT_SSA]:
+ return []
+ result = []
+ for operand in self.operands:
+ if (isinstance(operand, function.Variable)) or (isinstance(operand, SSAVariable)):
+ result.append(operand)
+ elif isinstance(operand, MediumLevelILInstruction):
+ result += operand.vars_read
+ return result
- def get_ssa_var_possible_values(self, var, index):
+ def get_ssa_var_possible_values(self, ssa_var):
var_data = core.BNVariable()
- var_data.type = var.source_type
- var_data.index = var.index
- var_data.storage = var.storage
- value = core.BNGetMediumLevelILPossibleSSAVarValues(self.function.handle, var_data, index, self.instr_index)
+ var_data.type = ssa_var.var.source_type
+ var_data.index = ssa_var.var.index
+ var_data.storage = ssa_var.var.storage
+ value = core.BNGetMediumLevelILPossibleSSAVarValues(self.function.handle, var_data, ssa_var.version, self.instr_index)
result = function.RegisterValue(self.function.arch, value)
return result
- def get_ssa_var_index(self, var):
+ def get_ssa_var_version(self, var):
var_data = core.BNVariable()
var_data.type = var.source_type
var_data.index = var.index
var_data.storage = var.storage
- return core.BNGetMediumLevelILSSAVarIndexAtILInstruction(self.function.handle, var_data, self.instr_index)
+ return core.BNGetMediumLevelILSSAVarVersionAtILInstruction(self.function.handle, var_data, self.instr_index)
def get_var_for_reg(self, reg):
- if isinstance(reg, str):
- reg = self.function.arch.regs[reg].index
+ reg = self.function.arch.get_reg_index(reg)
result = core.BNGetMediumLevelILVariableForRegisterAtInstruction(self.function.handle, reg, self.instr_index)
return function.Variable(self.function.source_function, result.type, result.index, result.storage)
def get_var_for_flag(self, flag):
- if isinstance(flag, str):
- flag = self.function.arch.regs[flag].index
+ flag = self.function.arch.get_flag_index(flag)
result = core.BNGetMediumLevelILVariableForFlagAtInstruction(self.function.handle, flag, self.instr_index)
return function.Variable(self.function.source_function, result.type, result.index, result.storage)
@@ -318,60 +424,52 @@ class MediumLevelILInstruction(object):
return function.Variable(self.function.source_function, result.type, result.index, result.storage)
def get_reg_value(self, reg):
- if isinstance(reg, str):
- reg = self.function.arch.regs[reg].index
+ reg = self.function.arch.get_reg_index(reg)
value = core.BNGetMediumLevelILRegisterValueAtInstruction(self.function.handle, reg, self.instr_index)
result = function.RegisterValue(self.function.arch, value)
return result
def get_reg_value_after(self, reg):
- if isinstance(reg, str):
- reg = self.function.arch.regs[reg].index
+ reg = self.function.arch.get_reg_index(reg)
value = core.BNGetMediumLevelILRegisterValueAfterInstruction(self.function.handle, reg, self.instr_index)
result = function.RegisterValue(self.function.arch, value)
return result
def get_possible_reg_values(self, reg):
- if isinstance(reg, str):
- reg = self.function.arch.regs[reg].index
+ reg = self.function.arch.get_reg_index(reg)
value = core.BNGetMediumLevelILPossibleRegisterValuesAtInstruction(self.function.handle, reg, self.instr_index)
result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
def get_possible_reg_values_after(self, reg):
- if isinstance(reg, str):
- reg = self.function.arch.regs[reg].index
+ reg = self.function.arch.get_reg_index(reg)
value = core.BNGetMediumLevelILPossibleRegisterValuesAfterInstruction(self.function.handle, reg, self.instr_index)
result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
def get_flag_value(self, flag):
- if isinstance(flag, str):
- flag = self.function.arch.flags[flag].index
+ flag = self.function.arch.get_flag_index(flag)
value = core.BNGetMediumLevelILFlagValueAtInstruction(self.function.handle, flag, self.instr_index)
result = function.RegisterValue(self.function.arch, value)
return result
def get_flag_value_after(self, flag):
- if isinstance(flag, str):
- flag = self.function.arch.flags[flag].index
+ flag = self.function.arch.get_flag_index(flag)
value = core.BNGetMediumLevelILFlagValueAfterInstruction(self.function.handle, flag, self.instr_index)
result = function.RegisterValue(self.function.arch, value)
return result
def get_possible_flag_values(self, flag):
- if isinstance(flag, str):
- flag = self.function.arch.flags[flag].index
+ flag = self.function.arch.get_flag_index(flag)
value = core.BNGetMediumLevelILPossibleFlagValuesAtInstruction(self.function.handle, flag, self.instr_index)
result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
def get_possible_flag_values_after(self, flag):
- if isinstance(flag, str):
- flag = self.function.arch.flags[flag].index
+ flag = self.function.arch.get_flag_index(flag)
value = core.BNGetMediumLevelILPossibleFlagValuesAfterInstruction(self.function.handle, flag, self.instr_index)
result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
@@ -644,50 +742,50 @@ class MediumLevelILFunction(object):
def get_non_ssa_instruction_index(self, instr):
return core.BNGetMediumLevelILNonSSAInstructionIndex(self.handle, instr)
- def get_ssa_var_definition(self, var, index):
+ def get_ssa_var_definition(self, ssa_var):
var_data = core.BNVariable()
- var_data.type = var.source_type
- var_data.index = var.index
- var_data.storage = var.storage
- result = core.BNGetMediumLevelILSSAVarDefinition(self.handle, var_data, index)
+ var_data.type = ssa_var.var.source_type
+ var_data.index = ssa_var.var.index
+ var_data.storage = ssa_var.var.storage
+ result = core.BNGetMediumLevelILSSAVarDefinition(self.handle, var_data, ssa_var.version)
if result >= core.BNGetMediumLevelILInstructionCount(self.handle):
return None
return result
- def get_ssa_memory_definition(self, index):
- result = core.BNGetMediumLevelILSSAMemoryDefinition(self.handle, index)
+ def get_ssa_memory_definition(self, version):
+ result = core.BNGetMediumLevelILSSAMemoryDefinition(self.handle, version)
if result >= core.BNGetMediumLevelILInstructionCount(self.handle):
return None
return result
- def get_ssa_var_uses(self, var, index):
+ def get_ssa_var_uses(self, ssa_var):
count = ctypes.c_ulonglong()
var_data = core.BNVariable()
- var_data.type = var.source_type
- var_data.index = var.index
- var_data.storage = var.storage
- instrs = core.BNGetMediumLevelILSSAVarUses(self.handle, var_data, index, count)
+ var_data.type = ssa_var.var.source_type
+ var_data.index = ssa_var.var.index
+ var_data.storage = ssa_var.var.storage
+ instrs = core.BNGetMediumLevelILSSAVarUses(self.handle, var_data, ssa_var.version, count)
result = []
for i in xrange(0, count.value):
result.append(instrs[i])
core.BNFreeILInstructionList(instrs)
return result
- def get_ssa_memory_uses(self, index):
+ def get_ssa_memory_uses(self, version):
count = ctypes.c_ulonglong()
- instrs = core.BNGetMediumLevelILSSAMemoryUses(self.handle, index, count)
+ instrs = core.BNGetMediumLevelILSSAMemoryUses(self.handle, version, count)
result = []
for i in xrange(0, count.value):
result.append(instrs[i])
core.BNFreeILInstructionList(instrs)
return result
- def get_ssa_var_value(self, var, index):
+ def get_ssa_var_value(self, ssa_var):
var_data = core.BNVariable()
- var_data.type = var.source_type
- var_data.index = var.index
- var_data.storage = var.storage
- value = core.BNGetMediumLevelILSSAVarValue(self.handle, var_data, index)
+ var_data.type = ssa_var.var.source_type
+ var_data.index = ssa_var.var.index
+ var_data.storage = ssa_var.var.storage
+ value = core.BNGetMediumLevelILSSAVarValue(self.handle, var_data, ssa_var.version)
result = function.RegisterValue(self.arch, value)
return result