Пример #1
0
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
	if (__plugin_open (io, pathname, 0)) {
		const char *hostport = pathname + 6;
		RIOKdp *mal = R_NEW (RIOKdp);
		mal->fd = -2; /* causes r_io_desc_new() to set the correct fd */
		eprintf ("HOST:PORT = %s", hostport);
		//mal->sock = r_socket_new();
		mal->size = strlen (pathname);
		mal->buf = malloc (mal->size+1);
		mal->offset = 0;
		memset (mal->buf, 0, mal->size);
		mal->size = r_hex_str2bin (hostport, mal->buf);
		if ((int)mal->size<1) {
			free (mal->buf);
			mal->buf = NULL;
		}
		if (mal->buf != NULL) {
			RETURN_IO_DESC_NEW (&r_io_plugin_kdp,
				mal->fd, pathname, rw, mode,mal);
		}
		eprintf ("Cannot connect to %s\n", hostport);
		free (mal);
	}
	return NULL;
}
Пример #2
0
static RIODesc *__open(struct r_io_t *io, const char *file, int rw, int mode) {
	RIOMach *riom;
	int pid;
	task_t task;
	if (!__plugin_open (io, file))
		return NULL;
 	pid = atoi (file+(file[0]=='a'?9:7));
	if (pid<1)
		return NULL;
	task = debug_attach (pid);
	if ((int)task == -1) {
		switch (errno) {
		case EPERM:
			eprintf ("Operation not permitted\n");
			break;
		case EINVAL:
			perror ("ptrace: Cannot attach");
			eprintf ("ERRNO: %d (EINVAL)\n", errno);
			break;
		default:
			eprintf ("unknown error in debug_attach\n");
			break;
		}
		return NULL;
	}
	riom = R_NEW (RIOMach);
	riom->pid = pid;
	riom->task = task;
	return r_io_desc_new (&r_io_plugin_mach, riom->pid, file, 1, mode, riom);
}
Пример #3
0
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
	if (__plugin_open (io, pathname,0)) {
		RIOSparse *mal = R_NEW0 (RIOSparse);
		mal->fd = -2; /* causes r_io_desc_new() to set the correct fd */
		int size = (int)r_num_math (NULL, pathname+9);
		mal->buf = r_buf_new_sparse ();
		if (size>0) {
			ut8 *data = malloc (size);
			if (!data) {
				eprintf ("Cannot allocate (%s) %d bytes\n",
					pathname+9, size);
				mal->offset = 0;
			} else {
				memset (data, 0x00, size);
				r_buf_write_at (mal->buf, 0, data, size);
				free (data);
			}
		}
		if (mal->buf) {
			RETURN_IO_DESC_NEW (&r_io_plugin_sparse,
				mal->fd, pathname, rw, mode, mal);
		}
		r_buf_free (mal->buf);
		free (mal);
	}
	return NULL;
}
Пример #4
0
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
	if (__plugin_open (io, pathname,0)) {
		RIOMalloc *mal = R_NEW (RIOMalloc);
		mal->fd = -2; /* causes r_io_desc_new() to set the correct fd */
		if (!strncmp (pathname, "hex://", 6)) {
			mal->size = strlen (pathname);
			mal->buf = malloc (mal->size+1);
			mal->offset = 0;
			memset (mal->buf, 0, mal->size);
			mal->size = r_hex_str2bin (pathname+6, mal->buf);
			if ((int)mal->size<1) {
				free (mal->buf);
				mal->buf = NULL;
			}
		} else {
			mal->size = r_num_math (NULL, pathname+9);
			if (((int)mal->size) <= 0) {
				free (mal);
				eprintf ("Cannot allocate (%s) 0 bytes\n", pathname+9);
				return NULL;
			}
			mal->offset = 0;
			mal->buf = calloc (1, mal->size+1);
		}
		if (mal->buf != NULL) {
			RETURN_IO_DESC_NEW (&r_io_plugin_malloc,
				mal->fd, pathname, rw, mode,mal);
		}
		eprintf ("Cannot allocate (%s) %d bytes\n", pathname+9, mal->size);
		free (mal);
	}
	return NULL;
}
Пример #5
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;
}
Пример #6
0
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
	char *out;
	int rlen, code;
	if (__plugin_open (io, pathname, 0)) {
		RIOR2Web *mal = R_NEW0 (RIOR2Web);
		if (!mal) return NULL;
		char *url = r_str_newf ("http://%s/?V", pathname+8);
		//eprintf  ("URL:(%s)\n", url);
		out = r_socket_http_get (url, &code, &rlen);
		//eprintf ("RES %d %d\n", code, rlen);
		//eprintf ("OUT(%s)\n", out);
		if (out && rlen>0) {
			mal->fd = getmalfd (mal);
			mal->url = r_str_newf ("http://%s", pathname+8);
			free (out);
			free (url);
			return r_io_desc_new (&r_io_plugin_r2web,
				mal->fd, pathname, rw, mode, mal);
		}
		free (url);
		free (mal);
		free (out);
	}
	return NULL;
}
Пример #7
0
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) {
    void *io_ctx;
    WindCtx *ctx;

    if (!__plugin_open (io, file, 0))
        return NULL;

    if (!iob_select ("pipe")) {
        eprintf("Could not initialize the IO backend\n");
        return NULL;
    }

    io_ctx = iob_open (file + 9);
    if (!io_ctx) {
        eprintf ("Could not open the pipe\n");
        return NULL;
    }

    ctx = wind_ctx_new (io_ctx);

    if (!ctx)
        return NULL;

    return r_io_desc_new (&r_io_plugin_windbg, -1, file, R_TRUE, mode, ctx);
}
Пример #8
0
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
	if (__plugin_open (io, pathname,0)) {
		RIOSparse *mal = R_NEW0 (RIOSparse);
		int size = (int)r_num_math (NULL, pathname + 9);
		mal->buf = r_buf_new_sparse (io->Oxff);
		if (!mal->buf) {
			free (mal);
			return NULL;
		}
		if (size > 0) {
			ut8 *data = malloc (size);
			if (!data) {
				eprintf ("Cannot allocate (%s) %d byte(s)\n",
					pathname+9, size);
				mal->offset = 0;
			} else {
				memset (data, 0x00, size);
				r_buf_write_at (mal->buf, 0, data, size);
				free (data);
			}
		}
		if (mal->buf) {
			return r_io_desc_new (io, &r_io_plugin_sparse,
				pathname, rw, mode, mal);
		}
		r_buf_free (mal->buf);
		free (mal);
	}
	return NULL;
}
Пример #9
0
static RIODesc *__open(struct r_io_t *io, const char *pathname, int rw, int mode) {
	if (__plugin_open (io, pathname)) {
		RIOMalloc *mal = R_NEW (RIOMalloc);
		mal->fd = -2; /* causes r_io_desc_new() to set the correct fd */
		if (!memcmp (pathname, "hex://", 6)) {
			mal->size = strlen (pathname);
			mal->buf = malloc (mal->size);
			memset (mal->buf, 0, mal->size);
			mal->size = r_hex_str2bin (pathname+6, mal->buf);
		} else {
			mal->size = r_num_math (NULL, pathname+9);
			if ((mal->size)>0) {
				mal->buf = malloc (mal->size);
				memset (mal->buf, '\0', mal->size);
			} else {
				eprintf ("Cannot allocate (%s) 0 bytes\n", pathname+9);
				return NULL;
			}
		}
		if (mal->buf != NULL) {
			RETURN_IO_DESC_NEW(&r_io_plugin_malloc, mal->fd, pathname, rw, mode,mal);
			//return r_io_desc_new (&r_io_plugin_malloc, mal->fd, pathname, rw, mode, mal);
		}
		eprintf ("Cannot allocate (%s) %d bytes\n", pathname+9,
			mal->size);
		free (mal);
	}
	return NULL;
}
Пример #10
0
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) {
	char host[128], *port, *p;
	if (!__plugin_open (io, file, 0))
		return NULL;
	RIOGdb *riog;
	strncpy (host, file+6, sizeof (host)-1);
	port = strchr (host , ':');
	if (!port) {
		eprintf ("Port not specified. Please use gdb://[host]:[port]\n");
		return NULL;
	}
	*port = '\0';
	port++;
	p = strchr (port, '/');
	if (p) *p=0;

	if (r_sandbox_enable (0)) {
		eprintf ("sandbox: Cannot use network\n");
		return NULL;
	}
	riog = R_NEW (RIOGdb);
	gdbr_init(&riog->desc);
	int i_port = atoi(port);
	if (gdbr_connect(&riog->desc, host, i_port) == 0) {
		desc = &riog->desc;
		return r_io_desc_new (&r_io_plugin_gdb, riog->desc.fd, file, rw, mode, riog);
	}
	eprintf ("gdb.io.open: Cannot connect to host.\n");
	free (riog);
	return NULL;
}
Пример #11
0
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
	char *out;
	int rlen, code;
	if (__plugin_open (io, pathname, 0)) {
		out = r_socket_http_get (pathname, &code, &rlen);
		if (out && rlen>0) {
			RIOMalloc *mal = R_NEW0 (RIOMalloc);
			if (!mal) return NULL;
			mal->size = rlen;
			mal->buf = malloc (mal->size+1);
			if (!mal->buf) {
				free (mal);
				return NULL;
			}
			if (mal->buf != NULL) {
				mal->fd = getmalfd (mal);
				memcpy (mal->buf, out, mal->size);
				free (out);
				return r_io_desc_new (io, &r_io_plugin_http,
					pathname, rw, mode, mal);
			}
			eprintf ("Cannot allocate (%s) %d bytes\n", pathname+9, mal->size);
			free (mal);
		}
		free (out);
	}
	return NULL;
}
Пример #12
0
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
	char *out;
	int rlen;
	if (__plugin_open (io, pathname, 0)) {
		RIOBind iob;
		RIOBfdbg *mal = R_NEW0 (RIOBfdbg);
		r_io_bind (io, &iob);
		mal->fd = getmalfd (mal);
		mal->bfvm = bfvm_new (&iob);
		out = r_file_slurp (pathname+8, &rlen);
		if (!out || rlen < 1) {
			free (mal);
			free (out);
			return NULL;
		}
		mal->size = rlen;
		mal->buf = malloc (mal->size+1);
		if (mal->buf != NULL) {
			memcpy (mal->buf, out, rlen);
			free (out);
			return r_io_desc_new (&r_io_plugin_bfdbg,
				mal->fd, pathname, rw, mode, mal);
		}
		eprintf ("Cannot allocate (%s) %d bytes\n",
			pathname+9, mal->size);
		free (mal);
		free (out);
	}
	return NULL;
}
Пример #13
0
static RIODesc *__open(struct r_io_t *io, const char *file, int rw, int mode) {
	int ret = -1;
	if (__plugin_open (io, file)) {
		int pid = atoi (file+9);
		ret = ptrace (PTRACE_ATTACH, pid, 0, 0);
		if (file[0]=='p')  //ptrace
			ret = 0;
		else
		if (ret == -1) {
#ifdef __ANDROID__
		eprintf ("ptrace_attach: Operation not permitted\n");
#else
			switch (errno) {
			case EPERM:
				ret = pid;
				eprintf ("ptrace_attach: Operation not permitted\n");
				break;
			case EINVAL:
				perror ("ptrace: Cannot attach");
				eprintf ("ERRNO: %d (EINVAL)\n", errno);
				break;
			}
#endif
		} else
		if (__waitpid (pid))
			ret = pid;
		else eprintf ("Error in waitpid\n");
		if (ret != -1) {
			RIOPtrace *riop = R_NEW (RIOPtrace);
			riop->pid = riop->tid = pid;
			return r_io_desc_new (&r_io_plugin_ptrace, -1, file, R_TRUE, 0, riop);
		}
	}
	return NULL;
}
Пример #14
0
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
	R2Pipe *r2p = NULL;
	if (__plugin_open (io, pathname, 0)) {
		r2p = r2p_open (pathname+9);
	}
	return r2p? r_io_desc_new (&r_io_plugin_r2pipe,
		r2p->child, pathname, rw, mode, r2p): NULL;
}
Пример #15
0
static RIODesc* __open(RIO* io, const char* pathname, int rw, int mode) {
	RIONull* null;
	if (__plugin_open (io, pathname,0)) {
		if (!strncmp (pathname, "null://", 7) && strlen (pathname + 7)) {
			null = R_NEW0 (RIONull);
			null->size = r_num_math (NULL, pathname + 7) + 1;         //???
			null->offset = 0LL;
			return r_io_desc_new (io, &r_io_plugin_null, pathname, rw, mode, null);
		}
	}
	return NULL;
}
Пример #16
0
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) {
	RIODesc *ret = NULL;
	RIOMach *riom;
	const char *pidfile;
	char *pidpath, *endptr;
	int pid;
	task_t task;
	if (!__plugin_open (io, file, 0)) {
		return NULL;
	}
	pidfile = file + (file[0] == 'a' ? 9 : 7);
	pid = (int)strtol (pidfile, &endptr, 10);
	if (endptr == pidfile || pid < 0) {
		return NULL;
	}
	task = pid_to_task (pid);
	if (task == -1) {
		return NULL;
	}
	if (!task) {
		if (pid > 0 && io->referer && !strncmp (io->referer, "dbg://", 6)) {
			eprintf ("Child killed\n");
			kill (pid, 9);
		}
		switch (errno) {
		case EPERM:
			eprintf ("Operation not permitted\n");
			break;
		case EINVAL:
			perror ("ptrace: Cannot attach");
			eprintf ("Possibly unsigned r2. Please see doc/osx.md\n");
			eprintf ("ERRNO: %d (EINVAL)\n", errno);
			break;
		default:
			eprintf ("unknown error in debug_attach\n");
			break;
		}
		return NULL;
	}
	riom = R_NEW0 (RIOMach);
	riom->pid = pid;
	riom->task = task;
	// sleep 1s to get proper path (program name instead of ls) (racy)
	pidpath = pid
		? r_sys_pid_to_path (pid)
		: strdup ("kernel");
	ret = r_io_desc_new (&r_io_plugin_mach, riom->pid,
		pidpath, rw | R_IO_EXEC, mode, riom);
	free (pidpath);
	return ret;
}
Пример #17
0
static RIODesc *__open(struct r_io_t *io, const char *file, int rw, int mode) {
	if (__plugin_open (io, file, 0)) {
		char *pidpath;
		RIOW32Dbg *dbg = R_NEW (RIOW32Dbg);
		if (dbg == NULL)
			return NULL;
		dbg->pid = atoi (file+9);
		if (__attach (dbg) == -1) {
			free (dbg);
			return NULL;
		}
		pidpath = r_sys_pid_to_path (dbg->pid);
		RETURN_IO_DESC_NEW (&r_io_plugin_w32dbg, -1,
			pidpath, rw | R_IO_EXEC, mode, dbg);
	}
	return NULL;
}
Пример #18
0
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
	if (__plugin_open (io, pathname, 0)) {
		RIOGzip *mal = R_NEW0 (RIOGzip);
		if (!mal) return NULL;
		int len;
		ut8 *data = (ut8*)r_file_slurp (pathname+7, &len);
		mal->buf = r_inflate (data, len, NULL, &mal->size);
		if (mal->buf) {
			RETURN_IO_DESC_NEW (&r_io_plugin_malloc,
				mal->fd, pathname, rw, mode, mal);
		}
		free (data);
		eprintf ("Cannot allocate (%s) %d bytes\n", pathname+9,
			mal->size);
		free (mal);
	}
	return NULL;
}
Пример #19
0
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) {
    RIODesc *ret = NULL;
    RIOMach *riom;
    const char *pidfile;
    char *pidpath;
    int pid;
    task_t task;
    if (!__plugin_open (io, file, 0))
        return NULL;
    pidfile = file+(file[0]=='a'?9:7);
    if (!strcmp (pidfile, "0")) {
        /* tfp0 */
        pid = 0;
    } else {
        pid = atoi (pidfile);
        if (pid<1)
            return NULL;
    }
    task = debug_attach (pid);
    if ((int)task == -1) {
        switch (errno) {
        case EPERM:
            eprintf ("Operation not permitted\n");
            break;
        case EINVAL:
            perror ("ptrace: Cannot attach");
            eprintf ("ERRNO: %d (EINVAL)\n", errno);
            break;
        default:
            eprintf ("unknown error in debug_attach\n");
            break;
        }
        return NULL;
    }
    riom = R_NEW0 (RIOMach);
    riom->pid = pid;
    riom->task = task;
    // sleep 1s to get proper path (program name instead of ls) (racy)
    pidpath = r_sys_pid_to_path (pid);
    ret = r_io_desc_new (&r_io_plugin_mach, riom->pid,
                         pidpath, rw | R_IO_EXEC, mode, riom);
    free (pidpath);
    return ret;
}
Пример #20
0
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) {
	char host[128], *port, *p;
	RSocket *_fd;
	RIOGdb *riog;
	if (!__plugin_open (io, file, 0))
		return NULL;
	strncpy (host, file+6, sizeof (host)-1);
	port = strchr (host , ':');
	if (!port) {
		eprintf ("Port not specified. Please use gdb://[host]:[port]\n");
		return NULL;
	}
	*port = '\0';
	port++;
	p = strchr (port, '/');
	if (p) *p=0;

	if (r_sandbox_enable (0)) {
		eprintf ("sandbox: Cannot use network\n");
		return NULL;
	}
	_fd = r_socket_new (R_FALSE);
	if (_fd && r_socket_connect_tcp (_fd, host, port, 3)) {
		riog = R_NEW (RIOGdb);
		riog->fd = _fd;
		riog->desc = gdbwrap_init (_fd->fd, NUM_REGS, 4);
		if (!riog->desc) {
			r_socket_free (_fd);
			free (riog);
			return NULL;
		}
#if __WINDOWS__
		// XXX: bypass lazylinking
		RETURN_IO_DESC_NEW (&r_io_plugin_gdb, _fd->fd, file, rw, mode, riog);
#else
		return r_io_desc_new (&r_io_plugin_gdb, _fd->fd, file, rw, mode, riog);
#endif
	}
	eprintf ("gdb.io.open: Cannot connect to host.\n");
	return NULL;
}
Пример #21
0
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) {
	if (__plugin_open (io, file, 0)) {
		char *pidpath;
		RIODesc *ret;
		RIOW32Dbg *dbg = R_NEW0 (RIOW32Dbg);
		if (!dbg) {
			return NULL;
		}
		dbg->pid = atoi (file + 9);
		if (__open_proc (dbg, !strncmp (file, "attach://", 9)) == -1) {
			free (dbg);
			return NULL;
		}
		pidpath = r_sys_pid_to_path (dbg->pid);
		ret = r_io_desc_new (io, &r_io_plugin_w32dbg,
				file, rw | R_PERM_X, mode, dbg);
		ret->name = pidpath;
		return ret;
	}
	return NULL;
}
Пример #22
0
static RIODesc *__open(struct r_io_t *io, const char *file, int rw, int mode) {
	char procpidpath[64];
	int fd, ret = -1;
	if (__plugin_open (io, file,0)) {
		int pid = atoi (file+10);
		if (file[0]=='a') {
			ret = ptrace (PTRACE_ATTACH, pid, 0, 0);
			if (ret == -1) {
				switch (errno) {
				case EPERM:
					ret = pid;
					eprintf ("Operation not permitted\n");
					break;
				case EINVAL:
					perror ("ptrace: Cannot attach");
					eprintf ("ERRNO: %d (EINVAL)\n", errno);
					break;
				}
			} else
			if (__waitpid(pid))
				ret = pid;
			else eprintf ("Error in waitpid\n");
		} else ret = pid;
		fd = ret;//TODO: use r_io_fd api
		snprintf (procpidpath, sizeof (procpidpath), "/proc/%d/mem", pid);
		fd = open (procpidpath, O_RDWR);
		if (fd != -1) {
			RIOProcpid *riop = R_NEW (RIOProcpid);
			riop->pid = pid;
			riop->fd = fd;
			return r_io_desc_new (&r_io_plugin_procpid, -1, file, R_TRUE, 0, riop);
		}
		/* kill children */
		eprintf ("Cannot open /proc/%d/mem of already attached process\n", pid);
		ptrace (PTRACE_DETACH, pid, 0, 0);
	}
	return NULL;
}
Пример #23
0
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
	if (__plugin_open (io, pathname, 0)) {
		if (gs) {
			return NULL;
		}
		gs = r_socket_new (0);
		char *cmd = r_str_newf ("winedbg '%s'", pathname + 10);
		int res = r_socket_spawn (gs, cmd, 1000);
		free (cmd);
		if (!res) {
			return NULL;
		}
		char *reply = runcmd (NULL);
		if (reply) {
			int rw = 7;
			free (reply);
			eprintf ("Wine-dbg is ready to go!\n");
			return r_io_desc_new (io, &r_io_plugin_winedbg, pathname, rw, mode, gs);
		}
		eprintf ("Can't find the Wine-dbg prompt\n");
	}
	return NULL;
}
Пример #24
0
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;
}
Пример #25
0
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;
}
Пример #26
0
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) {
	RIODesc *ret = NULL;
	RIOMach *riom = NULL;
	const char *pidfile;
	char *pidpath, *endptr;
	int pid;
	task_t task;
	if (!__plugin_open (io, file, false) && !__plugin_open (io, (const char *)&file[1], false)) {
		return NULL;
	}
	pidfile = file + (file[0] == 'a' ? 9 : (file[0] == 's' ? 8 : 7));
	pid = (int)strtol (pidfile, &endptr, 10);
	if (endptr == pidfile || pid < 0) {
		return NULL;
	}
	task = pid_to_task (NULL, pid);
	if (task == -1) {
		return NULL;
	}
	if (!task) {
		if (pid > 0 && !strncmp (file, "smach://", 8)) {
			kill (pid, SIGKILL);
			eprintf ("Child killed\n");
		}
#if 0
		/* this is broken, referer gets set in the riodesc after this function returns the riodesc
		 * the pid > 0 check  doesn't seem to be reasonable to me too
		 * what was this intended to check anyway ? */
		if (pid > 0 && io->referer && !strncmp (io->referer, "dbg://", 6)) {
			eprintf ("Child killed\n");
			kill (pid, SIGKILL);
		}
#endif
		switch (errno) {
		case EPERM:
			eprintf ("Operation not permitted\n");
			break;
		case EINVAL:
			perror ("ptrace: Cannot attach");
			eprintf ("Possibly unsigned r2. Please see doc/macos.md\n");
			eprintf ("ERRNO: %d (EINVAL)\n", errno);
			break;
		default:
			eprintf ("unknown error in debug_attach\n");
			break;
		}
		return NULL;
	}
	RIODescData *iodd = R_NEW0 (RIODescData);
	if (iodd) {
		iodd->pid = pid;
		iodd->tid = pid;
		iodd->data = NULL;
	}
	riom = R_NEW0 (RIOMach);
	if (!riom) {
		return NULL;
	}
	riom->task = task;
	iodd->magic = r_str_hash ("mach");
	iodd->data = riom;
	// sleep 1s to get proper path (program name instead of ls) (racy)
	pidpath = pid
		? r_sys_pid_to_path (pid)
		: strdup ("kernel");
	if (!strncmp (file, "smach://", 8)) {
		ret = r_io_desc_new (io, &r_io_plugin_mach, &file[1],
			       rw | R_PERM_X, mode, iodd);
	} else {
		ret = r_io_desc_new (io, &r_io_plugin_mach, file,
			       rw | R_PERM_X, mode, iodd);
	}
	ret->name = pidpath;
	return ret;
}
Пример #27
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;
}
Пример #28
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;
}