summaryrefslogtreecommitdiff
path: root/python/lowlevelil.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/lowlevelil.py')
-rw-r--r--python/lowlevelil.py229
1 files changed, 152 insertions, 77 deletions
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