Beispiel #1
0
R_API int r_core_rtr_cmds (RCore *core, const char *port) {
	unsigned char buf[4097];
	RSocket *ch, *s;
	int i, ret;
	char *str;

	if (!port || port[0]=='?') {
		r_cons_printf ("Usage: .:[tcp-port]    run r2 commands for clients\n");
		return R_FALSE;
	}

	s = r_socket_new (0);
	if (!r_socket_listen (s, port, NULL)) {
		eprintf ("Error listening on port %s\n", port);
		r_socket_free (s);
		return R_FALSE;
	}

	eprintf ("Listening for commands on port %s\n", port);
	listenport = port;
	for (;;) {
		r_cons_break ((RConsBreak)http_break, core);
		ch = r_socket_accept (s);
		buf[0] = 0;
		ret = r_socket_read (ch, buf, sizeof (buf) - 1);
		if (ret>0) {
			buf[ret] = 0;
			for (i=0; buf[i]; i++)
				if (buf[i] == '\n')
					buf[i] = buf[i+1]? ';': '\0';
			if (!r_config_get_i (core->config, "scr.prompt") \
					&& !strcmp ((char*)buf, "q!"))
				break;
			str = r_core_cmd_str (core, (const char *)buf);
			if (str &&*str)  {
			r_socket_write (ch, str, strlen (str));
			} else
			r_socket_write (ch, "\n", 1);
			free (str);
		}
		if (r_cons_singleton()->breaked)
			break;
		r_socket_close (ch);
		r_cons_break_end ();
	}
	r_socket_free(s);
	r_socket_free(ch);
	return 0;
}
Beispiel #2
0
static int haret__read(RIO *io, RIODesc *fd, ut8 *buf, int count) {
	char tmp[1024];
	int i = 0;
	ut64 off;
	st64 j;
	RSocket *s = HARET_FD (fd);

	off = io->off & -4;
	sprintf (tmp, "pdump 0x%"PFMT64x" %i\r\n", off, count+4);
	r_socket_write (s, tmp, strlen (tmp));
	r_socket_read_block (s, (unsigned char *) tmp, strlen (tmp)+1);
	j = (io->off - off)*2;
	while (i<count && j >= 0) {
		r_socket_read_block (s, (ut8*) tmp, 11);
		r_socket_read_block (s, (ut8*) tmp, 35);
		if (i+16 < count || (io->off-off) == 0) {
			tmp[35] = 0;
			i += r_hex_str2bin (tmp+j, buf+i);
			r_socket_read_block (s, (unsigned char *) tmp, 21);
		} else {
			tmp[(io->off - off)*2] = 0;
			i += r_hex_str2bin (tmp+j, buf+i);
		}
		j = 0;
	}
	haret_wait_until_prompt (s);
	return i;
}
Beispiel #3
0
static int rap__read(struct r_io_t *io, RIODesc *fd, ut8 *buf, int count) {
	RSocket *s = RIORAP_FD (fd);
	int ret;
	int i = (int)count;
	ut8 tmp[5];

	if (count>RMT_MAX)
		count = RMT_MAX;
	// send
	tmp[0] = RMT_READ;
	r_mem_copyendian (tmp+1, (ut8*)&count, 4, ENDIAN);
	r_socket_write (s, tmp, 5);
	r_socket_flush (s);
	// recv
	ret = r_socket_read_block (s, tmp, 5);
	if (ret != 5 || tmp[0] != (RMT_READ|RMT_REPLY)) {
		eprintf ("rap__read: Unexpected rap read reply "
			"(%d=0x%02x) expected (%d=0x%02x)\n",
			ret, tmp[0], 2, (RMT_READ|RMT_REPLY));
		return -1;
	}
	r_mem_copyendian ((ut8*)&i, tmp+1, 4, ENDIAN);
	if (i>count) {
		eprintf ("rap__read: Unexpected data size %d\n", i);
		return -1;
	}
	r_socket_read_block (s, buf, i);
	return count;
}
Beispiel #4
0
R_API void r_core_rtr_pushout(RCore *core, const char *input) {
	int fd = atoi (input);
	const char *cmd = NULL;
	char *str = NULL;
	if (fd) {
		for (rtr_n = 0; rtr_host[rtr_n].fd->fd != fd \
			&& rtr_n < RTR_MAX_HOSTS; rtr_n++);
		if (!(cmd = strchr (input, ' '))) {
			eprintf ("Error\n");
			return;
		}
	} else cmd = input;

	if (!rtr_host[rtr_n].fd->fd) {
		eprintf("Error: Unknown host\n");
		return;
	}

	if (!(str = r_core_cmd_str (core, cmd))) {
		eprintf ("Error: radare_cmd_str returned NULL\n");
		return;
	}
	
	switch (rtr_host[rtr_n].proto) {
	case RTR_PROT_RAP:
		eprintf ("Error: Cannot use '=<' to a rap connection.\n");
		break;
	case RTR_PROT_TCP:
	case RTR_PROT_UDP:
	default:
		r_socket_write (rtr_host[rtr_n].fd, str, strlen (str));
		break;
	}
	free (str);
}
Beispiel #5
0
int send_packet(libgdbr_t *g) {
	if (!g) {
		eprintf ("Initialize libgdbr_t first\n");
		return -1;
	}
	return r_socket_write (g->sock, g->send_buff, g->send_len);
}
Beispiel #6
0
static int rap__write(RIO *io, RIODesc *fd, const ut8 *buf, int count) {
	RSocket *s = RIORAP_FD (fd);
	ut8 *tmp;
	int ret;

	if (count < 1) {
		return count;
	}
	// TOOD: if count > RMT_MAX iterate !
	if (count > RMT_MAX) {
		count = RMT_MAX;
	}
	if (!(tmp = (ut8 *)malloc (count + 5))) {
		eprintf ("rap__write: malloc failed\n");
		return -1;
	}
	tmp[0] = RMT_WRITE;
	r_write_be32 (tmp + 1, count);
	memcpy (tmp + 5, buf, count);

	ret = r_socket_write (s, tmp, count + 5);
	r_socket_flush (s);
	if (r_socket_read (s, tmp, 5) != 5) { // TODO read_block?
		eprintf ("rap__write: error\n");
		ret = -1;
	} else {
		ret = r_read_be32 (tmp + 1);
		if (!ret) {
			ret = -1;
		}
	}
	free (tmp);
	return ret;
}
Beispiel #7
0
// TODO: support len for binary data?
R_API char *r_core_rtr_cmds_query (RCore *core, const char *host, const char *port, const char *cmd) {
	int retries = 6;
	unsigned char buf[1024];
	char *rbuf = NULL;
	const int timeout = 0;
	RSocket *s = r_socket_new (0);
	for (;retries>0; r_sys_usleep (10*1000)) {
		if (r_socket_connect (s, host, port, R_SOCKET_PROTO_TCP, timeout))
			break;
		retries--;
	}
	if (retries>0) {
		rbuf = strdup ("");
		r_socket_write (s, (void*)cmd, strlen (cmd));
		//r_socket_write (s, "px\n", 3);
		for (;;) {
			int ret = r_socket_read (s, buf, sizeof (buf));
			if (ret<1) break;
			buf[ret] = 0;
			rbuf = r_str_concat (rbuf, (const char *)buf);
		}
	} else {
		eprintf ("Cannot connect\n");
	}
	r_socket_free (s);
	return rbuf;
}
Beispiel #8
0
static int rap__read(RIO *io, RIODesc *fd, ut8 *buf, int count) {
	RSocket *s = RIORAP_FD (fd);
	int ret, i = (int)count;
	ut8 tmp[5];

	// XXX. if count is > RMT_MAX, just perform multiple queries
	if (count > RMT_MAX) {
		count = RMT_MAX;
	}
	// send
	tmp[0] = RMT_READ;
	r_write_be32 (tmp + 1, count);
	r_socket_write (s, tmp, 5);
	r_socket_flush (s);
	// recv
	ret = r_socket_read_block (s, tmp, 5);
	if (ret != 5 || tmp[0] != (RMT_READ | RMT_REPLY)) {
		eprintf ("rap__read: Unexpected rap read reply "
			"(%d=0x%02x) expected (%d=0x%02x)\n",
			ret, tmp[0], 2, (RMT_READ | RMT_REPLY));
		return -1;
	}
	i = r_read_at_be32 (tmp, 1);
	if (i >count) {
		eprintf ("rap__read: Unexpected data size %d\n", i);
		return -1;
	}
	r_socket_read_block (s, buf, i);
	return count;
}
Beispiel #9
0
static int haret__system(RIO *io, RIODesc *fd, const char *command) {
	char buf;
	int off = 0;

	r_socket_write (HARET_FD (fd), (char *)command, strlen(command));
	r_socket_write (HARET_FD (fd), "\r\n", 2);
	for (;;) {
		r_socket_read_block (HARET_FD (fd), (unsigned char *)&buf, 1);
		eprintf ("%c", buf);
		switch(off) {
		case 0: if (buf == ')') off =1; break;
		case 1: if (buf == '#') return 0; else off = 0; break;
		}
	}

	return 0;
}
Beispiel #10
0
R_API void r_core_rtr_cmd(RCore *core, const char *input) {
	char bufw[1024], bufr[8];
	const char *cmd = NULL, *cmd_output = NULL;
	int i, cmd_len, fd = atoi (input);

	if (*input==':' && !strchr (input+1, ':')) {
		r_core_cmdf (core, "o rap://%s", input);
		return;
	}
	if (fd != 0) {
		if (rtr_host[rtr_n].fd)
			for (rtr_n = 0; rtr_host[rtr_n].fd->fd != fd
				&& rtr_n < RTR_MAX_HOSTS - 1; rtr_n++);
		if (!(cmd = strchr (input, ' '))) {
			eprintf ("Error\n");
			return;
		}
	} else cmd = input;

	if (!rtr_host[rtr_n].fd){
		eprintf ("Error: Unknown host\n");
		core->num->value = 1; // fail
		return;
	}

	if (!rtr_host[rtr_n].proto == RTR_PROT_RAP){
		eprintf ("Error: Not a rap:// host\n");
		return;
	}

	core->num->value = 0; // that's fine
	if (!strlen (cmd)) {
		// just check if we can connect
		r_socket_close (rtr_host[rtr_n].fd);
		return;
	}
	/* send */
	bufw[0] = RTR_RAP_CMD;
	i = strlen (cmd) + 1;
	r_mem_copyendian ((ut8*)bufw+1, (ut8*)&i, 4, endian);
	memcpy (bufw+5, cmd, i);
	r_socket_write (rtr_host[rtr_n].fd, bufw, 5+i);
	/* read */
	r_socket_read (rtr_host[rtr_n].fd, (ut8*)bufr, 5);
	if (bufr[0] != (char)(RTR_RAP_CMD|RTR_RAP_REPLY)) {
		eprintf ("Error: Wrong reply\n");
		return;
	}
	r_mem_copyendian ((ut8*)&cmd_len, (ut8*)bufr+1, 4, endian);
	cmd_output = malloc (cmd_len);
	if (!cmd_output) {
		eprintf ("Error: Allocating cmd output\n");
		return;
	}
	r_socket_read (rtr_host[rtr_n].fd, (ut8*)cmd_output, cmd_len);
	r_cons_printf ("%s\n", cmd_output);
	free ((void *)cmd_output);
}
Beispiel #11
0
static int rap__system(RIO *io, RIODesc *fd, const char *command) {
	RSocket *s = RIORAP_FD (fd);
	ut8 buf[RMT_MAX];
	char *ptr;
	int op, ret, i, j = 0;

	// send
	if (*command=='!') {
		op = RMT_SYSTEM;
		command++;
	} else
		op = RMT_CMD;
	buf[0] = op;
	i = strlen (command)+1;
	if (i>RMT_MAX) {
		eprintf ("Command too long\n");
		return -1;
	}
	r_mem_copyendian (buf+1, (ut8*)&i, 4, ENDIAN);
	memcpy (buf+5, command, i);
	r_socket_write (s, buf, i+5);
	r_socket_flush (s);

	// read
	ret = r_socket_read_block (s, buf, 5);
	if (ret != 5)
		return -1;
	if (buf[0] != (op | RMT_REPLY)) {
		eprintf ("Unexpected system reply\n");
		return -1;
	}
	r_mem_copyendian ((ut8*)&i, buf+1, 4, ENDIAN);
	if (i == -1)
		return -1;
	ret = 0;
	ptr = (char *)malloc (i);
	if (ptr) {
		int ir, tr = 0;
		do {
			ir = r_socket_read_block (s, (ut8*)ptr+tr, i-tr);
			if (ir>0) tr += ir;
			else break;
		} while (tr<i);
		// TODO: use io->printf() with support for \x00
		ptr[i] = 0;
		if (io->printf) {
			io->printf ("%s", ptr);
			j = i;
		} else j = write (1, ptr, i);
		free (ptr);
	}
	/* Clean */
	if (ret > 0) {
		ret -= r_socket_read (s, (ut8*)buf, RMT_MAX);
	}
	return i-j;
}
Beispiel #12
0
R_API void r_socket_printf(RSocket *s, const char *fmt, ...) {
	char buf[BUFFER_SIZE];
	va_list ap;
	if (s->fd >= 0) {
		va_start (ap, fmt);
		vsnprintf (buf, BUFFER_SIZE, fmt, ap);
		r_socket_write (s, buf, strlen(buf));
		va_end (ap);
	}
}
Beispiel #13
0
R_API void r_core_rtr_cmd(RCore *core, const char *input) {
	char bufw[1024], bufr[8];
	const char *cmd = NULL, *cmd_output = NULL;
	int i, cmd_len, fd = atoi (input);

	if (fd != 0) {
		if (rtr_host[rtr_n].fd)
			for (rtr_n = 0; rtr_host[rtr_n].fd->fd != fd
				&& rtr_n < RTR_MAX_HOSTS; rtr_n++);
		if (!(cmd = strchr (input, ' '))) {
			eprintf ("Error\n");
			return;
		}
	} else cmd = input;

	if (!rtr_host[rtr_n].fd){
		eprintf ("Error: Unknown host\n");
		return;
	}

	if (!rtr_host[rtr_n].proto == RTR_PROT_RAP){
		eprintf ("Error: Not a rap:// host\n");
		return;
	}

	/* send */
	bufw[0] = RTR_RAP_CMD;
	i = strlen (cmd) + 1;
	r_mem_copyendian ((ut8*)bufw+1, (ut8*)&i, 4, endian);
	memcpy (bufw+5, cmd, i);
	r_socket_write (rtr_host[rtr_n].fd, bufw, 5+i);
	/* read */
	r_socket_read (rtr_host[rtr_n].fd, (ut8*)bufr, 5);
	if (bufr[0] != (char)(RTR_RAP_CMD|RTR_RAP_REPLY)) {
		eprintf ("Error: Wrong reply\n");
		return;
	}
	r_mem_copyendian ((ut8*)&cmd_len, (ut8*)bufr+1, 4, endian);
	if (i == 0)
		return;
	if (i < 0) {
		eprintf ("Error: cmd length < 0\n");
		return;
	}
	cmd_output = malloc (cmd_len);
	if (!cmd_output) {
		eprintf ("Error: Allocating cmd output\n");
		return;
	}
	r_socket_read (rtr_host[rtr_n].fd, (ut8*)cmd_output, cmd_len);
	r_cons_printf ("%s\n", cmd_output);
	free ((void *)cmd_output);
}
Beispiel #14
0
R_API void r_socket_proc_printf (RSocketProc *sp, const char *fmt, ...) {
	RSocket s;
	char buf[BUFFER_SIZE];
	va_list ap;
	s.is_ssl = false;
	s.fd = sp->fd0[1];
	if (s.fd >= 0) {
		va_start (ap, fmt);
		vsnprintf (buf, BUFFER_SIZE, fmt, ap);
		r_socket_write (&s, buf, strlen(buf));
		va_end (ap);
	}
}
Beispiel #15
0
static int rap__system(RIO *io, RIODesc *fd, const char *command) {
	RSocket *s = RIORAP_FD (fd);
	ut8 buf[RMT_MAX];
	char *ptr;
	int op, ret, i, j = 0;

	// send
	if (*command=='!') {
		op = RMT_SYSTEM;
		command++;
	} else
		op = RMT_CMD;
	buf[0] = op;
	i = strlen (command);
	if (i>RMT_MAX) {
		eprintf ("Command too long\n");
		return -1;
	}
	r_mem_copyendian (buf+1, (ut8*)&i, 4, ENDIAN);
	memcpy (buf+5, command, i);
	r_socket_write (s, buf, i+5);
	r_socket_flush (s);

	// read
	ret = r_socket_read_block (s, buf, 5);
	if (ret != 5)
		return -1;
	if (buf[0] != (op | RMT_REPLY)) {
		eprintf ("Unexpected system reply\n");
		return -1;
	}
	r_mem_copyendian ((ut8*)&i, buf+1, 4, ENDIAN);
	if (i == -1)
		return -1;
	ret = 0;
	if (i>RMT_MAX) {
		ret = i-RMT_MAX;
		i = RMT_MAX;
	}
	ptr = (char *)malloc (i);
	if (ptr) {
		r_socket_read_block (s, (ut8*)ptr, i);
		j = write (1, ptr, i);
		free (ptr);
	}
	/* Clean */
	if (ret > 0) {
		ret -= r_socket_read (s, (ut8*)buf, RMT_MAX);
	}
	return i-j;
}
Beispiel #16
0
R_API void r_socket_http_response (RSocketHTTPRequest *rs, int code, const char *out, int len, const char *headers) {
	const char *strcode = \
		code==200?"ok":
		code==301?"moved permanently":
		code==302?"Found":
		code==404?"not found":
		"UNKNOWN";
	if (len<1) len = out? strlen (out): 0;
	if (!headers) headers = "";
	r_socket_printf (rs->s, "HTTP/1.0 %d %s\r\n%s"
		"Connection: close\r\nContent-Length: %d\r\n\r\n",
		code, strcode, headers, len);
	if (out && len>0) r_socket_write (rs->s, (void*)out, len);
}
Beispiel #17
0
R_API char *r_socket_http_post (const char *url, const char *data, int *code, int *rlen) {
	RSocket *s;
	int ssl = !memcmp (url, "https://", 8);
	char *response, *host, *path, *port = "80";
	char *uri = strdup (url);
	if (!uri) return NULL;

	host = strstr (uri, "://");
	if (!host) {
		free (uri);
		printf ("Invalid URI");
		return NULL;
	}
	host += 3;
	port = strchr (host, ':');
	if (!port)
		port = (ssl)?"443":"80";
	else
		*port++ = 0;
	path = strchr (host, '/');
	if (!path)
		path = "";
	else
		*path++ = 0;
	s = r_socket_new (ssl);
	if (!s) {
		printf ("Cannot create socket\n");
		free (uri);
		return NULL;
	}
	if (!r_socket_connect_tcp (s, host, port, 0)) {
		eprintf ("Cannot connect to %s:%s\n", host, port);
		free (uri);
		return NULL;
	}
	/* Send */
	r_socket_printf (s,
			"POST /%s HTTP/1.0\r\n"
			"User-Agent: radare2 "R2_VERSION"\r\n"
			"Accept: */*\r\n"
			"Host: %s\r\n"
			"Content-Length: %i\r\n"
			"Content-Type: application/x-www-form-urlencoded\r\n"
			"\r\n", path, host, strlen (data));
	r_socket_write (s, (void *)data, strlen (data));
	response = r_socket_http_answer (s, code, rlen);
	free (uri);
	return response;
}
Beispiel #18
0
static ut64 rap__lseek(struct r_io_t *io, RIODesc *fd, ut64 offset, int whence) {
	RSocket *s = RIORAP_FD (fd);
	int ret;
	ut8 tmp[10];
	// query
	tmp[0] = RMT_SEEK;
	tmp[1] = (ut8)whence;
	r_mem_copyendian (tmp+2, (ut8*)&offset, 8, ENDIAN);
	r_socket_write (s, &tmp, 10);
	r_socket_flush (s);
	// get reply
	ret = r_socket_read_block (s, (ut8*)&tmp, 9);
	if (ret!=9)
		return -1;
	if (tmp[0] != (RMT_SEEK | RMT_REPLY)) {
		eprintf ("Unexpected lseek reply\n");
		return -1;
	}
	r_mem_copyendian ((ut8 *)&offset, tmp+1, 8, !ENDIAN);
	return offset;
}
Beispiel #19
0
static ut64 rap__lseek(RIO *io, RIODesc *fd, ut64 offset, int whence) {
	RSocket *s = RIORAP_FD (fd);
	ut8 tmp[10];
	int ret;
	// query
	tmp[0] = RMT_SEEK;
	tmp[1] = (ut8)whence;
	r_write_be64 (tmp + 2, offset);
	r_socket_write (s, &tmp, 10);
	r_socket_flush (s);
	// get reply
	memset (tmp, 0, 9);
	ret = r_socket_read_block (s, (ut8*)&tmp, 9);
	if (ret != 9 || tmp[0] != (RMT_SEEK | RMT_REPLY)) {
		// eprintf ("%d %d  - %02x %02x %02x %02x %02x %02x %02x\n", 
		// ret, whence, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6]);
		eprintf ("Unexpected lseek reply\n");
		return -1;
	}
	offset = r_read_at_be64 (tmp, 1);
	return offset;
}
Beispiel #20
0
static int rap__write(struct r_io_t *io, RIODesc *fd, const ut8 *buf, int count) {
	RSocket *s = RIORAP_FD (fd);
	int ret;
	ut8 *tmp;
	if (count>RMT_MAX)
		count = RMT_MAX;
	if (!(tmp = (ut8 *)malloc (count+5))) {
		eprintf ("rap__write: malloc failed\n");
		return -1;
	}
	tmp[0] = RMT_WRITE;
	r_mem_copyendian ((ut8 *)tmp+1, (ut8*)&count, 4, ENDIAN);
	memcpy (tmp+5, buf, count);

	ret = r_socket_write (s, tmp, count+5);
	r_socket_flush (s);
	if (r_socket_read (s, tmp, 5) != 5) { // TODO read_block?
		eprintf ("rap__write: error\n");
		ret = -1;
	}
	free (tmp);
	// TODO: get reply
	return ret;
}
Beispiel #21
0
static RIODesc *rap__open(RIO *io, const char *pathname, int rw, int mode) {
	int i, p, listenmode;
	char *file, *port;
	const char *ptr;
	RSocket *rap_fd;
	char buf[1024];
	RIORap *rior;

	if (!rap__plugin_open (io, pathname, 0)) {
		return NULL;
	}
	bool is_ssl = (!strncmp (pathname, "raps://", 7));
	ptr = pathname + (is_ssl? 7: 6);
	if (!(port = strchr (ptr, ':'))) {
		eprintf ("rap: wrong uri\n");
		return NULL;
	}
	listenmode = (*ptr == ':');
	*port++ = 0;
	if (!*port) {
		return NULL;
	}
	p = atoi (port);
	if ((file = strchr (port + 1, '/'))) {
		*file = 0;
		file++;
	}
	if (r_sandbox_enable (0)) {
		eprintf ("sandbox: Cannot use network\n");
		return NULL;
	}
	if (listenmode) {
		if (p <= 0) {
			eprintf ("rap: cannot listen here. Try rap://:9999\n");
			return NULL;
		}
		//TODO: Handle ^C signal (SIGINT, exit); // ???
		eprintf ("rap: listening at port %s ssl %s\n", port, (is_ssl)?"on":"off");
		rior = R_NEW0 (RIORap);
		rior->listener = true;
		rior->client = rior->fd = r_socket_new (is_ssl);
		if (!rior->fd) {
			free (rior);
			return NULL;
		}
		if (is_ssl) {
			if (file && *file) {
				if (!r_socket_listen (rior->fd, port, file)) {
					free (rior);
					return NULL;
				}
			} else {
				free (rior);
				return NULL;
			}
		} else {
			if (!r_socket_listen (rior->fd, port, NULL)) {
				return NULL;
			}
		}
		return r_io_desc_new (&r_io_plugin_rap, rior->fd->fd,
			pathname, rw, mode, rior);
	}
	if (!(rap_fd = r_socket_new (is_ssl))) {
		eprintf ("Cannot create new socket\n");
		return NULL;
	}
	if (r_socket_connect_tcp (rap_fd, ptr, port, 30) == false) {
		eprintf ("Cannot connect to '%s' (%d)\n", ptr, p);
		r_socket_free (rap_fd);
		return NULL;
	}
	eprintf ("Connected to: %s at port %s\n", ptr, port);
	rior = R_NEW0 (RIORap);
	rior->listener = false;
	rior->client = rior->fd = rap_fd;
	if (file && *file) {
		// send
		buf[0] = RMT_OPEN;
		buf[1] = rw;
		buf[2] = (ut8)strlen (file);
		memcpy (buf + 3, file, buf[2]);
		r_socket_write (rap_fd, buf, buf[2] + 3);
		r_socket_flush (rap_fd);
		// read
		eprintf ("waiting... ");
		buf[0] = 0;
		r_socket_read_block (rap_fd, (ut8*)buf, 5);
		if (buf[0] != (char)(RMT_OPEN | RMT_REPLY)) {
			eprintf ("rap: Expecting OPEN|REPLY packet. got %02x\n", buf[0]);
			r_socket_free (rap_fd);
			free (rior);
			return NULL;
		}
		i = r_read_at_be32 (buf, 1);
		if (i > 0) {
			eprintf ("ok\n");
		}
#if 0
		/* Read meta info */
		r_socket_read (rap_fd, (ut8 *)&buf, 4);
		r_mem_copyendian ((ut8 *)&i, (ut8*)buf, 4, ENDIAN);
		while (i>0) {
			int n = r_socket_read (rap_fd, (ut8 *)&buf, i);
			if (n<1) break;
			buf[i] = 0;
			io->core_cmd_cb (io->user, buf);
			n = r_socket_read (rap_fd, (ut8 *)&buf, 4);
			if (n<1) break;
			r_mem_copyendian ((ut8 *)&i, (ut8*)buf, 4, ENDIAN);
			i -= n;
		}
#endif
	} else {
	//	r_socket_free (rap_fd);
	//	free (rior);
		//return NULL;
	}
	//r_socket_free (rap_fd);
	return r_io_desc_new (&r_io_plugin_rap, rior->fd->fd,
		pathname, rw, mode, rior);
}
Beispiel #22
0
/* TODO: simplify using r_write */
static int cmd_write(void *data, const char *input) {
	int wseek, i, size, len;
	RCore *core = (RCore *)data;
	char *tmp, *str, *ostr;
	const char *arg, *filename = "";
	char _fn[32];
	ut64 off;
	ut8 *buf;
	st64 num = 0;
	const char* help_msg[] = {
		"Usage:","w[x] [str] [<file] [<<EOF] [@addr]","",
		"w","[1248][+-][n]","increment/decrement byte,word..",
		"w"," foobar","write string 'foobar'",
		"w0"," [len]","write 'len' bytes with value 0x00",
		"w6","[de] base64/hex","write base64 [d]ecoded or [e]ncoded string",
		"wa","[?] push ebp","write opcode, separated by ';' (use '\"' around the command)",
		"waf"," file","assemble file and write bytes",
		"wao"," [?] op","modify opcode (change conditional of jump. nop, etc)",
		"wA"," [?] r 0","alter/modify opcode at current seek (see wA?)",
		"wb"," 010203","fill current block with cyclic hexpairs",
		"wB","[-]0xVALUE","set or unset bits with given value",
		"wc","","list all write changes",
		"wc","[?][ir*?]","write cache undo/commit/reset/list (io.cache)",
		"wd"," [off] [n]","duplicate N bytes from offset at current seek (memcpy) (see y?)",
		"we","[?] [nNsxX] [arg]","extend write operations (insert instead of replace)",
		"wf"," -|file","write contents of file at current offset",
		"wh"," r2","whereis/which shell command",
		"wm"," f0ff","set binary mask hexpair to be used as cyclic write mask",
		"wo","[?] hex","write in block with operation. 'wo?' fmi",
		"wp"," [?] -|file","apply radare patch file. See wp? fmi",
		"wr"," 10","write 10 random bytes",
		"ws"," pstring","write 1 byte for length and then the string",
		"wt[f]"," [?] file [sz]","write to file (from current seek, blocksize or sz bytes)",
		"wts"," host:port [sz]", "send data to remote host:port via tcp://",
		"ww"," foobar","write wide string 'f\\x00o\\x00o\\x00b\\x00a\\x00r\\x00'",
		"wx","[?][fs] 9090","write two intel nops (from wxfile or wxseek)",
		"wv","[?] eip+34","write 32-64 bit value",
		"wz"," string","write zero terminated string (like w + \\x00)",
		NULL
	};

	if (!input) {
		return 0;
	}

	len = strlen (input);
	wseek = r_config_get_i (core->config, "cfg.wseek");
	str = ostr = strdup (*input? input + 1: "");
	_fn[0] = 0;

	switch (*input) {
	case 'B':
		switch (input[1]) {
		case ' ':
			cmd_write_bits (core, 1, r_num_math (core->num, input + 2));
			break;
		case '-':
			cmd_write_bits (core, 0, r_num_math (core->num, input + 2));
			break;
		default:
			eprintf ("Usage: wB 0x2000  # or wB-0x2000\n");
			break;
		}
		break;
	case '0':
		{
			ut64 len = r_num_math (core->num, input+1);
			if (len>0) {
				ut8 *buf = calloc (1, len);
				if (buf) {
					r_io_write_at (core->io, core->offset, buf, len);
					r_core_block_read (core);
					free (buf);
				} else eprintf ("Cannot allocate %d bytes\n", (int)len);
			}
		}
		break;
	case '1':
	case '2':
	case '4':
	case '8':
		if (input[1] && input[2]) {
			if (input[1]==input[2]) {
				num = 1;
			} else num = r_num_math (core->num, input+2);
		}
		switch (input[2] ? input[1] : 0) {
		case '+':
			cmd_write_inc (core, *input-'0', num);
			break;
		case '-':
			cmd_write_inc (core, *input-'0', -num);
			break;
		default:
			eprintf ("Usage: w[1248][+-][num]   # inc/dec byte/word/..\n");
		}
		break;
	case '6':
		{
		int fail = 0;
		ut8 *buf = NULL;
		int len = 0, str_len;
		const char *str;

		if (input[1] && input[2] != ' ')
			fail = 1;

		if (input[1] && input[2] && input[3])
			str = input + 3;
		else
			str = "";
		str_len = strlen (str) + 1;
		if (!fail) {
			switch (input[1]) {
			case 'd':
				buf = malloc (str_len);
				len = r_base64_decode (buf, str, 0);
				if(len == 0) {
					free(buf);
					fail = 1;
				}
				break;
			case 'e':
				{
				ut8 *bin_buf = malloc (str_len);
				const int bin_len = r_hex_str2bin (str, bin_buf);
				if (bin_len <= 0) {
					fail = 1;
				} else {
					buf = calloc (str_len + 1, 4);
					len = r_base64_encode ((char *)buf, bin_buf, bin_len);
					if(len == 0) {
						free (buf);
						fail = 1;
					}
				}
				free (bin_buf);
				break;
				}
			default:
				fail = 1;
				break;
			}
		}
		if (!fail) {
			r_core_write_at (core, core->offset, buf, len);
			WSEEK (core, len);
			r_core_block_read (core);
			free (buf);
		} else {
			eprintf ("Usage: w6[de] base64/hex\n");
		}
		break;
		}
	case 'h':
		{
		char *p = strchr (input, ' ');
		if (p) {
			while (*p==' ') p++;
			p = r_file_path (p);
			if (p) {
				r_cons_println (p);
				free (p);
			}
		}
		}
		break;
	case 'e':
		{
		ut64 addr = 0, len = 0, b_size = 0;
		st64 dist = 0;
		ut8* bytes = NULL;
		int cmd_suc = false;
		char *input_shadow = NULL, *p = NULL;

		switch (input[1]) {
		case 'n':
			if (input[2] == ' ') {
				len = *input ? r_num_math (core->num, input+3) : 0;
				if (len > 0) {
					const ut64 cur_off = core->offset;
					cmd_suc = r_core_extend_at (core, core->offset, len);
					core->offset = cur_off;
					r_core_block_read (core);
				}
			}
			break;
		case 'N':
			if (input[2] == ' ') {
				input += 3;
				while (*input && *input == ' ') input++;
				addr = r_num_math (core->num, input);
				while (*input && *input != ' ') input++;
				input++;
				len = *input ? r_num_math (core->num, input) : 0;
				if (len > 0){
					ut64 cur_off = core->offset;
					cmd_suc = r_core_extend_at (core, addr, len);
					cmd_suc = r_core_seek (core, cur_off, 1);
					core->offset = addr;
					r_core_block_read (core);
				}
			}
			break;
		case 'x':
			if (input[2] == ' ') {
				input += 2;
				len = *input ? strlen (input) : 0;
				bytes = len > 1? malloc (len+1) : NULL;
				len = bytes ? r_hex_str2bin (input, bytes) : 0;
				if (len > 0) {
					ut64 cur_off = core->offset;
					cmd_suc = r_core_extend_at (core, cur_off, len);
					if (cmd_suc) {
						r_core_write_at (core, cur_off, bytes, len);
					}
					core->offset = cur_off;
					r_core_block_read (core);
				}
				free (bytes);
			}
			break;
		case 'X':
			if (input[2] == ' ') {
				addr = r_num_math (core->num, input+3);
				input += 3;
				while (*input && *input != ' ') input++;
				input++;
				len = *input ? strlen (input) : 0;
				bytes = len > 1? malloc (len+1) : NULL;
				len = bytes ? r_hex_str2bin (input, bytes) : 0;
				if (len > 0) {
					//ut64 cur_off = core->offset;
					cmd_suc = r_core_extend_at (core, addr, len);
					if (cmd_suc) {
						r_core_write_at (core, addr, bytes, len);
					}
					core->offset = addr;
					r_core_block_read (core);
				}
				free (bytes);
			}
			break;
		case 's':
			input +=  3;
			while (*input && *input == ' ') input++;
			len = strlen (input);
			input_shadow = len > 0? malloc (len+1): 0;

			// since the distance can be negative,
			// the r_num_math will perform an unwanted operation
			// the solution is to tokenize the string :/
			if (input_shadow) {
				strncpy (input_shadow, input, len+1);
				p = strtok (input_shadow, " ");
				addr = p && *p ? r_num_math (core->num, p) : 0;

				p = strtok (NULL, " ");
				dist = p && *p ? r_num_math (core->num, p) : 0;

				p = strtok (NULL, " ");
				b_size = p && *p ? r_num_math (core->num, p) : 0;
				if (dist != 0){
					r_core_shift_block (core, addr, b_size, dist);
					r_core_seek (core, addr, 1);
					cmd_suc = true;
				}
			}
			free (input_shadow);
			break;
		case '?':
		default:
			cmd_suc = false;
		}


		if (cmd_suc == false) {
			const char* help_msg[] = {
			"Usage", "", "write extend",
			"wen", " <num>", "insert num null bytes at current offset",
			"wex", " <hex_bytes>", "insert bytes at current offset",
			"weN", " <addr> <len>", "insert bytes at address",
			"weX", " <addr> <hex_bytes>", "insert bytes at address",
			"wes", " <addr>  <dist> <block_size>", "shift a blocksize left or write in the editor",
			NULL};
			r_core_cmd_help (core, help_msg);
		}
		}
		break;
	case 'p':
		if (input[1]=='-' || (input[1]==' ' && input[2]=='-')) {
			char *out = r_core_editor (core, NULL, NULL);
			if (out) {
				r_core_patch (core, out);
				free (out);
			}
		} else {
			if (input[1]==' ' && input[2]) {
				char *data = r_file_slurp (input+2, NULL);
				if (data) {
					r_core_patch (core, data);
					free (data);
				}
			} else {
				r_cons_printf ("Usage: wp [-|r2patch-file]\n"
					" ^# -> comments\n"
					" . -> execute command\n"
					" ! -> execute command\n"
					" OFFSET { code block }\n"
					" OFFSET \"string\"\n"
					" OFFSET 01020304\n"
					" OFFSET : assembly\n"
					" + {code}|\"str\"|0210|: asm\n");
			}
		}
		break;
	case 'u':
		// TODO: implement it in an API RCore.write_unified_hexpatch() is ETOOLONG
		if (input[1]==' ') {
			char *data = r_file_slurp (input+2, NULL);
			if (data) {
				char sign = ' ';
				int line = 0, offs = 0, hexa = 0;
				int newline = 1;
				for (i=0; data[i]; i++) {
					switch (data[i]) {
					case '+':
						if (newline)
							sign = 1;
						break;
					case '-':
						if (newline) {
							sign = 0;
							offs = i + ((data[i+1]==' ')?2:1);
						}
						break;
					case ' ':
						data[i] = 0;
						if (sign) {
							if (!line) line = i+1;
							else
							if (!hexa) hexa = i+1;
						}
						break;
					case '\r':
						break;
					case '\n':
						newline = 1;
						if (sign == -1) {
							offs = 0;
							line = 0;
							hexa = 0;
						} else if (sign) {
							if (offs && hexa) {
								r_cons_printf ("wx %s @ %s\n", data+hexa, data+offs);
							} else eprintf ("food\n");
							offs = 0;
							line = 0;
						} else hexa = 0;
						sign = -1;
						continue;
					}
					newline = 0;
				}
				free (data);
			}
		} else {
			eprintf ("|Usage: wu [unified-diff-patch]    # see 'cu'\n");
		}
		break;
	case 'r': //wr
		off = r_num_math (core->num, input+1);
		len = (int)off;
		if (len > 0) {
			buf = malloc (len);
			if (buf != NULL) {
				r_num_irand ();
				for (i=0; i<len; i++)
					buf[i] = r_num_rand (256);
				r_core_write_at (core, core->offset, buf, len);
				WSEEK (core, len);
				free (buf);
			} else eprintf ("Cannot allocate %d bytes\n", len);
		}
		break;
	case 'A':
		switch (input[1]) {
		case ' ':
			if (input[2] && input[3]==' ') {
				r_asm_set_pc (core->assembler, core->offset);
				eprintf ("modify (%c)=%s\n", input[2], input+4);
				len = r_asm_modify (core->assembler, core->block, input[2],
					r_num_math (core->num, input+4));
				eprintf ("len=%d\n", len);
				if (len>0) {
					r_core_write_at (core, core->offset, core->block, len);
					WSEEK (core, len);
				} else eprintf ("r_asm_modify = %d\n", len);
			} else eprintf ("Usage: wA [type] [value]\n");
			break;
		case '?':
		default:
			{
			const char* help_msg[] = {
				"Usage:", " wA", "[type] [value]",
				"Types", "", "",
				"r", "", "raw write value",
				"v", "", "set value (taking care of current address)",
				"d", "", "destination register",
				"0", "", "1st src register",
				"1", "", "2nd src register",
				"Example:",  "wA r 0", "# e800000000",
				NULL};
			r_core_cmd_help (core, help_msg);
			break;
			}
		}
		break;
	case 'c':
		switch (input[1]) {
		case 'i':
			r_io_cache_commit (core->io, 0, UT64_MAX);
			r_core_block_read (core);
			break;
		case 'r':
			r_io_cache_reset (core->io, true);
			/* Before loading the core block we have to make sure that if
			 * the cache wrote past the original EOF these changes are no
			 * longer displayed. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core);
			break;
		case '+':
			if (input[2]=='*') {
				//r_io_cache_reset (core->io, true);
				eprintf ("TODO\n");
			} else if (input[2]==' ') {
				char *p = strchr (input+3, ' ');
				ut64 to, from;
				from = r_num_math (core->num, input+3);
				if (p) {
					*p = 0;
					to = r_num_math (core->num, input+3);
					if (to<from) {
						eprintf ("Invalid range (from>to)\n");
						return 0;
					}
				} else {
					to = from + core->blocksize;
				}
				r_io_cache_commit (core->io, from, to);
			} else {
				eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
				r_io_cache_commit (core->io, core->offset, core->offset+1);
			}
			break;
		case '-':
			if (input[2]=='*') {
				r_io_cache_reset (core->io, true);
			} else if (input[2]==' ') {
				char *p = strchr (input+3, ' ');
				ut64 to, from;
				if (p) {
					*p = 0;
					from = r_num_math (core->num, input+3);
					to = r_num_math (core->num, input+3);
					if (to<from) {
						eprintf ("Invalid range (from>to)\n");
						return 0;
					}
				} else {
					from = r_num_math (core->num, input+3);
					to = from + core->blocksize;
				}
				r_io_cache_invalidate (core->io, from, to);
			} else {
				eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
				r_io_cache_invalidate (core->io, core->offset, core->offset+core->blocksize);
			}
			/* See 'r' above. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core);
			break;
		case '?':
			{
				const char* help_msg[] = {
					"Usage:", "wc[ir+-*?]","  # NOTE: Uses io.cache=true",
					"wc","","list all write changes",
					"wc-"," [from] [to]","remove write op at curseek or given addr",
					"wc+"," [addr]","commit change from cache to io",
					"wc*","","\"\" in radare commands",
					"wcr","","reset all write changes in cache",
					"wci","","commit write cache",
					NULL
				};
				r_core_cmd_help (core, help_msg);
			}
			break;
		case '*':
			r_io_cache_list (core->io, 1);
			break;
		case 'j':
			r_io_cache_list (core->io, 2);
			break;
		case '\0':
			//if (!r_config_get_i (core->config, "io.cache"))
			//	eprintf ("[warning] e io.cache must be true\n");
			r_io_cache_list (core->io, 0);
			break;
		}
		break;
	case ' ': // "w"
		/* write string */
		len = r_str_unescape (str);
		r_core_write_at (core, core->offset, (const ut8*)str, len);
#if 0
		r_io_use_desc (core->io, core->file->desc);
		r_io_write_at (core->io, core->offset, (const ut8*)str, len);
#endif
		WSEEK (core, len);
		r_core_block_read (core);
		break;
	case 'z': // "wz"
		/* write zero-terminated string */
		len = r_str_unescape (str);
		r_core_write_at (core, core->offset, (const ut8*)str + 1, len);
		if (len > 0) {
			core->num->value = len;
		} else {
			core->num->value = 0;
		}
#if 0
		r_io_use_desc (core->io, core->file->desc);
#endif
		WSEEK (core, len + 1);
		r_core_block_read (core);
		break;
	case 't': // "wt"
		if (*str == 's') { // "wts"
			if (str[1] == ' ') {
				eprintf ("Write to server\n");
				st64 sz = r_io_size (core->io);
				if (sz > 0) {
					ut64 addr = 0;
					char *host = str + 2;
					char *port = strchr (host, ':');
					if (port) {
						*port ++= 0;
						char *space = strchr (port, ' ');
						if (space) {
							*space++ = 0;
							sz = r_num_math (core->num, space);
							addr = core->offset;
						}
						ut8 *buf = calloc (1, sz);
						r_io_read_at (core->io, addr, buf, sz);
						RSocket *s = r_socket_new (false);
						if (r_socket_connect (s, host, port, R_SOCKET_PROTO_TCP, 0)) {
							int done = 0;
							eprintf ("Transfering file to the end-point...\n");
							while (done < sz) {
								int rc = r_socket_write (s, buf + done, sz - done);
								if (rc <1) {
									eprintf ("oops\n");
									break;
								}
								done += rc;
							}
						} else {
							eprintf ("Cannot connect\n");
						}
						r_socket_free (s);
						free (buf);
					} else {
						eprintf ("Usage wts host:port [sz]\n");
					}
				} else {
					eprintf ("Unknown file size\n");
				}
			} else {
				eprintf ("Usage wts host:port [sz]\n");
			}
		} else if (*str == '?' || *str == '\0') {
			const char* help_msg[] = {
				"Usage:", "wt[a] file [size]", " Write 'size' bytes in current blok to 'file'",
				"wta", " [filename]", "append to 'filename'",
				"wtf", " [filename] [size]", "write to file (see also 'wxf' and 'wf?')",
				"wtf!", " [filename]", "write to file from current addresss to eof",
				NULL};
			r_core_cmd_help (core, help_msg);
			free (ostr);
			return 0;
		} else {
			bool append = false;
			bool toend = false;
			st64 sz = core->blocksize;
			if (*str == 'f') { // "wtf"
				str++;
				if (*str == '!') {
					toend = true;
					str++;
				}
				if (*str) {
					filename = str + ((*str == ' ')? 1: 0);
				} else {
					filename = "";
				}
			} else if (*str=='a') { // "wta"
				append = 1;
				str++;
				if (str[0] == ' ') {
					filename = str + 1;
				} else {
					const char* prefix = r_config_get (core->config, "cfg.prefixdump");
					snprintf (_fn, sizeof (_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
					filename = _fn;
				}
			} else if (*str != ' ') {
				const char* prefix = r_config_get (core->config, "cfg.prefixdump");
				snprintf (_fn, sizeof (_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
				filename = _fn;
			} else {
				filename = str + 1;
			}
			tmp = strchr (str + 1, ' ');
			if (!filename || !*filename) {
				const char* prefix = r_config_get (core->config, "cfg.prefixdump");
				snprintf (_fn, sizeof (_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
				filename = _fn;
			}
			if (tmp) {
				if (toend) {
					sz = r_io_desc_size (core->io, core->file->desc) - core->offset;
				} else {
					sz = (st64) r_num_math (core->num, tmp + 1);
					if (!sz) {
						sz = core->blocksize;
					}
					*tmp = 0;
				}
				if (sz < 1) {
					eprintf ("Invalid length\n");
				} else {
					r_core_dump (core, filename, core->offset, (ut64)sz, append);
				}
			} else {
				if (toend) {
					sz = r_io_desc_size (core->io, core->file->desc) - core->offset;
					r_core_dump (core, filename, core->offset, (ut64)sz, append);
				} else {
					if (!r_file_dump (filename, core->block, core->blocksize, append)) {
						sz = 0;
					} else {
						sz = core->blocksize;
					}
				}
			}
			eprintf ("Dumped %"PFMT64d" bytes from 0x%08"PFMT64x" into %s\n",
				sz, core->offset, filename);
		}
		break;
	case 'f':
		cmd_wf (core, input);
		break;
	case 'w':
		str++;
		len = (len - 1) << 1;
		tmp = (len > 0) ? malloc (len + 1) : NULL;
		if (tmp) {
			for (i=0; i<len; i++) {
				if (i%2) tmp[i] = 0;
				else tmp[i] = str[i>>1];
			}
			str = tmp;
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, (const ut8*)str, len);
			WSEEK (core, len);
			r_core_block_read (core);
			free (tmp);
		} else {
			eprintf ("Cannot malloc %d\n", len);
		}
		break;
	case 'x': // "wx"
		switch (input[1]) {
		case 'f': // "wxf"
			arg = (const char *)(input + ((input[2]==' ')? 3: 2));
			if (!strcmp (arg, "-")) {
				int len;
				ut8 *out;
				char *in = r_core_editor (core, NULL, NULL);
				if (in) {
					out = (ut8 *)strdup (in);
					if (out) {
						len = r_hex_str2bin (in, out);
						if (len > 0) {
							r_io_write_at (core->io, core->offset, out, len);
							core->num->value = len;
						} else {
							core->num->value = 0;
						}
						free (out);
					}
					free (in);
				}
			} else if (r_file_exists (arg)) {
				if ((buf = r_file_slurp_hexpairs (arg, &size))) {
					r_io_use_desc (core->io, core->file->desc);
					if (r_io_write_at (core->io, core->offset, buf, size) > 0) {
						core->num->value = size;
						WSEEK (core, size);
					}
					free (buf);
					r_core_block_read (core);
				} else {
					eprintf ("This file doesnt contains hexpairs\n");
				}
			} else {
				eprintf ("Cannot open file '%s'\n", arg);
			}
			break;
		case 's': // "wxs"
			{
				int len = cmd_write_hexpair (core, input + 2);
				if (len > 0) {
					r_core_seek_delta (core, len);
					core->num->value = len;
				} else {
					core->num->value = 0;
				}
			}
			break;
		case ' ': // "wx ..."
			cmd_write_hexpair (core, input + 1);
			break;
		default:
			{
			const char* help_msg[] = {
				"Usage:", "wx[f] [arg]", "",
				"wx", " 9090", "write two intel nops",
				"wxf", " -|file", "write contents of hexpairs file here",
				"wxs", " 9090", "write hexpairs and seek at the end",
				NULL};
			r_core_cmd_help (core, help_msg);
			break;
			}
		}
		break;
	case 'a': // "wa"
		switch (input[1]) {
		case 'o': // "wao"
			if (input[2] == ' ')
				r_core_hack (core, input+3);
			else r_core_hack_help (core);
			break;
		case ' ':
		case '*':
			{ const char *file = input[1]=='*'? input+2: input+1;
			RAsmCode *acode;
			r_asm_set_pc (core->assembler, core->offset);
			acode = r_asm_massemble (core->assembler, file);
			if (acode) {
				if (input[1]=='*') {
					cmd_write_hexpair(core, acode->buf_hex);
				} else {
					if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s) = wx %s\n", acode->len, input+2, acode->buf_hex);
					r_core_write_at (core, core->offset, acode->buf, acode->len);
					WSEEK (core, acode->len);
					r_core_block_read (core);
				}
				r_asm_code_free (acode);
			}
			} break;
		case 'f': // "wof"
			if ((input[2]==' '||input[2]=='*')) {
				const char *file = input[2]=='*'? input+4: input+3;
				RAsmCode *acode;
				r_asm_set_pc (core->assembler, core->offset);
				acode = r_asm_assemble_file (core->assembler, file);
				if (acode) {
					if (input[2]=='*') {
						cmd_write_hexpair(core, acode->buf_hex);
					} else {
						if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s)=wx %s\n", acode->len, input+1, acode->buf_hex);
						r_core_write_at (core, core->offset, acode->buf, acode->len);
						WSEEK (core, acode->len);
						r_core_block_read (core);
					}
					r_asm_code_free (acode);
				} else eprintf ("Cannot assemble file\n");
			} else eprintf ("Wrong argument\n");
			break;
		default:
			{
			const char* help_msg[] = {
				"Usage:", "wa[of*] [arg]", "",
				"wa", " nop", "write nopcode using asm.arch and asm.bits",
				"wa*", " mov eax, 33", "show 'wx' op with hexpair bytes of assembled opcode",
				"\"wa nop;nop\"", "" , "assemble more than one instruction (note the quotes)",
				"waf", "foo.asm" , "assemble file and write bytes",
				"wao?", "", "show help for assembler operation on current opcode (hack)",
				NULL};
			r_core_cmd_help (core, help_msg);
			break;
			}
		}
		break;
	case 'b': // "wb"
		{
		int len = strlen (input);
		ut8 *buf = malloc (len+1);
		if (buf) {
			len = r_hex_str2bin (input+1, buf);
			if (len > 0) {
				r_mem_copyloop (core->block, buf, core->blocksize, len);
				r_core_write_at (core, core->offset, core->block, core->blocksize);
				WSEEK (core, core->blocksize);
				r_core_block_read (core);
			} else eprintf ("Wrong argument\n");
			free (buf);
		} else eprintf ("Cannot malloc %d\n", len+1);
		}
		break;
	case 'm':
		size = r_hex_str2bin (input+1, (ut8*)str);
		switch (input[1]) {
		case '\0':
			eprintf ("Current write mask: TODO\n");
			// TODO
			break;
		case '?':
			break;
		case '-':
			r_io_set_write_mask (core->io, 0, 0);
			eprintf ("Write mask disabled\n");
			break;
		case ' ':
			if (size>0) {
				r_io_use_desc (core->io, core->file->desc);
				r_io_set_write_mask (core->io, (const ut8*)str, size);
				WSEEK (core, size);
				eprintf ("Write mask set to '");
				for (i=0; i<size; i++)
					eprintf ("%02x", str[i]);
				eprintf ("'\n");
			} else eprintf ("Invalid string\n");
			break;
		}
		break;
	case 'v':
		cmd_write_value (core, input);
		break;
	case 'o':
		cmd_write_op (core, input);
		break;
	case 'd':
		if (input[1] && input[1]==' ') {
			char *arg, *inp = strdup (input+2);
			arg = strchr (inp, ' ');
			if (arg) {
				*arg = 0;
				ut64 addr = r_num_math (core->num, input+2);
				ut64 len = r_num_math (core->num, arg+1);
				ut8 *data = malloc (len);
				r_io_read_at (core->io, addr, data, len);
				r_io_write_at (core->io, core->offset, data, len);
				free (data);
			} else eprintf ("See wd?\n");
			free (inp);
		} else eprintf ("Usage: wd [source-offset] [length] @ [dest-offset]\n");
		break;
	case 's':
		if (str && *str && str[1]) {
			len = r_str_unescape (str+1);
			if (len>255) {
				eprintf ("Too large\n");
			} else {
				ut8 ulen = (ut8)len;
				r_core_write_at (core, core->offset, &ulen, 1);
				r_core_write_at (core, core->offset+1, (const ut8*)str+1, len);
				WSEEK (core, len);
				r_core_block_read (core);
			}
		} else eprintf ("Too short.\n");
		break;
	default:
	case '?':
		if (core->oobi) {
			eprintf ("Writing oobi buffer!\n");
			r_io_use_desc (core->io, core->file->desc);
			r_io_write (core->io, core->oobi, core->oobi_len);
			WSEEK (core, core->oobi_len);
			r_core_block_read (core);
		} else {
			r_core_cmd_help (core, help_msg);
		}
		break;
	}
Beispiel #23
0
R_API void r_core_rtr_add(RCore *core, const char *_input) {
	char *port, input[1024], *host = NULL, *file = NULL, *ptr = NULL, buf[1024];
	int proto, i;
	RSocket *fd;

	strncpy (input, _input, sizeof (input)-4);
	/* Parse uri */
	if ((ptr = strstr(input, "tcp://"))) {
		proto = RTR_PROT_TCP;
		host = ptr+6;
	} else if ((ptr = strstr(input, "udp://"))) {
		proto = RTR_PROT_UDP;
		host = ptr+6;
	} else if ((ptr = strstr(input, "rap://"))) {
		proto = RTR_PROT_RAP;
		host = ptr+6;
	} else {
		proto = RTR_PROT_RAP;
		host = input;
	}
	while (*host&&iswhitechar(*host))
		host++;

	if (!(ptr = strchr (host, ':'))) {
		eprintf ("Error: Port is not specified\n");
		return;
	}
	ptr[0] = '\0';
	ptr = ptr+1;

	if (!(file = strchr (ptr, '/'))) {
		eprintf("Error: Missing '/'\n");
		return;
	}
	file[0] = '\0';
	file = file+1;
	port = ptr;

	fd = r_socket_new (R_FALSE);
	if (!fd) {
		eprintf ("Error: Cannot create new socket\n");
		return;
	}
	switch (proto) {
	case RTR_PROT_RAP:
		if (!r_socket_connect_tcp (fd, host, port)) { //TODO: Use rap.ssl
			eprintf ("Error: Cannot connect to '%s' (%s)\n", host, port);
			return;
		}
		eprintf ("Connected to: %s at port %s\n", host, port);
		/* send */
		buf[0] = RTR_RAP_OPEN;
		buf[1] = 0;
		buf[2] = (ut8)(strlen (file)+1);
		memcpy (buf+3, file, buf[2]);
		r_socket_write(fd, buf, 3+buf[2]);
		/* read */
		eprintf ("waiting... "); fflush(stdout);
		r_socket_read (fd, (ut8*)buf, 5);
		r_mem_copyendian ((ut8 *)&i, (ut8*)buf+1, 4, core->assembler->big_endian);
		if (buf[0] != (char)(RTR_RAP_OPEN|RTR_RAP_REPLY) || i<= 0) {
			eprintf ("Error: Wrong reply\n");
			return;
		}
		eprintf ("ok\n");
		break;
	case RTR_PROT_TCP:
		if (!r_socket_connect_tcp (fd, host, port)) { //TODO: Use rap.ssl
			eprintf("Error: Cannot connect to '%s' (%s)\n", host, port);
			return;
		}
		eprintf ("Connected to: %s at port %s\n", host, port);
		break;
	case RTR_PROT_UDP:
		if (!r_socket_connect_udp(fd, host, port)) { //TODO: Use rap.ssl
			eprintf("Error: Cannot connect to '%s' (%s)\n", host, port);
			return;
		}
		eprintf("Connected to: %s at port %s\n", host, port);
		break;
	}

	for (i = 0; i < RTR_MAX_HOSTS; i++)
		if (!rtr_host[i].fd) {
			rtr_host[i].proto = proto;
			memcpy (rtr_host[i].host, host, 512);
			rtr_host[i].port = atoi(port);
			memcpy (rtr_host[i].file, file, 1024);
			rtr_host[i].fd = fd;
			rtr_n = i;
			break;
		}

	r_core_rtr_list (core);
}
Beispiel #24
0
R_API int r_socket_puts(RSocket *s, char *buf) {
	return r_socket_write (s, buf, strlen (buf));
}
Beispiel #25
0
R_API int r_socket_proc_write (RSocketProc *sp, void *buf, int len) {
	RSocket s;
	s.is_ssl = false;
	s.fd = sp->fd0[1];
	return r_socket_write (&s, buf, len);
}
Beispiel #26
0
static int rap__system(RIO *io, RIODesc *fd, const char *command) {
	RSocket *s = RIORAP_FD (fd);
	ut8 buf[RMT_MAX];
	char *ptr;
	int op, ret;
	unsigned int i, j = 0;

	// send
	if (*command=='!') {
		op = RMT_SYSTEM;
		command++;
	} else {
		op = RMT_CMD;
	}
	buf[0] = op;
	i = strlen (command)+1;
	if (i>RMT_MAX-5) {
		eprintf ("Command too long\n");
		return -1;
	}
	r_mem_copyendian (buf+1, (ut8*)&i, 4, ENDIAN);
	memcpy (buf+5, command, i);
	r_socket_write (s, buf, i+5);
	r_socket_flush (s);

	/* read reverse cmds */
	for (;;) {
		ret = r_socket_read_block (s, buf, 1);
		if (ret != 1) {
			return -1;
		}
		/* system back in the middle */
		/* TODO: all pkt handlers should check for reverse queries */
		if (buf[0] == RMT_SYSTEM || buf[0] == RMT_CMD) {
			char *res, *str;
			ut32 reslen = 0, cmdlen = 0;
			// run io->cmdstr
			// return back the string
			buf[0] |= RMT_REPLY;
			ret = r_socket_read_block (s, buf+1, 4);
			r_mem_copyendian ((ut8*)&cmdlen, buf+1, 4, ENDIAN);
			if (cmdlen+1==0) // check overflow
				cmdlen = 0;
			str = calloc (1, cmdlen+1);
			ret = r_socket_read_block (s, (ut8*)str, cmdlen);
			//eprintf ("RUN CMD(%s)\n", str);
			res = io->cb_core_cmdstr (io->user, str);
			eprintf ("[%s]=>(%s)\n", str, res);
			reslen = strlen (res);
			free (str);
			r_mem_copyendian ((ut8*)buf+1, (const ut8*)&reslen,
				sizeof(ut32), ENDIAN);
			memcpy (buf+5, res, reslen);
			free (res);
			r_socket_write (s, buf, 5+reslen);
			r_socket_flush (s);
		} else {
			break;
		}
	}

	// read
	ret = r_socket_read_block (s, buf+1, 4);
	if (ret != 4)
		return -1;
	if (buf[0] != (op | RMT_REPLY)) {
		eprintf ("Unexpected system reply\n");
		return -1;
	}

	r_mem_copyendian ((ut8*)&i, buf+1, 4, ENDIAN);
	ret = 0;
	if (i>0xffffffff) {
		eprintf ("Invalid length\n");
		return -1;
	}
	ptr = (char *)malloc (i+1);
	if (ptr) {
		int ir;
		unsigned int tr = 0;
		do {
			ir = r_socket_read_block (s, (ut8*)ptr+tr, i-tr);
			if (ir>0) tr += ir;
			else break;
		} while (tr<i);
		// TODO: use io->cb_printf() with support for \x00
		ptr[i] = 0;
		if (io->cb_printf) {
			io->cb_printf ("%s", ptr);
			j = i;
		} else j = write (1, ptr, i);
		free (ptr);
	}
	/* Clean */
	if (ret > 0) {
		ret -= r_socket_read (s, (ut8*)buf, RMT_MAX);
	}
	return i-j;
}
Beispiel #27
0
R_API int r_socket_rap_server_continue (RSocketRapServer *rap_s)
{
	int endian, i, pipe_fd, ret;
	ut64 offset;
	char *ptr = NULL;
	if (	!rap_s || !rap_s->fd || !r_socket_is_connected (rap_s->fd))
		return R_FALSE;
	r_socket_read_block (rap_s->fd, rap_s->buf, 1);
	endian = getEndian();
	ret = rap_s->buf[0];
	switch (rap_s->buf[0]) {
		case RAP_RMT_OPEN:
			r_socket_read_block (rap_s->fd, &rap_s->buf[1], 2);
			r_socket_read_block (rap_s->fd, &rap_s->buf[3], (int)rap_s->buf[2]);
			rap_s->open (rap_s->user, (const char *)&rap_s->buf[3], (int)rap_s->buf[1], 0);
			rap_s->buf[0] = RAP_RMT_OPEN | RAP_RMT_REPLY;
			r_socket_write (rap_s->fd, rap_s->buf, 5);
			r_socket_flush (rap_s->fd);
			break;
		case RAP_RMT_READ:
			r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4);
			r_mem_copyendian ((ut8*)&i, &rap_s->buf[1], 4, !endian);
			if (i > RAP_RMT_MAX || i < 0)
				i = RAP_RMT_MAX;
			rap_s->read (rap_s->user, &rap_s->buf[5], i);
			rap_s->buf[0] = RAP_RMT_READ | RAP_RMT_REPLY;
			r_socket_write (rap_s->fd, rap_s->buf, i + 5);
			r_socket_flush (rap_s->fd);
			break;
		case RAP_RMT_WRITE:
			r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4);
			r_mem_copyendian ((ut8*)&i, &rap_s->buf[1], 4, !endian);
			if (i > RAP_RMT_MAX || i < 0)
				i = RAP_RMT_MAX;
			r_socket_read_block (rap_s->fd, &rap_s->buf[5], i);
			rap_s->write(rap_s->user, &rap_s->buf[5], i);
			rap_s->buf[0] = RAP_RMT_WRITE | RAP_RMT_REPLY;
			r_socket_write (rap_s->fd, rap_s->buf, 1);
			r_socket_flush (rap_s->fd);
			break;
		case RAP_RMT_SEEK:
			r_socket_read_block (rap_s->fd, &rap_s->buf[1], 9);
			i = rap_s->buf[1];
			r_mem_copyendian ((ut8*)&offset, &rap_s->buf[2], 8, !endian);
			rap_s->seek (rap_s->user, offset, i);
			rap_s->buf[0] = RAP_RMT_WRITE | RAP_RMT_REPLY;
			r_socket_write (rap_s->fd, rap_s->buf, 1);
			r_socket_flush (rap_s->fd);
			break;
		case RAP_RMT_SYSTEM:
			r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4);
			r_mem_copyendian ((ut8 *)&i, &rap_s->buf[1], 4, !endian);
			r_socket_read_block (rap_s->fd, &rap_s->buf[5], i);
			ptr = rap_s->system (rap_s->user, &rap_s->buf[5]);
			if (ptr)
				i = strlen (ptr) + 1;
			else	i = 0;
			r_mem_copyendian (&rap_s->buf[1], (ut8 *)&i, 4, !endian);
			rap_s->buf[0] = RAP_RMT_SYSTEM | RAP_RMT_REPLY;
			r_socket_write (rap_s->fd, rap_s->buf, 5);
			if (i)	r_socket_write (rap_s->fd, ptr, i);
			r_socket_flush (rap_s->fd);
			free (ptr);
			ptr = NULL;
			break;
		case RAP_RMT_CMD:
			r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4);
			r_mem_copyendian ((ut8 *)&i, &rap_s->buf[1], 4, !endian);
			r_socket_read_block (rap_s->fd, &rap_s->buf[5], i);
			ptr = rap_s->cmd (rap_s->user, &rap_s->buf[5]);
			if (ptr)
				i = strlen (ptr) + 1;
			else	i = 0;
			r_mem_copyendian (&rap_s->buf[1], (ut8 *)&i, 4, !endian);
			rap_s->buf[0] = RAP_RMT_CMD | RAP_RMT_REPLY;
			r_socket_write (rap_s->fd, rap_s->buf, 5);
			if (i)	r_socket_write (rap_s->fd, ptr, i);
			r_socket_flush (rap_s->fd);
			free (ptr);
			ptr = NULL;
			break;
		case RAP_RMT_CLOSE:
			r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4);
			r_mem_copyendian ((ut8 *)&i, &rap_s->buf[1], 4, !endian);
			rap_s->close (rap_s->user, i);
			rap_s->buf[0] = RAP_RMT_CLOSE | RAP_RMT_REPLY;
			r_socket_write (rap_s->fd, rap_s->buf, 5);
			r_socket_flush (rap_s->fd);
			break;
		default:
			eprintf ("unknown command 0x%02hhx\n", rap_s->buf[0]);
			r_socket_close (rap_s->fd);
			ret = -1;
			break;
	}
	return ret;
}
Beispiel #28
0
static int rap__system(RIO *io, RIODesc *fd, const char *command) {
	int ret, reslen = 0, cmdlen = 0;
	RSocket *s = RIORAP_FD (fd);
	unsigned int i, j = 0;
	char *ptr, *res, *str;
	ut8 buf[RMT_MAX];

	buf[0] = RMT_CMD;
	i = strlen (command) + 1;
	if (i > RMT_MAX - 5) {
		eprintf ("Command too long\n");
		return -1;
	}
	r_write_be32 (buf + 1, i);
	memcpy (buf + 5, command, i);
	r_socket_write (s, buf, i+5);
	r_socket_flush (s);

	/* read reverse cmds */
	for (;;) {
		ret = r_socket_read_block (s, buf, 1);
		if (ret != 1) {
			return -1;
		}
		/* system back in the middle */
		/* TODO: all pkt handlers should check for reverse queries */
		if (buf[0] != RMT_CMD) {
			break;
		}
		// run io->cmdstr
		// return back the string
		buf[0] |= RMT_REPLY;
		memset (buf + 1, 0, 4);
		ret = r_socket_read_block (s, buf + 1, 4);
		cmdlen = r_read_at_be32 (buf, 1);
		if (cmdlen + 1 == 0) // check overflow
			cmdlen = 0;
		str = calloc (1, cmdlen + 1);
		ret = r_socket_read_block (s, (ut8*)str, cmdlen);
		eprintf ("RUN %d CMD(%s)\n", ret, str);
		if (str && *str) {
			res = io->cb_core_cmdstr (io->user, str);
		} else {
			res = strdup ("");
		}
		eprintf ("[%s]=>(%s)\n", str, res);
		reslen = strlen (res);
		free (str);
		r_write_be32 (buf + 1, reslen);
		memcpy (buf + 5, res, reslen);
		free (res);
		r_socket_write (s, buf, reslen + 5);
		r_socket_flush (s);
	}

	// read
	ret = r_socket_read_block (s, buf + 1, 4);
	if (ret != 4) {
		return -1;
	}
	if (buf[0] != (RMT_CMD | RMT_REPLY)) {
		eprintf ("Unexpected rap cmd reply\n");
		return -1;
	}

	i = r_read_at_be32 (buf, 1);
	ret = 0;
	if (i > ST32_MAX) {
		eprintf ("Invalid length\n");
		return -1;
	}
	ptr = (char *)calloc (1, i + 1);
	if (ptr) {
		int ir, tr = 0;
		do {
			ir = r_socket_read_block (s, (ut8*)ptr + tr, i - tr);
			if (ir < 1) break;
			tr += ir;
		} while (tr < i);
		// TODO: use io->cb_printf() with support for \x00
		ptr[i] = 0;
		if (io->cb_printf) {
			io->cb_printf ("%s", ptr);
			j = i;
		} else {
			j = write (1, ptr, i);
		}
		free (ptr);
	}
#if DEAD_CODE
	/* Clean */
	if (ret > 0) {
		ret -= r_socket_read (s, (ut8*)buf, RMT_MAX);
	}
#endif
	return i - j;
}
Beispiel #29
0
int send_vcont(libgdbr_t *g, const char *command, const char *thread_id) {
	char tmp[255] = {0};
	int ret;
	if (!g) {
		return -1;
	}
	if (!g->stub_features.vContSupported) {
		ret = snprintf (tmp, sizeof (tmp) - 1, "%s", command);
	} else {
		bool supported = false;
		switch (*command) {
		case 's':
			if (g->stub_features.vcont.s) {
				supported = true;
			}
			break;
		case 'S':
			if (g->stub_features.vcont.S) {
				supported = true;
			}
			break;
		case 'c':
			if (g->stub_features.vcont.c) {
				supported = true;
			}
			break;
		case 'C':
			if (g->stub_features.vcont.C) {
				supported = true;
			}
			break;
		case 't':
			if (g->stub_features.vcont.t) {
				supported = true;
			}
			break;
		case 'r':
			if (g->stub_features.vcont.r) {
				supported = true;
			}
			break;
		}
		if (supported) {
			if (!thread_id) {
				ret = snprintf (tmp, sizeof (tmp) - 1, "%s;%s", CMD_C, command);
			} else {
				ret = snprintf (tmp, sizeof (tmp) - 1, "%s;%s:%s", CMD_C, command, thread_id);
			}
		} else {
			ret = snprintf (tmp, sizeof (tmp) - 1, "%s", command);
		}
	}
	if (ret < 0) {
		return ret;
	}
	reg_cache.valid = false;
	g->stop_reason.is_valid = false;
	ret = send_msg (g, tmp);
	if (ret < 0) {
		return ret;
	}

	SET_SIGINT_HANDLER (g, _sigint_handler);
	while ((ret = read_packet (g, true)) < 0 && !_isbreaked && r_socket_is_connected (g->sock));
	UNSET_SIGINT_HANDLER ();
	if (_isbreaked) {
		_isbreaked = false;
		// Stop target
		r_socket_write (g->sock, "\x03", 1);
		// Read the stop reason
		if (read_packet (g, false) < 0) {
			return -1;
		}
	}
	return handle_cont (g);
}
Beispiel #30
0
R_API void r_core_rtr_add(RCore *core, const char *_input) {
	char *port, input[1024], *host = NULL, *file = NULL, *ptr = NULL, buf[1024];
	int proto, i, timeout, ret;
	RSocket *fd;

	timeout = r_config_get_i (core->config, "http.timeout");
	strncpy (input, _input, sizeof (input)-4);
	/* Parse uri */
	if ((ptr = strstr (input, "tcp://"))) {
		proto = RTR_PROT_TCP;
		host = ptr+6;
	} else if ((ptr = strstr(input, "http://"))) {
		proto = RTR_PROT_HTTP;
		host = ptr+7;
	} else if ((ptr = strstr(input, "udp://"))) {
		proto = RTR_PROT_UDP;
		host = ptr+6;
	} else if ((ptr = strstr(input, "rap://"))) {
		proto = RTR_PROT_RAP;
		host = ptr+6;
	} else {
		proto = RTR_PROT_RAP;
		host = input;
	}
	while (*host && iswhitechar (*host))
		host++;

	if (!(ptr = strchr (host, ':'))) {
		ptr = host;
		port = "80";
	} else {
		*ptr++ = '\0';
		port = ptr;
	}

	if (!(file = strchr (ptr, '/'))) {
		eprintf("Error: Missing '/'\n");
		return;
	}
	*file++ = 0;
	port = r_str_chop (port);
	while (*file==' ') file++;
	if (r_sandbox_enable (0)) {
		eprintf ("sandbox: connect disabled\n");
		return;
	}

	fd = r_socket_new (R_FALSE);
	if (!fd) {
		eprintf ("Error: Cannot create new socket\n");
		return;
	}
	switch (proto) {
	case RTR_PROT_HTTP:
		{
			char uri[1024], prompt[64];
			int len;
			char *str, *res;
			if (file[strlen (file)-1]=='/') {
				snprintf (prompt, sizeof (prompt), "[http://%s:%s/%s]> ",
					host, port, file);
				r_line_set_prompt (prompt);
				for (;;) {
					char *ptr, *str = r_line_readline ();
					if (!str || !*str) break;
					if (*str == 'q') break;
					ptr = r_str_uri_encode (str);
					if (ptr) str = ptr;
					snprintf (uri, sizeof (uri), "http://%s:%s/%s%s",
						host, port, file, str);
					if (ptr == str) free (ptr);
					str = r_socket_http_get (uri, NULL, &len);
					if (str) {
						str[len] = 0;
						res = strstr (str, "\n\n");
						if (res) res = strstr (res+1, "\n\n");
						if (res) res += 2; else res = str;
						printf ("%s%s", res, (res[strlen (res)-1]=='\n')?"":"\n");
						r_line_hist_add (str);
						free (str);
					}
				}
				r_socket_free (fd);
				return;
			}
			snprintf (uri, sizeof (uri), "http://%s:%s/%s",
				host, port, file);
			str = r_socket_http_get (uri, NULL, &len);
			if (str) {
				str[len] = 0;
				res = strstr (str, "\n\n");
				if (res) res = strstr (res+1, "\n\n");
				if (res) res += 2; else res = str;
				printf ("%s", res);
				free (str);
			} else eprintf ("HTTP connection has failed\n");
			// do not add connection. wtf
			return;
		}
		break;
	case RTR_PROT_RAP:
		if (!r_socket_connect_tcp (fd, host, port, timeout)) { //TODO: Use rap.ssl
			eprintf ("Error: Cannot connect to '%s' (%s)\n", host, port);
			return;
		}
		eprintf ("Connected to %s at port %s\n", host, port);
		/* send */
		buf[0] = RTR_RAP_OPEN;
		buf[1] = 0;
		buf[2] = (ut8)(strlen (file)+1);
		memcpy (buf+3, file, buf[2]);
		r_socket_write(fd, buf, 3+buf[2]);
		/* read */
		eprintf ("waiting... "); fflush(stdout);
		r_socket_read (fd, (ut8*)buf, 5);
		r_mem_copyendian ((ut8 *)&i, (ut8*)buf+1, 4, core->assembler->big_endian);
		if (buf[0] != (char)(RTR_RAP_OPEN|RTR_RAP_REPLY) || i<= 0) {
			eprintf ("Error: Wrong reply\n");
			return;
		}
		eprintf ("ok\n");
		break;
	case RTR_PROT_TCP:
		if (!r_socket_connect_tcp (fd, host, port, timeout)) { //TODO: Use rap.ssl
			core->num->value = 1;
			eprintf("Error: Cannot connect to '%s' (%s)\n", host, port);
			return;
		}
		core->num->value = 0;
		eprintf ("Connected to: %s at port %s\n", host, port);
		break;
	case RTR_PROT_UDP:
		if (!r_socket_connect_udp (fd, host, port, timeout)) { //TODO: Use rap.ssl
			core->num->value = 1;
			eprintf ("Error: Cannot connect to '%s' (%s)\n", host, port);
			return;
		}
		core->num->value = 0;
		eprintf("Connected to: %s at port %s\n", host, port);
		break;
	}

	ret = core->num->value;
	for (i = 0; i < RTR_MAX_HOSTS; i++)
		if (!rtr_host[i].fd) {
			rtr_host[i].proto = proto;
			memcpy (rtr_host[i].host, host, 512);
			rtr_host[i].port = r_num_get (core->num, port);
			memcpy (rtr_host[i].file, file, 1024);
			rtr_host[i].fd = fd;
			rtr_n = i;
			break;
		}
	core->num->value = ret;
	r_socket_free(fd);
	//r_core_rtr_list (core);
}