static int __read(RIO *io, RIODesc *fd, ut8 *buf, int len) { vm_size_t size = 0; int blen, err, copied = 0; int blocksize = 32; RIOMach *riom = (RIOMach *)fd->data; if (task_is_dead (riom->pid)) { return -1; } memset (buf, 0xff, len); if (RIOMACH_PID (fd->data) == 0) { if (io->off < 4096) { return len; } } copied = getNextValid (io, fd, io->off) - io->off; if (copied < 0) copied = 0; while (copied < len) { blen = R_MIN ((len - copied), blocksize); //blen = len; err = vm_read_overwrite (RIOMACH_TASK (fd->data), (ut64)io->off + copied, blen, (pointer_t)buf + copied, &size); switch (err) { case KERN_PROTECTION_FAILURE: //eprintf ("r_io_mach_read: kern protection failure.\n"); break; case KERN_INVALID_ADDRESS: if (blocksize == 1) { memset (buf+copied, 0xff, len-copied); return size+copied; } blocksize = 1; blen = 1; buf[copied] = 0xff; break; } if (err == -1 || size < 1) { return -1; } if (size == 0) { if (blocksize == 1) { memset (buf+copied, 0xff, len-copied); return len; } blocksize = 1; blen = 1; buf[copied] = 0xff; } copied += blen; } return len; }
static int mach_write_at(RIO *io, RIODesc *desc, const void *buf, int len, ut64 addr) { vm_address_t vaddr = addr; vm_address_t pageaddr; vm_size_t pagesize; vm_size_t total_size; int operms = 0; int pid = __get_pid (desc); if (!desc || pid < 0) { return 0; } task_t task = pid_to_task (desc, pid); if (len < 1 || task_is_dead (desc, task)) { return 0; } pageaddr = tsk_getpagebase (desc, addr); pagesize = tsk_pagesize (desc); total_size = (len > pagesize) ? pagesize * (1 + (len / pagesize)) : pagesize; if (tsk_write (task, vaddr, buf, len)) { return len; } operms = tsk_getperm (io, task, pageaddr); if (!tsk_setperm (io, task, pageaddr, total_size, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY)) { eprintf ("io.mach: Cannot set page perms for %d byte(s) at 0x%08" PFMT64x"\n", (int)pagesize, (ut64)pageaddr); return -1; } if (!tsk_write (task, vaddr, buf, len)) { eprintf ("io.mach: Cannot write on memory\n"); len = -1; } if (operms) { if (!tsk_setperm (io, task, pageaddr, total_size, operms)) { eprintf ("io.mach: Cannot restore page perms\n"); return -1; } } return len; }
static int mach_write_at(RIO *io, RIOMach *riom, const void *buf, int len, ut64 addr) { vm_address_t vaddr = addr; vm_address_t pageaddr; vm_size_t pagesize; vm_size_t total_size; int operms = 0; task_t task; if (!riom || len < 1) return 0; if (task_is_dead (riom->pid)) return 0; task = riom->task; pageaddr = tsk_getpagebase (riom, addr); pagesize = tsk_pagesize (riom); if (len > pagesize) total_size = pagesize * (1 + (len / pagesize)); else total_size = pagesize; if (tsk_write (task, vaddr, buf, len)) return len; operms = tsk_getperm (io, task, pageaddr); if (!tsk_setperm (io, task, pageaddr, total_size, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY)) { eprintf ("io.mach: Cannot set page perms for %d bytes at 0x%08" PFMT64x"\n", (int)pagesize, (ut64)pageaddr); return -1; } if (!tsk_write (task, vaddr, buf, len)) { eprintf ("io.mach: Cannot write on memory\n"); len = -1; } if (operms) { if (!tsk_setperm (io, task, pageaddr, total_size, operms)) { eprintf ("io.mach: Cannot restore page perms\n"); return -1; } } return len; }
static int __read(RIO *io, RIODesc *desc, ut8 *buf, int len) { vm_size_t size = 0; int blen, err, copied = 0; int blocksize = 32; RIODescData *dd = (RIODescData *)desc->data; if (!io || !desc || !buf || !dd) { return -1; } if (dd ->magic != r_str_hash ("mach")) { return -1; } memset (buf, 0xff, len); int pid = __get_pid (desc); task_t task = pid_to_task (desc, pid); if (task_is_dead (desc, pid)) { return -1; } if (pid == 0) { if (io->off < 4096) { return len; } } copied = getNextValid (io, desc, io->off) - io->off; if (copied < 0) { copied = 0; } while (copied < len) { blen = R_MIN ((len - copied), blocksize); //blen = len; err = vm_read_overwrite (task, (ut64)io->off + copied, blen, (pointer_t)buf + copied, &size); switch (err) { case KERN_PROTECTION_FAILURE: //eprintf ("r_io_mach_read: kern protection failure.\n"); break; case KERN_INVALID_ADDRESS: if (blocksize == 1) { memset (buf+copied, 0xff, len-copied); return size+copied; } blocksize = 1; blen = 1; buf[copied] = 0xff; break; } if (err == -1 || size < 1) { return -1; } if (size == 0) { if (blocksize == 1) { memset (buf + copied, 0xff, len - copied); return len; } blocksize = 1; blen = 1; buf[copied] = 0xff; } copied += blen; } return len; }