From f1d88ff8186813e2c2ad3d431ac57329b9dd145a Mon Sep 17 00:00:00 2001 From: Bernhard Mueller Date: Sat, 20 Jan 2018 11:03:34 +0700 Subject: [PATCH] Add workaround to prevent crash when dynamic contract address is encountered in bytecode --- mythril/analysis/modules/integer_underflow.py | 3 ++- mythril/ether/ethcontract.py | 9 ++++++++- mythril/ether/util.py | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/mythril/analysis/modules/integer_underflow.py b/mythril/analysis/modules/integer_underflow.py index 1ae9d601..d74b930e 100644 --- a/mythril/analysis/modules/integer_underflow.py +++ b/mythril/analysis/modules/integer_underflow.py @@ -38,7 +38,8 @@ def execute(statespace): continue if (re.search(r'calldatasize_', str(op0))) \ - or (re.search(r'256\*.*If\(1', str(op0), re.DOTALL) or re.search(r'256\*.*If\(1', str(op1), re.DOTALL)): + or (re.search(r'256\*.*If\(1', str(op0), re.DOTALL) or re.search(r'256\*.*If\(1', str(op1), re.DOTALL)) \ + or (re.search(r'32 \+.*calldata', str(op0), re.DOTALL) or re.search(r'32 \+.*calldata', str(op1), re.DOTALL)): # Filter for patterns that contain possible (but apparently non-exploitable) Integer underflows. diff --git a/mythril/ether/ethcontract.py b/mythril/ether/ethcontract.py index 5a5f3ffe..dd5622d6 100644 --- a/mythril/ether/ethcontract.py +++ b/mythril/ether/ethcontract.py @@ -8,11 +8,18 @@ class ETHContract(persistent.Persistent): def __init__(self, code, creation_code="", name="", address=""): - self.code = code self.creation_code = creation_code self.name = name self.address = address + # Workaround: We currently do not support compile-time linking. + # Dynamic contract addresses of the format __[contract-name]_____________ are replaced with a generic address + + code = re.sub(r'(_+[A-Za-z0-9]+_+)', 'aa' * 20, code) + + self.code = code + + def as_dict(self): return { diff --git a/mythril/ether/util.py b/mythril/ether/util.py index 350e08c2..98c7f7d1 100644 --- a/mythril/ether/util.py +++ b/mythril/ether/util.py @@ -9,6 +9,7 @@ import re def safe_decode(hex_encoded_string): + if (hex_encoded_string.startswith("0x")): return bytes.fromhex(hex_encoded_string[2:]) else: