Пример #1
0
    def delegatecall_(self, global_state):
        instr = global_state.get_current_instruction()
        environment = global_state.environment

        try:
            callee_address, callee_account, call_data, _, call_data_type, gas, _, _ = get_call_parameters(global_state,
                                                                                                          self.dynamic_loader)
        except ValueError as e:
            logging.info(
                "Could not determine required parameters for call, putting fresh symbol on the stack. \n{}".format(e)
            )
            global_state.mstate.stack.append(BitVec("retval_" + str(instr['address']), 256))
            return [global_state]

        transaction = MessageCallTransaction(global_state.world_state,
                                             environment.active_account,
                                             environment.sender,
                                             call_data,
                                             environment.gasprice,
                                             environment.callvalue,
                                             environment.origin,
                                             call_data_type,
                                             callee_account.code
                                             )
        raise TransactionStartSignal(transaction, self.op_code)
Пример #2
0
    def call_(self, global_state):

        instr = global_state.get_current_instruction()
        environment = global_state.environment

        try:
            callee_address, callee_account, call_data, value, call_data_type, gas, memory_out_offset, memory_out_size = get_call_parameters(
                global_state, self.dynamic_loader, True)
        except ValueError as e:
            logging.info(
                "Could not determine required parameters for call, putting fresh symbol on the stack. \n{}".format(e)
            )
            # TODO: decide what to do in this case
            global_state.mstate.stack.append(global_state.new_bitvec("retval_" + str(instr['address']), 256))
            return [global_state]
        global_state.mstate.stack.append(global_state.new_bitvec("retval_" + str(instr['address']), 256))

        if 0 < int(callee_address, 16) < 5:
            logging.info("Native contract called: " + callee_address)
            if call_data == [] and call_data_type == CalldataType.SYMBOLIC:
                logging.debug("CALL with symbolic data not supported")
                return [global_state]

            try:
                mem_out_start = helper.get_concrete_int(memory_out_offset)
                mem_out_sz = memory_out_size.as_long()
            except AttributeError:
                logging.debug("CALL with symbolic start or offset not supported")
                return [global_state]

            global_state.mstate.mem_extend(mem_out_start, mem_out_sz)
            call_address_int = int(callee_address, 16)
            try:
                data = natives.native_contracts(call_address_int, call_data)
            except natives.NativeContractException:
                contract_list = ['ecerecover', 'sha256', 'ripemd160', 'identity']
                for i in range(mem_out_sz):
                    global_state.mstate.memory[mem_out_start + i] = global_state.new_bitvec(contract_list[call_address_int - 1] +
                                                                           "(" + str(call_data) + ")", 256)

                return [global_state]

            for i in range(min(len(data), mem_out_sz)):  # If more data is used then it's chopped off
                global_state.mstate.memory[mem_out_start + i] = data[i]

            # TODO: maybe use BitVec here constrained to 1
            return [global_state]

        transaction = MessageCallTransaction(global_state.world_state,
                                             callee_account,
                                             BitVecVal(int(environment.active_account.address, 16), 256),
                                             call_data=call_data,
                                             gas_price=environment.gasprice,
                                             call_value=value,
                                             origin=environment.origin,
                                             call_data_type=call_data_type)
        raise TransactionStartSignal(transaction, self.op_code)
Пример #3
0
    def execute_message_call(self, callee_address):
        caller = BitVec("caller", 256)
        gas_price = BitVec("gasprice", 256)
        call_value = BitVec("callvalue", 256)
        origin = BitVec("origin", 256)

        open_states = self.open_states[:]
        del self.open_states[:]

        for open_world_state in open_states:

            transaction = MessageCallTransaction(
                open_world_state,
                open_world_state[callee_address],
                caller,
                [],
                gas_price,
                call_value,
                origin,
                CalldataType.SYMBOLIC,
            )
            global_state = transaction.initial_global_state()
            global_state.transaction_stack.append((transaction, None))

            new_node = Node(
                global_state.environment.active_account.contract_name)
            self.instructions_covered = [
                False for _ in global_state.environment.code.instruction_list
            ]

            self.nodes[new_node.uid] = new_node
            if open_world_state.node:
                self.edges.append(
                    Edge(open_world_state.node.uid,
                         new_node.uid,
                         edge_type=JumpType.Transaction,
                         condition=None))
            global_state.node = new_node
            new_node.states.append(global_state)
            self.work_list.append(global_state)

        self.exec()
        logging.info("Execution complete")
        logging.info("Achieved {0:.3g}% coverage".format(self.coverage))
Пример #4
0
def test_calldata_constraints_in_transaction():
    # Arrange
    laser_evm = LaserEVM({})
    world_state = WorldState()

    correct_constraints = [MagicMock(), MagicMock(), MagicMock()]

    transaction = MessageCallTransaction(world_state, Account("ca11ee"),
                                         Account("ca114"))
    transaction.call_data = MagicMock()
    transaction.call_data.constraints = correct_constraints

    # Act
    _setup_global_state_for_execution(laser_evm, transaction)

    # Assert
    state = laser_evm.work_list[0]
    for constraint in correct_constraints:
        assert constraint in state.environment.calldata.constraints