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]
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]
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]
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)
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)