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>
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);
24 #include <sys/sysctl.h>
27 #elif __OpenBSD__ || __NetBSD__
28 #include <sys/sysctl.h>
30 #include <sys/types.h>
32 #include <sys/sysctl.h>
36 bool bsd_proc_vmmaps(
RzIO *io,
int pid);
39 #include <kernel/image.h>
41 #if defined __sun && defined _LP64
42 #define _STRUCTURED_PROC 1
43 #include <sys/procfs.h>
59 static RzIOSelfSection self_sections[1024];
60 static int self_sections_count = 0;
61 static bool mameio =
false;
63 static int self_in_section(
RzIO *io,
ut64 addr,
int *left,
int *perm) {
65 for (
i = 0;
i < self_sections_count;
i++) {
68 *left = self_sections[
i].to -
addr;
71 *perm = self_sections[
i].perm;
79 static int update_self_regions(
RzIO *io,
int pid) {
80 self_sections_count = 0;
84 rc = task_for_pid(mach_task_self(),
pid, &task);
86 eprintf(
"task_for_pid failed\n");
89 macosx_debug_regions(io, task, (
size_t)1, 1000);
95 char region[100], region2[100], perms[5];
107 if (
line[0] ==
'\0') {
111 sscanf(
line,
"%s %s %*s %*s %*s %[^\n]", region + 2, perms,
path);
113 pos_c = strchr(region + 2,
'-');
118 memcpy(region2 + 2, pos_c, l);
124 for (
i = 0;
i < 4 && perms[
i];
i++) {
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++;
142 return bsd_proc_vmmaps(io,
pid);
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++;
155 #elif __sun && defined _LP64
158 pid_t self = getpid();
159 struct ps_prochandle *Pself = Pgrab(
self, PGRAB_RDONLY, &
err);
166 size_t hint = (1 << 20);
180 while (hint > 0 && (
rd =
pread(
fd,
map, hint, 0)) == hint) {
191 for (
c =
map;
rd > 0;
c++,
rd -=
sizeof(prmap_t)) {
193 Pobjname(Pself,
c->pr_vaddr,
name,
sizeof(
name));
195 if (
name[0] ==
'\0') {
197 strcpy(
name,
"[anon]");
202 if ((
c->pr_mflags & MA_READ)) {
205 if ((
c->pr_mflags & MA_WRITE)) {
208 if ((
c->pr_mflags & MA_EXEC)) {
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++;
225 const size_t name_size = 1024;
227 MEMORY_BASIC_INFORMATION mbi;
228 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0,
pid);
231 RZ_LOG_ERROR(
"io_self/update_self_regions: Failed to allocate memory.\n");
235 while (VirtualQuery(
to, &mbi,
sizeof(mbi))) {
236 to = (PBYTE)mbi.BaseAddress + mbi.RegionSize;
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)) {
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++;
258 #warning not yet implemented for this platform
265 return (!strncmp(
file,
"self://", 7));
269 int ret,
pid = getpid();
271 ret = update_self_regions(io,
pid);
281 if (self_in_section(io, io->
off, &left, &perm)) {
295 if (self_in_section(io, io->
off, &left, &perm)) {
320 #if !defined(__WINDOWS__)
321 static void got_alarm(
int sig) {
323 kill(getpid(), SIGUSR1);
328 if (!strcmp(
cmd,
"pid")) {
330 }
else if (!strncmp(
cmd,
"pid", 3)) {
332 #if !defined(__WINDOWS__)
333 }
else if (!strncmp(
cmd,
"kill", 4)) {
337 }
else if (!strncmp(
cmd,
"call ", 5)) {
343 eprintf(
"Usage: R!call [fcnptr] [a0] [a1] ...\n");
349 const char *symbol =
cmd + 6;
353 cbptr = (
ut64)(
size_t)ptr;
360 size_t (*
cb)() = (
size_t(*)())cbptr;
364 eprintf(
"No callback defined\n");
366 }
else if (argc == 2) {
372 eprintf(
"No callback defined\n");
374 }
else if (argc == 3) {
381 eprintf(
"No callback defined\n");
383 }
else if (argc == 4) {
384 size_t (*
cb)(
size_t a0,
size_t a1,
size_t a2) =
390 result =
cb(
a0, a1, a2);
392 eprintf(
"No callback defined\n");
394 }
else if (argc == 5) {
395 size_t (*
cb)(
size_t a0,
size_t a1,
size_t a2,
size_t a3) =
402 result =
cb(
a0, a1, a2, a3);
404 eprintf(
"No callback defined\n");
406 }
else if (argc == 6) {
407 size_t (*
cb)(
size_t a0,
size_t a1,
size_t a2,
size_t a3,
size_t a4) =
415 result =
cb(
a0, a1, a2, a3, a4);
417 eprintf(
"No callback defined\n");
420 eprintf(
"Unsupported number of arguments in call\n");
424 #if !defined(__WINDOWS__)
425 }
else if (!strncmp(
cmd,
"alarm ", 6)) {
426 struct itimerval tmout;
427 int secs = atoi(
cmd + 6);
430 tmout.it_value.tv_sec = secs;
431 tmout.it_value.tv_usec = 0;
433 setitimer(ITIMER_REAL, &tmout,
NULL);
436 #pragma message("self:// alarm is not implemented for this platform yet")
438 #warning "self:// alarm is not implemented for this platform yet"
441 }
else if (!strncmp(
cmd,
"dlsym ", 6)) {
442 const char *symbol =
cmd + 6;
447 }
else if (!strcmp(
cmd,
"mameio")) {
454 eprintf(
"TODO: No MAME IO implemented yet\n");
457 eprintf(
"This process is not a MAME!");
460 }
else if (!strcmp(
cmd,
"maps")) {
462 for (
i = 0;
i < self_sections_count;
i++) {
464 self_sections[
i].
from, self_sections[
i].
to,
466 self_sections[
i].
name);
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");
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");
485 .desc =
"Read memory from self",
497 #ifndef RZ_PLUGIN_INCORE
508 vm_map_t target_task,
509 mach_vm_address_t *address,
510 mach_vm_size_t *
size,
512 vm_region_recurse_info_t
info,
513 mach_msg_type_number_t *infoCnt);
515 void macosx_debug_regions(
RzIO *io, task_t task, mach_vm_address_t address,
int max) {
518 struct vm_region_submap_info_64
info;
521 natural_t nsubregions = 1;
522 mach_msg_type_number_t
count;
525 static const char *share_mode[] = {
538 count = VM_REGION_SUBMAP_INFO_COUNT_64;
540 (vm_region_recurse_info_t)&
info, &
count);
541 if (kret != KERN_SUCCESS) {
543 eprintf(
"mach_vm_region_recurse: Error %d - %s", kret, mach_error_string(kret));
548 if (!
info.is_submap) {
550 char *print_size_unit;
553 io->
cb_printf(num_printed ?
" ... " :
"Region ");
557 if (print_size > 1024) {
559 print_size_unit =
"K";
561 if (print_size > 1024) {
563 print_size_unit =
"M";
565 if (print_size > 1024) {
567 print_size_unit =
"G";
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),
578 share_mode[
info.share_mode],
580 info.pages_swapped_out,
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);
610 if ((
max > 0) && (num_printed >=
max)) {
611 eprintf(
"Max %d num_printed %d\n",
max, num_printed);
617 bool bsd_proc_vmmaps(
RzIO *io,
int pid) {
622 CTL_KERN, KERN_PROC, KERN_PROC_VMMAP,
pid
626 eprintf(
"sysctl failed: %s\n", strerror(errno));
635 eprintf(
"sysctl failed: %s\n", strerror(errno));
641 while (p_start < p_end) {
642 struct kinfo_vmentry *
entry = (
struct kinfo_vmentry *)p_start;
643 size_t sz =
entry->kve_structsize;
649 if (
entry->kve_protection & KVME_PROT_READ) {
652 if (
entry->kve_protection & KVME_PROT_WRITE) {
655 if (
entry->kve_protection & KVME_PROT_EXEC) {
659 if (
entry->kve_path[0] !=
'\0') {
661 (
void *)
entry->kve_start,
662 (
void *)
entry->kve_end,
667 self_sections[self_sections_count].from =
entry->kve_start;
668 self_sections[self_sections_count].to =
entry->kve_end;
670 self_sections[self_sections_count].perm = perm;
671 self_sections_count++;
677 eprintf(
"buffer allocation failed\n");
684 size_t size =
sizeof(
struct kinfo_vmentry);
685 struct kinfo_vmentry
entry = { .kve_start = 0 };
688 CTL_KERN, KERN_PROC_VMMAP,
pid
692 eprintf(
"sysctl failed: %s\n", strerror(errno));
699 if (
entry.kve_end == endq) {
703 if (
entry.kve_protection & KVE_PROT_READ) {
706 if (
entry.kve_protection & KVE_PROT_WRITE) {
709 if (
entry.kve_protection & KVE_PROT_EXEC) {
713 io->
cb_printf(
" %p - %p %s [off. %zu]\n",
714 (
void *)
entry.kve_start,
715 (
void *)
entry.kve_end,
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++;
731 CTL_VM, VM_PROC, VM_PROC_MAP,
pid,
sizeof(
struct kinfo_vmentry)
735 eprintf(
"sysctl failed: %s\n", strerror(errno));
744 eprintf(
"sysctl failed: %s\n", strerror(errno));
750 while (p_start < p_end) {
751 struct kinfo_vmentry *
entry = (
struct kinfo_vmentry *)p_start;
752 size_t sz =
sizeof(*entry);
758 if (
entry->kve_protection & KVME_PROT_READ) {
761 if (
entry->kve_protection & KVME_PROT_WRITE) {
764 if (
entry->kve_protection & KVME_PROT_EXEC) {
768 if (
entry->kve_path[0] !=
'\0') {
770 (
void *)
entry->kve_start,
771 (
void *)
entry->kve_end,
776 self_sections[self_sections_count].from =
entry->kve_start;
777 self_sections[self_sections_count].to =
entry->kve_end;
779 self_sections[self_sections_count].perm = perm;
780 self_sections_count++;
786 eprintf(
"buffer allocation failed\n");
793 struct kinfo_proc *
proc;
796 struct vm_map_entry
entry, *ep;
799 char e[_POSIX2_LINE_MAX];
803 eprintf(
"kvm_openfiles: `%s`\n",
e);
807 proc = kvm_getprocs(
k, KERN_PROC_PID,
pid, &nm);
813 ep = kvm_vm_map_entry_first(
k,
map, &
entry);
828 io->
cb_printf(
" %p - %p %s [off. %zu]\n",
829 (
void *)
entry.ba.start,
830 (
void *)
entry.ba.end,
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);
850 .desc =
"read memory from myself using 'self://' (UNSUPPORTED)",
853 #ifndef RZ_PLUGIN_INCORE
RzBinInfo * info(RzBinFile *bf)
static static fork const void static count static fd const char const char static newpath const char static path const char path
static static fork const void static count close
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
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
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
size_t map(int syms, int left, int len)
RZ_API void Ht_() free(HtName_(Ht) *ht)
static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int count)
static bool __plugin_open(RzIO *io, const char *pathname, bool many)
static RzIODesc * __open(RzIO *io, const char *pathname, int rw, int mode)
static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count)
static ut64 __lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence)
static int __close(RzIODesc *fd)
static char * __system(RzIO *io, RzIODesc *fd, const char *cmd)
RzIOPlugin rz_io_plugin_self
RZ_API RzLibStruct rizin_plugin
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * realloc(void *ptr, size_t size)
void * malloc(size_t size)
void * calloc(size_t number, size_t size)
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
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
static static fork const void static count static fd const char const char static newpath char char argv
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")
#define rz_return_val_if_fail(expr, val)
RZ_API RzIODesc * rz_io_desc_new(RzIO *io, RzIOPlugin *plugin, const char *uri, int flags, int mode, void *data)
RzIOPlugin rz_io_plugin_mach
RZ_API void * rz_lib_dl_sym(void *handler, const char *name)
RZ_API void * rz_lib_dl_open(const char *libname)
RZ_API int rz_lib_dl_close(void *handler)
#define RZ_LOG_ERROR(fmtstr,...)
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
RZ_API const char * rz_str_rwx_i(int rwx)
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API int rz_str_word_set0(char *str)
RZ_API const char * rz_str_word_get0(const char *str, int idx)
RZ_API FILE * rz_sys_fopen(const char *path, const char *mode)
RZ_API int rz_sys_signal(int sig, void(*handler)(int))
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr from
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr socklen_t static fromlen const void const struct sockaddr to
_W64 unsigned int uintptr_t
if(dbg->bits==RZ_SYS_BITS_64)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
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[]