summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2017-10-03 23:07:48 -0400
committerPeter LaFosse <peter@vector35.com>2018-03-23 17:10:05 -0400
commitceab7825606b37d1dc142f73931660c9600b340d (patch)
treeccdf6ce16485d20e9b71249db7e0c8d57542992a /python
parentc7e9bb6b63e96a6cc779f3f1f64556ebe71b9bfb (diff)
Adding support for register stacks in IL (for x87)
Diffstat (limited to 'python')
-rw-r--r--python/architecture.py101
-rw-r--r--python/callingconvention.py4
-rw-r--r--python/function.py59
-rw-r--r--python/lowlevelil.py165
-rw-r--r--python/mediumlevelil.py9
5 files changed, 336 insertions, 2 deletions
diff --git a/python/architecture.py b/python/architecture.py
index a893c1d4..ea9d40ab 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -123,6 +123,7 @@ class Architecture(object):
flag_roles = {}
flags_required_for_flag_condition = {}
flags_written_by_flag_write_type = {}
+ reg_stacks = {}
__metaclass__ = _ArchitectureMetaClass
next_address = 0
@@ -218,6 +219,19 @@ class Architecture(object):
for i in xrange(0, count.value):
self.global_regs.append(core.BNGetArchitectureRegisterName(self.handle, regs[i]))
core.BNFreeRegisterList(regs)
+
+ count = ctypes.c_ulonglong()
+ regs = core.BNGetAllArchitectureRegisterStacks(self.handle, count)
+ self.__dict__["reg_stacks"] = {}
+ for i in xrange(0, count.value):
+ name = core.BNGetArchitectureRegisterStackName(self.handle, regs[i])
+ info = core.BNGetArchitectureRegisterStackInfo(self.handle, regs[i])
+ storage = []
+ for j in xrange(0, info.count):
+ storage.append(core.BNGetArchitectureRegisterName(self.handle, info.firstStorageReg + j))
+ top = core.BNGetArchitectureRegisterName(self.handle, info.stackTopReg)
+ self.reg_stacks[name] = function.RegisterStackInfo(storage, top)
+ core.BNFreeRegisterList(regs)
else:
startup._init_plugins()
@@ -262,6 +276,9 @@ class Architecture(object):
self._get_stack_pointer_register)
self._cb.getLinkRegister = self._cb.getLinkRegister.__class__(self._get_link_register)
self._cb.getGlobalRegisters = self._cb.getGlobalRegisters.__class__(self._get_global_registers)
+ self._cb.getRegisterStackName = self._cb.getRegisterStackName.__class__(self._get_register_stack_name)
+ self._cb.getAllRegisterStacks = self._cb.getAllRegisterStacks.__class__(self._get_all_register_stacks)
+ self._cb.getRegisterStackInfo = self._cb.getRegisterStackInfo.__class__(self._get_register_stack_info)
self._cb.assemble = self._cb.assemble.__class__(self._assemble)
self._cb.isNeverBranchPatchAvailable = self._cb.isNeverBranchPatchAvailable.__class__(
self._is_never_branch_patch_available)
@@ -283,6 +300,25 @@ class Architecture(object):
self._regs_by_index = {}
self.__dict__["regs"] = self.__class__.regs
reg_index = 0
+
+ # Registers used for storage in register stacks must be sequential, so allocate these in order first
+ self._all_reg_stacks = {}
+ self._reg_stacks_by_index = {}
+ self.__dict__["reg_stacks"] = self.__class__.reg_stacks
+ reg_stack_index = 0
+ for reg_stack in self.reg_stacks:
+ info = self.reg_stacks[reg_stack]
+ for reg in info.storage_regs:
+ self._all_regs[reg] = reg_index
+ self._regs_by_index[reg_index] = reg
+ self.regs[reg].index = reg_index
+ reg_index += 1
+ if reg_stack not in self._all_reg_stacks:
+ self._all_reg_stacks[reg_stack] = reg_stack_index
+ self._reg_stacks_by_index[reg_stack_index] = reg_stack
+ self.reg_stacks[reg_stack].index = reg_stack_index
+ reg_stack_index += 1
+
for reg in self.regs:
info = self.regs[reg]
if reg not in self._all_regs:
@@ -756,6 +792,47 @@ class Architecture(object):
count[0] = 0
return None
+ def _get_register_stack_name(self, ctxt, reg_stack):
+ try:
+ if reg_stack in self._reg_stacks_by_index:
+ return core.BNAllocString(self._reg_stacks_by_index[reg_stack])
+ return core.BNAllocString("")
+ except (KeyError, OSError):
+ log.log_error(traceback.format_exc())
+ return core.BNAllocString("")
+
+ def _get_all_register_stacks(self, ctxt, count):
+ try:
+ regs = self._reg_stacks_by_index.keys()
+ count[0] = len(regs)
+ reg_buf = (ctypes.c_uint * len(regs))()
+ for i in xrange(0, len(regs)):
+ reg_buf[i] = regs[i]
+ result = ctypes.cast(reg_buf, ctypes.c_void_p)
+ self._pending_reg_lists[result.value] = (result, reg_buf)
+ return result.value
+ except KeyError:
+ log.log_error(traceback.format_exc())
+ count[0] = 0
+ return None
+
+ def _get_register_stack_info(self, ctxt, reg_stack, result):
+ try:
+ if reg_stack not in self._reg_stacks_by_index:
+ result[0].firstStorageReg = 0
+ result[0].count = 0
+ result[0].stackTopReg = 0
+ return
+ info = self.__class__.regs[self._reg_stacks_by_index[reg_stack]]
+ result[0].firstStorageReg = self._all_regs[info.storage_regs[0]]
+ result[0].count = len(info.storage_regs)
+ result[0].stackTopReg = self._all_regs[info.stack_top_reg]
+ except KeyError:
+ log.log_error(traceback.format_exc())
+ result[0].firstStorageReg = 0
+ result[0].count = 0
+ result[0].stackTopReg = 0
+
def _assemble(self, ctxt, code, addr, result, errors):
try:
data, error_str = self.perform_assemble(code, addr)
@@ -1264,6 +1341,23 @@ class Architecture(object):
"""
return core.BNGetArchitectureRegisterName(self.handle, reg)
+ def get_reg_stack_name(self, reg_stack):
+ """
+ ``get_reg_stack_name`` gets a register stack name from a register stack number.
+
+ :param int reg_stack: register stack number
+ :return: the corresponding register string
+ :rtype: str
+ """
+ return core.BNGetArchitectureRegisterStackName(self.handle, reg_stack)
+
+ def get_reg_stack_for_reg(self, reg):
+ reg = self.get_reg_index(reg)
+ result = core.BNGetArchitectureRegisterStackForRegister(self.handle, reg)
+ if result == 0xffffffff:
+ return None
+ return self.get_reg_stack_name(result)
+
def get_flag_name(self, flag):
"""
``get_flag_name`` gets a flag name from a flag number.
@@ -1281,6 +1375,13 @@ class Architecture(object):
return reg.index
return reg
+ def get_reg_stack_index(self, reg_stack):
+ if isinstance(reg_stack, str):
+ return self.reg_stacks[reg_stack].index
+ elif isinstance(reg_stack, lowlevelil.ILRegisterStack):
+ return reg_stack.index
+ return reg_stack
+
def get_flag_index(self, flag):
if isinstance(flag, str):
return self._flags[flag]
diff --git a/python/callingconvention.py b/python/callingconvention.py
index e72475c9..18662fc5 100644
--- a/python/callingconvention.py
+++ b/python/callingconvention.py
@@ -308,6 +308,10 @@ class CallingConvention(object):
return self.name
def perform_get_incoming_reg_value(self, reg, func):
+ reg_stack = self.arch.get_reg_stack_for_reg(reg)
+ if reg_stack is not None:
+ if reg == self.arch.reg_stacks[reg_stack].stack_top_reg:
+ return function.RegisterValue.constant(0)
return function.RegisterValue()
def perform_get_incoming_flag_value(self, reg, func):
diff --git a/python/function.py b/python/function.py
index 58bee8f4..13979e37 100644
--- a/python/function.py
+++ b/python/function.py
@@ -51,11 +51,11 @@ class LookupTableEntry(object):
class RegisterValue(object):
def __init__(self, arch = None, value = None, confidence = types.max_confidence):
+ self.is_constant = False
if value is None:
self.type = RegisterValueType.UndeterminedValue
else:
self.type = RegisterValueType(value.state)
- self.is_constant = False
if value.state == RegisterValueType.EntryValue:
self.arch = arch
if arch is not None:
@@ -103,6 +103,54 @@ class RegisterValue(object):
result.value = self.value
return result
+ @classmethod
+ def undetermined(self):
+ return RegisterValue()
+
+ @classmethod
+ def entry_value(self, arch, reg):
+ result = RegisterValue()
+ result.type = RegisterValueType.EntryValue
+ result.arch = arch
+ result.reg = reg
+ return result
+
+ @classmethod
+ def constant(self, value):
+ result = RegisterValue()
+ result.type = RegisterValueType.ConstantValue
+ result.value = value
+ result.is_constant = True
+ return result
+
+ @classmethod
+ def constant_ptr(self, value):
+ result = RegisterValue()
+ result.type = RegisterValueType.ConstantPointerValue
+ result.value = value
+ result.is_constant = True
+ return result
+
+ @classmethod
+ def stack_frame_offset(self, offset):
+ result = RegisterValue()
+ result.type = RegisterValueType.StackFrameOffset
+ result.offset = offset
+ return result
+
+ @classmethod
+ def imported_address(self, value):
+ result = RegisterValue()
+ result.type = RegisterValueType.ImportedAddressValue
+ result.value = value
+ return result
+
+ @classmethod
+ def return_address(self):
+ result = RegisterValue()
+ result.type = RegisterValueType.ReturnAddressValue
+ return result
+
class ValueRange(object):
def __init__(self, start, end, step):
@@ -1739,6 +1787,15 @@ class RegisterInfo(object):
return "<reg: size %d, offset %d in %s%s>" % (self.size, self.offset, self.full_width_reg, extend)
+class RegisterStackInfo(object):
+ def __init__(self, storage_regs, stack_top_reg):
+ self.storage_regs = storage_regs
+ self.stack_top_reg = stack_top_reg
+
+ def __repr__(self):
+ return "<reg stack: %d regs, stack top in %s>" % (len(self.storage_regs), self.stack_top_reg)
+
+
class InstructionBranch(object):
def __init__(self, branch_type, target = 0, arch = None):
self.type = branch_type
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index d9b00271..5f389206 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -26,6 +26,7 @@ from .enums import LowLevelILOperation, LowLevelILFlagCondition, InstructionText
import function
import basicblock
import mediumlevelil
+import struct
class LowLevelILLabel(object):
@@ -61,6 +62,26 @@ class ILRegister(object):
return self.info == other.info
+class ILRegisterStack(object):
+ def __init__(self, arch, reg_stack):
+ self.arch = arch
+ self.index = reg_stack
+ self.name = self.arch.get_reg_stack_name(self.index)
+
+ @property
+ def info(self):
+ return self.arch.reg_stacks[self.name]
+
+ def __str__(self):
+ return self.name
+
+ def __repr__(self):
+ return self.name
+
+ def __eq__(self, other):
+ return self.info == other.info
+
+
class ILFlag(object):
def __init__(self, arch, flag):
self.arch = arch
@@ -87,6 +108,15 @@ class SSARegister(object):
return "<ssa %s version %d>" % (repr(self.reg), self.version)
+class SSARegisterStack(object):
+ def __init__(self, reg_stack, version):
+ self.reg_stack = reg_stack
+ self.version = version
+
+ def __repr__(self):
+ return "<ssa %s version %d>" % (repr(self.reg_stack), self.version)
+
+
class SSAFlag(object):
def __init__(self, flag, version):
self.flag = flag
@@ -118,15 +148,20 @@ class LowLevelILInstruction(object):
LowLevelILOperation.LLIL_NOP: [],
LowLevelILOperation.LLIL_SET_REG: [("dest", "reg"), ("src", "expr")],
LowLevelILOperation.LLIL_SET_REG_SPLIT: [("hi", "reg"), ("lo", "reg"), ("src", "expr")],
+ LowLevelILOperation.LLIL_SET_REG_STACK_REL: [("stack", "reg_stack"), ("dest", "expr"), ("src", "expr")],
+ LowLevelILOperation.LLIL_REG_STACK_PUSH: [("stack", "reg_stack"), ("src", "expr")],
LowLevelILOperation.LLIL_SET_FLAG: [("dest", "flag"), ("src", "expr")],
LowLevelILOperation.LLIL_LOAD: [("src", "expr")],
LowLevelILOperation.LLIL_STORE: [("dest", "expr"), ("src", "expr")],
LowLevelILOperation.LLIL_PUSH: [("src", "expr")],
LowLevelILOperation.LLIL_POP: [],
LowLevelILOperation.LLIL_REG: [("src", "reg")],
- LowLevelILOperation.LLIL_REG_SPLIT: [("hi", "reg", "lo", "reg")],
+ LowLevelILOperation.LLIL_REG_SPLIT: [("hi", "reg"), ("lo", "reg")],
+ LowLevelILOperation.LLIL_REG_STACK_REL: [("stack", "reg_stack"), ("src", "expr")],
+ LowLevelILOperation.LLIL_REG_STACK_POP: [("stack", "reg_stack")],
LowLevelILOperation.LLIL_CONST: [("constant", "int")],
LowLevelILOperation.LLIL_CONST_PTR: [("constant", "int")],
+ LowLevelILOperation.LLIL_FLOAT_CONST: [("constant", "float")],
LowLevelILOperation.LLIL_FLAG: [("src", "flag")],
LowLevelILOperation.LLIL_FLAG_BIT: [("src", "flag"), ("bit", "int")],
LowLevelILOperation.LLIL_ADD: [("left", "expr"), ("right", "expr")],
@@ -207,10 +242,15 @@ class LowLevelILInstruction(object):
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_SET_REG_STACK_REL_SSA: [("stack", "expr"), ("dest", "expr"), ("top", "expr"), ("src", "expr")],
+ LowLevelILOperation.LLIL_SET_REG_STACK_ABS_SSA: [("stack", "expr"), ("dest", "reg"), ("src", "expr")],
LowLevelILOperation.LLIL_REG_SPLIT_DEST_SSA: [("dest", "reg_ssa")],
+ LowLevelILOperation.LLIL_REG_STACK_DEST_SSA: [("src", "reg_stack_ssa_dest_and_src")],
LowLevelILOperation.LLIL_REG_SSA: [("src", "reg_ssa")],
LowLevelILOperation.LLIL_REG_SSA_PARTIAL: [("full_reg", "reg_ssa"), ("src", "reg")],
LowLevelILOperation.LLIL_REG_SPLIT_SSA: [("hi", "reg_ssa"), ("lo", "reg_ssa")],
+ LowLevelILOperation.LLIL_REG_STACK_REL_SSA: [("stack", "reg_stack_ssa"), ("src", "expr"), ("top", "expr")],
+ LowLevelILOperation.LLIL_REG_STACK_ABS_SSA: [("stack", "reg_stack_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")],
@@ -222,6 +262,7 @@ class LowLevelILInstruction(object):
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_ssa"), ("src", "reg_ssa_list")],
+ LowLevelILOperation.LLIL_REG_STACK_PHI: [("dest", "reg_stack_ssa"), ("src", "reg_stack_ssa_list")],
LowLevelILOperation.LLIL_FLAG_PHI: [("dest", "flag_ssa"), ("src", "flag_ssa_list")],
LowLevelILOperation.LLIL_MEM_PHI: [("dest_memory", "int"), ("src_memory", "int_list")]
}
@@ -248,14 +289,35 @@ class LowLevelILInstruction(object):
name, operand_type = operand
if operand_type == "int":
value = instr.operands[i]
+ elif operand_type == "float":
+ if instr.size == 4:
+ value = struct.unpack("f", struct.pack("I", instr.operands[i] & 0xffffffff))[0]
+ elif instr.size == 8:
+ value = struct.unpack("d", struct.pack("Q", instr.operands[i]))[0]
+ else:
+ value = instr.operands[i]
elif operand_type == "expr":
value = LowLevelILInstruction(func, instr.operands[i])
elif operand_type == "reg":
value = ILRegister(func.arch, instr.operands[i])
+ elif operand_type == "reg_stack":
+ value = ILRegisterStack(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 == "reg_stack_ssa":
+ reg_stack = ILRegisterStack(func.arch, instr.operands[i])
+ i += 1
+ value = SSARegisterStack(reg_stack, instr.operands[i])
+ elif operand_type == "reg_stack_ssa_dest_and_src":
+ reg_stack = ILRegisterStack(func.arch, instr.operands[i])
+ i += 1
+ value = SSARegisterStack(reg_stack, instr.operands[i])
+ i += 1
+ self.operands.append(value)
+ self.dest = value
+ value = SSARegisterStack(reg_stack, instr.operands[i])
elif operand_type == "flag":
value = ILFlag(func.arch, instr.operands[i])
elif operand_type == "flag_ssa":
@@ -282,6 +344,16 @@ class LowLevelILInstruction(object):
reg_version = operand_list[(i * 2) + 1]
value.append(SSARegister(ILRegister(func.arch, reg), reg_version))
core.BNLowLevelILFreeOperandList(operand_list)
+ elif operand_type == "reg_stack_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_stack = operand_list[i * 2]
+ reg_version = operand_list[(i * 2) + 1]
+ value.append(SSARegisterStack(ILRegisterStack(func.arch, reg_stack), 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)
@@ -729,6 +801,38 @@ class LowLevelILFunction(object):
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_reg_stack_top_relative(self, size, reg_stack, entry, value, flags = 0):
+ """
+ ``set_reg_stack_top_relative`` sets the top-relative entry ``entry`` of size ``size`` in register
+ stack ``reg_stack`` to the expression ``value``
+
+ :param int size: size of the register parameter in bytes
+ :param str reg_stack: the register stack name
+ :param LowLevelILExpr entry: an expression for which stack entry to set
+ :param LowLevelILExpr value: an expression to set the entry to
+ :param str flags: which flags are set by this operation
+ :return: The expression ``reg_stack[entry] = value``
+ :rtype: LowLevelILExpr
+ """
+ reg_stack = self.arch.get_reg_stack_index(reg_stack)
+ return self.expr(LowLevelILOperation.LLIL_SET_REG_STACK_REL, reg_stack, entry.index, value.index,
+ size = size, flags = flags)
+
+ def reg_stack_push(self, size, reg_stack, value, flags = 0):
+ """
+ ``reg_stack_push`` pushes the expression ``value`` of size ``size`` onto the top of the register
+ stack ``reg_stack``
+
+ :param int size: size of the register parameter in bytes
+ :param str reg_stack: the register stack name
+ :param LowLevelILExpr value: an expression to push
+ :param str flags: which flags are set by this operation
+ :return: The expression ``reg_stack.push(value)``
+ :rtype: LowLevelILExpr
+ """
+ reg_stack = self.arch.get_reg_stack_index(reg_stack)
+ return self.expr(LowLevelILOperation.LLIL_REG_STACK_PUSH, reg_stack, value.index, size = size, flags = flags)
+
def set_flag(self, flag, value):
"""
``set_flag`` sets the flag ``flag`` to the LowLevelILExpr ``value``
@@ -811,6 +915,33 @@ class LowLevelILFunction(object):
lo = self.arch.get_reg_index(lo)
return self.expr(LowLevelILOperation.LLIL_REG_SPLIT, hi, lo, size=size)
+ def reg_stack_top_relative(self, size, reg_stack, entry):
+ """
+ ``reg_stack_top_relative`` returns a register stack entry of size ``size`` at top-relative
+ location ``entry`` in register stack with name ``reg_stack``
+
+ :param int size: the size of the register in bytes
+ :param str reg_stack: the name of the register stack
+ :param LowLevelILExpr entry: an expression for which stack entry to fetch
+ :return: The expression ``reg_stack[entry]``
+ :rtype: LowLevelILExpr
+ """
+ reg_stack = self.arch.get_reg_stack_index(reg_stack)
+ return self.expr(LowLevelILOperation.LLIL_REG_STACK_REL, reg_stack, entry.index, size=size)
+
+ def reg_stack_pop(self, size, reg_stack):
+ """
+ ``reg_stack_pop`` returns the top entry of size ``size`` in register stack with name ``reg_stack``, and
+ removes the entry from the stack
+
+ :param int size: the size of the register in bytes
+ :param str reg_stack: the name of the register stack
+ :return: The expression ``reg_stack.pop``
+ :rtype: LowLevelILExpr
+ """
+ reg_stack = self.arch.get_reg_stack_index(reg_stack)
+ return self.expr(LowLevelILOperation.LLIL_REG_STACK_POP, reg_stack, size=size)
+
def const(self, size, value):
"""
``const`` returns an expression for the constant integer ``value`` with size ``size``
@@ -833,6 +964,38 @@ class LowLevelILFunction(object):
"""
return self.expr(LowLevelILOperation.LLIL_CONST_PTR, value, size=size)
+ def float_const_raw(self, size, value):
+ """
+ ``float_const_raw`` returns an expression for the constant raw binary floating point
+ value ``value`` with size ``size``
+
+ :param int size: the size of the constant in bytes
+ :param int value: integer value for the raw binary representation of the constant
+ :return: A constant expression of given value and size
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_FLOAT_CONST, value, size=size)
+
+ def float_const_single(self, value):
+ """
+ ``float_const_single`` returns an expression for the single precision floating point value ``value``
+
+ :param float value: float value for the constant
+ :return: A constant expression of given value and size
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_FLOAT_CONST, struct.unpack("I", struct.pack("f", value))[0], size=4)
+
+ def float_const_double(self, value):
+ """
+ ``float_const_double`` returns an expression for the double precision floating point value ``value``
+
+ :param float value: float value for the constant
+ :return: A constant expression of given value and size
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_FLOAT_CONST, struct.unpack("Q", struct.pack("d", value))[0], size=8)
+
def flag(self, reg):
"""
``flag`` returns a flag expression for the given flag name.
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index be8e7b6e..85feba0a 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -27,6 +27,7 @@ import function
import basicblock
import lowlevelil
import types
+import struct
class SSAVariable(object):
@@ -90,6 +91,7 @@ class MediumLevelILInstruction(object):
MediumLevelILOperation.MLIL_ADDRESS_OF_FIELD: [("src", "var"), ("offset", "int")],
MediumLevelILOperation.MLIL_CONST: [("constant", "int")],
MediumLevelILOperation.MLIL_CONST_PTR: [("constant", "int")],
+ MediumLevelILOperation.MLIL_FLOAT_CONST: [("constant", "float")],
MediumLevelILOperation.MLIL_IMPORT: [("constant", "int")],
MediumLevelILOperation.MLIL_ADD: [("left", "expr"), ("right", "expr")],
MediumLevelILOperation.MLIL_ADC: [("left", "expr"), ("right", "expr"), ("carry", "expr")],
@@ -211,6 +213,13 @@ class MediumLevelILInstruction(object):
name, operand_type = operand
if operand_type == "int":
value = instr.operands[i]
+ elif operand_type == "float":
+ if instr.size == 4:
+ value = struct.unpack("f", struct.pack("I", instr.operands[i] & 0xffffffff))[0]
+ elif instr.size == 8:
+ value = struct.unpack("d", struct.pack("Q", instr.operands[i]))[0]
+ else:
+ value = instr.operands[i]
elif operand_type == "expr":
value = MediumLevelILInstruction(func, instr.operands[i])
elif operand_type == "var":