mirror of https://github.com/ConsenSys/mythril
parent
35743e84d6
commit
cc17f7ee90
@ -0,0 +1,96 @@ |
||||
from z3 import * |
||||
from laser.ethereum import helper |
||||
import re |
||||
import logging |
||||
from enum import Enum |
||||
|
||||
|
||||
class TransferType(Enum): |
||||
HARDCODED = 1 |
||||
CALLDATA = 2 |
||||
CALLER = 3 |
||||
OTHER = 3 |
||||
|
||||
|
||||
def execute(svm): |
||||
|
||||
for k in svm.nodes: |
||||
node = svm.nodes[k] |
||||
|
||||
for instruction in node.instruction_list: |
||||
|
||||
if(instruction['opcode'] == "CALL"): |
||||
|
||||
state = node.states[instruction['address']] |
||||
|
||||
gas, to, value, meminstart, meminsz, memoutstart, memoutsz = \ |
||||
state.stack.pop(), state.stack.pop(), state.stack.pop(), state.stack.pop(), state.stack.pop(), state.stack.pop(), state.stack.pop() |
||||
|
||||
interesting = False |
||||
|
||||
try: |
||||
value = helper.get_concrete_int(value) |
||||
if(value > 0): |
||||
print ("Call with non-zero value: " + str(value)) |
||||
interesting = True |
||||
except AttributeError: |
||||
print ("Call with symbolic value: " + str(value)) |
||||
interesting = True |
||||
|
||||
if interesting: |
||||
|
||||
try: |
||||
to = helper.get_concrete_int(to).hex() |
||||
except AttributeError: |
||||
to = str(simplify(to)) |
||||
|
||||
print("Function name: " + str(node.function_name)) |
||||
|
||||
m = re.search(r'calldata_(\d)', to) |
||||
|
||||
if m: |
||||
cd_index = m.group(1) |
||||
print("Transfer to [calldata_" + str(cd_index) + "] " + str(node.function_name)) |
||||
transfer_type = TransferType.CALLDATA |
||||
else: |
||||
m = re.search(r'caller', to) |
||||
|
||||
if m: |
||||
print("Transfer to msg.sender") |
||||
transfer_type = TransferType.CALLER |
||||
else: |
||||
m = re.match(r'0x[0-9a-f]+', to) |
||||
if m: |
||||
print("Transfer to address " + to) |
||||
transfer_type = TransferType.HARDCODED |
||||
else: |
||||
print("Transfer to " + to) |
||||
transfer_type = TransferType.OTHER |
||||
|
||||
|
||||
for constraint in node.constraints: |
||||
m = re.search(r'caller', str(constraint)) |
||||
n = re.search(r'storage_(\d+)', str(constraint)) |
||||
|
||||
if (m and n): |
||||
storage_index = n.group(1) |
||||
|
||||
print("constraint on caller == storage_" + str(storage_index)) |
||||
break |
||||
|
||||
s = Solver() |
||||
|
||||
s.set(timeout=5000) |
||||
|
||||
for constraint in node.constraints: |
||||
s.add(constraint) |
||||
|
||||
if (s.check() == sat): |
||||
|
||||
m = s.model() |
||||
|
||||
for d in m.decls(): |
||||
print("%s = 0x%x" % (d.name(), m[d].as_long())) |
||||
|
||||
else: |
||||
print("unsat") |
@ -0,0 +1,31 @@ |
||||
from z3 import * |
||||
|
||||
|
||||
def execute(svm): |
||||
|
||||
for k in svm.nodes: |
||||
node = svm.nodes[k] |
||||
|
||||
for instruction in node.instruction_list: |
||||
|
||||
if(instruction['opcode'] == "SUICIDE"): |
||||
state = node.states[instruction['address']] |
||||
to = state.stack.pop() |
||||
|
||||
print("SUICIDE to: " + str(to)) |
||||
print("function: " + str(node.function_name)) |
||||
|
||||
s = Solver() |
||||
|
||||
for constraint in node.constraints: |
||||
s.add(constraint) |
||||
|
||||
if (s.check() == sat): |
||||
print("MODEL:") |
||||
|
||||
m = s.model() |
||||
|
||||
for d in m.decls(): |
||||
print("%s = 0x%x" % (d.name(), m[d].as_long())) |
||||
else: |
||||
print("unsat") |
@ -0,0 +1,3 @@ |
||||
def fire_lasers: |
||||
pass |
||||
|
@ -0,0 +1,26 @@ |
||||
from laser.ethereum import svm |
||||
from .modules import unchecked_suicide, ether_send |
||||
import logging |
||||
|
||||
|
||||
class StateSpace: |
||||
|
||||
''' |
||||
Symbolic EVM wrapper |
||||
''' |
||||
|
||||
def __init__(self, contracts, main_contract, dynloader = None, simplify=True): |
||||
|
||||
# Convert ETHContract objects to LASER SVM "modules" |
||||
|
||||
modules = {} |
||||
|
||||
for contract in contracts: |
||||
modules[contract.address] = contract.as_dict() |
||||
|
||||
_svm = svm.SVM(modules, modules[0], dynamic_loader=dynloader, simplify=simplify) |
||||
|
||||
_svm.sym_exec() |
||||
|
||||
self.nodes = _svm.nodes |
||||
self.edges = _svm.edges |
Loading…
Reference in new issue