int Utils::ReadMemAndDeAllocate(task_t target, task_t self, mach_vm_address_t address, type * content) { vm_offset_t data; uint32_t sz; auto re = vm_read(target, address, sizeof(type), &data, &sz); if (re != 0){ return -1; } *content = (type) *(type *)(data); // release ram vm_deallocate(self, data, sz); return 0; }
int32_t k5_ipc_server_send_reply (mach_port_t in_reply_port, k5_ipc_stream in_reply_stream) { kern_return_t err = KERN_SUCCESS; k5_ipc_inl_reply_t inl_reply; mach_msg_type_number_t inl_reply_length = 0; k5_ipc_ool_reply_t ool_reply = NULL; mach_msg_type_number_t ool_reply_length = 0; if (!MACH_PORT_VALID (in_reply_port)) { err = EINVAL; } if (!in_reply_stream ) { err = EINVAL; } if (!err) { /* depending on how big the message is, use the fast inline buffer or * the slow dynamically allocated buffer */ mach_msg_type_number_t reply_length = krb5int_ipc_stream_size (in_reply_stream); if (reply_length > K5_IPC_MAX_INL_MSG_SIZE) { //dprintf ("%s choosing out of line buffer (size is %d)", // __FUNCTION__, reply_length); err = vm_read (mach_task_self (), (vm_address_t) krb5int_ipc_stream_data (in_reply_stream), reply_length, (vm_address_t *) &ool_reply, &ool_reply_length); } else { //cci_debug_printf ("%s choosing in line buffer (size is %d)", // __FUNCTION__, reply_length); inl_reply_length = reply_length; memcpy (inl_reply, krb5int_ipc_stream_data (in_reply_stream), reply_length); } } if (!err) { err = k5_ipc_server_reply (in_reply_port, inl_reply, inl_reply_length, ool_reply, ool_reply_length); } if (!err) { /* Because we use ",dealloc" ool_reply will be freed by mach. Don't double free it. */ ool_reply = NULL; ool_reply_length = 0; } if (ool_reply_length) { vm_deallocate (mach_task_self (), (vm_address_t) ool_reply, ool_reply_length); } return err; }
static PyObject *MachTask_vm_read(PyObject *self, PyObject *args) { PyObject *buffer; kern_return_t err; unsigned int address, size; vm_offset_t data; vm_size_t data_count; if (!PyArg_ParseTuple(args, "II", &address, &size)) return NULL; err = vm_read(((MachPort *)self)->port, address, size, &data, &data_count); if (err != KERN_SUCCESS) { PyErr_SetString(MachError, mach_error_string(err)); return NULL; } buffer = PyString_FromStringAndSize((char *)data, data_count); vm_deallocate(mach_task_self(), data, data_count); return buffer; }
int main() { mach_port_t process_to_write; kern_return_t error; int pid; if(getuid() && geteuid()) { printf("You need to be root to vm_write!\n"); } else{ printf("PID: "); scanf("%d", &pid); error = task_for_pid(mach_task_self(), pid, &process_to_write); if ((error != KERN_SUCCESS) || !MACH_PORT_VALID(process_to_write)) { printf("Error getting the process!\n"); } kern_return_t krc = KERN_SUCCESS; vm_address_t address = 0; vm_size_t size = 0; uint32_t depth = 1; int c = 0; uintptr_t base; while (1) { struct vm_region_submap_info_64 info; mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64; krc = vm_region_recurse_64(process_to_write, &address, &size, &depth, (vm_region_info_64_t)&info, &count); if (krc == KERN_INVALID_ADDRESS){ break; } if (info.is_submap){ depth++; } else { if (c == 16) { base = (uintptr_t)address; } c++; address += size; } } printf ("%012" PRIxPTR "\n", base); int negativeOffset = 0x14; int positiveBaseOffset = 0x7ffb30; int sz; int sz2; vm_offset_t dataPointer = 0; vm_offset_t dataPointer2 = 0; void **bytes; void **bytes2; printf("%012" PRIxPTR "\n", (uintptr_t)(base + positiveBaseOffset)); error = vm_read(process_to_write, (uintptr_t)(base + positiveBaseOffset), sizeof(vm_address_t), &dataPointer, &sz); if (error == KERN_SUCCESS) { bytes = (uintptr_t)dataPointer; printf("%012" PRIxPTR "\n", *bytes); error = vm_read(process_to_write, (uintptr_t)(*bytes-negativeOffset), sizeof(int), &dataPointer2, &sz2); if (error == KERN_SUCCESS) { bytes2 = (void *)dataPointer2; printf("%d\n", *bytes2); } } /* mach_port_name_t task; vm_map_offset_t vmoffset; vm_map_size_t vmsize; uint32_t nesting_depth = 0; struct vm_region_submap_info_64 vbr; mach_msg_type_number_t vbrcount = 16; kern_return_t kr; if ((kr = mach_vm_region_recurse(process_to_write, &vmoffset, &vmsize, &nesting_depth, (vm_region_recurse_info_t)&vbr, &vbrcount)) != KERN_SUCCESS) { printf("Error"); } printf("%p\n", (void *) (uintptr_t)vmoffset); */ } return 0; }
int32_t k5_ipc_send_request (const char *in_service_id, int32_t in_launch_server, k5_ipc_stream in_request_stream, k5_ipc_stream *out_reply_stream) { int err = 0; int32_t done = 0; int32_t try_count = 0; mach_port_t server_port = MACH_PORT_NULL; k5_ipc_connection_info cinfo = NULL; k5_ipc_connection connection = NULL; mach_port_t reply_port = MACH_PORT_NULL; const char *inl_request = NULL; /* char * so we can pass the buffer in directly */ mach_msg_type_number_t inl_request_length = 0; k5_ipc_ool_request_t ool_request = NULL; mach_msg_type_number_t ool_request_length = 0; if (!in_request_stream) { err = EINVAL; } if (!out_reply_stream ) { err = EINVAL; } if (!err) { err = CALL_INIT_FUNCTION (k5_cli_ipc_thread_init); } if (!err) { /* depending on how big the message is, use the fast inline buffer or * the slow dynamically allocated buffer */ mach_msg_type_number_t request_length = k5_ipc_stream_size (in_request_stream); if (request_length > K5_IPC_MAX_INL_MSG_SIZE) { /*dprintf ("%s choosing out of line buffer (size is %d)", * __FUNCTION__, request_length); */ err = vm_read (mach_task_self (), (vm_address_t) k5_ipc_stream_data (in_request_stream), request_length, (vm_address_t *) &ool_request, &ool_request_length); } else { /*dprintf ("%s choosing in line buffer (size is %d)", * __FUNCTION__, request_length); */ inl_request_length = request_length; inl_request = k5_ipc_stream_data (in_request_stream); } } if (!err) { cinfo = k5_getspecific (K5_KEY_IPC_CONNECTION_INFO); if (!cinfo) { err = k5_ipc_client_cinfo_allocate (&cinfo); if (!err) { err = k5_setspecific (K5_KEY_IPC_CONNECTION_INFO, cinfo); } } if (!err) { int i, found = 0; for (i = 0; i < KIPC_SERVICE_COUNT; i++) { if (!strcmp (in_service_id, cinfo->connections[i].service_id)) { found = 1; connection = &cinfo->connections[i]; break; } } if (!found) { err = EINVAL; } } } if (!err) { err = k5_ipc_client_lookup_server (in_service_id, in_launch_server, TRUE, &server_port); } if (!err) { err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &reply_port); } while (!err && !done) { if (!err && !MACH_PORT_VALID (connection->port)) { err = k5_ipc_client_create_client_connection (server_port, &connection->port); } if (!err) { err = k5_ipc_client_request (connection->port, reply_port, inl_request, inl_request_length, ool_request, ool_request_length); } if (err == MACH_SEND_INVALID_DEST) { if (try_count < 2) { try_count++; err = 0; } if (MACH_PORT_VALID (connection->port)) { mach_port_mod_refs (mach_task_self(), connection->port, MACH_PORT_RIGHT_SEND, -1 ); connection->port = MACH_PORT_NULL; } /* Look up server name again without using the cached copy */ err = k5_ipc_client_lookup_server (in_service_id, in_launch_server, FALSE, &server_port); } else { /* Talked to server, though we may have gotten an error */ done = 1; /* Because we use ",dealloc" ool_request will be freed by mach. * Don't double free it. */ ool_request = NULL; ool_request_length = 0; } } if (!err) { err = k5_ipc_stream_new (&cinfo->reply_stream); } if (!err) { mach_port_t old_notification_target = MACH_PORT_NULL; /* request no-senders notification so we know when server dies */ err = mach_port_request_notification (mach_task_self (), reply_port, MACH_NOTIFY_NO_SENDERS, 1, reply_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &old_notification_target); if (!err && old_notification_target != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), old_notification_target); } } if (!err) { cinfo->server_died = 0; err = mach_msg_server_once (k5_ipc_reply_demux, K5_IPC_MAX_MSG_SIZE, reply_port, MACH_MSG_TIMEOUT_NONE); if (!err && cinfo->server_died) { err = ENOTCONN; } } if (err == BOOTSTRAP_UNKNOWN_SERVICE && !in_launch_server) { err = 0; /* If server is not running just return an empty stream. */ } if (!err) { *out_reply_stream = cinfo->reply_stream; cinfo->reply_stream = NULL; } if (reply_port != MACH_PORT_NULL) { mach_port_destroy (mach_task_self (), reply_port); } if (ool_request_length) { vm_deallocate (mach_task_self (), (vm_address_t) ool_request, ool_request_length); } if (cinfo && cinfo->reply_stream) { k5_ipc_stream_release (cinfo->reply_stream); cinfo->reply_stream = NULL; } return err; }
int main(int argv,char *args[]){ while(1){ int r=getinput(); if(r==R_CODE_EXIT) break; else if(r==R_CODE_INFO) printf("-help info:\n"HELP); else if(r==R_CODE_PS||r==R_CODE_AT){ GetBSDProcessList(); int i = 0; for (i = 0; i < gprocCount; i++) { kinfo_proc *pro = (gprocList + i); if(r==R_CODE_PS){ printf("%d pid:%d name:%s user_stack:%p\n", i, pro->kp_proc.p_pid, pro->kp_proc.p_comm, pro->kp_proc.user_stack); }else{ pid_t targetpid = pro->kp_proc.p_pid; int num=-1; MioGetArg2Num(1,&num); if(num==targetpid){ kern_return_t kr=task_for_pid(current_task(), targetpid, >ask); if(kr==KERN_SUCCESS){ printf("[attach proccess %s %d]\n",pro->kp_proc.p_comm,num); gproc=pro; }else{ printf("task_for_pid fail %d pid:%d\n",kr,num); gproc=NULL; } break; } } } }else if(r==R_CODE_SUS){ kern_return_t kr = task_suspend(gtask); if(kr==KERN_SUCCESS){ printf("[suspend]\n"); }else{ printf("task_suspend fail %d\n",kr); } }else if(r==R_CODE_RES){ kern_return_t kr = task_resume(gtask); if(kr==KERN_SUCCESS){ printf("[resume]\n"); }else{ printf("task_resume fail %d\n",kr); } }else if(r==R_CODE_SSI){ int num=-1; if(MioGetArg2Num(1,&num)!=0){ printf("arg error"); continue; } findmemoryspace(); int i=0; int index=0; for(i=0;i<gspace_count;i++){ space *target_space=gspaces+i; vm_address_t target_add=target_space->address; vm_address_t end_add=target_space->address+target_space->size; printf("start search %d from %p to %p of %dK space.\n",num,target_add,end_add,target_space->size/1024); do{ int *buf; uint32_t sz; kern_return_t kr=vm_read(gtask,target_add,sizeof(int),&buf,&sz); if(kr!=KERN_SUCCESS){ printf("error %d\n",kr); } if((*buf)==num){ if(index<MAX_ADDS){ printf("find the var at %p=%lu\n",target_add,target_add); gadds[index]=target_add; index++; }else{ printf("gadds over flow\n"); } } target_add=target_add+sizeof(int); }while(target_add<end_add); printf("there are %d vars\n",index); gadds[index]=0; } //end of start search int }else if(r==R_CODE_CSI){ int num=-1; if(MioGetArg2Num(1,&num)!=0){ printf("arg error"); continue; } char *add=NULL; int index=0; while((add=gadds[index])!=0){ int *buf; uint32_t sz; kern_return_t kr=vm_read(gtask,add,sizeof(int),&buf,&sz); if(kr!=KERN_SUCCESS){ printf("error %d\n",kr); break; } if((*buf)==num){ printf("still find the var at %p=%lu\n",add,add); int t=0; char *tadd=NULL; while(1){ tadd=gadds[t]; if(tadd=-1){ gadds[t]=add; break; }else{ continue; } } index++; }else{ gadds[index]=0; index++; } } gadds[index]=0; }else if(r==R_CODE_MOD){ char *add=-1; if(MioGetArg2Long(1,&add)!=0){ printf("address arg error"); continue; } int num=-1; if(MioGetArg2Num(2,&num)!=0){ printf("change to arg error"); continue; } printf("mod %p to %d\n",add,num); kern_return_t kr=vm_write(gtask,add,(vm_offset_t)&num,sizeof(int)); if(kr==KERN_SUCCESS){ printf("OK!\n"); }else{ printf("vm_write fail %d\n",kr); } } } return 0; }