|
|
@ -1,12 +1,9 @@ |
|
|
|
"""This module contains a wrapper around LASER for extended analysis |
|
|
|
"""This module contains a wrapper around LASER for extended analysis |
|
|
|
purposes.""" |
|
|
|
purposes.""" |
|
|
|
|
|
|
|
|
|
|
|
import copy |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from mythril.analysis.security import get_detection_module_hooks, get_detection_modules |
|
|
|
from mythril.analysis.security import get_detection_module_hooks, get_detection_modules |
|
|
|
from mythril.laser.ethereum import svm |
|
|
|
from mythril.laser.ethereum import svm |
|
|
|
from mythril.laser.ethereum.plugins.plugin_factory import PluginFactory |
|
|
|
|
|
|
|
from mythril.laser.ethereum.plugins.plugin_loader import LaserPluginLoader |
|
|
|
|
|
|
|
from mythril.laser.ethereum.state.account import Account |
|
|
|
from mythril.laser.ethereum.state.account import Account |
|
|
|
from mythril.laser.ethereum.state.world_state import WorldState |
|
|
|
from mythril.laser.ethereum.state.world_state import WorldState |
|
|
|
from mythril.laser.ethereum.strategy.basic import ( |
|
|
|
from mythril.laser.ethereum.strategy.basic import ( |
|
|
@ -30,9 +27,9 @@ from mythril.laser.ethereum.strategy.extensions.bounded_loops import ( |
|
|
|
BoundedLoopsStrategy, |
|
|
|
BoundedLoopsStrategy, |
|
|
|
) |
|
|
|
) |
|
|
|
from mythril.laser.smt import symbol_factory, BitVec |
|
|
|
from mythril.laser.smt import symbol_factory, BitVec |
|
|
|
from typing import Union, List, Dict, Type |
|
|
|
from typing import Union, List, Type |
|
|
|
from mythril.solidity.soliditycontract import EVMContract, SolidityContract |
|
|
|
from mythril.solidity.soliditycontract import EVMContract, SolidityContract |
|
|
|
from .ops import Call, SStore, VarType, get_variable |
|
|
|
from .ops import Call, VarType, get_variable |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SymExecWrapper: |
|
|
|
class SymExecWrapper: |
|
|
@ -171,10 +168,9 @@ class SymExecWrapper: |
|
|
|
self.nodes = self.laser.nodes |
|
|
|
self.nodes = self.laser.nodes |
|
|
|
self.edges = self.laser.edges |
|
|
|
self.edges = self.laser.edges |
|
|
|
|
|
|
|
|
|
|
|
# Generate lists of interesting operations |
|
|
|
# Parse calls to make them easily accessible |
|
|
|
|
|
|
|
|
|
|
|
self.calls = [] # type: List[Call] |
|
|
|
self.calls = [] # type: List[Call] |
|
|
|
self.sstors = {} # type: Dict[int, Dict[str, List[SStore]]] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for key in self.nodes: |
|
|
|
for key in self.nodes: |
|
|
|
|
|
|
|
|
|
|
@ -249,50 +245,4 @@ class SymExecWrapper: |
|
|
|
Call(self.nodes[key], state, state_index, op, to, gas) |
|
|
|
Call(self.nodes[key], state, state_index, op, to, gas) |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
elif op == "SSTORE": |
|
|
|
|
|
|
|
stack = copy.copy(state.mstate.stack) |
|
|
|
|
|
|
|
address = state.environment.active_account.address.value |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
index, value = stack.pop(), stack.pop() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
self.sstors[address] |
|
|
|
|
|
|
|
except KeyError: |
|
|
|
|
|
|
|
self.sstors[address] = {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
self.sstors[address][str(index)].append( |
|
|
|
|
|
|
|
SStore(self.nodes[key], state, state_index, value) |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
except KeyError: |
|
|
|
|
|
|
|
self.sstors[address][str(index)] = [ |
|
|
|
|
|
|
|
SStore(self.nodes[key], state, state_index, value) |
|
|
|
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
state_index += 1 |
|
|
|
state_index += 1 |
|
|
|
|
|
|
|
|
|
|
|
def find_storage_write(self, address, index): |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
:param address: |
|
|
|
|
|
|
|
:param index: |
|
|
|
|
|
|
|
:return: |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
# Find an SSTOR not constrained by caller that writes to storage index "index" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
for s in self.sstors[address][index]: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
taint = True |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for constraint in s.node.constraints: |
|
|
|
|
|
|
|
if "caller" in str(constraint): |
|
|
|
|
|
|
|
taint = False |
|
|
|
|
|
|
|
break |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if taint: |
|
|
|
|
|
|
|
return s.node.function_name |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return None |
|
|
|
|
|
|
|
except KeyError: |
|
|
|
|
|
|
|
return None |
|
|
|
|
|
|
|