PageRenderTime 52ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/libr/debug/p/native/maps/darwin.c

https://bitbucket.org/radare/radare2
C | 321 lines | 268 code | 25 blank | 28 comment | 67 complexity | d53c3a3acc5ebe82875de405788a077b MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0, Unlicense, BSD-3-Clause, LGPL-2.1
  1. #if __APPLE__
  2. kern_return_t mach_vm_region_recurse (
  3. vm_map_t target_task,
  4. mach_vm_address_t *address,
  5. mach_vm_size_t *size,
  6. natural_t *nesting_depth,
  7. vm_region_recurse_info_t info,
  8. mach_msg_type_number_t *infoCnt
  9. );
  10. static const char * unparse_inheritance (vm_inherit_t i) {
  11. switch (i) {
  12. case VM_INHERIT_SHARE: return "share";
  13. case VM_INHERIT_COPY: return "copy";
  14. case VM_INHERIT_NONE: return "none";
  15. default: return "???";
  16. }
  17. }
  18. #if __LP64__
  19. #define ADDR "%16lx"
  20. #define HEADER_SIZE 0x1000
  21. #define IMAGE_OFFSET 0x2000
  22. #define KERNEL_LOWER 0xffffff8000000000
  23. #else
  24. #define ADDR "%8x"
  25. #define HEADER_SIZE 0x1000
  26. #define IMAGE_OFFSET 0x201000
  27. #define KERNEL_LOWER 0x80000000
  28. #endif
  29. vm_address_t get_kernel_base(task_t ___task) {
  30. kern_return_t ret;
  31. task_t task;
  32. vm_region_submap_info_data_64_t info;
  33. ut64 size;
  34. mach_msg_type_number_t info_count = VM_REGION_SUBMAP_INFO_COUNT_64;
  35. unsigned int depth = 0;
  36. ut64 addr = KERNEL_LOWER; // lowest possible kernel base address
  37. int count;
  38. ret = task_for_pid(mach_task_self(), 0, &task);
  39. if (ret != KERN_SUCCESS)
  40. return 0;
  41. ut64 naddr;
  42. eprintf ("%d vs %d\n", task, ___task);
  43. for (count=128; count; count--) {
  44. // get next memory region
  45. naddr = addr;
  46. ret = vm_region_recurse_64 (task, (vm_address_t*)&naddr, (vm_size_t*)&size,
  47. &depth, (vm_region_info_t)&info, &info_count);
  48. if (ret != KERN_SUCCESS)
  49. break;
  50. if (size<1) break;
  51. if (addr == naddr) {
  52. addr += size;
  53. continue;
  54. }
  55. eprintf ("0x%08"PFMT64x" size 0x%08"PFMT64x" perm 0x%x\n", (ut64)addr, (ut64)size, info.max_protection);
  56. // the kernel maps over a GB of RAM at the address where it maps
  57. // itself so we use that fact to detect it's position
  58. if (size > 1024*1024*1024) {
  59. return addr + IMAGE_OFFSET;
  60. }
  61. addr += size;
  62. }
  63. return (vm_address_t)0;
  64. }
  65. extern int proc_regionfilename(int pid, uint64_t address, void * buffer, uint32_t buffersize);
  66. static RList *ios_dbg_maps(RDebug *dbg) {
  67. bool contiguous = false;
  68. ut32 oldprot = UT32_MAX;
  69. char buf[1024];
  70. mach_vm_address_t address = MACH_VM_MIN_ADDRESS;
  71. mach_vm_size_t size = (mach_vm_size_t) 0;
  72. mach_vm_size_t osize = (mach_vm_size_t) 0;
  73. natural_t depth = 0;
  74. task_t task = pid_to_task (dbg->tid);
  75. RDebugMap *mr = NULL;
  76. RList *list = NULL;
  77. int i = 0;
  78. #if __arm64__ || __aarch64__
  79. size = osize = 16384; // acording to frida
  80. #else
  81. size = osize = 4096;
  82. #endif
  83. #if 0
  84. if (dbg->pid == 0) {
  85. vm_address_t base = get_kernel_base (task);
  86. eprintf ("Kernel Base Address: 0x%"PFMT64x"\n", (ut64)base);
  87. return NULL;
  88. }
  89. #endif
  90. kern_return_t kr;
  91. for (;;) {
  92. struct vm_region_submap_info_64 info;
  93. mach_msg_type_number_t info_count;
  94. depth = VM_REGION_BASIC_INFO_64;
  95. info_count = VM_REGION_SUBMAP_INFO_COUNT_64;
  96. memset (&info, 0, sizeof (info));
  97. kr = mach_vm_region_recurse (task, &address, &size, &depth,
  98. (vm_region_recurse_info_t) &info, &info_count);
  99. if (kr != KERN_SUCCESS) {
  100. //eprintf ("Cannot kern succ recurse\n");
  101. break;
  102. }
  103. if (!list) {
  104. list = r_list_new ();
  105. //list->free = (RListFree*)r_debug_map_free;
  106. }
  107. if (mr) {
  108. if (address == mr->addr + mr->size) {
  109. if (oldprot != UT32_MAX && oldprot == info.protection) {
  110. /* expand region */
  111. mr->size += size;
  112. contiguous = true;
  113. } else {
  114. contiguous = false;
  115. }
  116. } else {
  117. contiguous = false;
  118. }
  119. } else contiguous = false;
  120. oldprot = info.protection;
  121. if (info.max_protection!=0 && !contiguous) {
  122. char module_name[1024];
  123. module_name[0] = 0;
  124. int ret = proc_regionfilename (dbg->pid, address,
  125. module_name, sizeof (module_name));
  126. module_name[ret] = 0;
  127. #define xwr2rwx(x) ((x&1)<<2) | (x&2) | ((x&4)>>2)
  128. // XXX: if its shared, it cannot be read?
  129. snprintf (buf, sizeof (buf), "%s %02x %s%s%s%s%s %s depth=%d",
  130. r_str_rwx_i (xwr2rwx (info.max_protection)), i,
  131. unparse_inheritance (info.inheritance),
  132. info.user_tag? " user": "",
  133. info.is_submap? " sub": "",
  134. info.inheritance? " inherit": "",
  135. info.is_submap ? " submap": "",
  136. module_name, depth);
  137. //info.shared ? "shar" : "priv",
  138. //info.reserved ? "reserved" : "not-reserved",
  139. //""); //module_name);
  140. mr = r_debug_map_new (buf, address, address+size,
  141. xwr2rwx (info.protection), 0);
  142. if (mr == NULL) {
  143. eprintf ("Cannot create r_debug_map_new\n");
  144. break;
  145. }
  146. mr->file = strdup (module_name);
  147. i++;
  148. r_list_append (list, mr);
  149. }
  150. if (size<1) size = osize; // fuck
  151. address += size;
  152. size = 0;
  153. }
  154. return list;
  155. }
  156. #if 0
  157. // TODO: this loop MUST be cleaned up
  158. static RList *osx_dbg_maps (RDebug *dbg) {
  159. RDebugMap *mr;
  160. char buf[1024];
  161. int i, print;
  162. kern_return_t kret;
  163. vm_region_basic_info_data_64_t info, prev_info;
  164. mach_vm_address_t prev_address;
  165. mach_vm_size_t size, prev_size;
  166. mach_port_t object_name;
  167. mach_msg_type_number_t count;
  168. int nsubregions = 0;
  169. int num_printed = 0;
  170. size_t address = 0;
  171. task_t task = pid_to_task (dbg->pid);
  172. RList *list = r_list_new ();
  173. // XXX: wrong for 64bits
  174. /*
  175. count = VM_REGION_BASIC_INFO_COUNT_64;
  176. kret = mach_vm_region (pid_to_task (dbg->pid), &address, &size, VM_REGION_BASIC_INFO_64,
  177. (vm_region_info_t) &info, &count, &object_name);
  178. if (kret != KERN_SUCCESS) {
  179. printf("No memory regions.\n");
  180. return;
  181. }
  182. memcpy (&prev_info, &info, sizeof (vm_region_basic_info_data_64_t));
  183. */
  184. #if __arm64__ || __aarch64__
  185. size = 16384; // acording to frida
  186. #else
  187. size = 4096;
  188. #endif
  189. memset (&prev_info, 0, sizeof (prev_info));
  190. prev_address = address;
  191. prev_size = size;
  192. nsubregions = 1;
  193. for (i=0; ; i++) {
  194. int done = 0;
  195. address = prev_address + prev_size;
  196. print = 0;
  197. if (prev_size==0)
  198. break;
  199. /* Check to see if address space has wrapped around. */
  200. if (address == 0)
  201. done = 1;
  202. if (!done) {
  203. count = VM_REGION_BASIC_INFO_COUNT_64;
  204. kret = mach_vm_region (task, (mach_vm_address_t *)&address,
  205. &size, VM_REGION_BASIC_INFO_64,
  206. (vm_region_info_t) &info, &count, &object_name);
  207. if (kret != KERN_SUCCESS) {
  208. size = 0;
  209. print = done = 1;
  210. }
  211. }
  212. if (address != prev_address + prev_size)
  213. print = 1;
  214. if ((info.protection != prev_info.protection)
  215. || (info.max_protection != prev_info.max_protection)
  216. || (info.inheritance != prev_info.inheritance)
  217. || (info.shared != prev_info.reserved)
  218. || (info.reserved != prev_info.reserved))
  219. print = 1;
  220. //#if __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
  221. {
  222. char module_name[1024];
  223. module_name[0] = 0;
  224. int ret = proc_regionfilename (dbg->pid, address, module_name, sizeof (module_name));
  225. module_name[ret] = 0;
  226. #define xwr2rwx(x) ((x&1)<<2) | (x&2) | ((x&4)>>2)
  227. if (print && size>0 && prev_info.inheritance != VM_INHERIT_SHARE) {
  228. snprintf (buf, sizeof (buf), "%s %02x %s/%s/%s %s",
  229. r_str_rwx_i (xwr2rwx (prev_info.max_protection)), i,
  230. unparse_inheritance (prev_info.inheritance),
  231. prev_info.shared ? "shar" : "priv",
  232. prev_info.reserved ? "reserved" : "not-reserved",
  233. module_name);
  234. // TODO: MAPS can have min and max protection rules
  235. // :: prev_info.max_protection
  236. mr = r_debug_map_new (buf, prev_address, prev_address+prev_size,
  237. xwr2rwx (prev_info.protection), 0);
  238. if (mr == NULL) {
  239. eprintf ("Cannot create r_debug_map_new\n");
  240. break;
  241. }
  242. mr->file = strdup (module_name);
  243. r_list_append (list, mr);
  244. }
  245. }
  246. #if 0
  247. if (1==0 && rest) { /* XXX never pritn this info here */
  248. addr = 0LL;
  249. addr = (ut64) (ut32) prev_address;
  250. if (num_printed == 0)
  251. fprintf(stderr, "Region ");
  252. else fprintf(stderr, " ... ");
  253. fprintf(stderr, " 0x%08llx - 0x%08llx %s (%s) %s, %s, %s",
  254. addr, addr + prev_size,
  255. unparse_protection (prev_info.protection),
  256. unparse_protection (prev_info.max_protection),
  257. unparse_inheritance (prev_info.inheritance),
  258. prev_info.shared ? "shared" : " private",
  259. prev_info.reserved ? "reserved" : "not-reserved");
  260. if (nsubregions > 1)
  261. fprintf(stderr, " (%d sub-regions)", nsubregions);
  262. fprintf(stderr, "\n");
  263. prev_address = address;
  264. prev_size = size;
  265. memcpy (&prev_info, &info, sizeof (vm_region_basic_info_data_64_t));
  266. nsubregions = 1;
  267. num_printed++;
  268. } else {
  269. #endif
  270. #if 0
  271. prev_size += size;
  272. nsubregions++;
  273. #else
  274. prev_address = address;
  275. prev_size = size;
  276. memcpy (&prev_info, &info, sizeof (vm_region_basic_info_data_64_t));
  277. nsubregions = 1;
  278. num_printed++;
  279. #endif
  280. // }
  281. }
  282. return list;
  283. }
  284. #endif
  285. static RList *darwin_dbg_maps(RDebug *dbg) {
  286. //return osx_dbg_maps (dbg);
  287. return ios_dbg_maps (dbg);
  288. #if 0
  289. const char *osname = dbg->anal->syscall->os;
  290. if (osname && !strcmp (osname, "ios")) {
  291. return ios_dbg_maps (dbg);
  292. }
  293. return osx_dbg_maps (dbg);
  294. #endif
  295. }
  296. #endif