diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 780194152bc..5b3ca7792ff 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -2549,7 +2549,7 @@ NTSTATUS WINAPI NtReadVirtualMemory( HANDLE process, const void *addr, void *buf SERVER_START_REQ( read_process_memory ) { req->handle = wine_server_obj_handle( process ); - req->addr = (void *)addr; + req->addr = wine_server_client_ptr( addr ); wine_server_set_reply( req, buffer, size ); if ((status = wine_server_call( req ))) size = 0; } @@ -2571,7 +2571,7 @@ NTSTATUS WINAPI NtWriteVirtualMemory( HANDLE process, void *addr, const void *bu SERVER_START_REQ( write_process_memory ) { req->handle = wine_server_obj_handle( process ); - req->addr = addr; + req->addr = wine_server_client_ptr( addr ); wine_server_add_data( req, buffer, size ); if ((status = wine_server_call( req ))) size = 0; } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 8130a3c7b72..bc9ea96edb6 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -1940,7 +1940,7 @@ struct read_process_memory_request { struct request_header __header; obj_handle_t handle; - void* addr; + client_ptr_t addr; }; struct read_process_memory_reply { @@ -1954,7 +1954,7 @@ struct write_process_memory_request { struct request_header __header; obj_handle_t handle; - void* addr; + client_ptr_t addr; /* VARARG(data,bytes); */ }; struct write_process_memory_reply @@ -5052,6 +5052,6 @@ union generic_reply struct set_window_layered_info_reply set_window_layered_info_reply; }; -#define SERVER_PROTOCOL_VERSION 364 +#define SERVER_PROTOCOL_VERSION 365 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/mach.c b/server/mach.c index 345fb27b2bc..05652ab4af2 100644 --- a/server/mach.c +++ b/server/mach.c @@ -292,7 +292,7 @@ int send_thread_signal( struct thread *thread, int sig ) } /* read data from a process memory space */ -int read_process_memory( struct process *process, const void *ptr, data_size_t size, char *dest ) +int read_process_memory( struct process *process, client_ptr_t ptr, data_size_t size, char *dest ) { kern_return_t ret; mach_msg_type_number_t bytes_read; @@ -307,6 +307,11 @@ int read_process_memory( struct process *process, const void *ptr, data_size_t s set_error( STATUS_ACCESS_DENIED ); return 0; } + if ((vm_address_t)ptr != ptr) + { + set_error( STATUS_ACCESS_DENIED ); + return 0; + } if ((ret = task_suspend( process_port )) != KERN_SUCCESS) { @@ -314,8 +319,8 @@ int read_process_memory( struct process *process, const void *ptr, data_size_t s return 0; } - offset = (unsigned long)ptr % page_size; - aligned_address = (vm_address_t)((char *)ptr - offset); + offset = ptr % page_size; + aligned_address = (vm_address_t)(ptr - offset); aligned_size = (size + offset + page_size - 1) / page_size * page_size; ret = vm_read( process_port, aligned_address, aligned_size, &data, &bytes_read ); @@ -330,7 +335,7 @@ int read_process_memory( struct process *process, const void *ptr, data_size_t s } /* write data to a process memory space */ -int write_process_memory( struct process *process, void *ptr, data_size_t size, const char *src ) +int write_process_memory( struct process *process, client_ptr_t ptr, data_size_t size, const char *src ) { kern_return_t ret; vm_address_t aligned_address, region_address; @@ -347,9 +352,14 @@ int write_process_memory( struct process *process, void *ptr, data_size_t size, set_error( STATUS_ACCESS_DENIED ); return 0; } + if ((vm_address_t)ptr != ptr) + { + set_error( STATUS_ACCESS_DENIED ); + return 0; + } - offset = (unsigned long)ptr % page_size; - aligned_address = (vm_address_t)((char *)ptr - offset); + offset = ptr % page_size; + aligned_address = (vm_address_t)(ptr - offset); aligned_size = (size + offset + page_size - 1) / page_size * page_size; if ((ret = task_suspend( process_port )) != KERN_SUCCESS) diff --git a/server/process.c b/server/process.c index 69e83c2fb20..c2936c5b8f6 100644 --- a/server/process.c +++ b/server/process.c @@ -829,7 +829,7 @@ int set_process_debug_flag( struct process *process, int flag ) char data = (flag != 0); /* BeingDebugged flag is the byte at offset 2 in the PEB */ - return write_process_memory( process, (char *)process->peb + 2, 1, &data ); + return write_process_memory( process, (client_ptr_t)(unsigned long)((char *)process->peb + 2), 1, &data ); } /* take a snapshot of currently running processes */ diff --git a/server/process.h b/server/process.h index fa80818c1ac..c8313ff893b 100644 --- a/server/process.h +++ b/server/process.h @@ -138,8 +138,8 @@ extern struct thread *console_get_renderer( struct console_input *console ); extern void init_tracing_mechanism(void); extern void init_process_tracing( struct process *process ); extern void finish_process_tracing( struct process *process ); -extern int read_process_memory( struct process *process, const void *ptr, data_size_t size, char *dest ); -extern int write_process_memory( struct process *process, void *ptr, data_size_t size, const char *src ); +extern int read_process_memory( struct process *process, client_ptr_t ptr, data_size_t size, char *dest ); +extern int write_process_memory( struct process *process, client_ptr_t ptr, data_size_t size, const char *src ); static inline process_id_t get_process_id( struct process *process ) { return process->id; } diff --git a/server/procfs.c b/server/procfs.c index da22af30c44..8c789c59f68 100644 --- a/server/procfs.c +++ b/server/procfs.c @@ -124,12 +124,18 @@ int send_thread_signal( struct thread *thread, int sig ) } /* read data from a process memory space */ -int read_process_memory( struct process *process, const void *ptr, size_t size, char *dest ) +int read_process_memory( struct process *process, client_ptr_t ptr, size_t size, char *dest ) { ssize_t ret; - int fd = open_proc_as( process, O_RDONLY ); + int fd; - if (fd == -1) return 0; + if ((off_t)ptr != ptr) + { + set_error( STATUS_ACCESS_DENIED ); + return 0; + } + + if ((fd = open_proc_as( process, O_RDONLY )) == -1) return 0; ret = pread( fd, dest, size, (off_t)ptr ); close( fd ); @@ -141,12 +147,18 @@ int read_process_memory( struct process *process, const void *ptr, size_t size, } /* write data to a process memory space */ -int write_process_memory( struct process *process, void *ptr, size_t size, const char *src ) +int write_process_memory( struct process *process, client_ptr_t ptr, size_t size, const char *src ) { ssize_t ret; - int fd = open_proc_as( process, O_WRONLY ); + int fd; - if (fd == -1) return 0; + if ((off_t)ptr != ptr) + { + set_error( STATUS_ACCESS_DENIED ); + return 0; + } + + if ((fd = open_proc_as( process, O_RDONLY )) == -1) return 0; ret = pwrite( fd, src, size, (off_t)ptr ); close( fd ); diff --git a/server/protocol.def b/server/protocol.def index ea7da5e71d4..962446aff8c 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1500,7 +1500,7 @@ enum char_info_mode /* Read data from a process address space */ @REQ(read_process_memory) obj_handle_t handle; /* process handle */ - void* addr; /* addr to read from */ + client_ptr_t addr; /* addr to read from */ @REPLY VARARG(data,bytes); /* result data */ @END @@ -1509,7 +1509,7 @@ enum char_info_mode /* Write data to a process address space */ @REQ(write_process_memory) obj_handle_t handle; /* process handle */ - void* addr; /* addr to write to */ + client_ptr_t addr; /* addr to write to */ VARARG(data,bytes); /* data to write */ @END diff --git a/server/ptrace.c b/server/ptrace.c index 343e38e54d7..accaf4db33d 100644 --- a/server/ptrace.c +++ b/server/ptrace.c @@ -354,7 +354,7 @@ static struct thread *get_ptrace_thread( struct process *process ) } /* read data from a process memory space */ -int read_process_memory( struct process *process, const void *ptr, data_size_t size, char *dest ) +int read_process_memory( struct process *process, client_ptr_t ptr, data_size_t size, char *dest ) { struct thread *thread = get_ptrace_thread( process ); unsigned int first_offset, last_offset, len; @@ -362,11 +362,17 @@ int read_process_memory( struct process *process, const void *ptr, data_size_t s if (!thread) return 0; - first_offset = (unsigned long)ptr % sizeof(int); + if ((unsigned long)ptr != ptr) + { + set_error( STATUS_ACCESS_DENIED ); + return 0; + } + + first_offset = ptr % sizeof(int); last_offset = (size + first_offset) % sizeof(int); if (!last_offset) last_offset = sizeof(int); - addr = (int *)((char *)ptr - first_offset); + addr = (int *)(unsigned long)(ptr - first_offset); len = (size + first_offset + sizeof(int) - 1) / sizeof(int); if (suspend_for_ptrace( thread )) @@ -415,7 +421,7 @@ static int check_process_write_access( struct thread *thread, int *addr, data_si } /* write data to a process memory space */ -int write_process_memory( struct process *process, void *ptr, data_size_t size, const char *src ) +int write_process_memory( struct process *process, client_ptr_t ptr, data_size_t size, const char *src ) { struct thread *thread = get_ptrace_thread( process ); int ret = 0, data = 0; @@ -425,9 +431,15 @@ int write_process_memory( struct process *process, void *ptr, data_size_t size, if (!thread) return 0; + if ((unsigned long)ptr != ptr) + { + set_error( STATUS_ACCESS_DENIED ); + return 0; + } + /* compute the mask for the first int */ first_mask = ~0; - first_offset = (unsigned long)ptr % sizeof(int); + first_offset = ptr % sizeof(int); memset( &first_mask, 0, first_offset ); /* compute the mask for the last int */ @@ -436,7 +448,7 @@ int write_process_memory( struct process *process, void *ptr, data_size_t size, last_mask = 0; memset( &last_mask, 0xff, last_offset ); - addr = (int *)((char *)ptr - first_offset); + addr = (int *)(unsigned long)(ptr - first_offset); len = (size + first_offset + sizeof(int) - 1) / sizeof(int); if (suspend_for_ptrace( thread )) diff --git a/server/trace.c b/server/trace.c index a986d959bd4..391f65cf216 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1964,7 +1964,8 @@ static void dump_set_debugger_kill_on_exit_request( const struct set_debugger_ki static void dump_read_process_memory_request( const struct read_process_memory_request *req ) { fprintf( stderr, " handle=%04x,", req->handle ); - fprintf( stderr, " addr=%p", req->addr ); + fprintf( stderr, " addr=" ); + dump_uint64( &req->addr ); } static void dump_read_process_memory_reply( const struct read_process_memory_reply *req ) @@ -1976,7 +1977,9 @@ static void dump_read_process_memory_reply( const struct read_process_memory_rep static void dump_write_process_memory_request( const struct write_process_memory_request *req ) { fprintf( stderr, " handle=%04x,", req->handle ); - fprintf( stderr, " addr=%p,", req->addr ); + fprintf( stderr, " addr=" ); + dump_uint64( &req->addr ); + fprintf( stderr, "," ); fprintf( stderr, " data=" ); dump_varargs_bytes( cur_size ); }