static RIODesc *__open(RIO *io, const char *file, int rw, int mode) { char uri[128]; if (__plugin_open (io, file, 0)) { const char *pidfile = file + 6; char *endptr; int pid = (int)strtol (pidfile, &endptr, 10); if (endptr == pidfile || pid < 0) pid = -1; if (pid == -1) { pid = fork_and_ptraceme (io, io->bits, file+6); if (pid == -1) return NULL; #if __WINDOWS__ sprintf (uri, "w32dbg://%d", pid); #elif __APPLE__ sprintf (uri, "mach://%d", pid); #else // TODO: use io_procpid here? faster or what? sprintf (uri, "ptrace://%d", pid); #endif my_io_redirect (io, file, uri); } else { sprintf (uri, "attach://%d", pid); my_io_redirect (io, file, uri); } return NULL; } my_io_redirect (io, file, NULL); return NULL; }
static int fork_and_ptraceme(const char *cmd) { char **argv; int ret, status, pid = vfork (); switch (pid) { case -1: perror ("fork_and_ptraceme"); break; case 0: #if __APPLE__ signal (SIGTRAP, SIG_IGN); //NEED BY STEP #endif #if __APPLE__ || __BSD__ /* we can probably remove this #if..as long as PT_TRACE_ME is redefined for OSX in r_debug.h */ signal (SIGABRT, inferior_abort_handler); if (ptrace (PT_TRACE_ME, 0, 0, 0) != 0) { #else if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) != 0) { #endif eprintf ("ptrace-traceme failed\n"); exit (MAGIC_EXIT); } // TODO: Add support to redirect filedescriptors // TODO: Configure process environment argv = r_str_argv (cmd, NULL); execvp (argv[0], argv); r_str_argv_free (argv); perror ("fork_and_attach: execv"); //printf(stderr, "[%d] %s execv failed.\n", getpid(), ps.filename); exit (MAGIC_EXIT); /* error */ return 0; // invalid pid // if exit is overriden.. :) default: /* XXX: clean this dirty code */ ret = wait (&status); if (ret != pid) eprintf ("Wait event received by different pid %d\n", ret); if (WIFSTOPPED (status)) eprintf ("Process with PID %d started...\n", (int)pid); if (WEXITSTATUS (status) == MAGIC_EXIT) pid = -1; // XXX kill (pid, SIGSTOP); break; } eprintf ("PID = %d\n", pid); return pid; } #endif static int __plugin_open(struct r_io_t *io, const char *file) { if (!memcmp (file, "dbg://", 6) && file[6]) return R_TRUE; return R_FALSE; } static RIODesc *__open(RIO *io, const char *file, int rw, int mode) { char uri[128]; if (__plugin_open (io, file)) { int pid = atoi (file+6); if (pid == 0) { pid = fork_and_ptraceme (file+6); if (pid==-1) return NULL; #if __WINDOWS__ sprintf (uri, "w32dbg://%d", pid); #elif __APPLE__ sprintf (uri, "mach://%d", pid); #else // TODO: use io_procpid here? faster or what? sprintf (uri, "ptrace://%d", pid); #endif eprintf ("io_redirect: %s\n", uri); r_io_redirect (io, uri); return NULL; } else { sprintf (uri, "attach://%d", pid); r_io_redirect (io, uri); return NULL; } } r_io_redirect (io, NULL); return NULL; }
// __UNIX__ (not windows) static int fork_and_ptraceme(RIO *io, int bits, const char *cmd) { char **argv; int ret, status, pid = r_sys_fork (); switch (pid) { case -1: perror ("fork_and_ptraceme"); break; case 0: #if __APPLE__ signal (SIGTRAP, SIG_IGN); //NEED BY STEP #endif #if __APPLE__ || __BSD__ /* we can probably remove this #if..as long as PT_TRACE_ME is redefined for OSX in r_debug.h */ signal (SIGABRT, inferior_abort_handler); if (ptrace (PT_TRACE_ME, 0, 0, 0) != 0) { #else if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) != 0) { #endif r_sys_perror ("ptrace-traceme"); exit (MAGIC_EXIT); } if (io->runprofile && *(io->runprofile)) { char *expr = NULL; int i; RRunProfile *rp = r_run_new (NULL); argv = r_str_argv (cmd, NULL); for (i=0; argv[i]; i++) { rp->_args[i] = argv[i]; } rp->_args[i] = NULL; rp->_program = argv[0]; if (io->runprofile && *io->runprofile) { if (!r_run_parsefile (rp, io->runprofile)) { eprintf ("Can't find profile '%s'\n", io->runprofile); exit (MAGIC_EXIT); } } if (bits==64) r_run_parseline (rp, expr=strdup ("bits=64")); else if (bits==32) r_run_parseline (rp, expr=strdup ("bits=32")); free (expr); r_run_start (rp); r_run_free (rp); // double free wtf // r_str_argv_free (argv); exit (1); } else { // TODO: Add support to redirect filedescriptors // TODO: Configure process environment char *_cmd = strdup (cmd); argv = r_str_argv (_cmd, NULL); if (!argv) { free (_cmd); return -1; } #if __APPLE__ { #define _POSIX_SPAWN_DISABLE_ASLR 0x0100 ut32 ps_flags = POSIX_SPAWN_SETEXEC; posix_spawnattr_t attr = {0}; size_t copied = 1; cpu_type_t cpu; pid_t p = -1; int ret; int useASLR = 1; posix_spawnattr_init (&attr); if (useASLR != -1) { if (useASLR) { // enable aslr if not enabled? really? } else { ps_flags |= _POSIX_SPAWN_DISABLE_ASLR; } } (void)posix_spawnattr_setflags (&attr, ps_flags); #if __i386__ || __x86_64__ cpu = CPU_TYPE_I386; if (bits == 64) cpu |= CPU_ARCH_ABI64; #else cpu = CPU_TYPE_ANY; #endif posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &copied); ret = posix_spawnp (&p, argv[0], NULL, &attr, argv, NULL); switch (ret) { case 0: eprintf ("Success\n"); break; case 22: eprintf ("posix_spawnp: Invalid argument\n"); break; case 86: eprintf ("Unsupported architecture\n"); break; default: eprintf ("posix_spawnp: unknown error %d\n", ret); perror ("posix_spawnp"); break; } /* only required if no SETEXEC called if (p != -1) wait (p); */ exit (MAGIC_EXIT); /* error */ } #else if (argv && *argv) { execvp (argv[0], argv); } else { eprintf ("Invalid execvp\n"); } #endif free (_cmd); } perror ("fork_and_attach: execv"); //printf(stderr, "[%d] %s execv failed.\n", getpid(), ps.filename); exit (MAGIC_EXIT); /* error */ return 0; // invalid pid // if exit is overriden.. :) default: /* XXX: clean this dirty code */ do { ret = wait (&status); if (ret == -1) return -1; if (ret != pid) eprintf ("Wait event received by different pid %d\n", ret); } while (ret!=pid); if (WIFSTOPPED (status)) eprintf ("Process with PID %d started...\n", (int)pid); if (WEXITSTATUS (status) == MAGIC_EXIT) pid = -1; // XXX kill (pid, SIGSTOP); break; } eprintf ("PID = %d\n", pid); return pid; } #endif static int __plugin_open(RIO *io, const char *file, ut8 many) { if (!strncmp (file, "dbg://", 6) && file[6]) return R_TRUE; return R_FALSE; } static RIODesc *__open(RIO *io, const char *file, int rw, int mode) { char uri[128]; if (__plugin_open (io, file, 0)) { const char *pidfile = file + 6; char *endptr; int pid = (int)strtol (pidfile, &endptr, 10); if (endptr == pidfile || pid < 0) pid = -1; if (pid == -1) { pid = fork_and_ptraceme (io, io->bits, file+6); if (pid == -1) return NULL; #if __WINDOWS__ sprintf (uri, "w32dbg://%d", pid); #elif __APPLE__ sprintf (uri, "mach://%d", pid); #else // TODO: use io_procpid here? faster or what? sprintf (uri, "ptrace://%d", pid); #endif my_io_redirect (io, file, uri); } else { sprintf (uri, "attach://%d", pid); my_io_redirect (io, file, uri); } return NULL; } my_io_redirect (io, file, NULL); return NULL; }
// __UNIX__ (not windows) static int fork_and_ptraceme(RIO *io, int bits, const char *cmd) { char **argv; int ret, status, pid = fork (); switch (pid) { case -1: perror ("fork_and_ptraceme"); break; case 0: #if __APPLE__ signal (SIGTRAP, SIG_IGN); //NEED BY STEP #endif #if __APPLE__ || __BSD__ /* we can probably remove this #if..as long as PT_TRACE_ME is redefined for OSX in r_debug.h */ signal (SIGABRT, inferior_abort_handler); if (ptrace (PT_TRACE_ME, 0, 0, 0) != 0) { #else if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) != 0) { #endif r_sys_perror ("ptrace-traceme"); exit (MAGIC_EXIT); } { char *expr = NULL; int i; RRunProfile *rp = r_run_new (NULL); argv = r_str_argv (cmd, NULL); for (i=0; argv[i]; i++) { rp->_args[i] = argv[i]; } rp->_args[i] = NULL; rp->_program = argv[0]; if (io->runprofile && *io->runprofile) { if (!r_run_parsefile (rp, io->runprofile)) { eprintf ("Can't find profile '%s'\n", io->runprofile); exit (MAGIC_EXIT); } } if (bits==64) r_run_parseline (rp, expr=strdup ("bits=64")); else if (bits==32) r_run_parseline (rp, expr=strdup ("bits=32")); free (expr); r_run_start (rp); r_run_free (rp); // double free wtf // r_str_argv_free (argv); exit (1); } perror ("fork_and_attach: execv"); //printf(stderr, "[%d] %s execv failed.\n", getpid(), ps.filename); exit (MAGIC_EXIT); /* error */ return 0; // invalid pid // if exit is overriden.. :) default: /* XXX: clean this dirty code */ ret = wait (&status); if (ret != pid) eprintf ("Wait event received by different pid %d\n", ret); if (WIFSTOPPED (status)) eprintf ("Process with PID %d started...\n", (int)pid); if (WEXITSTATUS (status) == MAGIC_EXIT) pid = -1; // XXX kill (pid, SIGSTOP); break; } eprintf ("PID = %d\n", pid); return pid; } #endif static int __plugin_open(RIO *io, const char *file, ut8 many) { if (!strncmp (file, "dbg://", 6) && file[6]) return R_TRUE; return R_FALSE; } static RIODesc *__open(RIO *io, const char *file, int rw, int mode) { char uri[128]; if (__plugin_open (io, file, 0)) { int pid = atoi (file+6); if (pid == 0) { pid = fork_and_ptraceme (io, io->bits, file+6); if (pid==-1) return NULL; #if __WINDOWS__ sprintf (uri, "w32dbg://%d", pid); #elif __APPLE__ sprintf (uri, "mach://%d", pid); #else // TODO: use io_procpid here? faster or what? sprintf (uri, "ptrace://%d", pid); #endif my_io_redirect (io, uri); } else { sprintf (uri, "attach://%d", pid); my_io_redirect (io, uri); } return NULL; } my_io_redirect (io, NULL); return NULL; }
static int fork_and_ptraceme(int bits, const char *cmd) { char **argv; int ret, status, pid = fork (); switch (pid) { case -1: perror ("fork_and_ptraceme"); break; case 0: #if __APPLE__ signal (SIGTRAP, SIG_IGN); //NEED BY STEP #endif #if __APPLE__ || __BSD__ /* we can probably remove this #if..as long as PT_TRACE_ME is redefined for OSX in r_debug.h */ signal (SIGABRT, inferior_abort_handler); if (ptrace (PT_TRACE_ME, 0, 0, 0) != 0) { #else if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) != 0) { #endif eprintf ("ptrace-traceme failed\n"); exit (MAGIC_EXIT); } // TODO: Add support to redirect filedescriptors // TODO: Configure process environment argv = r_str_argv (cmd, NULL); #if __APPLE__ #include <spawn.h> { posix_spawnattr_t attr = {0}; size_t copied = 1; cpu_type_t cpu; int ret; pid_t p = -1; posix_spawnattr_init (&attr); posix_spawnattr_setflags (&attr, POSIX_SPAWN_SETEXEC); #if __i386__ || __x86_64__ cpu = CPU_TYPE_I386; if (bits == 64) cpu |= CPU_ARCH_ABI64; #else cpu = CPU_TYPE_ANY; #endif posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &copied); //ret = posix_spawnp (NULL, argv[0], NULL, &attr, argv, NULL); ret = posix_spawnp (&p, argv[0], NULL, &attr, argv, NULL); switch (ret) { case 0: eprintf ("Success\n"); break; case 22: eprintf ("posix_spawnp: Invalid argument\n"); break; case 86: eprintf ("Unsupported architecture\n"); break; default: eprintf ("posix_spawnp: unknown error %d\n", ret); perror ("posix_spawnp"); break; } /* only required if no SETEXEC called if (p != -1) wait (p); */ exit (MAGIC_EXIT); /* error */ } #else execvp (argv[0], argv); #endif r_str_argv_free (argv); perror ("fork_and_attach: execv"); //printf(stderr, "[%d] %s execv failed.\n", getpid(), ps.filename); exit (MAGIC_EXIT); /* error */ return 0; // invalid pid // if exit is overriden.. :) default: /* XXX: clean this dirty code */ ret = wait (&status); if (ret != pid) eprintf ("Wait event received by different pid %d\n", ret); if (WIFSTOPPED (status)) eprintf ("Process with PID %d started...\n", (int)pid); if (WEXITSTATUS (status) == MAGIC_EXIT) pid = -1; // XXX kill (pid, SIGSTOP); break; } eprintf ("PID = %d\n", pid); return pid; } #endif static int __plugin_open(RIO *io, const char *file) { if (!memcmp (file, "dbg://", 6) && file[6]) return R_TRUE; return R_FALSE; } static RIODesc *__open(RIO *io, const char *file, int rw, int mode) { char uri[128]; if (__plugin_open (io, file)) { int pid = atoi (file+6); if (pid == 0) { // TODO: get bits from ELF? pid = fork_and_ptraceme (io->bits, file+6); if (pid==-1) return NULL; #if __WINDOWS__ sprintf (uri, "w32dbg://%d", pid); #elif __APPLE__ sprintf (uri, "mach://%d", pid); #else // TODO: use io_procpid here? faster or what? sprintf (uri, "ptrace://%d", pid); #endif eprintf ("io_redirect: %s\n", uri); r_io_redirect (io, uri); return NULL; } else { sprintf (uri, "attach://%d", pid); r_io_redirect (io, uri); return NULL; } } r_io_redirect (io, NULL); return NULL; }