#include "dobby_internal.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "UnifiedInterface/platform-darwin/mach_vm.h" #include "PlatformUtil/ProcessRuntimeUtility.h" #include // ================================================================ // GetProcessMemoryLayout static bool memory_region_comparator(MemoryRegion a, MemoryRegion b) { return (a.address < b.address); } std::vector ProcessRuntimeUtility::GetProcessMemoryLayout() { std::vector ProcessMemoryLayout; struct vm_region_submap_short_info_64 submap_info; mach_msg_type_number_t count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64; mach_vm_address_t addr = 0; mach_vm_size_t size = 0; natural_t depth = 0; while (true) { count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64; kern_return_t kr = mach_vm_region_recurse(mach_task_self(), &addr, &size, &depth, (vm_region_recurse_info_t)&submap_info, &count); if (kr != KERN_SUCCESS) { if (kr == KERN_INVALID_ADDRESS) { break; } else { break; } } if (submap_info.is_submap) { depth++; } else { MemoryPermission permission; if ((submap_info.protection & PROT_READ) && (submap_info.protection & PROT_WRITE)) { permission = MemoryPermission::kReadWrite; } else if ((submap_info.protection & PROT_READ) == submap_info.protection) { permission = MemoryPermission::kRead; } else if ((submap_info.protection & PROT_READ) && (submap_info.protection & PROT_EXEC)) { permission = MemoryPermission::kReadExecute; } else { continue; } MemoryRegion region = {(void *)addr, static_cast(size), permission}; #if 0 DLOG(0, "%p --- %p", addr, addr + size); #endif ProcessMemoryLayout.push_back(region); addr += size; } } std::sort(ProcessMemoryLayout.begin(), ProcessMemoryLayout.end(), memory_region_comparator); return ProcessMemoryLayout; } // ================================================================ // GetProcessModuleMap std::vector ProcessRuntimeUtility::GetProcessModuleMap() { std::vector ProcessModuleMap; kern_return_t kr; task_dyld_info_data_t task_dyld_info; mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; kr = task_info(mach_task_self_, TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count); if (kr != KERN_SUCCESS) { return ProcessModuleMap; } struct dyld_all_image_infos *infos = (struct dyld_all_image_infos *)task_dyld_info.all_image_info_addr; const struct dyld_image_info *infoArray = infos->infoArray; uint32_t infoArrayCount = infos->infoArrayCount; for (int i = 0; i < infoArrayCount; ++i) { const struct dyld_image_info *info = &infoArray[i]; RuntimeModule module = {0}; { strncpy(module.path, info->imageFilePath, sizeof(module.path)); module.load_address = (void *)info->imageLoadAddress; } ProcessModuleMap.push_back(module); } return ProcessModuleMap; } RuntimeModule ProcessRuntimeUtility::GetProcessModule(const char *name) { std::vector ProcessModuleMap = GetProcessModuleMap(); for (auto module : ProcessModuleMap) { if (strstr(module.path, name) != 0) { return module; } } return RuntimeModule{0}; }