diff --git a/dist/plugins-cfg/plugins.def.cfg b/dist/plugins-cfg/plugins.def.cfg index 337e79bc27..c17257c154 100644 --- a/dist/plugins-cfg/plugins.def.cfg +++ b/dist/plugins-cfg/plugins.def.cfg @@ -247,6 +247,7 @@ io.r2pipe io.gzip io.http io.tcpslurp +io.socket io.r2web io.ihex io.mach diff --git a/dist/plugins-cfg/plugins.static.cfg b/dist/plugins-cfg/plugins.static.cfg index 7475dbee5c..3f92c92f7b 100644 --- a/dist/plugins-cfg/plugins.static.cfg +++ b/dist/plugins-cfg/plugins.static.cfg @@ -193,6 +193,7 @@ io.r2pipe io.gzip io.http io.tcpslurp +io.socket io.r2web io.ihex io.mach diff --git a/dist/plugins-cfg/plugins.static.nogpl.cfg b/dist/plugins-cfg/plugins.static.nogpl.cfg index b0d5e799e8..8a5a6b9a67 100644 --- a/dist/plugins-cfg/plugins.static.nogpl.cfg +++ b/dist/plugins-cfg/plugins.static.nogpl.cfg @@ -169,6 +169,7 @@ io.r2pipe io.gzip io.http io.tcpslurp +io.socket io.r2web io.ihex io.mach diff --git a/doc/fortunes.fun b/doc/fortunes.fun index 98876a1558..9af07c701f 100644 --- a/doc/fortunes.fun +++ b/doc/fortunes.fun @@ -66,7 +66,7 @@ Documentation is for weak people. PEBCAK ERROR: Documentation not found. License server overloaded (ETOOMUCHCASH) Error: cannot yank negative sleep -If you're not satisfied by our product, we'll be happy to refund you. +If you're not satisfied by our product, you may ask for a refund. Already up-to-date. How about a nice game of chess? THE ONLY WINNING MOVE IS NOT TO PLAY. diff --git a/libr/anal/p/anal_arm_cs.c b/libr/anal/p/anal_arm_cs.c index 811daa99df..c9c0d2ce8d 100644 --- a/libr/anal/p/anal_arm_cs.c +++ b/libr/anal/p/anal_arm_cs.c @@ -1265,18 +1265,6 @@ static int analop64_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int l const char *r0 = REG64 (0); const char *r1 = REG64 (1); int size = REGSIZE64 (1); -#if 0 - r_strbuf_setf (&op->esil, - "0,%s,=," // dst = 0 - "%d," // initial counter = size - "DUP," // counter: size -> 0 (repeat here) - "DUP,1,SWAP,-,8,*," // counter to bits in source - "DUP,0xff,<<,%s,&,>>," // src byte moved to LSB - "SWAP,%d,-,8,*," // invert counter, calc dst bit - "SWAP,<<,%s,|=," // shift left to there and insert - "4,REPEAT", // goto 5th instruction - r0, size, r1, size, r0); -#endif if (size == 8) { r_strbuf_setf (&op->esil, "56,0xff,%s,&,<<,tmp,=," diff --git a/libr/core/cmd_open.c b/libr/core/cmd_open.c index 338e8cfa38..50b07678e3 100644 --- a/libr/core/cmd_open.c +++ b/libr/core/cmd_open.c @@ -604,7 +604,7 @@ static bool cmd_om(RCore *core, const char *input) { break; } if (fd < 3) { - eprintf ("wrong fd, it must be greater than 3\n"); + eprintf ("Wrong fd, it must be greater than 3.\n"); return false; } desc = r_io_desc_get (core->io, fd); diff --git a/libr/include/r_io.h b/libr/include/r_io.h index 8be68f8778..7fc205d05e 100644 --- a/libr/include/r_io.h +++ b/libr/include/r_io.h @@ -520,6 +520,7 @@ extern RIOPlugin r_io_plugin_rbuf; extern RIOPlugin r_io_plugin_winedbg; extern RIOPlugin r_io_plugin_gprobe; extern RIOPlugin r_io_plugin_fd; +extern RIOPlugin r_io_plugin_socket; #if __cplusplus } diff --git a/libr/include/r_socket.h b/libr/include/r_socket.h index 36a1293307..74b72a1dfd 100644 --- a/libr/include/r_socket.h +++ b/libr/include/r_socket.h @@ -112,7 +112,7 @@ R_API bool r_socket_block_time(RSocket *s, bool block, int sec, int usec); R_API int r_socket_flush(RSocket *s); R_API int r_socket_ready(RSocket *s, int secs, int usecs); R_API char *r_socket_to_string(RSocket *s); -R_API int r_socket_write(RSocket *s, void *buf, int len); +R_API int r_socket_write(RSocket *s, const void *buf, int len); R_API int r_socket_puts(RSocket *s, char *buf); R_API void r_socket_printf(RSocket *s, const char *fmt, ...) R_PRINTF_CHECK(2, 3); R_API int r_socket_read(RSocket *s, ut8 *read, int len); diff --git a/libr/io/io_memory.c b/libr/io/io_memory.c index 18b15bcfdc..ebd7145a37 100644 --- a/libr/io/io_memory.c +++ b/libr/io/io_memory.c @@ -10,16 +10,6 @@ static inline ut32 _io_malloc_sz(RIODesc *desc) { return mal? mal->size: 0; } -static inline void _io_malloc_set_sz(RIODesc *desc, ut32 sz) { - if (!desc) { - return; - } - RIOMalloc *mal = (RIOMalloc*)desc->data; - if (mal) { - mal->size = sz; - } -} - static inline ut8* _io_malloc_buf(RIODesc *desc) { if (!desc) { return NULL; @@ -72,7 +62,6 @@ int io_memory_write(RIO *io, RIODesc *fd, const ut8 *buf, int count) { } bool io_memory_resize(RIO *io, RIODesc *fd, ut64 count) { - ut8 * new_buf = NULL; if (!fd || !fd->data || count == 0) { return false; } @@ -80,17 +69,16 @@ bool io_memory_resize(RIO *io, RIODesc *fd, ut64 count) { if (_io_malloc_off (fd) > mallocsz) { return false; } - new_buf = malloc (count); + RIOMalloc *mal = (RIOMalloc*)fd->data; + ut8 *new_buf = realloc (mal->buf, count); if (!new_buf) { return false; } - memcpy (new_buf, _io_malloc_buf (fd), R_MIN (count, mallocsz)); - if (count > mallocsz) { - memset (new_buf + mallocsz, 0, count - mallocsz); + mal->buf = new_buf; + if (count > mal->size) { + memset (mal->buf + mal->size, 0, count - mal->size); } - free (_io_malloc_buf (fd)); - _io_malloc_set_buf (fd, new_buf); - _io_malloc_set_sz (fd, count); + mal->size = count; return true; } diff --git a/libr/io/io_memory.h b/libr/io/io_memory.h index 1b12789e7f..08a203ece9 100644 --- a/libr/io/io_memory.h +++ b/libr/io/io_memory.h @@ -7,6 +7,7 @@ typedef struct { ut8 *buf; ut32 size; ut64 offset; + void *data; } RIOMalloc; int io_memory_close(RIODesc *fd); diff --git a/libr/io/meson.build b/libr/io/meson.build index cca8b88a3a..fab941cb3f 100644 --- a/libr/io/meson.build +++ b/libr/io/meson.build @@ -13,6 +13,7 @@ r_io_sources = [ 'p/io_fd.c', 'p/io_bfdbg.c', 'p/io_bochs.c', + 'p/io_socket.c', 'p/io_debug.c', 'p/io_default.c', 'p/io_gdb.c', diff --git a/libr/io/p/io_socket.c b/libr/io/p/io_socket.c new file mode 100644 index 0000000000..cf41454adc --- /dev/null +++ b/libr/io/p/io_socket.c @@ -0,0 +1,156 @@ +/* radare - LGPL - Copyright 2021 - pancake */ + +#include +#include +#include +#include "../io_memory.h" + +#define SOCKETURI "socket://" + +typedef struct { + RSocket *sc; + RSocket *sl; + int count; +} RIOSocketData; + + +static void free_socketdata(RIOSocketData *sd) { + r_socket_free (sd->sc); + r_socket_free (sd->sl); + free (sd); +} + +static int __write(RIO *io, RIODesc *desc, const ut8 *buf, int count) { + RIOMalloc *mal = (RIOMalloc*)desc->data; + if (mal) { + r_cons_break_push (NULL, NULL); + RSocket *s = ((RIOSocketData*)(mal->data))->sc; + return r_socket_write (s, buf, count); + } + return -1; +} + +static int __read(RIO *io, RIODesc *desc, ut8 *buf, int count) { + RIOMalloc *mal = (RIOMalloc*)desc->data; + if (mal) { + ut64 addr = mal->offset; + r_cons_break_push (NULL, NULL); + RIOSocketData *sdat = mal->data; + RSocket *s = sdat->sc; + ut8 *mem = malloc (4096); + if (mem) { + int c = r_socket_read (s, mem, 4096); + if (c > 0) { + int osz = mal->size; + io_memory_resize (io, desc, mal->size + c); + memcpy (mal->buf + osz, mem, c); + io->corebind.cmdf (io->corebind.core, "f nread_%d %d %d", + sdat->count, c, mal->size); + io->corebind.cmdf (io->corebind.core, "omr 1 %d", mal->size); + sdat->count++; + } + free (mem); + } + r_cons_break_pop (); + mal->offset = addr; + return io_memory_read (io, desc, buf, count); + } + return -1; +} + +static int __close(RIODesc *desc) { + R_FREE (desc->data); + return 0; +} + +static bool __check(RIO *io, const char *pathname, bool many) { + return !strncmp (pathname, SOCKETURI, strlen (SOCKETURI)); +} + +static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) { + if (r_sandbox_enable (false)) { + eprintf ("Do not permit " SOCKETURI " in sandbox mode.\n"); + return NULL; + } + if (!__check (io, pathname, 0)) { + return NULL; + } + RIOMalloc *mal = R_NEW0 (RIOMalloc); + RIOSocketData *data = R_NEW0 (RIOSocketData); + if (!mal || !data) { + free (mal); + free_socketdata (data); + return NULL; + } + mal->data = data; + mal->buf = calloc (1, 1); + if (!mal->buf) { + free (mal); + free_socketdata (data); + return NULL; + } + mal->size = 1; + mal->offset = 0; + pathname += strlen ("socket://"); + + if (*pathname == '?') { + eprintf ("Usage: $ nc -l -p 9999 ; r2 socket://localhost:9999\n"); + eprintf (" or: $ nc localhost 9999 ; r2 socket://:9999\n"); + } else if (*pathname == ':') { + /* listen and wait for connection */ + data->sl = r_socket_new (false); + if (!r_socket_listen (data->sl, pathname + 1, NULL)) { + eprintf ("Cannot listen\n"); + r_socket_free (data->sl); + data->sl = NULL; + return NULL; + } + data->sc = r_socket_accept (data->sl); + r_socket_block_time (data->sc, false, 0, 0); + } else { + /* connect and slurp the end point */ + char *host = strdup (pathname); + if (!host) { + return NULL; + } + char *port = strchr (host, ':'); + if (port) { + *port++ = 0; + } else { + eprintf ("Missing port.\n"); + free_socketdata (data); + return NULL; + } + /* listen and wait for connection */ + data->sc = r_socket_new (false); + if (!r_socket_connect (data->sc, host, port, R_SOCKET_PROTO_TCP, 0)) { + eprintf ("Cannot connect\n"); + free_socketdata (data); + return NULL; + } + r_socket_block_time (data->sc, false, 0, 0); + free (host); + } + return r_io_desc_new (io, &r_io_plugin_socket, pathname, R_PERM_RW | rw, mode, mal); +} + +RIOPlugin r_io_plugin_socket = { + .name = "socket", + .desc = "Connect or listen via TCP on a growing io.", + .uris = SOCKETURI, + .license = "MIT", + .open = __open, + .close = __close, + .read = __read, + .lseek = io_memory_lseek, + .check = __check, + .write = __write, +}; + +#ifndef R2_PLUGIN_INCORE +R_API RLibStruct radare_plugin = { + .type = R_LIB_TYPE_IO, + .data = &r_io_plugin_socket, + .version = R2_VERSION +}; +#endif diff --git a/libr/io/p/socket.mk b/libr/io/p/socket.mk new file mode 100644 index 0000000000..85182873d6 --- /dev/null +++ b/libr/io/p/socket.mk @@ -0,0 +1,17 @@ +OBJ_SOCKET=io_socket.o + +STATIC_OBJ+=${OBJ_SOCKET} +TARGET_SOCKET=io_socket.${EXT_SO} +ALL_TARGETS+=${TARGET_SOCKET} + +ifeq (${WITHPIC},0) +LINKFLAGS+=../../util/libr_util.a +LINKFLAGS+=../../io/libr_io.a +else +LINKFLAGS+=-L../../util -lr_util +LINKFLAGS+=-L.. -lr_io +endif + +${TARGET_SOCKET}: ${OBJ_SOCKET} + ${CC_LIB} $(call libname,io_socket) ${CFLAGS} -o ${TARGET_SOCKET} \ + ${LDFLAGS} ${OBJ_SOCKET} ${LINKFLAGS} diff --git a/libr/socket/socket.c b/libr/socket/socket.c index ddefeb31e3..65f81383af 100644 --- a/libr/socket/socket.c +++ b/libr/socket/socket.c @@ -716,8 +716,7 @@ R_API char *r_socket_to_string(RSocket *s) { } /* Read/Write functions */ -R_API int r_socket_write(RSocket *s, void *buf, int len) { - D { eprintf ("WRITE "); int i; ut8 *b = buf; for (i = 0; i