Example #1
0
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;
}
Example #2
0
// __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;
}
Example #3
0
// __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;
}