Ejemplo n.º 1
0
    def test_get_source_info_with_contract_name_specified_constructor(self):
        input_file = TEST_FILES / "constructor_assert.sol"
        contract = SolidityContract(str(input_file), name="AssertFail")

        code_info = contract.get_source_info(70, constructor=True)

        self.assertEqual(code_info.filename, str(input_file))
        self.assertEqual(code_info.lineno, 6)
        self.assertEqual(code_info.code, "assert(var1 > 0)")
Ejemplo n.º 2
0
    def test_get_source_info_with_contract_name_specified(self):
        input_file = TEST_FILES / "multi_contracts.sol"
        contract = SolidityContract(str(input_file), name="Transfer1")

        code_info = contract.get_source_info(142)

        self.assertEqual(code_info.filename, str(input_file))
        self.assertEqual(code_info.lineno, 6)
        self.assertEqual(code_info.code, "msg.sender.transfer(1 ether)")
Ejemplo n.º 3
0
    def test_get_source_info_without_name_gets_latest_contract_info(self):
        input_file = TEST_FILES / "multi_contracts.sol"
        contract = SolidityContract(str(input_file))

        code_info = contract.get_source_info(142)

        self.assertEqual(code_info.filename, str(input_file))
        self.assertEqual(code_info.lineno, 14)
        self.assertEqual(code_info.code, "msg.sender.transfer(2 ether)")
Ejemplo n.º 4
0
    def test_laser_result(self):
        for input_file in TESTDATA_INPUTS_CONTRACTS.iterdir():
            if input_file.name in ["weak_random.sol", "environments.sol"]:
                continue
            output_expected = TESTDATA_OUTPUTS_EXPECTED_LASER_RESULT / (
                input_file.name + ".json")
            output_current = TESTDATA_OUTPUTS_CURRENT_LASER_RESULT / (
                input_file.name + ".json")

            disassembly = SolidityContract(
                str(input_file),
                solc_binary=Mythril._init_solc_binary("0.5.0")).disassembly
            account = Account("0x0000000000000000000000000000000000000000",
                              disassembly)
            accounts = {account.address: account}

            laser = svm.LaserEVM(accounts, max_depth=22, transaction_count=1)
            laser.register_hooks(hook_type="post",
                                 hook_dict=get_detection_module_hooks())
            laser.sym_exec(account.address)
            laser_info = _all_info(laser)

            output_current.write_text(
                json.dumps(laser_info, cls=LaserEncoder, indent=4))

            if not (output_expected.read_text()
                    == output_expected.read_text()):
                self.found_changed_files(input_file, output_expected,
                                         output_current)

        self.assert_and_show_changed_files()
def test_sym_exec():
    contract = SolidityContract(
        str(tests.TESTDATA_INPUTS_CONTRACTS / "calls.sol"),
        solc_binary=Mythril._init_solc_binary("0.5.0"),
    )

    sym = SymExecWrapper(contract,
                         address=(util.get_indexed_address(0)),
                         strategy="dfs")
    issues = fire_lasers(sym)

    assert len(issues) != 0
Ejemplo n.º 6
0
def test_sym_exec():
    contract = SolidityContract(
        str(tests.TESTDATA_INPUTS_CONTRACTS / "calls.sol"))

    sym = SymExecWrapper(
        contract,
        address=(util.get_indexed_address(0)),
        strategy="dfs",
        execution_timeout=25,
    )
    issues = fire_lasers(sym)

    assert len(issues) != 0
Ejemplo n.º 7
0
    def load_from_solidity(self, solidity_files):
        """

        :param solidity_files:
        :return:
        """
        address = util.get_indexed_address(0)
        contracts = []
        for file in solidity_files:
            if ":" in file:
                file, contract_name = file.split(":")
            else:
                contract_name = None

            file = os.path.expanduser(file)

            try:
                # import signatures from solidity source
                self.sigs.import_solidity_file(file,
                                               solc_binary=self.solc_binary,
                                               solc_args=self.solc_args)
                if contract_name is not None:
                    contract = SolidityContract(
                        input_file=file,
                        name=contract_name,
                        solc_args=self.solc_args,
                        solc_binary=self.solc_binary,
                    )
                    self.contracts.append(contract)
                    contracts.append(contract)
                else:
                    for contract in get_contracts_from_file(
                            input_file=file,
                            solc_args=self.solc_args,
                            solc_binary=self.solc_binary,
                    ):
                        self.contracts.append(contract)
                        contracts.append(contract)

            except FileNotFoundError:
                raise CriticalError("Input file not found: " + file)
            except CompilerError as e:
                raise CriticalError(e)
            except NoContractFoundError:
                log.error("The file " + file +
                          " does not contain a compilable contract.")

        return address, contracts
Ejemplo n.º 8
0
    def runTest():
        """"""
        disassembly = SolidityContract(
            "./tests/native_tests.sol", solc_binary=Mythril._init_solc_binary("0.5.0")
        ).disassembly
        account = Account("0x0000000000000000000000000000000000000000", disassembly)
        accounts = {account.address: account}

        laser = svm.LaserEVM(accounts, max_depth=100, transaction_count=1)
        laser.sym_exec(account.address)

        laser_info = str(_all_info(laser))

        _test_natives(laser_info, SHA256_TEST, "SHA256")
        _test_natives(laser_info, RIPEMD160_TEST, "RIPEMD160")
        _test_natives(laser_info, ECRECOVER_TEST, "ECRECOVER")
        _test_natives(laser_info, IDENTITY_TEST, "IDENTITY")
Ejemplo n.º 9
0
def AnalyseSherlockSolidity(nameContract, addressContract, locationContract):

    startTime = time.time()  # pour calculer temps exécution

    accounts = {}
    contractAddress = addressContract
    contractName = nameContract
    contract = SolidityContract(locationContract)

    account = svm.Account(contractAddress, contract.disassembly)
    accounts = {contractAddress: account}

    laser = svm.LaserEVM(accounts,
                         max_depth=maxDept,
                         execution_timeout=executionTimeOut,
                         create_timeout=createTimeOut,
                         transaction_count=transactionCount)
    ExecutionSymbolique(laser, contractAddress, contractName, startTime)
Ejemplo n.º 10
0
    def runTest():
        """"""
        disassembly = SolidityContract(
            "./tests/native_tests.sol",
            solc_binary=MythrilDisassembler._init_solc_binary("0.5.3"),
        ).disassembly
        account = Account("0x0000000000000000000000000000000000000000",
                          disassembly)
        world_state = WorldState()
        world_state.put_account(account)
        laser = svm.LaserEVM(max_depth=100, transaction_count=1)
        laser.sym_exec(world_state=world_state,
                       target_address=account.address.value)

        laser_info = str(_all_info(laser))

        _test_natives(laser_info, SHA256_TEST, "SHA256")
        _test_natives(laser_info, RIPEMD160_TEST, "RIPEMD160")
        _test_natives(laser_info, ECRECOVER_TEST, "ECRECOVER")
        _test_natives(laser_info, IDENTITY_TEST, "IDENTITY")
Ejemplo n.º 11
0
def test_create():
    contract = SolidityContract(
        str(tests.TESTDATA_INPUTS_CONTRACTS / "calls.sol"))

    laser_evm = svm.LaserEVM({})

    laser_evm.time = datetime.now()
    execute_contract_creation(laser_evm, contract.creation_code)

    resulting_final_state = laser_evm.open_states[0]

    for address, created_account in resulting_final_state.accounts.items():
        created_account_code = created_account.code
        actual_code = Disassembly(contract.code)

        for i in range(len(created_account_code.instruction_list)):
            found_instruction = created_account_code.instruction_list[i]
            actual_instruction = actual_code.instruction_list[i]

            assert found_instruction["opcode"] == actual_instruction["opcode"]
Ejemplo n.º 12
0
    def load_from_solidity(
            self,
            solidity_files: List[str]) -> Tuple[str, List[SolidityContract]]:
        """

        :param solidity_files: List of solidity_files
        :return: tuple of address, contract class list
        """
        address = util.get_indexed_address(0)
        contracts = []
        for file in solidity_files:
            if ":" in file:
                file, contract_name = file.split(":")
            else:
                contract_name = None

            file = os.path.expanduser(file)

            try:
                # import signatures from solidity source
                self.sigs.import_solidity_file(
                    file,
                    solc_binary=self.solc_binary,
                    solc_settings_json=self.solc_settings_json,
                )
                if contract_name is not None:
                    contract = SolidityContract(
                        input_file=file,
                        name=contract_name,
                        solc_settings_json=self.solc_settings_json,
                        solc_binary=self.solc_binary,
                    )
                    self.contracts.append(contract)
                    contracts.append(contract)
                else:
                    for contract in get_contracts_from_file(
                            input_file=file,
                            solc_settings_json=self.solc_settings_json,
                            solc_binary=self.solc_binary,
                    ):
                        self.contracts.append(contract)
                        contracts.append(contract)

            except FileNotFoundError:
                raise CriticalError("Input file not found: " + file)
            except CompilerError as e:
                error_msg = str(e)
                # Check if error is related to solidity version mismatch
                if ("Error: Source file requires different compiler version"
                        in error_msg):
                    # Grab relevant line "pragma solidity <solv>...", excluding any comments
                    solv_pragma_line = error_msg.split("\n")[-3].split("//")[0]
                    # Grab solidity version from relevant line
                    solv_match = re.findall(r"[0-9]+\.[0-9]+\.[0-9]+",
                                            solv_pragma_line)
                    error_suggestion = ("<version_number>"
                                        if len(solv_match) != 1 else
                                        solv_match[0])
                    error_msg = (
                        error_msg +
                        '\nSolidityVersionMismatch: Try adding the option "--solv '
                        + error_suggestion + '"\n')

                raise CriticalError(error_msg)
            except NoContractFoundError:
                log.error("The file " + file +
                          " does not contain a compilable contract.")

        return address, contracts
Ejemplo n.º 13
0
 def contract(self) -> EVMContract:
     return SolidityContract(self._file_path, solc_binary=self._solc)
Ejemplo n.º 14
0
# compile test contracts
from pathlib import Path
from mythril.solidity.soliditycontract import SolidityContract

# Recompiles all the to be tested contracts
root = Path(__file__).parent
input = root / "input_contracts"
output = root / "inputs"

for contract in input.iterdir():
    sol = SolidityContract(str(contract))
    code = sol.code

    output_file = output / "{}.o".format(contract.name)
    output_file.write_text(code)