From: Marc-Aurel Zent mzent@codeweavers.com
--- server/mach.c | 72 ++++++--------------------------------------------- 1 file changed, 8 insertions(+), 64 deletions(-)
diff --git a/server/mach.c b/server/mach.c index 5aa37d4c93c..f1073835e00 100644 --- a/server/mach.c +++ b/server/mach.c @@ -415,15 +415,9 @@ int read_process_memory( struct process *process, client_ptr_t ptr, data_size_t int write_process_memory( struct process *process, client_ptr_t ptr, data_size_t size, const char *src ) { kern_return_t ret; - mach_vm_address_t aligned_address, region_address; - mach_vm_size_t aligned_size, region_size; - mach_msg_type_number_t info_size, bytes_read; - mach_vm_offset_t offset; - vm_offset_t task_mem = 0; - struct vm_region_basic_info_64 info; - mach_port_t dummy; unsigned int page_size = get_page_size(); mach_port_t process_port = get_process_port( process ); + mach_vm_offset_t data;
if (!process_port) { @@ -435,68 +429,18 @@ int write_process_memory( struct process *process, client_ptr_t ptr, data_size_t set_error( STATUS_ACCESS_DENIED ); return 0; } - - offset = ptr % page_size; - aligned_address = (mach_vm_address_t)(ptr - offset); - aligned_size = (size + offset + page_size - 1) / page_size * page_size; - - if ((ret = task_suspend( process_port )) != KERN_SUCCESS) + if (posix_memalign( &data, page_size, size )) { - mach_set_error( ret ); + set_error( STATUS_NO_MEMORY ); return 0; }
- ret = mach_vm_read( process_port, aligned_address, aligned_size, &task_mem, &bytes_read ); - if (ret != KERN_SUCCESS) - { - mach_set_error( ret ); - goto failed; - } - region_address = aligned_address; - info_size = sizeof(info); - ret = mach_vm_region( process_port, ®ion_address, ®ion_size, VM_REGION_BASIC_INFO_64, - (vm_region_info_t)&info, &info_size, &dummy ); - if (ret != KERN_SUCCESS) - { - mach_set_error( ret ); - goto failed; - } - if (region_address > aligned_address || - region_address + region_size < aligned_address + aligned_size) - { - /* FIXME: should support multiple regions */ - set_error( ERROR_ACCESS_DENIED ); - goto failed; - } - ret = mach_vm_protect( process_port, aligned_address, aligned_size, 0, VM_PROT_READ | VM_PROT_WRITE ); - if (ret != KERN_SUCCESS) - { - mach_set_error( ret ); - goto failed; - } - - /* FIXME: there's an optimization that can be made: check first and last */ - /* pages for writability; read first and last pages; write interior */ - /* pages to task without ever reading&modifying them; if that succeeds, */ - /* modify first and last pages and write them. */ - - memcpy( (char*)task_mem + offset, src, size ); - - ret = mach_vm_write( process_port, aligned_address, task_mem, bytes_read ); - if (ret != KERN_SUCCESS) mach_set_error( ret ); - else - { - mach_vm_deallocate( mach_task_self(), task_mem, bytes_read ); - /* restore protection */ - mach_vm_protect( process_port, aligned_address, aligned_size, 0, info.protection ); - task_resume( process_port ); - return 1; - } + memcpy( data, src, size );
-failed: - if (task_mem) mach_vm_deallocate( mach_task_self(), task_mem, bytes_read ); - task_resume( process_port ); - return 0; + ret = mach_vm_write( process_port, (mach_vm_address_t)ptr, data, (mach_msg_type_number_t)size ); + free( data ); + mach_set_error( ret ); + return (ret == KERN_SUCCESS); }
/* retrieve an LDT selector entry */