static int check_bytes(const ut8* bytes, ut64 sz) { const ut8 *h; ut8 buf[4]; int off, ret = false; if (!bytes || sz < 0x300) { return false; } // XXX assuming BE off = r_read_at_be32 (bytes, 4 * sizeof (int)); h = bytes; if (sz >= 0x300 && !memcmp (h, "\xca\xfe\xba\xbe", 4)) { // XXX assuming BE off = r_read_at_be32 (h, 4 * sizeof (int)); if (off > 0 && off < sz) { memcpy (buf, h+off, 4); if (!memcmp (buf, "\xce\xfa\xed\xfe", 4) || !memcmp (buf, "\xfe\xed\xfa\xce", 4) || !memcmp (buf, "\xfe\xed\xfa\xcf", 4) || !memcmp (buf, "\xcf\xfa\xed\xfe", 4)) ret = true; } } return ret; }
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 bool checkHeader(const ut8 *h, int sz) { ut8 buf[4]; if (sz >= 0x300 && !memcmp (h, "\xca\xfe\xba\xbe", 4)) { // XXX assuming BE int off = r_read_at_be32 (h, 4 * sizeof (int)); if (off > 0 && off + 4 < sz) { memcpy (buf, h + off, 4); if (!memcmp (buf, "\xce\xfa\xed\xfe", 4) || !memcmp (buf, "\xfe\xed\xfa\xce", 4) || !memcmp (buf, "\xfe\xed\xfa\xcf", 4) || !memcmp (buf, "\xcf\xfa\xed\xfe", 4)) { return true; } } } return false; }
static int check(RBin *bin) { ut8 *h, buf[4]; int off, ret = false; RMmap *m = r_file_mmap (bin->file, false, 0); if (!m || !m->buf) { r_file_mmap_free (m); return false; } h = m->buf; if (m->len >= 0x300 && !memcmp (h, "\xca\xfe\xba\xbe", 4)) { // XXX assuming BE off = r_read_at_be32 (h, 4 * sizeof (int)); if (off > 0 && off < m->len) { memcpy (buf, h + off, 4); if (!memcmp (buf, "\xce\xfa\xed\xfe", 4) || !memcmp (buf, "\xfe\xed\xfa\xce", 4) || !memcmp (buf, "\xfe\xed\xfa\xcf", 4) || !memcmp (buf, "\xcf\xfa\xed\xfe", 4)) ret = true; } } r_file_mmap_free (m); 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; }
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); }