summaryrefslogtreecommitdiff
path: root/python/lowlevelil.py
diff options
context:
space:
mode:
authorAndrew Lamoureux <lwerdna@users.noreply.github.com>2017-03-15 20:33:55 -0400
committerGitHub <noreply@github.com>2017-03-15 20:33:55 -0400
commit31d34d5d067ed4c5fe071eb8637b10ed50607555 (patch)
tree9347ba4e5e6a2b26baf620f59e56db7965bb47b5 /python/lowlevelil.py
parent164c7a680697be72d7f42af28b89012e5c6dd53b (diff)
parent1f7523ce2b1edac1014d781fc771d5b82568e2f1 (diff)
Merge branch 'dev' into dev
Diffstat (limited to 'python/lowlevelil.py')
-rw-r--r--python/lowlevelil.py1294
1 files changed, 1294 insertions, 0 deletions
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
new file mode 100644
index 00000000..c80fcd0d
--- /dev/null
+++ b/python/lowlevelil.py
@@ -0,0 +1,1294 @@
+# Copyright (c) 2015-2016 Vector 35 LLC
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+import ctypes
+
+# Binary Ninja components
+import _binaryninjacore as core
+from .enums import LowLevelILOperation, LowLevelILFlagCondition, InstructionTextTokenType
+import function
+import basicblock
+
+
+class LowLevelILLabel(object):
+ def __init__(self, handle = None):
+ if handle is None:
+ self.handle = (core.BNLowLevelILLabel * 1)()
+ core.BNLowLevelILInitLabel(self.handle)
+ else:
+ self.handle = handle
+
+
+class LowLevelILInstruction(object):
+ """
+ ``class LowLevelILInstruction`` Low Level Intermediate Language Instructions are infinite length tree-based
+ instructions. Tree-based instructions use infix notation with the left hand operand being the destination operand.
+ Infix notation is thus more natural to read than other notations (e.g. x86 ``mov eax, 0`` vs. LLIL ``eax = 0``).
+ """
+
+ ILOperations = {
+ 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_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_CONST: [("value", "int")],
+ LowLevelILOperation.LLIL_FLAG: [("src", "flag")],
+ LowLevelILOperation.LLIL_FLAG_BIT: [("src", "flag"), ("bit", "int")],
+ LowLevelILOperation.LLIL_ADD: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_ADC: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_SUB: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_SBB: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_AND: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_OR: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_XOR: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_LSL: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_LSR: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_ASR: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_ROL: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_RLC: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_ROR: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_RRC: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_MUL: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_MULU_DP: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_MULS_DP: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_DIVU: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_DIVU_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_DIVS: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_DIVS_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_MODU: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_MODU_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_MODS: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_MODS_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_NEG: [("src", "expr")],
+ LowLevelILOperation.LLIL_NOT: [("src", "expr")],
+ LowLevelILOperation.LLIL_SX: [("src", "expr")],
+ LowLevelILOperation.LLIL_ZX: [("src", "expr")],
+ LowLevelILOperation.LLIL_JUMP: [("dest", "expr")],
+ LowLevelILOperation.LLIL_JUMP_TO: [("dest", "expr"), ("targets", "int_list")],
+ LowLevelILOperation.LLIL_CALL: [("dest", "expr")],
+ LowLevelILOperation.LLIL_RET: [("dest", "expr")],
+ LowLevelILOperation.LLIL_NORET: [],
+ LowLevelILOperation.LLIL_IF: [("condition", "expr"), ("true", "int"), ("false", "int")],
+ LowLevelILOperation.LLIL_GOTO: [("dest", "int")],
+ LowLevelILOperation.LLIL_FLAG_COND: [("condition", "cond")],
+ LowLevelILOperation.LLIL_CMP_E: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_CMP_NE: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_CMP_SLT: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_CMP_ULT: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_CMP_SLE: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_CMP_ULE: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_CMP_SGE: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_CMP_UGE: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_CMP_SGT: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_CMP_UGT: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_TEST_BIT: [("left", "expr"), ("right", "expr")],
+ LowLevelILOperation.LLIL_BOOL_TO_INT: [("src", "expr")],
+ LowLevelILOperation.LLIL_SYSCALL: [],
+ LowLevelILOperation.LLIL_BP: [],
+ LowLevelILOperation.LLIL_TRAP: [("value", "int")],
+ LowLevelILOperation.LLIL_UNDEF: [],
+ LowLevelILOperation.LLIL_UNIMPL: [],
+ LowLevelILOperation.LLIL_UNIMPL_MEM: [("src", "expr")]
+ }
+
+ def __init__(self, func, expr_index, instr_index=None):
+ instr = core.BNGetLowLevelILByIndex(func.handle, expr_index)
+ self.function = func
+ self.expr_index = expr_index
+ self.instr_index = instr_index
+ self.operation = LowLevelILOperation(instr.operation)
+ self.size = instr.size
+ self.address = instr.address
+ self.source_operand = instr.sourceOperand
+ if instr.flags == 0:
+ self.flags = None
+ else:
+ self.flags = func.arch.get_flag_write_type_name(instr.flags)
+ if self.source_operand == 0xffffffff:
+ self.source_operand = None
+ operands = LowLevelILInstruction.ILOperations[instr.operation]
+ self.operands = []
+ for i in xrange(0, len(operands)):
+ name, operand_type = operands[i]
+ 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])
+ elif operand_type == "flag":
+ value = func.arch.get_flag_name(instr.operands[i])
+ elif operand_type == "cond":
+ value = LowLevelILFlagCondition(instr.operands[i])
+ elif operand_type == "int_list":
+ count = ctypes.c_ulonglong()
+ operands = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count)
+ value = []
+ for i in xrange(count.value):
+ value.append(operands[i])
+ core.BNLowLevelILFreeOperandList(operands)
+ self.operands.append(value)
+ self.__dict__[name] = value
+
+ def __str__(self):
+ tokens = self.tokens
+ if tokens is None:
+ return "invalid"
+ result = ""
+ for token in tokens:
+ result += token.text
+ return result
+
+ def __repr__(self):
+ return "<il: %s>" % str(self)
+
+ @property
+ def tokens(self):
+ """LLIL tokens (read-only)"""
+ count = ctypes.c_ulonglong()
+ tokens = ctypes.POINTER(core.BNInstructionTextToken)()
+ if (self.instr_index is not None) and (self.function.source_function is not None):
+ if not core.BNGetLowLevelILInstructionText(self.function.handle, self.function.source_function.handle,
+ self.function.arch.handle, self.instr_index, tokens, count):
+ return None
+ else:
+ if not core.BNGetLowLevelILExprText(self.function.handle, self.function.arch.handle,
+ self.expr_index, tokens, count):
+ return None
+ result = []
+ for i in xrange(0, count.value):
+ token_type = InstructionTextTokenType(tokens[i].type)
+ text = tokens[i].text
+ value = tokens[i].value
+ size = tokens[i].size
+ operand = tokens[i].operand
+ context = tokens[i].context
+ address = tokens[i].address
+ result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address))
+ core.BNFreeInstructionText(tokens, count.value)
+ return result
+
+ def __setattr__(self, name, value):
+ try:
+ object.__setattr__(self, name, value)
+ except AttributeError:
+ raise AttributeError("attribute '%s' is read only" % name)
+
+
+class LowLevelILExpr(object):
+ """
+ ``class LowLevelILExpr`` hold the index of IL Expressions.
+
+ .. note:: This class shouldn't be instantiated directly. Rather the helper members of LowLevelILFunction should be \
+ used instead.
+ """
+ def __init__(self, index):
+ self.index = index
+
+
+class LowLevelILFunction(object):
+ """
+ ``class LowLevelILFunction`` contains the list of LowLevelILExpr objects that make up a function. LowLevelILExpr
+ objects can be added to the LowLevelILFunction by calling ``append`` and passing the result of the various class
+ methods which return LowLevelILExpr objects.
+
+
+ LowLevelILFlagCondition values used as parameters in the ``flag_condition`` method.
+
+ ======================= ========== ===============================
+ LowLevelILFlagCondition Operator Description
+ ======================= ========== ===============================
+ LLFC_E == Equal
+ LLFC_NE != Not equal
+ LLFC_SLT s< Signed less than
+ LLFC_ULT u< Unsigned less than
+ LLFC_SLE s<= Signed less than or equal
+ LLFC_ULE u<= Unsigned less than or equal
+ LLFC_SGE s>= Signed greater than or equal
+ LLFC_UGE u>= Unsigned greater than or equal
+ LLFC_SGT s> Signed greather than
+ LLFC_UGT u> Unsigned greater than
+ LLFC_NEG - Negative
+ LLFC_POS + Positive
+ LLFC_O overflow Overflow
+ LLFC_NO !overflow No overflow
+ ======================= ========== ===============================
+ """
+ def __init__(self, arch, handle = None, source_func = None):
+ self.arch = arch
+ self.source_function = source_func
+ if handle is not None:
+ self.handle = core.handle_of_type(handle, core.BNLowLevelILFunction)
+ else:
+ func_handle = None
+ if self.source_function is not None:
+ func_handle = self.source_function.handle
+ self.handle = core.BNCreateLowLevelILFunction(arch.handle, func_handle)
+
+ def __del__(self):
+ core.BNFreeLowLevelILFunction(self.handle)
+
+ def __eq__(self, value):
+ if not isinstance(value, LowLevelILFunction):
+ return False
+ return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+
+ def __ne__(self, value):
+ if not isinstance(value, LowLevelILFunction):
+ return True
+ return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+
+ @property
+ def current_address(self):
+ """Current IL Address (read/write)"""
+ return core.BNLowLevelILGetCurrentAddress(self.handle)
+
+ @current_address.setter
+ def current_address(self, value):
+ core.BNLowLevelILSetCurrentAddress(self.handle, value)
+
+ @property
+ def temp_reg_count(self):
+ """Number of temporary registers (read-only)"""
+ return core.BNGetLowLevelILTemporaryRegisterCount(self.handle)
+
+ @property
+ def temp_flag_count(self):
+ """Number of temporary flags (read-only)"""
+ return core.BNGetLowLevelILTemporaryFlagCount(self.handle)
+
+ @property
+ def basic_blocks(self):
+ """list of LowLevelILBasicBlock objects (read-only)"""
+ count = ctypes.c_ulonglong()
+ blocks = core.BNGetLowLevelILBasicBlockList(self.handle, count)
+ result = []
+ view = None
+ if self.source_function is not None:
+ view = self.source_function.view
+ for i in xrange(0, count.value):
+ result.append(LowLevelILBasicBlock(view, core.BNNewBasicBlockReference(blocks[i]), self))
+ core.BNFreeBasicBlockList(blocks, count.value)
+ return result
+
+ def __setattr__(self, name, value):
+ try:
+ object.__setattr__(self, name, value)
+ except AttributeError:
+ raise AttributeError("attribute '%s' is read only" % name)
+
+ def __len__(self):
+ return int(core.BNGetLowLevelILInstructionCount(self.handle))
+
+ def __getitem__(self, i):
+ if isinstance(i, slice) or isinstance(i, tuple):
+ raise IndexError("expected integer instruction index")
+ if isinstance(i, LowLevelILExpr):
+ return LowLevelILInstruction(self, i.index)
+ if (i < 0) or (i >= len(self)):
+ raise IndexError("index out of range")
+ return LowLevelILInstruction(self, core.BNGetLowLevelILIndexForInstruction(self.handle, i), i)
+
+ def __setitem__(self, i, j):
+ raise IndexError("instruction modification not implemented")
+
+ def __iter__(self):
+ count = ctypes.c_ulonglong()
+ blocks = core.BNGetLowLevelILBasicBlockList(self.handle, count)
+ view = None
+ if self.source_function is not None:
+ view = self.source_function.view
+ try:
+ for i in xrange(0, count.value):
+ yield LowLevelILBasicBlock(view, core.BNNewBasicBlockReference(blocks[i]), self)
+ finally:
+ core.BNFreeBasicBlockList(blocks, count.value)
+
+ def clear_indirect_branches(self):
+ core.BNLowLevelILClearIndirectBranches(self.handle)
+
+ def set_indirect_branches(self, branches):
+ branch_list = (core.BNArchitectureAndAddress * len(branches))()
+ for i in xrange(len(branches)):
+ branch_list[i].arch = branches[i][0].handle
+ branch_list[i].address = branches[i][1]
+ core.BNLowLevelILSetIndirectBranches(self.handle, branch_list, len(branches))
+
+ def expr(self, operation, a = 0, b = 0, c = 0, d = 0, size = 0, flags = None):
+ if isinstance(operation, str):
+ operation = LowLevelILOperation[operation]
+ elif isinstance(operation, LowLevelILOperation):
+ operation = operation.value
+ if isinstance(flags, str):
+ flags = self.arch.get_flag_write_type_by_name(flags)
+ elif flags is None:
+ flags = 0
+ return LowLevelILExpr(core.BNLowLevelILAddExpr(self.handle, operation, size, flags, a, b, c, d))
+
+ def append(self, expr):
+ """
+ ``append`` adds the LowLevelILExpr ``expr`` to the current LowLevelILFunction.
+
+ :param LowLevelILExpr expr: the LowLevelILExpr to add to the current LowLevelILFunction
+ :return: number of LowLevelILExpr in the current function
+ :rtype: int
+ """
+ return core.BNLowLevelILAddInstruction(self.handle, expr.index)
+
+ def nop(self):
+ """
+ ``nop`` no operation, this instruction does nothing
+
+ :return: The no operation expression
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_NOP)
+
+ def set_reg(self, size, reg, value, flags = 0):
+ """
+ ``set_reg`` sets the register ``reg`` of size ``size`` to the expression ``value``
+
+ :param int size: size of the register parameter in bytes
+ :param str reg: the register name
+ :param LowLevelILExpr value: an expression to set the register to
+ :param str flags: which flags are set by this operation
+ :return: The expression ``reg = value``
+ :rtype: LowLevelILExpr
+ """
+ if isinstance(reg, str):
+ reg = self.arch.regs[reg].index
+ 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):
+ """
+ ``set_reg_split`` uses ``hi`` and ``lo`` as a single extended register setting ``hi:lo`` to the expression
+ ``value``.
+
+ :param int size: size of the register parameter in bytes
+ :param str hi: the high register name
+ :param str lo: the low register name
+ :param LowLevelILExpr value: an expression to set the split regiters to
+ :param str flags: which flags are set by this operation
+ :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
+ return self.expr(LowLevelILOperation.LLIL_SET_REG_SPLIT, hi, lo, value.index, size = size, flags = flags)
+
+ def set_flag(self, flag, value):
+ """
+ ``set_flag`` sets the flag ``flag`` to the LowLevelILExpr ``value``
+
+ :param str flag: the low register name
+ :param LowLevelILExpr value: an expression to set the flag to
+ :return: The expression FLAG.flag = value
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_SET_FLAG, self.arch.get_flag_by_name(flag), value.index)
+
+ def load(self, size, addr):
+ """
+ ``laod`` Reads ``size`` bytes from the expression ``addr``
+
+ :param int size: number of bytes to read
+ :param LowLevelILExpr addr: the expression to read memory from
+ :return: The expression ``[addr].size``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_LOAD, addr.index, size=size)
+
+ def store(self, size, addr, value):
+ """
+ ``store`` Writes ``size`` bytes to expression ``addr`` read from expression ``value``
+
+ :param int size: number of bytes to write
+ :param LowLevelILExpr addr: the expression to write to
+ :param LowLevelILExpr value: the expression to be written
+ :return: The expression ``[addr].size = value``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_STORE, addr.index, value.index, size=size)
+
+ def push(self, size, value):
+ """
+ ``push`` writes ``size`` bytes from expression ``value`` to the stack, adjusting the stack by ``size``.
+
+ :param int size: number of bytes to write and adjust the stack by
+ :param LowLevelILExpr value: the expression to write
+ :return: The expression push(value)
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_PUSH, value.index, size=size)
+
+ def pop(self, size):
+ """
+ ``pop`` reads ``size`` bytes from the stack, adjusting the stack by ``size``.
+
+ :param int size: number of bytes to read from the stack
+ :return: The expression ``pop``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_POP, size=size)
+
+ def reg(self, size, reg):
+ """
+ ``reg`` returns a register of size ``size`` with name ``name``
+
+ :param int size: the size of the register in bytes
+ :param str reg: the name of the register
+ :return: A register expression for the given string
+ :rtype: LowLevelILExpr
+ """
+ if isinstance(reg, str):
+ reg = self.arch.regs[reg].index
+ return self.expr(LowLevelILOperation.LLIL_REG, reg, size=size)
+
+ def const(self, size, value):
+ """
+ ``const`` returns an expression for the constant integer ``value`` with size ``size``
+
+ :param int size: the size of the constant in bytes
+ :param int value: integer value of the constant
+ :return: A constant expression of given value and size
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_CONST, value, size=size)
+
+ def flag(self, reg):
+ """
+ ``flag`` returns a flag expression for the given flag name.
+
+ :param str reg: name of the flag expression to retrieve
+ :return: A flag expression of given flag name
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_FLAG, self.arch.get_flag_by_name(reg))
+
+ def flag_bit(self, size, reg, bit):
+ """
+ ``flag_bit`` sets the flag named ``reg`` and size ``size`` to the constant integer value ``bit``
+
+ :param int size: the size of the flag
+ :param str reg: flag value
+ :param int bit: integer value to set the bit to
+ :return: A constant expression of given value and size ``FLAG.reg = bit``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_FLAG_BIT, self.arch.get_flag_by_name(reg), bit, size=size)
+
+ def add(self, size, a, b, flags=None):
+ """
+ ``add`` adds expression ``a`` to expression ``b`` potentially setting flags ``flags`` and returning
+ an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: flags to set
+ :return: The expression ``add.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_ADD, a.index, b.index, size=size, flags=flags)
+
+ def add_carry(self, size, a, b, flags=None):
+ """
+ ``add_carry`` adds with carry expression ``a`` to expression ``b`` potentially setting flags ``flags`` and
+ returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: flags to set
+ :return: The expression ``adc.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_ADC, a.index, b.index, size=size, flags=flags)
+
+ def sub(self, size, a, b, flags=None):
+ """
+ ``sub`` subtracts expression ``b`` from expression ``a`` potentially setting flags ``flags`` and returning
+ an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: flags to set
+ :return: The expression ``sub.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_SUB, a.index, b.index, size=size, flags=flags)
+
+ def sub_borrow(self, size, a, b, flags=None):
+ """
+ ``sub_borrow`` subtracts with borrow expression ``b`` from expression ``a`` potentially setting flags ``flags``
+ and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: flags to set
+ :return: The expression ``sbc.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_SBB, a.index, b.index, size=size, flags=flags)
+
+ def and_expr(self, size, a, b, flags=None):
+ """
+ ``and_expr`` bitwise and's expression ``a`` and expression ``b`` potentially setting flags ``flags``
+ and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``and.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_AND, a.index, b.index, size=size, flags=flags)
+
+ def or_expr(self, size, a, b, flags=None):
+ """
+ ``or_expr`` bitwise or's expression ``a`` and expression ``b`` potentially setting flags ``flags``
+ and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``or.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_OR, a.index, b.index, size=size, flags=flags)
+
+ def xor_expr(self, size, a, b, flags=None):
+ """
+ ``xor_expr`` xor's expression ``a`` with expression ``b`` potentially setting flags ``flags``
+ and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``xor.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_XOR, a.index, b.index, size=size, flags=flags)
+
+ def shift_left(self, size, a, b, flags=None):
+ """
+ ``shift_left`` subtracts with borrow expression ``b`` from expression ``a`` potentially setting flags ``flags``
+ and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``lsl.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_LSL, a.index, b.index, size=size, flags=flags)
+
+ def logical_shift_right(self, size, a, b, flags=None):
+ """
+ ``logical_shift_right`` shifts logically right expression ``a`` by expression ``b`` potentially setting flags
+ ``flags``and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``lsr.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_LSR, a.index, b.index, size=size, flags=flags)
+
+ def arith_shift_right(self, size, a, b, flags=None):
+ """
+ ``arith_shift_right`` shifts arithmatic right expression ``a`` by expression ``b`` potentially setting flags
+ ``flags`` and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``asr.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_ASR, a.index, b.index, size=size, flags=flags)
+
+ def rotate_left(self, size, a, b, flags=None):
+ """
+ ``rotate_left`` bitwise rotates left expression ``a`` by expression ``b`` potentially setting flags ``flags``
+ and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``rol.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_ROL, a.index, b.index, size=size, flags=flags)
+
+ def rotate_left_carry(self, size, a, b, flags=None):
+ """
+ ``rotate_left_carry`` bitwise rotates left with carry expression ``a`` by expression ``b`` potentially setting
+ flags ``flags`` and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``rcl.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_RLC, a.index, b.index, size=size, flags=flags)
+
+ def rotate_right(self, size, a, b, flags=None):
+ """
+ ``rotate_right`` bitwise rotates right expression ``a`` by expression ``b`` potentially setting flags ``flags``
+ and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``ror.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_ROR, a.index, b.index, size=size, flags=flags)
+
+ def rotate_right_carry(self, size, a, b, flags=None):
+ """
+ ``rotate_right_carry`` bitwise rotates right with carry expression ``a`` by expression ``b`` potentially setting
+ flags ``flags`` and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``rcr.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_RRC, a.index, b.index, size=size, flags=flags)
+
+ def mult(self, size, a, b, flags=None):
+ """
+ ``mult`` multiplies expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an
+ expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``sbc.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_MUL, a.index, b.index, size=size, flags=flags)
+
+ def mult_double_prec_signed(self, size, a, b, flags=None):
+ """
+ ``mult_double_prec_signed`` multiplies signed with double precision expression ``a`` by expression ``b``
+ potentially setting flags ``flags`` and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``muls.dp.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_MULS_DP, a.index, b.index, size=size, flags=flags)
+
+ def mult_double_prec_unsigned(self, size, a, b, flags=None):
+ """
+ ``mult_double_prec_unsigned`` multiplies unsigned with double precision expression ``a`` by expression ``b``
+ potentially setting flags ``flags`` and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``muls.dp.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_MULU_DP, a.index, b.index, size=size, flags=flags)
+
+ def div_signed(self, size, a, b, flags=None):
+ """
+ ``div_signed`` signed divide expression ``a`` by expression ``b`` potentially setting flags ``flags``
+ and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``divs.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_DIVS, a.index, b.index, size=size, flags=flags)
+
+ def div_double_prec_signed(self, size, hi, lo, b, flags=None):
+ """
+ ``div_double_prec_signed`` signed double precision divide using expression ``hi`` and expression ``lo`` as a
+ single double precision register by expression ``b`` potentially setting flags ``flags`` and returning an
+ expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr hi: high LHS expression
+ :param LowLevelILExpr lo: low LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``divs.dp.<size>{<flags>}(hi:lo, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_DIVS_DP, hi.index, lo.index, b.index, size=size, flags=flags)
+
+ def div_unsigned(self, size, a, b, flags=None):
+ """
+ ``div_unsigned`` unsigned divide expression ``a`` by expression ``b`` potentially setting flags ``flags``
+ and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``divs.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_DIVS, a.index, b.index, size=size, flags=flags)
+
+ def div_double_prec_unsigned(self, size, hi, lo, b, flags=None):
+ """
+ ``div_double_prec_unsigned`` unsigned double precision divide using expression ``hi`` and expression ``lo`` as
+ a single double precision register by expression ``b`` potentially setting flags ``flags`` and returning an
+ expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr hi: high LHS expression
+ :param LowLevelILExpr lo: low LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``divs.dp.<size>{<flags>}(hi:lo, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_DIVS_DP, hi.index, lo.index, b.index, size=size, flags=flags)
+
+ def mod_signed(self, size, a, b, flags=None):
+ """
+ ``mod_signed`` signed modulus expression ``a`` by expression ``b`` potentially setting flags ``flags``
+ and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``mods.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_MODS, a.index, b.index, size=size, flags=flags)
+
+ def mod_double_prec_signed(self, size, hi, lo, b, flags=None):
+ """
+ ``mod_double_prec_signed`` signed double precision modulus using expression ``hi`` and expression ``lo`` as a single
+ double precision register by expression ``b`` potentially setting flags ``flags`` and returning an expression
+ of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr hi: high LHS expression
+ :param LowLevelILExpr lo: low LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``mods.dp.<size>{<flags>}(hi:lo, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_MODS_DP, hi.index, lo.index, b.index, size=size, flags=flags)
+
+ def mod_unsigned(self, size, a, b, flags=None):
+ """
+ ``mod_unsigned`` unsigned modulus expression ``a`` by expression ``b`` potentially setting flags ``flags``
+ and returning an expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr a: LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``modu.<size>{<flags>}(a, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_MODS, a.index, b.index, size=size, flags=flags)
+
+ def mod_double_prec_unsigned(self, size, hi, lo, b, flags=None):
+ """
+ ``mod_double_prec_unsigned`` unsigned double precision modulus using expression ``hi`` and expression ``lo`` as
+ a single double precision register by expression ``b`` potentially setting flags ``flags`` and returning an
+ expression of ``size`` bytes.
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr hi: high LHS expression
+ :param LowLevelILExpr lo: low LHS expression
+ :param LowLevelILExpr b: RHS expression
+ :param str flags: optional, flags to set
+ :return: The expression ``modu.dp.<size>{<flags>}(hi:lo, b)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_MODS_DP, hi.index, lo.index, b.index, size=size, flags=flags)
+
+ def neg_expr(self, size, value, flags=None):
+ """
+ ``neg_expr`` two's complement sign negation of expression ``value`` of size ``size`` potentially setting flags
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr value: the expression to negate
+ :param str flags: optional, flags to set
+ :return: The expression ``neg.<size>{<flags>}(value)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_NEG, value.index, size=size, flags=flags)
+
+ def not_expr(self, size, value, flags=None):
+ """
+ ``not_expr`` bitwise inverse of expression ``value`` of size ``size`` potentially setting flags
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr value: the expression to bitwise invert
+ :param str flags: optional, flags to set
+ :return: The expression ``not.<size>{<flags>}(value)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_NOT, value.index, size=size, flags=flags)
+
+ def sign_extend(self, size, value, flags=None):
+ """
+ ``sign_extend`` two's complement sign-extends the expression in ``value`` to ``size`` bytes
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr value: the expression to sign extn
+ :param str flags: optional, flags to set
+ :return: The expression ``sx.<size>(value)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_SX, value.index, size=size, flags=flags)
+
+ def zero_extend(self, size, value):
+ """
+ ``zero_extend`` zero-extends the expression in ``value`` to ``size`` bytes
+
+ :param int size: the size of the result in bytes
+ :param LowLevelILExpr value: the expression to zero extend
+ :return: The expression ``sx.<size>(value)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_ZX, value.index, size=size)
+
+ def jump(self, dest):
+ """
+ ``jump`` returns an expression which jumps (branches) to the expression ``dest``
+
+ :param LowLevelILExpr dest: the expression to jump to
+ :return: The expression ``jump(dest)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_JUMP, dest.index)
+
+ def call(self, dest):
+ """
+ ``call`` returns an expression which first pushes the address of the next instruction onto the stack then jumps
+ (branches) to the expression ``dest``
+
+ :param LowLevelILExpr dest: the expression to call
+ :return: The expression ``call(dest)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_CALL, dest.index)
+
+ def ret(self, dest):
+ """
+ ``ret`` returns an expression which jumps (branches) to the expression ``dest``. ``ret`` is a special alias for
+ jump that makes the disassembler top disassembling.
+
+ :param LowLevelILExpr dest: the expression to jump to
+ :return: The expression ``jump(dest)``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_RET, dest.index)
+
+ def no_ret(self):
+ """
+ ``no_ret`` returns an expression halts disassembly
+
+ :return: The expression ``noreturn``
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_NORET)
+
+ def flag_condition(self, cond):
+ """
+ ``flag_condition`` returns a flag_condition expression for the given LowLevelILFlagCondition
+
+ :param LowLevelILFlagCondition cond: Flag condition expression to retrieve
+ :return: A flag_condition expression
+ :rtype: LowLevelILExpr
+ """
+ if isinstance(cond, str):
+ cond = LowLevelILFlagCondition[cond]
+ elif isinstance(cond, LowLevelILFlagCondition):
+ cond = cond.value
+ return self.expr(LowLevelILOperation.LLIL_FLAG_COND, cond)
+
+ def compare_equal(self, size, a, b):
+ """
+ ``compare_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is equal to
+ expression ``b``
+
+ :param int size: size in bytes
+ :param LowLevelILExpr a: LHS of comparison
+ :param LowLevelILExpr b: RHS of comparison
+ :return: a comparison expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_CMP_E, a.index, b.index, size = size)
+
+ def compare_not_equal(self, size, a, b):
+ """
+ ``compare_not_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is not equal to
+ expression ``b``
+
+ :param int size: size in bytes
+ :param LowLevelILExpr a: LHS of comparison
+ :param LowLevelILExpr b: RHS of comparison
+ :return: a comparison expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_CMP_NE, a.index, b.index, size = size)
+
+ def compare_signed_less_than(self, size, a, b):
+ """
+ ``compare_signed_less_than`` returns comparison expression of size ``size`` checking if expression ``a`` is
+ signed less than expression ``b``
+
+ :param int size: size in bytes
+ :param LowLevelILExpr a: LHS of comparison
+ :param LowLevelILExpr b: RHS of comparison
+ :return: a comparison expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_CMP_SLT, a.index, b.index, size = size)
+
+ def compare_unsigned_less_than(self, size, a, b):
+ """
+ ``compare_unsigned_less_than`` returns comparison expression of size ``size`` checking if expression ``a`` is
+ unsigned less than expression ``b``
+
+ :param int size: size in bytes
+ :param LowLevelILExpr a: LHS of comparison
+ :param LowLevelILExpr b: RHS of comparison
+ :return: a comparison expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_CMP_ULT, a.index, b.index, size = size)
+
+ def compare_signed_less_equal(self, size, a, b):
+ """
+ ``compare_signed_less_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is
+ signed less than or equal to expression ``b``
+
+ :param int size: size in bytes
+ :param LowLevelILExpr a: LHS of comparison
+ :param LowLevelILExpr b: RHS of comparison
+ :return: a comparison expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_CMP_SLE, a.index, b.index, size = size)
+
+ def compare_unsigned_less_equal(self, size, a, b):
+ """
+ ``compare_unsigned_less_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is
+ unsigned less than or equal to expression ``b``
+
+ :param int size: size in bytes
+ :param LowLevelILExpr a: LHS of comparison
+ :param LowLevelILExpr b: RHS of comparison
+ :return: a comparison expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_CMP_ULE, a.index, b.index, size = size)
+
+ def compare_signed_greater_equal(self, size, a, b):
+ """
+ ``compare_signed_greater_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is
+ signed greater than or equal toexpression ``b``
+
+ :param int size: size in bytes
+ :param LowLevelILExpr a: LHS of comparison
+ :param LowLevelILExpr b: RHS of comparison
+ :return: a comparison expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_CMP_SGE, a.index, b.index, size = size)
+
+ def compare_unsigned_greater_equal(self, size, a, b):
+ """
+ ``compare_unsigned_greater_equal`` returns comparison expression of size ``size`` checking if expression ``a``
+ is unsigned greater than or equal to expression ``b``
+
+ :param int size: size in bytes
+ :param LowLevelILExpr a: LHS of comparison
+ :param LowLevelILExpr b: RHS of comparison
+ :return: a comparison expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_CMP_UGE, a.index, b.index, size = size)
+
+ def compare_signed_greater_than(self, size, a, b):
+ """
+ ``compare_signed_greater_than`` returns comparison expression of size ``size`` checking if expression ``a`` is
+ signed greater than or equal to expression ``b``
+
+ :param int size: size in bytes
+ :param LowLevelILExpr a: LHS of comparison
+ :param LowLevelILExpr b: RHS of comparison
+ :return: a comparison expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_CMP_SGT, a.index, b.index, size = size)
+
+ def compare_unsigned_greater_than(self, size, a, b):
+ """
+ ``compare_unsigned_greater_than`` returns comparison expression of size ``size`` checking if expression ``a`` is
+ unsigned greater than or equal to expression ``b``
+
+ :param int size: size in bytes
+ :param LowLevelILExpr a: LHS of comparison
+ :param LowLevelILExpr b: RHS of comparison
+ :return: a comparison expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_CMP_UGT, a.index, b.index, size = size)
+
+ def test_bit(self, size, a, b):
+ return self.expr(LowLevelILOperation.LLIL_TEST_BIT, a.index, b.index, size = size)
+
+ def system_call(self):
+ """
+ ``system_call`` return a system call expression.
+
+ :return: a system call expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_SYSCALL)
+
+ def breakpoint(self):
+ """
+ ``breakpoint`` returns a processor breakpoint expression.
+
+ :return: a breakpoint expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_BP)
+
+ def trap(self, value):
+ """
+ ``trap`` returns a processor trap (interrupt) expression of the given integer ``value``.
+
+ :param int value: trap (interrupt) number
+ :return: a trap expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_TRAP, value)
+
+ def undefined(self):
+ """
+ ``undefined`` returns the undefined expression. This should be used for instructions which perform functions but
+ aren't important for dataflow or partial emulation purposes.
+
+ :return: the unimplemented expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_UNDEF)
+
+ def unimplemented(self):
+ """
+ ``unimplemented`` returns the unimplemented expression. This should be used for all instructions which aren't
+ implemented.
+
+ :return: the unimplemented expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_UNIMPL)
+
+ def unimplemented_memory_ref(self, size, addr):
+ """
+ ``unimplemented_memory_ref`` a memory reference to expression ``addr`` of size ``size`` with unimplemented operation.
+
+ :param int size: size in bytes of the memory reference
+ :param LowLevelILExpr addr: expression to reference memory
+ :return: the unimplemented memory reference expression.
+ :rtype: LowLevelILExpr
+ """
+ return self.expr(LowLevelILOperation.LLIL_UNIMPL_MEM, addr.index, size = size)
+
+ def goto(self, label):
+ """
+ ``goto`` returns a goto expression which jumps to the provided LowLevelILLabel.
+
+ :param LowLevelILLabel label: Label to jump to
+ :return: the LowLevelILExpr that jumps to the provided label
+ :rtype: LowLevelILExpr
+ """
+ return LowLevelILExpr(core.BNLowLevelILGoto(self.handle, label.handle))
+
+ def if_expr(self, operand, t, f):
+ """
+ ``if_expr`` returns the ``if`` expression which depending on condition ``operand`` jumps to the LowLevelILLabel
+ ``t`` when the condition expression ``operand`` is non-zero and ``f`` when it's zero.
+
+ :param LowLevelILExpr operand: comparison expression to evaluate.
+ :param LowLevelILLabel t: Label for the true branch
+ :param LowLevelILLabel f: Label for the false branch
+ :return: the LowLevelILExpr for the if expression
+ :rtype: LowLevelILExpr
+ """
+ return LowLevelILExpr(core.BNLowLevelILIf(self.handle, operand.index, t.handle, f.handle))
+
+ def mark_label(self, label):
+ """
+ ``mark_label`` assigns a LowLevelILLabel to the current IL address.
+
+ :param LowLevelILLabel label:
+ :rtype: None
+ """
+ core.BNLowLevelILMarkLabel(self.handle, label.handle)
+
+ def add_label_list(self, labels):
+ """
+ ``add_label_list`` returns a label list expression for the given list of LowLevelILLabel objects.
+
+ :param list(LowLevelILLabel) lables: the list of LowLevelILLabel to get a label list expression from
+ :return: the label list expression
+ :rtype: LowLevelILExpr
+ """
+ label_list = (ctypes.POINTER(core.BNLowLevelILLabel) * len(labels))()
+ for i in xrange(len(labels)):
+ label_list[i] = labels[i].handle
+ return LowLevelILExpr(core.BNLowLevelILAddLabelList(self.handle, label_list, len(labels)))
+
+ def add_operand_list(self, operands):
+ """
+ ``add_operand_list`` returns an operand list expression for the given list of integer operands.
+
+ :param list(int) operands: list of operand numbers
+ :return: an operand list expression
+ :rtype: LowLevelILExpr
+ """
+ operand_list = (ctypes.c_ulonglong * len(operands))()
+ for i in xrange(len(operands)):
+ operand_list[i] = operands[i]
+ return LowLevelILExpr(core.BNLowLevelILAddOperandList(self.handle, operand_list, len(operands)))
+
+ def operand(self, n, expr):
+ """
+ ``operand`` sets the operand number of the expression ``expr`` and passes back ``expr`` without modification.
+
+ :param int n:
+ :param LowLevelILExpr expr:
+ :return: returns the expression ``expr`` unmodified
+ :rtype: LowLevelILExpr
+ """
+ core.BNLowLevelILSetExprSourceOperand(self.handle, expr.index, n)
+ return expr
+
+ def finalize(self):
+ """
+ ``finalize`` ends the function and computes the list of basic blocks.
+
+ :rtype: None
+ """
+ core.BNFinalizeLowLevelILFunction(self.handle)
+
+ def add_label_for_address(self, arch, addr):
+ """
+ ``add_label_for_address`` adds a low-level IL label for the given architecture ``arch`` at the given virtual
+ address ``addr``
+
+ :param Architecture arch: Architecture to add labels for
+ :param int addr: the IL address to add a label at
+ """
+ if arch is not None:
+ arch = arch.handle
+ core.BNAddLowLevelILLabelForAddress(self.handle, arch, addr)
+
+ def get_label_for_address(self, arch, addr):
+ """
+ ``get_label_for_address`` returns the LowLevelILLabel for the given Architecture ``arch`` and IL address ``addr``.
+
+ :param Architecture arch:
+ :param int addr: IL Address label to retrieve
+ :return: the LowLevelILLabel for the given IL address
+ :rtype: LowLevelILLabel
+ """
+ if arch is not None:
+ arch = arch.handle
+ label = core.BNGetLowLevelILLabelForAddress(self.handle, arch, addr)
+ if label is None:
+ return None
+ return LowLevelILLabel(label)
+
+
+class LowLevelILBasicBlock(basicblock.BasicBlock):
+ def __init__(self, view, handle, owner):
+ super(LowLevelILBasicBlock, self).__init__(view, handle)
+ self.il_function = owner
+
+ def __iter__(self):
+ for idx in xrange(self.start, self.end):
+ yield self.il_function[idx]
+
+ def __getitem__(self, idx):
+ size = self.end - self.start
+ if idx > size or idx < -size:
+ raise IndexError("list index is out of range")
+ if idx >= 0:
+ return self.il_function[idx + self.start]
+ else:
+ return self.il_function[self.end + idx]
+
+
+def LLIL_TEMP(n):
+ return n | 0x80000000
+
+
+def LLIL_REG_IS_TEMP(n):
+ return (n & 0x80000000) != 0
+
+
+def LLIL_GET_TEMP_REG_INDEX(n):
+ return n & 0x7fffffff