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

        try:
            _, _, _, _, _, _, memory_out_offset, memory_out_size =\
                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(
                global_state.new_bitvec("retval_" + str(instr['address']),
                                        256))
            return [global_state]

        if global_state.last_return_data is None:
            # Put return value on stack
            return_value = global_state.new_bitvec(
                "retval_" + str(instr['address']), 256)
            global_state.mstate.stack.append(return_value)
            global_state.mstate.constraints.append(return_value == 0)

            return [global_state]

        try:
            memory_out_offset = util.get_concrete_int(
                memory_out_offset) if isinstance(
                    memory_out_offset, ExprRef) else memory_out_offset
            memory_out_size = util.get_concrete_int(
                memory_out_size) if isinstance(memory_out_size,
                                               ExprRef) else memory_out_size
        except AttributeError:
            global_state.mstate.stack.append(
                global_state.new_bitvec("retval_" + str(instr['address']),
                                        256))
            return [global_state]

            # Copy memory
        global_state.mstate.mem_extend(
            memory_out_offset,
            min(memory_out_size, len(global_state.last_return_data)))
        for i in range(min(memory_out_size,
                           len(global_state.last_return_data))):
            global_state.mstate.memory[
                i + memory_out_offset] = global_state.last_return_data[i]

        # Put return value on stack
        return_value = global_state.new_bitvec(
            "retval_" + str(instr['address']), 256)
        global_state.mstate.stack.append(return_value)
        global_state.mstate.constraints.append(return_value == 1)

        return [global_state]
Пример #2
0
    def callcode_(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, _, _ = 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))
            global_state.mstate.stack.append(
                BitVec("retval_" + str(instr['address']), 256))
            return [global_state]

        global_state.call_stack.append(instr['address'])

        environment = deepcopy(environment)

        environment.callvalue = value
        environment.caller = environment.address
        environment.calldata = call_data

        new_global_state = GlobalState(global_state.accounts, environment,
                                       MachineState(gas))
        new_global_state.mstate.depth = global_state.mstate.depth + 1
        new_global_state.mstate.constraints = copy(
            global_state.mstate.constraints)

        return [new_global_state]
Пример #3
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(
                BitVec("retval_" + str(instr['address']), 256))
            return [global_state]

        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")
                global_state.mstate.stack.append(
                    BitVec("retval_" + str(instr['address']), 256))
                return [global_state]

            data = natives.native_contracts(int(callee_address, 16), call_data)
            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")
                global_state.mstate.stack.append(
                    BitVec("retval_" + str(instr['address']), 256))
                return [global_state]

            global_state.mstate.mem_extend(mem_out_start, mem_out_sz)
            try:
                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]
            except:
                global_state.mstate.memory[mem_out_start] = BitVec(data, 256)

            # TODO: maybe use BitVec here constrained to 1
            global_state.mstate.stack.append(
                BitVec("retval_" + str(instr['address']), 256))
            return [global_state]

        global_state.call_stack.append(instr['address'])
        callee_environment = Environment(
            callee_account,
            BitVecVal(int(environment.active_account.address, 16), 256),
            call_data,
            environment.gasprice,
            value,
            environment.origin,
            calldata_type=call_data_type)
        new_global_state = GlobalState(global_state.accounts,
                                       callee_environment, MachineState(gas))
        new_global_state.mstate.depth = global_state.mstate.depth + 1
        new_global_state.mstate.constraints = copy(
            global_state.mstate.constraints)
        return [global_state]
Пример #4
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(
                BitVec("retval_" + str(instr['address']), 256))
            return [global_state]
        global_state.mstate.stack.append(
            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] = 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, environment.gasprice, value,
            environment.origin, call_data_type)
        raise TransactionStartSignal(transaction, self.op_code)
Пример #5
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)