summaryrefslogtreecommitdiff
path: root/python/lowlevelil.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/lowlevelil.py')
-rw-r--r--python/lowlevelil.py103
1 files changed, 93 insertions, 10 deletions
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index 94353aa7..7b1a702c 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -3963,7 +3963,13 @@ class LowLevelILFunction:
return dest.reg_stack_top_relative(expr.size, expr.stack, sub_expr_handler(expr.src), loc)
if expr.operation == LowLevelILOperation.LLIL_REG_STACK_POP:
expr: LowLevelILRegStackPop
- return dest.reg_stack_pop(expr.size, expr.stack, loc)
+ return dest.reg_stack_pop(expr.size, expr.stack, expr.flags, loc)
+ if expr.operation == LowLevelILOperation.LLIL_REG_STACK_FREE_REG:
+ expr: LowLevelILRegStackFreeReg
+ return dest.reg_stack_free_reg(expr.dest, loc)
+ if expr.operation == LowLevelILOperation.LLIL_REG_STACK_FREE_REL:
+ expr: LowLevelILRegStackFreeRel
+ return dest.reg_stack_free_top_relative(expr.stack, expr.dest, loc)
if expr.operation == LowLevelILOperation.LLIL_FLAG:
expr: LowLevelILFlag
return dest.flag(expr.src, loc)
@@ -3978,7 +3984,7 @@ class LowLevelILFunction:
return dest.call(sub_expr_handler(expr.dest), loc)
if expr.operation == LowLevelILOperation.LLIL_CALL_STACK_ADJUST:
expr: LowLevelILCallStackAdjust
- return dest.call_stack_adjust(sub_expr_handler(expr.dest), expr.stack_adjustment, loc)
+ return dest.call_stack_adjust(sub_expr_handler(expr.dest), expr.stack_adjustment, expr.reg_stack_adjustments, loc)
if expr.operation == LowLevelILOperation.LLIL_TAILCALL:
expr: LowLevelILTailcall
return dest.tailcall(sub_expr_handler(expr.dest), loc)
@@ -4339,28 +4345,41 @@ class LowLevelILFunction:
"""
return self.expr(LowLevelILOperation.LLIL_STORE, addr, value, size=size, flags=flags, source_location=loc)
- def push(self, size: int, value: ExpressionIndex, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
+ def push(
+ self,
+ size: int,
+ value: ExpressionIndex,
+ flags: Optional['architecture.FlagType'] = None,
+ loc: Optional['ILSourceLocation'] = None
+ ) -> ExpressionIndex:
"""
``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 ExpressionIndex value: the expression to write
+ :param FlagType flags: which flags are set by this operation
:param ILSourceLocation loc: location of returned expression
:return: The expression push(value)
:rtype: ExpressionIndex
"""
- return self.expr(LowLevelILOperation.LLIL_PUSH, value, size=size, source_location=loc)
+ return self.expr(LowLevelILOperation.LLIL_PUSH, value, size=size, flags=flags, source_location=loc)
- def pop(self, size: int, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
+ def pop(
+ self,
+ size: int,
+ flags: Optional['architecture.FlagType'] = None,
+ loc: Optional['ILSourceLocation'] = None
+ ) -> ExpressionIndex:
"""
``pop`` reads ``size`` bytes from the stack, adjusting the stack by ``size``.
:param int size: number of bytes to read from the stack
+ :param FlagType flags: which flags are set by this operation
:param ILSourceLocation loc: location of returned expression
:return: The expression ``pop``
:rtype: ExpressionIndex
"""
- return self.expr(LowLevelILOperation.LLIL_POP, size=size, source_location=loc)
+ return self.expr(LowLevelILOperation.LLIL_POP, size=size, flags=flags, source_location=loc)
def reg(self, size: int, reg: 'architecture.RegisterType', loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
"""
@@ -4412,7 +4431,7 @@ class LowLevelILFunction:
return self.expr(LowLevelILOperation.LLIL_REG_STACK_REL, _reg_stack, entry, size=size, source_location=loc)
def reg_stack_pop(
- self, size: int, reg_stack: 'architecture.RegisterStackType',
+ self, size: int, reg_stack: 'architecture.RegisterStackType', flags: Optional['architecture.FlagType'] = None,
loc: Optional['ILSourceLocation'] = None
) -> ExpressionIndex:
"""
@@ -4421,12 +4440,45 @@ class LowLevelILFunction:
:param int size: the size of the register in bytes
:param str reg_stack: the name of the register stack
+ :param FlagType flags: which flags are set by this operation
:param ILSourceLocation loc: location of returned expression
:return: The expression ``reg_stack.pop``
:rtype: ExpressionIndex
"""
_reg_stack = ExpressionIndex(self.arch.get_reg_stack_index(reg_stack))
- return self.expr(LowLevelILOperation.LLIL_REG_STACK_POP, _reg_stack, size=size, source_location=loc)
+ return self.expr(LowLevelILOperation.LLIL_REG_STACK_POP, _reg_stack, size=size, flags=flags, source_location=loc)
+
+ def reg_stack_free_reg(self, reg: 'architecture.RegisterType', loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
+ """
+ ``reg_stack_free_reg`` clears the given register ``reg`` from its register stack
+ without affecting the register at the top of the register stack.
+
+ :param str reg: the register being marked free
+ :param ILSourceLocation loc: location of returned expression
+ :return: The expression ``__free_slot(reg)``
+ :rtype: ExpressionIndex
+ """
+ _reg = ExpressionIndex(self.arch.get_reg_index(reg))
+ return self.expr(LowLevelILOperation.LLIL_REG_STACK_FREE_REG, _reg, source_location=loc)
+
+ def reg_stack_free_top_relative(
+ self,
+ reg_stack: 'architecture.RegisterStackType',
+ entry: ExpressionIndex,
+ loc: Optional['ILSourceLocation'] = None
+ ) -> ExpressionIndex:
+ """
+ ``reg_stack_free_top_relative`` clears an entry in the register stack ``reg_stack``
+ at a top-relative position specified by the value of ``entry``.
+
+ :param str reg_stack: the register stack name
+ :param ExpressionIndex entry: expression to calculate the top-relative position
+ :param ILSourceLocation loc: location of returned expression
+ :return: The expression ``__free_slot(reg_stack[entry])``
+ :rtype: ExpressionIndex
+ """
+ _reg_stack = ExpressionIndex(self.arch.get_reg_stack_index(reg_stack))
+ return self.expr(LowLevelILOperation.LLIL_REG_STACK_FREE_REL, _reg_stack, entry, source_location=loc)
def const(self, size: int, value: int, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
"""
@@ -5118,7 +5170,13 @@ class LowLevelILFunction:
"""
return self.expr(LowLevelILOperation.LLIL_CALL, dest, source_location=loc)
- def call_stack_adjust(self, dest: ExpressionIndex, stack_adjust: int, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
+ def call_stack_adjust(
+ self,
+ dest: ExpressionIndex,
+ stack_adjust: int,
+ reg_stack_adjustments: Optional[Dict['architecture.RegisterStackType', int]] = None,
+ loc: Optional['ILSourceLocation'] = None
+ ) -> ExpressionIndex:
"""
``call_stack_adjust`` returns an expression which first pushes the address of the next instruction onto the stack
then jumps (branches) to the expression ``dest``. After the function exits, ``stack_adjust`` is added to the
@@ -5129,7 +5187,14 @@ class LowLevelILFunction:
:return: The expression ``call(dest), stack += stack_adjust``
:rtype: ExpressionIndex
"""
- return self.expr(LowLevelILOperation.LLIL_CALL_STACK_ADJUST, dest, stack_adjust, source_location=loc)
+ list = []
+ if reg_stack_adjustments is not None:
+ for reg_stack, adjustment in reg_stack_adjustments.items():
+ reg_stack_index = self.arch.get_reg_stack_index(reg_stack)
+ list.append(reg_stack_index)
+ list.append(adjustment)
+
+ return self.expr(LowLevelILOperation.LLIL_CALL_STACK_ADJUST, dest, stack_adjust, len(list), self.add_index_list(list), source_location=loc)
def tailcall(self, dest: ExpressionIndex, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
"""
@@ -5923,6 +5988,24 @@ class LowLevelILFunction:
raise Exception("Invalid operand type")
return ExpressionIndex(core.BNLowLevelILAddOperandList(self.handle, operand_list, len(operands)))
+ def add_index_list(self, indices: List[int]) -> ExpressionIndex:
+ """
+ ``add_index_list`` returns an index list expression for the given list of integers.
+
+ :param indices: list of numbers
+ :type indices: List(int)
+ :return: an operand list expression
+ :rtype: ExpressionIndex
+ """
+ index_list = (ctypes.c_ulonglong * len(indices))()
+ for i in range(len(indices)):
+ index = indices[i]
+ if isinstance(index, int):
+ index_list[i] = ExpressionIndex(index)
+ else:
+ raise Exception("Invalid index type")
+ return ExpressionIndex(core.BNLowLevelILAddOperandList(self.handle, index_list, len(indices)))
+
def operand(self, n: int, expr: ExpressionIndex) -> ExpressionIndex:
"""
``operand`` sets the operand number of the expression ``expr`` and passes back ``expr`` without modification.