static RList *xnu_desc_list (int pid) { #if TARGET_OS_IPHONE return NULL; #else #define xwr2rwx(x) ((x&1)<<2) | (x&2) | ((x&4)>>2) RDebugDesc *desc; RList *ret = r_list_new(); struct vnode_fdinfowithpath vi; int i, nb, type = 0; int maxfd = getMaxFiles(); for (i=0 ; i<maxfd; i++) { nb = proc_pidfdinfo (pid, i, PROC_PIDFDVNODEPATHINFO, &vi, sizeof (vi)); if (nb<1) { continue; } if (nb < sizeof (vi)) { perror ("too few bytes"); break; } //printf ("FD %d RWX %x ", i, vi.pfi.fi_openflags); //printf ("PATH %s\n", vi.pvip.vip_path); desc = r_debug_desc_new (i, vi.pvip.vip_path, xwr2rwx(vi.pfi.fi_openflags), type, 0); r_list_append (ret, desc); } return ret; #endif }
static RList *ios_dbg_maps(RDebug *dbg, int only_modules) { boolt contiguous = R_FALSE; ut32 oldprot = UT32_MAX; ut32 oldmaxprot = UT32_MAX; char buf[1024]; char module_name[MAXPATHLEN]; mach_vm_address_t address = MACH_VM_MIN_ADDRESS; mach_vm_size_t size = (mach_vm_size_t) 0; mach_vm_size_t osize = (mach_vm_size_t) 0; natural_t depth = 0; int tid = dbg->pid; task_t task = pid_to_task (tid); RDebugMap *mr = NULL; RList *list = NULL; int i = 0; if (only_modules) { return xnu_dbg_modules (dbg); } #if __arm64__ || __aarch64__ size = osize = 16384; // acording to frida #else size = osize = 4096; #endif #if 0 if (dbg->pid == 0) { vm_address_t base = get_kernel_base (task); eprintf ("Kernel Base Address: 0x%"PFMT64x"\n", (ut64)base); return NULL; } #endif kern_return_t kr; for (;;) { struct vm_region_submap_info_64 info; mach_msg_type_number_t info_count; info_count = VM_REGION_SUBMAP_INFO_COUNT_64; memset (&info, 0, sizeof (info)); kr = mach_vm_region_recurse (task, &address, &size, &depth, (vm_region_recurse_info_t) &info, &info_count); if (kr != KERN_SUCCESS) { //eprintf ("Cannot kern succ recurse\n"); break; } if (info.is_submap) { depth++; continue; } if (!list) { list = r_list_new (); //list->free = (RListFree*)r_debug_map_free; } { module_name[0] = 0; int ret = proc_regionfilename (tid, address, module_name, sizeof (module_name)); module_name[ret] = 0; } #if 0 oldprot = info.protection; oldmaxprot = info.max_protection; // contiguous pages seems to hide some map names if (mr) { if (address == mr->addr + mr->size) { if (oldmaxprot == info.max_protection) { contiguous = R_FALSE; } else if (oldprot != UT32_MAX && oldprot == info.protection) { /* expand region */ mr->size += size; contiguous = R_TRUE; } else { contiguous = R_FALSE; } } else { contiguous = R_FALSE; } } else contiguous = R_FALSE; //if (info.max_protection == oldprot && !contiguous) { #endif if (1) { #define xwr2rwx(x) ((x&1)<<2) | (x&2) | ((x&4)>>2) // XXX: if its shared, it cannot be read? snprintf (buf, sizeof (buf), "%s %02x %s%s%s%s%s %s depth=%d", r_str_rwx_i (xwr2rwx (info.max_protection)), i, unparse_inheritance (info.inheritance), info.user_tag? " user": "", info.is_submap? " sub": "", info.inheritance? " inherit": "", info.is_submap ? " submap": "", module_name, depth); //info.shared ? "shar" : "priv", //info.reserved ? "reserved" : "not-reserved", //""); //module_name); mr = r_debug_map_new (buf, address, address+size, xwr2rwx (info.protection), 0); if (mr == NULL) { eprintf ("Cannot create r_debug_map_new\n"); break; } mr->file = strdup (module_name); i++; r_list_append (list, mr); } if (size<1) { eprintf ("EFUCK\n"); size = osize; // f**k } address += size; size = 0; } return list; }