LASER v2 compatibility

pull/62/merge
Bernhard Mueller 7 years ago
parent de09c01025
commit 620a88dc7a
  1. 28
      myth
  2. 8
      mythril/analysis/modules/unchecked_retval.py
  3. 2
      mythril/analysis/ops.py
  4. 18
      mythril/analysis/symbolic.py
  5. 3
      mythril/support/loader.py

28
myth

@ -364,13 +364,13 @@ elif (args.graph) or (args.fire_lasers):
if (args.graph): if (args.graph):
try: # try:
if (args.dynld): if (args.dynld):
states = StateSpace(contracts, dynloader=DynLoader(eth), max_depth=args.max_depth) states = StateSpace(contracts, dynloader=DynLoader(eth), max_depth=args.max_depth)
else: else:
states = StateSpace(contracts, max_depth=args.max_depth) states = StateSpace(contracts, max_depth=args.max_depth)
except: # except:
exitWithError(args.outform, "Symbolic exection error: " + str(e)) # exitWithError(args.outform, "Symbolic exection error: " + str(e))
if args.enable_physics is not None: if args.enable_physics is not None:
physics = True physics = True
@ -390,13 +390,13 @@ elif (args.graph) or (args.fire_lasers):
for contract in contracts: for contract in contracts:
try: # try:
if (args.dynld): if (args.dynld):
states = StateSpace([contract], dynloader=DynLoader(eth), max_depth=args.max_depth) states = StateSpace([contract], dynloader=DynLoader(eth), max_depth=args.max_depth)
else: else:
states = StateSpace([contract], max_depth=args.max_depth) states = StateSpace([contract], max_depth=args.max_depth)
except Exception as e: # except Exception as e:
exitWithError(args.outform, "Symbolic exection error: " + str(e)) # exitWithError(args.outform, "Symbolic exection error: " + str(e))
issues = fire_lasers(states) issues = fire_lasers(states)

@ -43,16 +43,20 @@ def execute(statespace):
# The instructions executed in each node (basic block) are saved in node.instruction_list, e.g.: # The instructions executed in each node (basic block) are saved in node.instruction_list, e.g.:
# [{address: "132", opcode: "CALL"}, {address: "133", opcode: "ISZERO"}] # [{address: "132", opcode: "CALL"}, {address: "133", opcode: "ISZERO"}]
'''
start_index = helper.get_instruction_index(call.node.instruction_list, call.addr) + 1 start_index = helper.get_instruction_index(call.node.instruction_list, call.addr) + 1
retval_checked = False retval_checked = False
# ISZERO retval should be found within the next few instructions. # ISZERO retval should be found within the next few instructions.
for i in range(0, 10): for i in range(0, 10):
try: try:
instr = call.node.instruction_list[start_index + i] instr = call.node.states[start_index + i].
except IndexError: except IndexError:
break break
@ -80,4 +84,6 @@ def execute(statespace):
issues.append(issue) issues.append(issue)
'''
return issues return issues

@ -23,8 +23,6 @@ class Op:
def __init__(self, node, addr): def __init__(self, node, addr):
self.node = node self.node = node
self.addr = addr self.addr = addr
self.state = node.states[addr]
class Call(Op): class Call(Op):

@ -1,15 +1,11 @@
from mythril.analysis import solver from mythril.analysis import solver
from mythril.exceptions import UnsatError from mythril.exceptions import UnsatError
from laser.ethereum import svm from laser.ethereum import svm
import copy
from .ops import * from .ops import *
import logging import logging
class SStorTaintStatus(Enum):
TAINTED = 1
UNTAINTED = 2
class StateSpace: class StateSpace:
''' '''
@ -21,9 +17,9 @@ class StateSpace:
self.accounts = {} self.accounts = {}
for contract in contracts: for contract in contracts:
self.accounts[contract.address] = svm.Account(contract.get_disassembly()) self.accounts[contract.address] = svm.Account(contract.address, contract.get_disassembly())
self.laser = svm.Laser(self.accounts, dynamic_loader=dynloader, max_depth=max_depth) self.laser = svm.LaserEVM(self.accounts, dynamic_loader=dynloader, max_depth=max_depth)
self.laser.sym_exec(contracts[0].address) self.laser.sym_exec(contracts[0].address)
# self.modules = modules # self.modules = modules
@ -43,7 +39,7 @@ class StateSpace:
op = instruction['opcode'] op = instruction['opcode']
if op in ('CALL', 'CALLCODE', 'DELEGATECALL', 'STATICCALL'): if op in ('CALL', 'CALLCODE', 'DELEGATECALL', 'STATICCALL'):
stack = copy.deepcopy(self.svm.nodes[key].states[instruction['address']].stack) stack = copy.deepcopy(state.mstate.stack)
if op in ('CALL', 'CALLCODE'): if op in ('CALL', 'CALLCODE'):
gas, to, value, meminstart, meminsz, memoutstart, memoutsz = \ gas, to, value, meminstart, meminsz, memoutstart, memoutsz = \
@ -55,7 +51,7 @@ class StateSpace:
continue continue
if (meminstart.type == VarType.CONCRETE and meminsz.type == VarType.CONCRETE): if (meminstart.type == VarType.CONCRETE and meminsz.type == VarType.CONCRETE):
self.calls.append(Call(self.nodes[key], instruction['address'], op, to, gas, value, self.svm.nodes[key].states[instruction['address']].memory[meminstart.val:meminsz.val*4])) self.calls.append(Call(self.nodes[key], instruction['address'], op, to, gas, value, state.mstate.memory[meminstart.val:meminsz.val*4]))
else: else:
self.calls.append(Call(self.nodes[key], instruction['address'], op, to, gas, value)) self.calls.append(Call(self.nodes[key], instruction['address'], op, to, gas, value))
else: else:
@ -64,8 +60,9 @@ class StateSpace:
self.calls.append(Call(self.nodes[key], instruction['address'], op, to, gas)) self.calls.append(Call(self.nodes[key], instruction['address'], op, to, gas))
'''
elif op == 'SSTORE': elif op == 'SSTORE':
stack = copy.deepcopy(self.svm.nodes[key].states[instruction['address']].stack) stack = copy.deepcopy(state.mstate.stack)
index, value = stack.pop(), stack.pop() index, value = stack.pop(), stack.pop()
@ -73,6 +70,7 @@ class StateSpace:
self.sstors[str(index)].append(SStore(self.nodes[key], instruction['address'], value)) self.sstors[str(index)].append(SStore(self.nodes[key], instruction['address'], value))
except KeyError: except KeyError:
self.sstors[str(index)] = [SStore(self.nodes[key], instruction['address'], value)] self.sstors[str(index)] = [SStore(self.nodes[key], instruction['address'], value)]
'''

@ -51,5 +51,4 @@ class DynLoader:
if (code == "0x"): if (code == "0x"):
return None return None
else: else:
contract = ETHContract(self.eth.eth_getCode(dependency_address), name=dependency_address, address=dependency_address) return ETHContract(self.eth.eth_getCode(dependency_address)).get_disassembly()
return contract.as_dict()

Loading…
Cancel
Save