Rizin
unix-like reverse engineering framework and cli tools
io_self.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2014-2020 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_userconf.h>
5 #include <rz_io.h>
6 #include <rz_lib.h>
7 #include <rz_cons.h>
8 
9 #if DEBUGGER
10 #if __APPLE__
11 #include <mach/vm_map.h>
12 #include <mach/mach_init.h>
13 #include <mach/mach_port.h>
14 #include <mach/mach_interface.h>
15 #include <mach/mach_traps.h>
16 #include <mach/mach_types.h>
17 //#include <mach/mach_vm.h>
18 #include <mach/mach_error.h>
19 #include <mach/task.h>
20 #include <mach/task_info.h>
21 void macosx_debug_regions(RzIO *io, task_t task, mach_vm_address_t address, int max);
22 #elif __BSD__
23 #if __FreeBSD__
24 #include <sys/sysctl.h>
25 #include <sys/user.h>
26 #include <libutil.h>
27 #elif __OpenBSD__ || __NetBSD__
28 #include <sys/sysctl.h>
29 #elif __DragonFly__
30 #include <sys/types.h>
31 #include <sys/user.h>
32 #include <sys/sysctl.h>
33 #include <kvm.h>
34 #endif
35 #include <errno.h>
36 bool bsd_proc_vmmaps(RzIO *io, int pid);
37 #endif
38 #ifdef __HAIKU__
39 #include <kernel/image.h>
40 #endif
41 #if defined __sun && defined _LP64
42 #define _STRUCTURED_PROC 1 // to access newer proc data with additional fields
43 #include <sys/procfs.h>
44 #include <libproc.h>
45 #endif
46 #ifdef _MSC_VER
47 #include <rz_windows.h>
48 #include <process.h> // to compile getpid for msvc windows
49 #include <psapi.h>
50 #endif
51 
52 typedef struct {
53  char *name;
54  ut64 from;
55  ut64 to;
56  int perm;
57 } RzIOSelfSection;
58 
59 static RzIOSelfSection self_sections[1024];
60 static int self_sections_count = 0;
61 static bool mameio = false;
62 
63 static int self_in_section(RzIO *io, ut64 addr, int *left, int *perm) {
64  int i;
65  for (i = 0; i < self_sections_count; i++) {
66  if (addr >= self_sections[i].from && addr < self_sections[i].to) {
67  if (left) {
68  *left = self_sections[i].to - addr;
69  }
70  if (perm) {
71  *perm = self_sections[i].perm;
72  }
73  return true;
74  }
75  }
76  return false;
77 }
78 
79 static int update_self_regions(RzIO *io, int pid) {
80  self_sections_count = 0;
81 #if __APPLE__
82  mach_port_t task;
83  kern_return_t rc;
84  rc = task_for_pid(mach_task_self(), pid, &task);
85  if (rc) {
86  eprintf("task_for_pid failed\n");
87  return false;
88  }
89  macosx_debug_regions(io, task, (size_t)1, 1000);
90  return true;
91 #elif __linux__
92  char *pos_c;
93  int i, l, perm;
94  char path[1024], line[1024];
95  char region[100], region2[100], perms[5];
96  snprintf(path, sizeof(path) - 1, "/proc/%d/maps", pid);
97  FILE *fd = rz_sys_fopen(path, "r");
98  if (!fd) {
99  return false;
100  }
101 
102  while (!feof(fd)) {
103  line[0] = '\0';
104  if (!fgets(line, sizeof(line), fd)) {
105  break;
106  }
107  if (line[0] == '\0') {
108  break;
109  }
110  path[0] = '\0';
111  sscanf(line, "%s %s %*s %*s %*s %[^\n]", region + 2, perms, path);
112  memcpy(region, "0x", 2);
113  pos_c = strchr(region + 2, '-');
114  if (pos_c) {
115  *pos_c++ = 0;
116  memcpy(region2, "0x", 2);
117  l = strlen(pos_c);
118  memcpy(region2 + 2, pos_c, l);
119  region2[2 + l] = 0;
120  } else {
121  region2[0] = 0;
122  }
123  perm = 0;
124  for (i = 0; i < 4 && perms[i]; i++) {
125  switch (perms[i]) {
126  case 'r': perm |= RZ_PERM_R; break;
127  case 'w': perm |= RZ_PERM_W; break;
128  case 'x': perm |= RZ_PERM_X; break;
129  }
130  }
131  self_sections[self_sections_count].from = rz_num_get(NULL, region);
132  self_sections[self_sections_count].to = rz_num_get(NULL, region2);
133  self_sections[self_sections_count].name = strdup(path);
134  self_sections[self_sections_count].perm = perm;
135  self_sections_count++;
136  rz_num_get(NULL, region2);
137  }
138  fclose(fd);
139 
140  return true;
141 #elif __BSD__
142  return bsd_proc_vmmaps(io, pid);
143 #elif __HAIKU__
144  image_info ii;
145  int32_t cookie = 0;
146 
147  while (get_next_image_info(0, &cookie, &ii) == B_OK) {
148  self_sections[self_sections_count].from = (ut64)ii.text;
149  self_sections[self_sections_count].to = (ut64)((char *)ii.text + ii.text_size);
150  self_sections[self_sections_count].name = strdup(ii.name);
151  self_sections[self_sections_count].perm = 0;
152  self_sections_count++;
153  }
154  return true;
155 #elif __sun && defined _LP64
156  char path[PATH_MAX];
157  int err;
158  pid_t self = getpid();
159  struct ps_prochandle *Pself = Pgrab(self, PGRAB_RDONLY, &err);
160 
161  if (!Pself) {
162  return false;
163  }
164 
165  snprintf(path, sizeof(path), "/proc/%d/map", self);
166  size_t hint = (1 << 20);
167  int fd = open(path, O_RDONLY);
168 
169  if (fd == -1) {
170  return false;
171  }
172 
173  ssize_t rd;
174  prmap_t *c, *map = malloc(hint);
175 
176  if (!map) {
177  return false;
178  }
179 
180  while (hint > 0 && (rd = pread(fd, map, hint, 0)) == hint) {
181  hint <<= 1;
182  prmap_t *tmp = realloc(map, hint);
183  if (!tmp) {
184  free(map);
185  return false;
186  }
187 
188  map = tmp;
189  }
190 
191  for (c = map; rd > 0; c++, rd -= sizeof(prmap_t)) {
192  char name[PATH_MAX];
193  Pobjname(Pself, c->pr_vaddr, name, sizeof(name));
194 
195  if (name[0] == '\0') {
196  // If no name, it is an anonymous map
197  strcpy(name, "[anon]");
198  }
199 
200  int perm = 0;
201 
202  if ((c->pr_mflags & MA_READ)) {
203  perm |= RZ_PERM_R;
204  }
205  if ((c->pr_mflags & MA_WRITE)) {
206  perm |= RZ_PERM_W;
207  }
208  if ((c->pr_mflags & MA_EXEC)) {
209  perm |= RZ_PERM_X;
210  }
211 
212  self_sections[self_sections_count].from = (ut64)c->pr_vaddr;
213  self_sections[self_sections_count].to = (ut64)(c->pr_vaddr + c->pr_size);
214  self_sections[self_sections_count].name = strdup(name);
215  self_sections[self_sections_count].perm = perm;
216  self_sections_count++;
217  }
218 
219  free(map);
220  close(fd);
221  return true;
222 #else
223 #ifdef _MSC_VER
224  int perm;
225  const size_t name_size = 1024;
226  PVOID to = NULL;
227  MEMORY_BASIC_INFORMATION mbi;
228  HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, pid);
229  LPWSTR name = calloc(name_size, sizeof(WCHAR));
230  if (!name) {
231  RZ_LOG_ERROR("io_self/update_self_regions: Failed to allocate memory.\n");
232  CloseHandle(h);
233  return false;
234  }
235  while (VirtualQuery(to, &mbi, sizeof(mbi))) {
236  to = (PBYTE)mbi.BaseAddress + mbi.RegionSize;
237  perm = 0;
238  perm |= mbi.Protect & PAGE_READONLY ? RZ_PERM_R : 0;
239  perm |= mbi.Protect & PAGE_READWRITE ? RZ_PERM_RW : 0;
240  perm |= mbi.Protect & PAGE_EXECUTE ? RZ_PERM_X : 0;
241  perm |= mbi.Protect & PAGE_EXECUTE_READ ? RZ_PERM_RX : 0;
242  perm |= mbi.Protect & PAGE_EXECUTE_READWRITE ? RZ_PERM_RWX : 0;
243  perm = mbi.Protect & PAGE_NOACCESS ? 0 : perm;
244  if (perm && !GetMappedFileNameW(h, (LPVOID)mbi.BaseAddress, name, name_size)) {
245  name[0] = L'\0';
246  }
247  self_sections[self_sections_count].from = (ut64)mbi.BaseAddress;
248  self_sections[self_sections_count].to = (ut64)to;
249  self_sections[self_sections_count].name = rz_utf16_to_utf8(name);
250  self_sections[self_sections_count].perm = perm;
251  self_sections_count++;
252  name[0] = L'\0';
253  }
254  free(name);
255  CloseHandle(h);
256  return true;
257 #else
258 #warning not yet implemented for this platform
259 #endif
260  return false;
261 #endif
262 }
263 
264 static bool __plugin_open(RzIO *io, const char *file, bool many) {
265  return (!strncmp(file, "self://", 7));
266 }
267 
268 static RzIODesc *__open(RzIO *io, const char *file, int rw, int mode) {
269  int ret, pid = getpid();
270  io->va = true; // nop
271  ret = update_self_regions(io, pid);
272  if (ret) {
273  return rz_io_desc_new(io, &rz_io_plugin_self,
274  file, rw, mode, NULL);
275  }
276  return NULL;
277 }
278 
279 static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int len) {
280  int left, perm;
281  if (self_in_section(io, io->off, &left, &perm)) {
282  if (perm & RZ_PERM_R) {
283  int newlen = RZ_MIN(len, left);
284  ut8 *ptr = (ut8 *)(size_t)io->off;
285  memcpy(buf, ptr, newlen);
286  return newlen;
287  }
288  }
289  return 0;
290 }
291 
292 static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int len) {
293  if (fd->perm & RZ_PERM_W) {
294  int left, perm;
295  if (self_in_section(io, io->off, &left, &perm)) {
296  int newlen = RZ_MIN(len, left);
297  ut8 *ptr = (ut8 *)(size_t)io->off;
298  if (newlen > 0) {
299  memcpy(ptr, buf, newlen);
300  }
301  return newlen;
302  }
303  }
304  return -1;
305 }
306 
307 static ut64 __lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence) {
308  switch (whence) {
309  case SEEK_SET: return offset;
310  case SEEK_CUR: return io->off + offset;
311  case SEEK_END: return UT64_MAX;
312  }
313  return offset;
314 }
315 
316 static int __close(RzIODesc *fd) {
317  return 0;
318 }
319 
320 #if !defined(__WINDOWS__)
321 static void got_alarm(int sig) {
322  // !!! may die if not running from r2preload !!! //
323  kill(getpid(), SIGUSR1);
324 }
325 #endif
326 
327 static char *__system(RzIO *io, RzIODesc *fd, const char *cmd) {
328  if (!strcmp(cmd, "pid")) {
329  return rz_str_newf("%d", fd->fd);
330  } else if (!strncmp(cmd, "pid", 3)) {
331  /* do nothing here */
332 #if !defined(__WINDOWS__)
333  } else if (!strncmp(cmd, "kill", 4)) {
334  /* do nothing here */
335  kill(getpid(), SIGKILL);
336 #endif
337  } else if (!strncmp(cmd, "call ", 5)) {
338  size_t cbptr = 0;
339  ut64 result = 0;
340  char *argv = strdup(cmd + 5);
341  int argc = rz_str_word_set0(argv);
342  if (argc == 0) {
343  eprintf("Usage: R!call [fcnptr] [a0] [a1] ...\n");
344  free(argv);
345  return NULL;
346  }
347  const char *sym = rz_str_word_get0(argv, 0);
348  if (sym) {
349  const char *symbol = cmd + 6;
350  void *lib = rz_lib_dl_open(NULL);
351  void *ptr = rz_lib_dl_sym(lib, symbol);
352  if (ptr) {
353  cbptr = (ut64)(size_t)ptr;
354  } else {
355  cbptr = rz_num_math(NULL, symbol);
356  }
357  rz_lib_dl_close(lib);
358  }
359  if (argc == 1) {
360  size_t (*cb)() = (size_t(*)())cbptr;
361  if (cb) {
362  result = cb();
363  } else {
364  eprintf("No callback defined\n");
365  }
366  } else if (argc == 2) {
367  size_t (*cb)(size_t a0) = (size_t(*)(size_t))cbptr;
368  if (cb) {
370  result = cb(a0);
371  } else {
372  eprintf("No callback defined\n");
373  }
374  } else if (argc == 3) {
375  size_t (*cb)(size_t a0, size_t a1) = (size_t(*)(size_t, size_t))cbptr;
378  if (cb) {
379  result = cb(a0, a1);
380  } else {
381  eprintf("No callback defined\n");
382  }
383  } else if (argc == 4) {
384  size_t (*cb)(size_t a0, size_t a1, size_t a2) =
385  (size_t(*)(size_t, size_t, size_t))cbptr;
389  if (cb) {
390  result = cb(a0, a1, a2);
391  } else {
392  eprintf("No callback defined\n");
393  }
394  } else if (argc == 5) {
395  size_t (*cb)(size_t a0, size_t a1, size_t a2, size_t a3) =
396  (size_t(*)(size_t, size_t, size_t, size_t))cbptr;
401  if (cb) {
402  result = cb(a0, a1, a2, a3);
403  } else {
404  eprintf("No callback defined\n");
405  }
406  } else if (argc == 6) {
407  size_t (*cb)(size_t a0, size_t a1, size_t a2, size_t a3, size_t a4) =
408  (size_t(*)(size_t, size_t, size_t, size_t, size_t))cbptr;
414  if (cb) {
415  result = cb(a0, a1, a2, a3, a4);
416  } else {
417  eprintf("No callback defined\n");
418  }
419  } else {
420  eprintf("Unsupported number of arguments in call\n");
421  }
422  eprintf("RES %" PFMT64d "\n", result);
423  free(argv);
424 #if !defined(__WINDOWS__)
425  } else if (!strncmp(cmd, "alarm ", 6)) {
426  struct itimerval tmout;
427  int secs = atoi(cmd + 6);
428  rz_return_val_if_fail(secs >= 0, NULL);
429 
430  tmout.it_value.tv_sec = secs;
431  tmout.it_value.tv_usec = 0;
432  rz_sys_signal(SIGALRM, got_alarm);
433  setitimer(ITIMER_REAL, &tmout, NULL);
434 #else
435 #ifdef _MSC_VER
436 #pragma message("self:// alarm is not implemented for this platform yet")
437 #else
438 #warning "self:// alarm is not implemented for this platform yet"
439 #endif
440 #endif
441  } else if (!strncmp(cmd, "dlsym ", 6)) {
442  const char *symbol = cmd + 6;
443  void *lib = rz_lib_dl_open(NULL);
444  void *ptr = rz_lib_dl_sym(lib, symbol);
445  eprintf("(%s) 0x%08" PFMT64x "\n", symbol, (ut64)(size_t)ptr);
446  rz_lib_dl_close(lib);
447  } else if (!strcmp(cmd, "mameio")) {
448  void *lib = rz_lib_dl_open(NULL);
449  void *ptr = rz_lib_dl_sym(lib, "_ZN12device_debug2goEj");
450  // void *readmem = dlsym (lib, "_ZN23device_memory_interface11memory_readE16address_spacenumjiRy");
451  // readmem(0, )
452  if (ptr) {
453  // gothis =
454  eprintf("TODO: No MAME IO implemented yet\n");
455  mameio = true;
456  } else {
457  eprintf("This process is not a MAME!");
458  }
459  rz_lib_dl_close(lib);
460  } else if (!strcmp(cmd, "maps")) {
461  int i;
462  for (i = 0; i < self_sections_count; i++) {
463  eprintf("0x%08" PFMT64x " - 0x%08" PFMT64x " %s %s\n",
464  self_sections[i].from, self_sections[i].to,
465  rz_str_rwx_i(self_sections[i].perm),
466  self_sections[i].name);
467  }
468  } else {
469  eprintf("|Usage: R![cmd] [args]\n");
470  eprintf("| R!pid show getpid()\n");
471  eprintf("| R!maps show map regions\n");
472  eprintf("| R!kill commit suicide\n");
473 #if !defined(__WINDOWS__)
474  eprintf("| R!alarm [secs] setup alarm signal to raise rizin prompt\n");
475 #endif
476  eprintf("| R!dlsym [sym] dlopen\n");
477  eprintf("| R!call [sym] [...] nativelly call a function\n");
478  eprintf("| R!mameio enter mame IO mode\n");
479  }
480  return NULL;
481 }
482 
484  .name = "self",
485  .desc = "Read memory from self",
486  .uris = "self://",
487  .license = "LGPL3",
488  .open = __open,
489  .close = __close,
490  .read = __read,
491  .check = __plugin_open,
492  .lseek = __lseek,
493  .system = __system,
494  .write = __write,
495 };
496 
497 #ifndef RZ_PLUGIN_INCORE
499  .type = RZ_LIB_TYPE_IO,
500  .data = &rz_io_plugin_mach,
502 };
503 #endif
504 
505 #if __APPLE__
506 // mach/mach_vm.h not available for iOS
507 kern_return_t mach_vm_region_recurse(
508  vm_map_t target_task,
509  mach_vm_address_t *address,
510  mach_vm_size_t *size,
511  natural_t *depth,
512  vm_region_recurse_info_t info,
513  mach_msg_type_number_t *infoCnt);
514 // TODO: unify that implementation in a single reusable place
515 void macosx_debug_regions(RzIO *io, task_t task, mach_vm_address_t address, int max) {
516  kern_return_t kret;
517 
518  struct vm_region_submap_info_64 info;
519  mach_vm_size_t size;
520 
521  natural_t nsubregions = 1;
522  mach_msg_type_number_t count;
523 
524  int num_printed = 0;
525  static const char *share_mode[] = {
526  "null",
527  "cow",
528  "private",
529  "empty",
530  "shared",
531  "true shared",
532  "prv aliased",
533  "shm aliased",
534  "large",
535  };
536 
537  for (;;) {
538  count = VM_REGION_SUBMAP_INFO_COUNT_64;
539  kret = mach_vm_region_recurse(task, &address, &size, &nsubregions,
540  (vm_region_recurse_info_t)&info, &count);
541  if (kret != KERN_SUCCESS) {
542  if (!num_printed) {
543  eprintf("mach_vm_region_recurse: Error %d - %s", kret, mach_error_string(kret));
544  }
545  break;
546  }
547 
548  if (!info.is_submap) {
549  int print_size;
550  char *print_size_unit;
551  int perm = 0;
552 
553  io->cb_printf(num_printed ? " ... " : "Region ");
554  // findListOfBinaries(task, prev_address, prev_size);
555  /* Quick hack to show size of segment, which GDB does not */
556  print_size = size;
557  if (print_size > 1024) {
558  print_size /= 1024;
559  print_size_unit = "K";
560  }
561  if (print_size > 1024) {
562  print_size /= 1024;
563  print_size_unit = "M";
564  }
565  if (print_size > 1024) {
566  print_size /= 1024;
567  print_size_unit = "G";
568  }
569  /* End Quick hack */
570  io->cb_printf(" %p - %p [%d%s](%x/%x; %d, %s, %u p. res, %u p. swp, %u p. drt, %u ref)",
571  (void *)(size_t)(address),
572  (void *)(size_t)(address + size),
573  print_size,
574  print_size_unit,
575  info.protection,
576  info.max_protection,
577  info.inheritance,
578  share_mode[info.share_mode],
579  info.pages_resident,
580  info.pages_swapped_out,
581  info.pages_dirtied,
582  info.ref_count);
583 
584  if (info.protection & VM_PROT_READ) {
585  perm |= RZ_PERM_R;
586  }
587  if (info.protection & VM_PROT_WRITE) {
588  perm |= RZ_PERM_W;
589  }
590  if (info.protection & VM_PROT_EXECUTE) {
591  perm |= RZ_PERM_X;
592  }
593 
594  self_sections[self_sections_count].from = address;
595  self_sections[self_sections_count].to = address + size;
596  self_sections[self_sections_count].perm = perm;
597  self_sections_count++;
598  if (nsubregions > 1) {
599  io->cb_printf(" (%d sub-regions)", nsubregions);
600  }
601  io->cb_printf("\n");
602 
603  num_printed++;
604  address += size;
605  size = 0;
606  } else {
607  nsubregions++;
608  }
609 
610  if ((max > 0) && (num_printed >= max)) {
611  eprintf("Max %d num_printed %d\n", max, num_printed);
612  break;
613  }
614  }
615 }
616 #elif __BSD__
617 bool bsd_proc_vmmaps(RzIO *io, int pid) {
618 #if __FreeBSD__
619  size_t size;
620  bool ret = false;
621  int mib[4] = {
622  CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, pid
623  };
624  int s = sysctl(mib, 4, NULL, &size, NULL, 0);
625  if (s == -1) {
626  eprintf("sysctl failed: %s\n", strerror(errno));
627  return false;
628  }
629 
630  size = size * 4 / 3;
631  ut8 *p = malloc(size);
632  if (p) {
633  s = sysctl(mib, 4, p, &size, NULL, 0);
634  if (s == -1) {
635  eprintf("sysctl failed: %s\n", strerror(errno));
636  goto exit;
637  }
638  ut8 *p_start = p;
639  ut8 *p_end = p + size;
640 
641  while (p_start < p_end) {
642  struct kinfo_vmentry *entry = (struct kinfo_vmentry *)p_start;
643  size_t sz = entry->kve_structsize;
644  int perm = 0;
645  if (sz == 0) {
646  break;
647  }
648 
649  if (entry->kve_protection & KVME_PROT_READ) {
650  perm |= RZ_PERM_R;
651  }
652  if (entry->kve_protection & KVME_PROT_WRITE) {
653  perm |= RZ_PERM_W;
654  }
655  if (entry->kve_protection & KVME_PROT_EXEC) {
656  perm |= RZ_PERM_X;
657  }
658 
659  if (entry->kve_path[0] != '\0') {
660  io->cb_printf(" %p - %p %s (%s)\n",
661  (void *)entry->kve_start,
662  (void *)entry->kve_end,
663  rz_str_rwx_i(perm),
664  entry->kve_path);
665  }
666 
667  self_sections[self_sections_count].from = entry->kve_start;
668  self_sections[self_sections_count].to = entry->kve_end;
669  self_sections[self_sections_count].name = strdup(entry->kve_path);
670  self_sections[self_sections_count].perm = perm;
671  self_sections_count++;
672  p_start += sz;
673  }
674 
675  ret = true;
676  } else {
677  eprintf("buffer allocation failed\n");
678  }
679 
680 exit:
681  free(p);
682  return ret;
683 #elif __OpenBSD__
684  size_t size = sizeof(struct kinfo_vmentry);
685  struct kinfo_vmentry entry = { .kve_start = 0 };
686  ut64 endq = 0;
687  int mib[3] = {
688  CTL_KERN, KERN_PROC_VMMAP, pid
689  };
690  int s = sysctl(mib, 3, &entry, &size, NULL, 0);
691  if (s == -1) {
692  eprintf("sysctl failed: %s\n", strerror(errno));
693  return false;
694  }
695  endq = size;
696 
697  while (sysctl(mib, 3, &entry, &size, NULL, 0) != -1) {
698  int perm = 0;
699  if (entry.kve_end == endq) {
700  break;
701  }
702 
703  if (entry.kve_protection & KVE_PROT_READ) {
704  perm |= RZ_PERM_R;
705  }
706  if (entry.kve_protection & KVE_PROT_WRITE) {
707  perm |= RZ_PERM_W;
708  }
709  if (entry.kve_protection & KVE_PROT_EXEC) {
710  perm |= RZ_PERM_X;
711  }
712 
713  io->cb_printf(" %p - %p %s [off. %zu]\n",
714  (void *)entry.kve_start,
715  (void *)entry.kve_end,
716  rz_str_rwx_i(perm),
717  entry.kve_offset);
718 
719  self_sections[self_sections_count].from = entry.kve_start;
720  self_sections[self_sections_count].to = entry.kve_end;
721  self_sections[self_sections_count].perm = perm;
722  self_sections_count++;
723  entry.kve_start = entry.kve_start + 1;
724  }
725 
726  return true;
727 #elif __NetBSD__
728  size_t size;
729  bool ret = false;
730  int mib[5] = {
731  CTL_VM, VM_PROC, VM_PROC_MAP, pid, sizeof(struct kinfo_vmentry)
732  };
733  int s = sysctl(mib, 5, NULL, &size, NULL, 0);
734  if (s == -1) {
735  eprintf("sysctl failed: %s\n", strerror(errno));
736  return false;
737  }
738 
739  size = size * 4 / 3;
740  ut8 *p = malloc(size);
741  if (p) {
742  s = sysctl(mib, 5, p, &size, NULL, 0);
743  if (s == -1) {
744  eprintf("sysctl failed: %s\n", strerror(errno));
745  goto exit;
746  }
747  ut8 *p_start = p;
748  ut8 *p_end = p + size;
749 
750  while (p_start < p_end) {
751  struct kinfo_vmentry *entry = (struct kinfo_vmentry *)p_start;
752  size_t sz = sizeof(*entry);
753  int perm = 0;
754  if (sz == 0) {
755  break;
756  }
757 
758  if (entry->kve_protection & KVME_PROT_READ) {
759  perm |= RZ_PERM_R;
760  }
761  if (entry->kve_protection & KVME_PROT_WRITE) {
762  perm |= RZ_PERM_W;
763  }
764  if (entry->kve_protection & KVME_PROT_EXEC) {
765  perm |= RZ_PERM_X;
766  }
767 
768  if (entry->kve_path[0] != '\0') {
769  io->cb_printf(" %p - %p %s (%s)\n",
770  (void *)entry->kve_start,
771  (void *)entry->kve_end,
772  rz_str_rwx_i(perm),
773  entry->kve_path);
774  }
775 
776  self_sections[self_sections_count].from = entry->kve_start;
777  self_sections[self_sections_count].to = entry->kve_end;
778  self_sections[self_sections_count].name = strdup(entry->kve_path);
779  self_sections[self_sections_count].perm = perm;
780  self_sections_count++;
781  p_start += sz;
782  }
783 
784  ret = true;
785  } else {
786  eprintf("buffer allocation failed\n");
787  }
788 
789 exit:
790  free(p);
791  return ret;
792 #elif __DragonFly__
793  struct kinfo_proc *proc;
794  struct vmspace vs;
795  struct vm_map *map;
796  struct vm_map_entry entry, *ep;
797  struct proc p;
798  int nm;
799  char e[_POSIX2_LINE_MAX];
800 
801  kvm_t *k = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, e);
802  if (!k) {
803  eprintf("kvm_openfiles: `%s`\n", e);
804  return false;
805  }
806 
807  proc = kvm_getprocs(k, KERN_PROC_PID, pid, &nm);
808 
809  kvm_read(k, (uintptr_t)proc->kp_paddr, (ut8 *)&p, sizeof(p));
810  kvm_read(k, (uintptr_t)p.p_vmspace, (ut8 *)&vs, sizeof(vs));
811 
812  map = &vs.vm_map;
813  ep = kvm_vm_map_entry_first(k, map, &entry);
814 
815  while (ep) {
816  int perm = 0;
817  if (entry.protection & VM_PROT_READ) {
818  perm |= RZ_PERM_R;
819  }
820  if (entry.protection & VM_PROT_WRITE) {
821  perm |= RZ_PERM_W;
822  }
823 
824  if (entry.protection & VM_PROT_EXECUTE) {
825  perm |= RZ_PERM_X;
826  }
827 
828  io->cb_printf(" %p - %p %s [off. %zu]\n",
829  (void *)entry.ba.start,
830  (void *)entry.ba.end,
831  rz_str_rwx_i(perm),
832  entry.ba.offset);
833 
834  self_sections[self_sections_count].from = entry.ba.start;
835  self_sections[self_sections_count].to = entry.ba.end;
836  self_sections[self_sections_count].perm = perm;
837  self_sections_count++;
838  ep = kvm_vm_map_entry_next(k, ep, &entry);
839  }
840 
841  kvm_close(k);
842  return true;
843 #endif
844 }
845 #endif
846 
847 #else // DEBUGGER
849  .name = "self",
850  .desc = "read memory from myself using 'self://' (UNSUPPORTED)",
851 };
852 
853 #ifndef RZ_PLUGIN_INCORE
855  .type = RZ_LIB_TYPE_IO,
856  .data = &rz_io_plugin_mach,
858 };
859 #endif
860 #endif
size_t len
Definition: 6502dis.c:15
#define e(frag)
#define rd()
lzma_index ** i
Definition: index.h:629
static bool err
Definition: armass.c:435
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
#define SIGKILL
#define RZ_API
#define NULL
Definition: cris-opc.c:27
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
static static fork const void static count close
Definition: sflib.h:33
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname pread
Definition: sflib.h:98
const char * k
Definition: dsignal.c:11
int max
Definition: enough.c:225
size_t map(int syms, int left, int len)
Definition: enough.c:237
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
a0
Definition: insn-good.s.cs:704
static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int count)
Definition: io_bfdbg.c:84
static bool __plugin_open(RzIO *io, const char *pathname, bool many)
Definition: io_bfdbg.c:151
static RzIODesc * __open(RzIO *io, const char *pathname, int rw, int mode)
Definition: io_bfdbg.c:159
static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count)
Definition: io_bfdbg.c:38
static ut64 __lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence)
Definition: io_bfdbg.c:142
static int __close(RzIODesc *fd)
Definition: io_bfdbg.c:130
static char * __system(RzIO *io, RzIODesc *fd, const char *cmd)
Definition: io_bochs.c:90
RzIOPlugin rz_io_plugin_self
Definition: io_self.c:848
RZ_API RzLibStruct rizin_plugin
Definition: io_self.c:854
voidpf void uLong size
Definition: ioapi.h:138
voidpf uLong offset
Definition: ioapi.h:144
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc kill
Definition: sflib.h:64
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc pid
Definition: sflib.h:64
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
@ VM_PROT_WRITE
@ VM_PROT_EXECUTE
@ VM_PROT_READ
string FILE
Definition: benchmark.py:21
line
Definition: setup.py:34
const char * name
Definition: op.c:541
#define eprintf(x, y...)
Definition: rlcc.c:7
static RzSocket * s
Definition: rtr.c:28
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API RzIODesc * rz_io_desc_new(RzIO *io, RzIOPlugin *plugin, const char *uri, int flags, int mode, void *data)
Definition: io_desc.c:11
RzIOPlugin rz_io_plugin_mach
Definition: io_mach.c:569
RZ_API void * rz_lib_dl_sym(void *handler, const char *name)
Definition: lib.c:90
RZ_API void * rz_lib_dl_open(const char *libname)
Definition: lib.c:54
@ RZ_LIB_TYPE_IO
Definition: rz_lib.h:69
RZ_API int rz_lib_dl_close(void *handler)
Definition: lib.c:104
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
RZ_API const char * rz_str_rwx_i(int rwx)
Definition: str.c:332
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API int rz_str_word_set0(char *str)
Definition: str.c:423
RZ_API const char * rz_str_word_get0(const char *str, int idx)
Definition: str.c:598
RZ_API FILE * rz_sys_fopen(const char *path, const char *mode)
Definition: sys.c:1815
RZ_API int rz_sys_signal(int sig, void(*handler)(int))
Definition: sys.c:178
#define PFMT64d
Definition: rz_types.h:394
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_PERM_RW
Definition: rz_types.h:96
#define RZ_PERM_W
Definition: rz_types.h:94
#define RZ_PERM_X
Definition: rz_types.h:95
#define RZ_PERM_RX
Definition: rz_types.h:97
#define RZ_PERM_RWX
Definition: rz_types.h:98
#define PFMT64x
Definition: rz_types.h:393
#define RZ_MIN(x, y)
#define UT64_MAX
Definition: rz_types_base.h:86
#define RZ_VERSION
Definition: rz_version.h:8
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr from
Definition: sfsocketcall.h:123
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr socklen_t static fromlen const void const struct sockaddr to
Definition: sfsocketcall.h:125
int int32_t
Definition: sftypes.h:33
int size_t
Definition: sftypes.h:40
#define O_RDONLY
Definition: sftypes.h:486
int pid_t
Definition: sftypes.h:38
int ssize_t
Definition: sftypes.h:39
#define c(i)
Definition: sha256.c:43
#define h(i)
Definition: sha256.c:48
_W64 unsigned int uintptr_t
Definition: zipcmp.c:77
char * name
Definition: zipcmp.c:78
Definition: gzappend.c:170
Definition: z80asm.h:102
const char * name
Definition: rz_io.h:115
const char * version
Definition: rz_io.h:117
Definition: rz_io.h:59
ut64 off
Definition: rz_io.h:61
PrintfCallback cb_printf
Definition: rz_io.h:91
int va
Definition: rz_io.h:63
struct Proc * proc
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4
DWORD LPWSTR
DWORD * HANDLE
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
PVOID
kern_return_t mach_vm_region_recurse(vm_map_t target_task, mach_vm_address_t *address, mach_vm_size_t *size, natural_t *nesting_depth, vm_region_recurse_info_t info, mach_msg_type_number_t *infoCnt)
static const z80_opcode fd[]
Definition: z80_tab.h:997
static const char * cb[]
Definition: z80_tab.h:176
static int addr
Definition: z80asm.c:58
#define SEEK_SET
Definition: zip.c:88
#define SEEK_CUR
Definition: zip.c:80
#define SEEK_END
Definition: zip.c:84
#define L
Definition: zip_err_str.c:7