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; }
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; }
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; }
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); }
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); }
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; }
// 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; }
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; }
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; }
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); }
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; }
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); } }
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); }
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); } }
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; }
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); }
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; }
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; }
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; }
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; }
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); }
/* 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; }
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); }
R_API int r_socket_puts(RSocket *s, char *buf) { return r_socket_write (s, buf, strlen (buf)); }
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); }
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; }
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; }
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; }
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); }
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); }