Merge pull request #971 from ConsenSys/jsonv2fix

Fix the jsonv2 output for the type of the contract
pull/997/head
Nikhil Parasaram 6 years ago committed by GitHub
commit d42153f592
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 35
      mythril/analysis/report.py
  2. 29
      mythril/ethereum/evmcontract.py
  3. 4
      mythril/mythril.py
  4. 2
      mythril/mythril/mythril_analyzer.py
  5. 20
      mythril/support/source_support.py
  6. 19
      mythril/support/support_utils.py
  7. 2
      tests/report_test.py
  8. 10
      tests/testdata/outputs_expected/ether_send.sol.o.jsonv2
  9. 10
      tests/testdata/outputs_expected/metacoin.sol.o.jsonv2
  10. 10
      tests/testdata/outputs_expected/nonascii.sol.o.jsonv2

@ -4,13 +4,13 @@ import json
import operator
from jinja2 import PackageLoader, Environment
from typing import Dict, List
import _pysha3 as sha3
import hashlib
from mythril.solidity.soliditycontract import SolidityContract
from mythril.analysis.swc_data import SWC_TO_TITLE
from mythril.support.source_support import Source
from mythril.support.start_time import StartTime
from mythril.support.support_utils import get_code_hash
from time import time
log = logging.getLogger(__name__)
@ -63,20 +63,7 @@ class Issue:
self.lineno = None
self.source_mapping = None
self.discovery_time = time() - StartTime().global_start_time
try:
keccak = sha3.keccak_256()
keccak.update(
bytes.fromhex(bytecode[2:])
if bytecode[:2] == "0x"
else bytes.fromhex(bytecode)
)
self.bytecode_hash = "0x" + keccak.hexdigest()
except ValueError:
log.debug(
"Unable to change the bytecode to bytes. Bytecode: {}".format(bytecode)
)
self.bytecode_hash = ""
self.bytecode_hash = get_code_hash(bytecode)
@property
def as_dict(self):
@ -144,7 +131,7 @@ class Report:
loader=PackageLoader("mythril.analysis"), trim_blocks=True
)
def __init__(self, verbose=False, source=None, exceptions=None):
def __init__(self, verbose=False, contracts=None, exceptions=None):
"""
:param verbose:
@ -153,7 +140,8 @@ class Report:
self.verbose = verbose
self.solc_version = ""
self.meta = {}
self.source = source or Source()
self.source = Source()
self.source.get_source_from_contracts_list(contracts)
self.exceptions = exceptions or []
def sorted_issues(self):
@ -210,12 +198,7 @@ class Report:
for key, issue in self.issues.items():
if issue.bytecode_hash not in source_list:
idx = len(source_list)
source_list.append(issue.bytecode_hash)
else:
idx = source_list.index(issue.bytecode_hash)
idx = self.source.get_source_index(issue.bytecode_hash)
try:
title = SWC_TO_TITLE[issue.swc_id]
except KeyError:
@ -238,9 +221,9 @@ class Report:
result = [
{
"issues": _issues,
"sourceType": "raw-bytecode",
"sourceFormat": "evm-byzantium-bytecode",
"sourceList": source_list,
"sourceType": self.source.source_type,
"sourceFormat": self.source.source_format,
"sourceList": self.source.source_list,
"meta": meta_data,
}
]

@ -1,15 +1,14 @@
"""This module contains the class representing EVM contracts, aka Smart
Contracts."""
import re
import _pysha3 as sha3
import logging
log = logging.getLogger(__name__)
import persistent
from ethereum import utils
from ethereum import utils
from mythril.disassembler.disassembly import Disassembly
from mythril.support.support_utils import get_code_hash
log = logging.getLogger(__name__)
class EVMContract(persistent.Persistent):
@ -47,7 +46,7 @@ class EVMContract(persistent.Persistent):
:return: runtime bytecode hash
"""
return self._get_hash(self.code[2:])
return get_code_hash(self.code)
@property
def creation_bytecode_hash(self):
@ -55,23 +54,7 @@ class EVMContract(persistent.Persistent):
:return: Creation bytecode hash
"""
return self._get_hash(self.creation_code[2:])
@staticmethod
def _get_hash(code):
"""
:param code: bytecode
:return: Returns hash of the given bytecode
"""
try:
keccak = sha3.keccak_256()
keccak.update(bytes.fromhex(code[2:]))
return "0x" + keccak.hexdigest()
except ValueError:
log.debug(
"Unable to change the bytecode to bytes. Bytecode: {}".format(code)
)
return ""
return get_code_hash(self.creation_code)
def as_dict(self):
"""

@ -608,10 +608,8 @@ class Mythril(object):
all_issues += issues
log.info("Solver statistics: \n{}".format(str(SolverStatistics())))
source_data = Source()
source_data.get_source_from_contracts_list(self.contracts)
# Finally, output the results
report = Report(verbose_report, source_data, exceptions=exceptions)
report = Report(verbose_report, self.contracts, exceptions=exceptions)
for issue in all_issues:
report.append_issue(issue)

@ -166,7 +166,7 @@ class MythrilAnalyzer:
source_data = Source()
source_data.get_source_from_contracts_list(self.contracts)
# Finally, output the results
report = Report(verbose_report, source_data, exceptions=exceptions)
report = Report(verbose_report, contracts=self.contracts, exceptions=exceptions)
for issue in all_issues:
report.append_issue(issue)

@ -5,9 +5,7 @@ from mythril.ethereum.evmcontract import EVMContract
class Source:
"""Class to handle to source data"""
def __init__(
self, source_type=None, source_format=None, source_list=None, meta=None
):
def __init__(self, source_type=None, source_format=None, source_list=None):
"""
:param source_type: whether it is a solidity-file or evm-bytecode
:param source_format: whether it is bytecode, ethereum-address or text
@ -17,7 +15,7 @@ class Source:
self.source_type = source_type
self.source_format = source_format
self.source_list = source_list or []
self.meta = meta
self._source_hash = []
def get_source_from_contracts_list(self, contracts):
"""
@ -32,16 +30,28 @@ class Source:
self.source_format = "text"
for contract in contracts:
self.source_list += [file.filename for file in contract.solidity_files]
self._source_hash.append(contract.bytecode_hash)
elif isinstance(contracts[0], EVMContract):
self.source_format = "evm-byzantium-bytecode"
self.source_type = (
"raw-bytecode" if contracts[0].name == "MAIN" else "ethereum-address"
"ethereum-address"
if len(contracts[0].name) == 42 and contracts[0].name[0:2] == "0x"
else "raw-bytecode"
)
for contract in contracts:
if contract.creation_code:
self.source_list.append(contract.creation_bytecode_hash)
if contract.code:
self.source_list.append(contract.bytecode_hash)
self._source_hash = self.source_list
else:
assert False # Fail hard
def get_source_index(self, bytecode_hash: str) -> int:
"""
Find the contract index in the list
:param bytecode_hash: The contract hash
:return: The index of the contract in the _source_hash list
"""
return self._source_hash.index(bytecode_hash)

@ -1,5 +1,9 @@
"""This module contains utility functions for the Mythril support package."""
from typing import Dict
import logging
import _pysha3 as sha3
log = logging.getLogger(__name__)
class Singleton(type):
@ -20,3 +24,18 @@ class Singleton(type):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
def get_code_hash(code: str) -> str:
"""
:param code: bytecode
:return: Returns hash of the given bytecode
"""
code = code[2:] if code[:2] == "0x" else code
try:
keccak = sha3.keccak_256()
keccak.update(bytes.fromhex(code))
return "0x" + keccak.hexdigest()
except ValueError:
log.debug("Unable to change the bytecode to bytes. Bytecode: {}".format(code))
return ""

@ -39,7 +39,7 @@ def _generate_report(input_file):
)
issues = fire_lasers(sym)
report = Report()
report = Report(contracts=[contract])
for issue in issues:
issue.filename = "test-filename.sol"
report.append_issue(issue)

@ -1,9 +1 @@
[
{
"issues": [],
"meta": {},
"sourceFormat": "evm-byzantium-bytecode",
"sourceList": [],
"sourceType": "raw-bytecode"
}
]
[{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x3746c7c2ae7b0d4c3f8b1905df9a7ea169b9f93bec68a10a00b4c9d27a18c6fb"], "sourceType": "raw-bytecode"}]

@ -1,9 +1 @@
[
{
"issues": [],
"meta": {},
"sourceFormat": "evm-byzantium-bytecode",
"sourceList": [],
"sourceType": "raw-bytecode"
}
]
[{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x0e6f727bb3301e02d3be831bf34357522fd2f1d40e90dff8e2214553b06b5f6c"], "sourceType": "raw-bytecode"}]

@ -1,9 +1 @@
[
{
"issues": [],
"meta": {},
"sourceFormat": "evm-byzantium-bytecode",
"sourceList": [],
"sourceType": "raw-bytecode"
}
]
[{"issues": [], "meta": {}, "sourceFormat": "evm-byzantium-bytecode", "sourceList": ["0x11a78eb09819f505ba4f10747e6d1f7a44480e602c67573b7abac2f733a85d93"], "sourceType": "raw-bytecode"}]

Loading…
Cancel
Save