Add partial abi support (#1655)

* Fix issues with arbitrary jump dest

* Support abi

* Add partial abi support

* Fix test

* Fix test directory
pull/1662/head
Nikhil Parasaram 2 years ago committed by GitHub
parent 842e3da3a4
commit d6e8813100
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 25
      mythril/analysis/report.py
  2. 56
      tests/analysis/abi_decode_test.py
  3. 2
      tests/analysis/arbitrary_jump_test.py

@ -1,7 +1,9 @@
"""This module provides classes that make up an issue report."""
import logging
import re
import json
import operator
from eth_abi import decode_abi
from jinja2 import PackageLoader, Environment
from typing import Dict, List, Any, Optional
import hashlib
@ -193,11 +195,34 @@ class Issue:
# TODO: Check other mythx tools for dependency before supporting multiple possible function names
if len(sig) > 0:
step["name"] = sig[0]
step["resolved_input"] = Issue.resolve_input(
step["calldata"], sig[0]
)
else:
step["name"] = "unknown"
except ValueError:
step["name"] = "unknown"
@staticmethod
def resolve_input(data, function_name):
"""
Adds decoded calldate to the tx sequence.
"""
data = data[10:]
# Eliminates the first and last brackets
# Since signature such as func((bytes32,bytes32,uint8)[],(address[],uint32)) are valid
type_info = function_name[function_name.find("(") + 1 : -1]
type_info = re.split(r",\s*(?![^()]*\))", type_info)
if len(data) % 64 > 0:
data += "0" * (64 - len(data) % 64)
try:
decoded_output = decode_abi(type_info, bytes.fromhex(data))
return decoded_output
except Exception as e:
return None
class Report:
"""A report containing the content of multiple issues."""

@ -0,0 +1,56 @@
import pytest
from mythril.analysis.report import Issue
from mythril.disassembler.disassembly import Disassembly
from mythril.laser.ethereum.state.environment import Environment
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
from mythril.laser.ethereum.state.world_state import WorldState
from mythril.laser.ethereum.instructions import Instruction
from mythril.laser.ethereum.transaction.transaction_models import MessageCallTransaction
from mythril.laser.smt import symbol_factory, simplify, LShR
test_data = (
(
"0xa9059cbb000000000000000000000000010801010101010120020101020401010408040402",
"func(uint256,uint256)",
(
5887484186314823854737699484601117092168074244,
904625697166532776746648320380374280103671755200316906558262375061821325312,
),
),
(
"0xa9059cbb00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002",
"func(uint256,uint256)",
(2, 2),
),
(
"0xa0cce1b3000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000",
"func(bytes32,(bytes32,bytes32,uint8,uint8)[],(address[],uint32))",
(
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02",
(
(
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90",
0,
0,
),
(
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
1,
0,
),
),
(("0x0000000000000000000000000000000000000000",), 0),
),
),
)
@pytest.mark.parametrize("call_data, signature, expected", test_data)
def test_abi_decode(call_data, signature, expected):
assert Issue.resolve_input(call_data, signature) == expected

@ -37,7 +37,6 @@ def get_global_state(constraints):
world_state = WorldState()
world_state.put_account(active_account)
state = GlobalState(world_state, environment, None, MachineState(gas_limit=8000000))
print(world_state.balances)
state.world_state.transaction_sequence = [
MessageCallTransaction(
world_state=world_state,
@ -56,7 +55,6 @@ def get_global_state(constraints):
None,
)
)
print(state.world_state.transaction_sequence[0].call_data.calldatasize)
state.mstate.stack = [symbol_factory.BitVecSym("jump_dest", 256)]
state.world_state.constraints = Constraints(constraints)
Loading…
Cancel
Save