Refactor machine stack

pull/503/head
Nikhil Parasaram 6 years ago
parent 01bb77cba5
commit b93abc166d
  1. 4
      mythril/laser/ethereum/exceptions.py
  2. 50
      mythril/laser/ethereum/instructions.py
  3. 29
      mythril/laser/ethereum/state.py

@ -6,5 +6,9 @@ class StackUnderflowException(VmException):
pass pass
class StackOverflowException(VmException):
pass
class StopSignal(Exception): class StopSignal(Exception):
pass pass

@ -14,7 +14,7 @@ from mythril.laser.ethereum.state import GlobalState, CalldataType
import mythril.laser.ethereum.natives as natives import mythril.laser.ethereum.natives as natives
from mythril.laser.ethereum.transaction import MessageCallTransaction, TransactionStartSignal, \ from mythril.laser.ethereum.transaction import MessageCallTransaction, TransactionStartSignal, \
ContractCreationTransaction ContractCreationTransaction
from mythril.laser.ethereum.exceptions import VmException, StackUnderflowException from mythril.laser.ethereum.exceptions import VmException
TT256 = 2 ** 256 TT256 = 2 ** 256
TT256M1 = 2 ** 256 - 1 TT256M1 = 2 ** 256 - 1
@ -92,51 +92,41 @@ class Instruction:
@instruction @instruction
def swap_(self, global_state): def swap_(self, global_state):
depth = int(self.op_code[4:]) depth = int(self.op_code[4:])
try: stack = global_state.mstate.stack
stack = global_state.mstate.stack stack[-depth - 1], stack[-1] = stack[-1], stack[-depth - 1]
stack[-depth - 1], stack[-1] = stack[-1], stack[-depth - 1]
except IndexError:
raise StackUnderflowException
return [global_state] return [global_state]
@instruction @instruction
def pop_(self, global_state): def pop_(self, global_state):
try: global_state.mstate.stack.pop()
global_state.mstate.stack.pop()
except IndexError:
raise StackUnderflowException
return [global_state] return [global_state]
@instruction @instruction
def and_(self, global_state): def and_(self, global_state):
try: stack = global_state.mstate.stack
stack = global_state.mstate.stack op1, op2 = stack.pop(), stack.pop()
op1, op2 = stack.pop(), stack.pop() if type(op1) == BoolRef:
if type(op1) == BoolRef: op1 = If(op1, BitVecVal(1, 256), BitVecVal(0, 256))
op1 = If(op1, BitVecVal(1, 256), BitVecVal(0, 256)) if type(op2) == BoolRef:
if type(op2) == BoolRef: op2 = If(op2, BitVecVal(1, 256), BitVecVal(0, 256))
op2 = If(op2, BitVecVal(1, 256), BitVecVal(0, 256))
stack.append(op1 & op2)
stack.append(op1 & op2)
except IndexError:
raise StackUnderflowException
return [global_state] return [global_state]
@instruction @instruction
def or_(self, global_state): def or_(self, global_state):
stack = global_state.mstate.stack stack = global_state.mstate.stack
try: op1, op2 = stack.pop(), stack.pop()
op1, op2 = stack.pop(), stack.pop()
if type(op1) == BoolRef: if type(op1) == BoolRef:
op1 = If(op1, BitVecVal(1, 256), BitVecVal(0, 256)) op1 = If(op1, BitVecVal(1, 256), BitVecVal(0, 256))
if type(op2) == BoolRef:
op2 = If(op2, BitVecVal(1, 256), BitVecVal(0, 256))
if type(op2) == BoolRef: stack.append(op1 | op2)
op2 = If(op2, BitVecVal(1, 256), BitVecVal(0, 256))
stack.append(op1 | op2)
except IndexError: # Stack underflow
raise StackUnderflowException
return [global_state] return [global_state]
@instruction @instruction

@ -3,6 +3,10 @@ from copy import copy, deepcopy
from enum import Enum from enum import Enum
from random import randint from random import randint
from mythril.laser.ethereum.exceptions import StackOverflowException, StackUnderflowException
STACK_LIMIT = 1024
class CalldataType(Enum): class CalldataType(Enum):
CONCRETE = 1 CONCRETE = 1
@ -122,6 +126,29 @@ class Environment:
calldata_type=self.calldata_type) calldata_type=self.calldata_type)
class MachineStack(list):
def __init__(self):
super(MachineStack, self).__init__([])
def append(self, element):
if super(MachineStack, self).__len__() >= STACK_LIMIT:
raise StackOverflowException
super(MachineStack, self).append(element)
def pop(self):
try:
return super(MachineStack, self).pop()
except IndexError:
raise StackUnderflowException
def __getitem__(self, item):
try:
return super(MachineStack, self).__getitem__(item)
except IndexError:
raise StackUnderflowException
class MachineState: class MachineState:
""" """
MachineState represents current machine state also referenced to as \mu MachineState represents current machine state also referenced to as \mu
@ -129,7 +156,7 @@ class MachineState:
def __init__(self, gas): def __init__(self, gas):
""" Constructor for machineState """ """ Constructor for machineState """
self.pc = 0 self.pc = 0
self.stack = [] self.stack = MachineStack()
self.memory = [] self.memory = []
self.gas = gas self.gas = gas
self.constraints = [] self.constraints = []

Loading…
Cancel
Save