Merge pull request #730 from ConsenSys/refactor_class_structure

Refactor package and module structure
pull/753/head
Bernhard Mueller 6 years ago committed by GitHub
commit 888ceff7ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      mythril/analysis/symbolic.py
  2. 2
      mythril/disassembler/disassembly.py
  3. 3
      mythril/ether/__init__.py
  4. 65
      mythril/ether/evm.py
  5. 2
      mythril/ethereum/evmcontract.py
  6. 4
      mythril/ethereum/interface/leveldb/accountindexing.py
  7. 4
      mythril/ethereum/interface/leveldb/client.py
  8. 0
      mythril/ethereum/util.py
  9. 12
      mythril/mythril.py
  10. 0
      mythril/solidity/__init__.py
  11. 6
      mythril/solidity/soliditycontract.py
  12. 9
      mythril/support/truffle.py
  13. 2
      tests/disassembler_test.py
  14. 20
      tests/evmcontract_test.py
  15. 6
      tests/graph_test.py
  16. 4
      tests/laser/transaction/create_transaction_test.py
  17. 2
      tests/native_test.py
  18. 7
      tests/report_test.py
  19. 2
      tests/solidity_contract_test.py
  20. 6
      tests/svm_test.py
  21. 2
      tests/testdata/compile.py

@ -1,9 +1,8 @@
from mythril.analysis.security import get_detection_module_hooks
from mythril.laser.ethereum import svm
from mythril.laser.ethereum.state.account import Account
from mythril.ether.soliditycontract import SolidityContract, ETHContract
from mythril.solidity.soliditycontract import SolidityContract, EVMContract
import copy
import logging
from .ops import get_variable, SStore, Call, VarType
from mythril.laser.ethereum.strategy.basic import (
DepthFirstSearchStrategy,
@ -68,7 +67,7 @@ class SymExecWrapper:
self.laser.sym_exec(
creation_code=contract.creation_code, contract_name=contract.name
)
elif isinstance(contract, ETHContract) and contract.creation_code:
elif isinstance(contract, EVMContract) and contract.creation_code:
self.laser.sym_exec(
creation_code=contract.creation_code, contract_name=contract.name
)

@ -1,4 +1,4 @@
from mythril.ether import util
from mythril.ethereum import util
from mythril.disassembler import asm
from mythril.support.signatures import SignatureDb
import logging

@ -1,3 +0,0 @@
import time
start_time = time.time()

@ -1,65 +0,0 @@
from ethereum import vm, messages, transactions
from ethereum.state import State
from ethereum.slogging import get_logger
from mythril.ether import util
from logging import StreamHandler
from io import StringIO
import re
def trace(code, calldata=""):
log_handlers = [
"eth.vm.op",
"eth.vm.op.stack",
"eth.vm.op.memory",
"eth.vm.op.storage",
]
output = StringIO()
stream_handler = StreamHandler(output)
for handler in log_handlers:
log_vm_op = get_logger(handler)
log_vm_op.setLevel("TRACE")
log_vm_op.addHandler(stream_handler)
addr = bytes.fromhex("0123456789ABCDEF0123456789ABCDEF01234567")
state = State()
ext = messages.VMExt(state, transactions.Transaction(0, 0, 21000, addr, 0, addr))
message = vm.Message(addr, addr, 0, 21000, calldata)
vm.vm_execute(ext, message, util.safe_decode(code))
stream_handler.flush()
ret = output.getvalue()
lines = ret.split("\n")
state_trace = []
for line in lines:
m = re.search(r"pc=b\'(\d+)\'.*op=([A-Z0-9]+)", line)
if m:
pc = m.group(1)
op = m.group(2)
m = re.match(r".*stack=(\[.*?\])", line)
if m:
stackitems = re.findall(r"b\'(\d+)\'", m.group(1))
stack = "["
if len(stackitems):
for i in range(0, len(stackitems) - 1):
stack += hex(int(stackitems[i])) + ", "
stack += hex(int(stackitems[-1]))
stack += "]"
else:
stack = "[]"
if re.match(r"^PUSH.*", op):
val = re.search(r"pushvalue=(\d+)", line).group(1)
pushvalue = hex(int(val))
state_trace.append(
{"pc": pc, "op": op, "stack": stack, "pushvalue": pushvalue}
)
else:
state_trace.append({"pc": pc, "op": op, "stack": stack})
return state_trace

@ -4,7 +4,7 @@ import persistent
import re
class ETHContract(persistent.Persistent):
class EVMContract(persistent.Persistent):
def __init__(
self, code="", creation_code="", name="Unknown", enable_online_lookup=False
):

@ -1,5 +1,5 @@
import logging
from mythril import ether
from mythril import ethereum
import time
from ethereum.messages import Log
import rlp
@ -156,7 +156,7 @@ class AccountIndexer(object):
processed += BATCH_SIZE
blockNum = min(blockNum + BATCH_SIZE, self.lastBlock + 1)
cost_time = time.time() - ether.start_time
cost_time = time.time() - ethereum.start_time
print(
"%d blocks processed (in %d seconds), %d unique addresses found, next block: %d"
% (processed, cost_time, count, min(self.lastBlock, blockNum))

@ -10,7 +10,7 @@ from ethereum import utils
from ethereum.block import BlockHeader, Block
from mythril.ethereum.interface.leveldb.state import State
from mythril.ethereum.interface.leveldb.eth_db import ETH_DB
from mythril.ether.ethcontract import ETHContract
from mythril.ethereum.evmcontract import EVMContract
from mythril.exceptions import AddressNotFoundError
# Per https://github.com/ethereum/go-ethereum/blob/master/core/rawdb/schema.go
@ -182,7 +182,7 @@ class EthLevelDB(object):
for account in self.reader._get_head_state().get_all_accounts():
if account.code is not None:
code = _encode_hex(account.code)
contract = ETHContract(code, enable_online_lookup=False)
contract = EVMContract(code, enable_online_lookup=False)
yield contract, account.address, account.balance

@ -17,9 +17,9 @@ import solc
from configparser import ConfigParser
import platform
from mythril.ether import util
from mythril.ether.ethcontract import ETHContract
from mythril.ether.soliditycontract import SolidityContract, get_contracts_from_file
from mythril.ethereum import util
from mythril.ethereum.evmcontract import EVMContract
from mythril.solidity.soliditycontract import SolidityContract, get_contracts_from_file
from mythril.ethereum.interface.rpc.client import EthJsonRpc
from mythril.ethereum.interface.rpc.exceptions import ConnectionError
from mythril.support import signatures
@ -323,7 +323,7 @@ class Mythril(object):
address = util.get_indexed_address(0)
if bin_runtime:
self.contracts.append(
ETHContract(
EVMContract(
code=code,
name="MAIN",
enable_online_lookup=self.enable_online_lookup,
@ -331,7 +331,7 @@ class Mythril(object):
)
else:
self.contracts.append(
ETHContract(
EVMContract(
creation_code=code,
name="MAIN",
enable_online_lookup=self.enable_online_lookup,
@ -360,7 +360,7 @@ class Mythril(object):
)
else:
self.contracts.append(
ETHContract(
EVMContract(
code,
name=address,
enable_online_lookup=self.enable_online_lookup,

@ -1,6 +1,6 @@
import mythril.laser.ethereum.util as helper
from mythril.ether.ethcontract import ETHContract
from mythril.ether.util import get_solc_json
from mythril.ethereum.evmcontract import EVMContract
from mythril.ethereum.util import get_solc_json
from mythril.exceptions import NoContractFoundError
@ -42,7 +42,7 @@ def get_contracts_from_file(input_file, solc_args=None, solc_binary="solc"):
raise NoContractFoundError
class SolidityContract(ETHContract):
class SolidityContract(EVMContract):
def __init__(self, input_file, name=None, solc_args=None, solc_binary="solc"):
data = get_solc_json(input_file, solc_args=solc_args, solc_binary=solc_binary)

@ -5,14 +5,13 @@ import sys
import json
import logging
from ethereum.utils import sha3
from mythril.ether.ethcontract import ETHContract
from mythril.ether.soliditycontract import SourceMapping
from mythril.exceptions import CriticalError
from mythril.ethereum.evmcontract import EVMContract
from mythril.solidity.soliditycontract import SourceMapping
from mythril.analysis.security import fire_lasers
from mythril.analysis.symbolic import SymExecWrapper
from mythril.analysis.report import Report
from mythril.ether import util
from mythril.ethereum import util
from mythril.laser.ethereum.util import get_instruction_index
@ -44,7 +43,7 @@ def analyze_truffle_project(sigs, args):
continue
get_sigs_from_truffle(sigs, contractdata)
ethcontract = ETHContract(bytecode, name=name)
ethcontract = EVMContract(bytecode, name=name)
address = util.get_indexed_address(0)
sym = SymExecWrapper(

@ -1,5 +1,5 @@
from mythril.disassembler.disassembly import Disassembly
from mythril.ether import util
from mythril.ethereum import util
from tests import *

@ -1,41 +1,41 @@
import unittest
from mythril.ether.ethcontract import ETHContract
from mythril.ethereum.evmcontract import EVMContract
class ETHContractTestCase(unittest.TestCase):
class EVMContractTestCase(unittest.TestCase):
def setUp(self):
self.code = "0x60606040525b603c5b60006010603e565b9050593681016040523660008237602060003683856040603f5a0204f41560545760206000f35bfe5b50565b005b73c3b2ae46792547a96b9f84405e36d0e07edcd05c5b905600a165627a7a7230582062a884f947232ada573f95940cce9c8bfb7e4e14e21df5af4e884941afb55e590029"
self.creation_code = "0x60606040525b603c5b60006010603e565b9050593681016040523660008237602060003683856040603f5a0204f41560545760206000f35bfe5b50565b005b73c3b2ae46792547a96b9f84405e36d0e07edcd05c5b905600a165627a7a7230582062a884f947232ada573f95940cce9c8bfb7e4e14e21df5af4e884941afb55e590029"
class Getinstruction_listTestCase(ETHContractTestCase):
class Getinstruction_listTestCase(EVMContractTestCase):
def runTest(self):
contract = ETHContract(self.code, self.creation_code)
contract = EVMContract(self.code, self.creation_code)
disassembly = contract.disassembly
self.assertEqual(
len(disassembly.instruction_list),
53,
"Error disassembling code using ETHContract.get_instruction_list()",
"Error disassembling code using EVMContract.get_instruction_list()",
)
class GetEASMTestCase(ETHContractTestCase):
class GetEASMTestCase(EVMContractTestCase):
def runTest(self):
contract = ETHContract(self.code)
contract = EVMContract(self.code)
instruction_list = contract.get_easm()
self.assertTrue(
"PUSH1 0x60" in instruction_list,
"Error obtaining EASM code through ETHContract.get_easm()",
"Error obtaining EASM code through EVMContract.get_easm()",
)
class MatchesExpressionTestCase(ETHContractTestCase):
class MatchesExpressionTestCase(EVMContractTestCase):
def runTest(self):
contract = ETHContract(self.code)
contract = EVMContract(self.code)
self.assertTrue(
contract.matches_expression("code#PUSH1# or code#PUSH1#"),

@ -1,7 +1,7 @@
from mythril.analysis.callgraph import generate_graph
from mythril.analysis.symbolic import SymExecWrapper
from mythril.ether import util
from mythril.ether.soliditycontract import ETHContract
from mythril.ethereum import util
from mythril.solidity.soliditycontract import EVMContract
from tests import *
import re
@ -17,7 +17,7 @@ class GraphTest(BaseTestCase):
input_file.name + ".graph.html"
)
contract = ETHContract(input_file.read_text())
contract = EVMContract(input_file.read_text())
sym = SymExecWrapper(
contract,

@ -1,9 +1,9 @@
from mythril.laser.ethereum.transaction import execute_contract_creation
from mythril.ether import util
from mythril.ethereum import util
import mythril.laser.ethereum.svm as svm
from mythril.disassembler.disassembly import Disassembly
from datetime import datetime
from mythril.ether.soliditycontract import SolidityContract
from mythril.solidity.soliditycontract import SolidityContract
import tests
from mythril.analysis.security import fire_lasers
from mythril.analysis.symbolic import SymExecWrapper

@ -1,4 +1,4 @@
from mythril.ether.soliditycontract import SolidityContract
from mythril.solidity.soliditycontract import SolidityContract
from mythril.laser.ethereum.state.account import Account
from mythril.laser.ethereum.state.machine_state import MachineState
from mythril.laser.ethereum.state.global_state import GlobalState

@ -1,10 +1,9 @@
from mythril.analysis.report import Report
from mythril.analysis.security import fire_lasers
from mythril.analysis.symbolic import SymExecWrapper
from mythril.ether import util
from mythril.ether.soliditycontract import ETHContract
from mythril.ethereum import util
from mythril.solidity.soliditycontract import EVMContract
from multiprocessing import Pool, cpu_count
import datetime
import pytest
import json
from tests import *
@ -23,7 +22,7 @@ def _fix_debug_data(json_str):
def _generate_report(input_file):
contract = ETHContract(input_file.read_text(), enable_online_lookup=False)
contract = EVMContract(input_file.read_text(), enable_online_lookup=False)
sym = SymExecWrapper(
contract,
address=(util.get_indexed_address(0)),

@ -1,6 +1,6 @@
from pathlib import Path
from mythril.ether.soliditycontract import SolidityContract
from mythril.solidity.soliditycontract import SolidityContract
from tests import BaseTestCase
TEST_FILES = Path(__file__).parent / "testdata/input_contracts"

@ -2,8 +2,8 @@ import json
from mythril.analysis.security import get_detection_module_hooks
from mythril.analysis.symbolic import SymExecWrapper
from mythril.analysis.callgraph import generate_graph
from mythril.ether.ethcontract import ETHContract
from mythril.ether.soliditycontract import SolidityContract
from mythril.ethereum.evmcontract import EVMContract
from mythril.solidity.soliditycontract import SolidityContract
from mythril.laser.ethereum.state.account import Account
from mythril.laser.ethereum.state.machine_state import MachineState
@ -105,7 +105,7 @@ class SVMTestCase(BaseTestCase):
code = "0x60606040525b603c5b60006010603e565b9050593681016040523660008237602060003683856040603f5a0204f41560545760206000f35bfe5b50565b005b73c3b2ae46792547a96b9f84405e36d0e07edcd05c5b905600a165627a7a7230582062a884f947232ada573f95940cce9c8bfb7e4e14e21df5af4e884941afb55e590029"
contract = ETHContract(code)
contract = EVMContract(code)
sym = SymExecWrapper(contract, "0xd0a6E6C543bC68Db5db3A191B171A77407Ff7ccf")
html = generate_graph(sym)

@ -1,6 +1,6 @@
# compile test contracts
from pathlib import Path
from mythril.ether.soliditycontract import SolidityContract
from mythril.solidity.soliditycontract import SolidityContract
# Recompiles all the to be tested contracts
root = Path(__file__).parent

Loading…
Cancel
Save