static void filesave () { char buf[128]; int i; if (!path) { eprintf ("File: "); buf[0] = 0; fgets (buf, sizeof(buf), stdin); i = strlen (buf); if (i>0) { buf[i-1] = 0; free (path); path = strdup (buf); } } if (lines) { for (i=0; i<bytes; i++) { if (lines[i]=='\0') lines[i]='\n'; } } r_file_dump (path, (const ut8*)lines, bytes); eprintf ("File '%s' saved (%d bytes)\n", path, bytes); // restore back zeroes nlines = r_str_split (lines, '\n'); }
R_API char *r_cons_editor (const char *file) { char *line; _n = 0; free (path); if (file) { path = strdup (file); lines = r_file_slurp (file, &bytes); nlines = r_str_split (lines, '\n'); eprintf ("Loaded %d lines on %d bytes\n", nlines-1, bytes); } else path = NULL; r_cons_new (); I->line->hist_up = up; I->line->hist_down = down; I->line->contents = I->line->buffer.data; for (;;) { setnewline (_n); snprintf (prompt, sizeof (prompt), "%d: ", _n); r_line_set_prompt (prompt); line = r_line_readline (); saveline (_n, line); _n++; if (!line) break; } filesave (); return NULL; }
R_API RSyscallItem *r_syscall_item_new_from_string(const char *name, const char *s) { RSyscallItem *si; char *o; if (!name || !s) { return NULL; } si = R_NEW0 (RSyscallItem); if (!si) { return NULL; } o = strdup (s); r_str_split (o, ','); si->name = strdup (name); si->swi = r_num_get (NULL, r_str_word_get0 (o, 0)); si->num = r_num_get (NULL, r_str_word_get0 (o, 1)); si->args = r_num_get (NULL, r_str_word_get0 (o, 2)); //in a definition such as syscall=0x80,0,4, //the string at index 3 is 0 causing oob read afterwards si->sargs = calloc (si->args + 1, sizeof (char)); if (!si->sargs) { free (si); free (o); return NULL; } strncpy (si->sargs, r_str_word_get0 (o, 3), si->args); free (o); return si; }
R_API RSyscallItem *r_syscall_item_new_from_string(const char *name, const char *s) { RSyscallItem *si; char *o; if (!s) return NULL; si = R_NEW0 (RSyscallItem); o = strdup (s); r_str_split (o, ','); /* return r_syscall_item_new (name, r_num_get (NULL, r_str_word_get0 (o, 0)), r_num_get (NULL, r_str_word_get0 (o, 1)), r_num_get (NULL, r_str_word_get0 (o, 2)), r_str_word_get0 (o, 3)); */ si->name = strdup (name); si->swi = r_num_get (NULL, r_str_word_get0 (o, 0)); si->num = r_num_get (NULL, r_str_word_get0 (o, 1)); si->args = r_num_get (NULL, r_str_word_get0 (o, 2)); si->sargs = strdup (r_str_word_get0 (o, 3)); free (o); return si; }
bool test_r_str_split(void) { char* hi = strdup ("hello world"); mu_assert_eq (r_str_split (hi, ' '), 1, "split on space"); char* hello = hi; char* world = hi + 6; mu_assert_streq (hello, "hello", "first string in split"); mu_assert_streq (world, "world", "second string in split"); free (hi); mu_end; }
R_API char *r_type_get_struct_memb(Sdb *TDB, const char *type, int offset) { int i, typesize = 0; char *res = NULL; if (offset < 0) { return NULL; } char* query = sdb_fmt ("struct.%s", type); char *members = sdb_get (TDB, query, 0); if (!members) { //eprintf ("%s is not a struct\n", type); return NULL; } int nargs = r_str_split (members, ','); for (i = 0; i < nargs ; i++) { const char *name = r_str_word_get0 (members, i); if (!name) { break; } query = sdb_fmt ("struct.%s.%s", type, name); char *subtype = sdb_get (TDB, query, 0); if (!subtype) { break; } int len = r_str_split (subtype, ','); if (len < 3) { free (subtype); break; } int val = r_num_math (NULL, r_str_word_get0 (subtype, len - 1)); int arrsz = val ? val : 1; if ((typesize / 8) == offset) { res = r_str_newf ("%s.%s", type, name); free (subtype); break; } typesize += r_type_get_bitsize (TDB, subtype) * arrsz; free (subtype); } free (members); return res; }
R_API int r_syscall_get_num(RSyscall *ctx, const char *str) { char *o; int i = 0; if (!ctx->syspair) return 0; o = r_pair_get (ctx->syspair, str); if (o && *o) { r_str_split (o, ','); i = r_num_get (NULL, r_str_word_get0 (o, 1)); } free (o); return i; }
R_API int r_syscall_get_num(RSyscall *s, const char *str) { char *o; int i = -1; // TODO: use sdb array api here if (!s || !s->db) return -1; o = sdb_get (s->db, str, 0); if (o && *o) { r_str_split (o, ','); i = r_num_get (NULL, r_str_word_get0 (o, 1)); } free (o); return i; }
R_API char *r_cons_pal_parse(const char *str) { int i; ut8 r, g, b; char out[128]; char *s = r_str_trim_head_tail (strdup (str)); r_str_split (s, ' '); int length = strlen (s); out[0] = 0; if (!strcmp (str, "random")) { free (s); return r_cons_color_random (0); } if (!strncmp (s, "rgb:", 4)) { int correct = 0; if (length == 7) { r = rgbnum (s[4],s[4]); g = rgbnum (s[5],s[5]); b = rgbnum (s[6],s[6]); correct = 1; } else if (length == 10) { r = rgbnum(s[4],s[5]); g = rgbnum(s[6],s[7]); b = rgbnum(s[8],s[9]); correct = 1; } if (correct) { r_cons_rgb_str (out, r, g, b, 0); } else { eprintf ("Invalid rgb string (%s)\n", str); } } for (i=0; colors[i].name; i++) { if (!strcmp (s, colors[i].name)) strcat (out, colors[i].code); } free (s); return *out? strdup (out): NULL; }
R_API char *r_type_get_struct_memb(Sdb *TDB, const char *type, int offset) { int i, prev_typesize, typesize = 0; char *res = NULL; if (offset < 0) { return NULL; } char* query = sdb_fmt ("struct.%s", type); char *members = sdb_get (TDB, query, 0); if (!members) { //eprintf ("%s is not a struct\n", type); return NULL; } int nargs = r_str_split (members, ','); for (i = 0; i < nargs ; i++) { const char *name = r_str_word_get0 (members, i); if (!name) { break; } query = sdb_fmt ("struct.%s.%s", type, name); char *subtype = sdb_get (TDB, query, 0); if (!subtype) { break; } int len = r_str_split (subtype, ','); if (len < 3) { free (subtype); break; } int val = r_num_math (NULL, r_str_word_get0 (subtype, len - 1)); int arrsz = val ? val : 1; if ((typesize / 8) == offset) { res = r_str_newf ("%s.%s", type, name); free (subtype); break; } prev_typesize = typesize; typesize += r_type_get_bitsize (TDB, subtype) * arrsz; // Handle nested structs if (offset < (typesize / 8)) { char *nested_type = (char *)r_str_word_get0 (subtype, 0); if (r_str_startswith (nested_type, "struct ") && !r_str_endswith (nested_type, " *")) { len = r_str_split (nested_type, ' '); if (len < 2) { free (subtype); break; } nested_type = (char *)r_str_word_get0 (nested_type, 1); char *nested_res = r_type_get_struct_memb (TDB, nested_type, offset - (prev_typesize / 8)); if (nested_res) { len = r_str_split(nested_res, '.'); res = r_str_newf ("%s.%s.%s", type, name, r_str_word_get0 (nested_res, len - 1)); free (nested_res); free (subtype); break; } } } free (subtype); } free (members); return res; }
R_API int r_core_rtr_http(RCore *core, int launch, const char *path) { char buf[32]; RSocketHTTPRequest *rs; int iport, oldsandbox = -1; int timeout = r_config_get_i (core->config, "http.timeout"); int x = r_config_get_i (core->config, "scr.html"); int y = r_config_get_i (core->config, "scr.color"); int z = r_config_get_i (core->config, "asm.bytes"); int u = r_config_get_i (core->config, "scr.interactive"); int v = r_config_get_i (core->config, "asm.cmtright"); const char *port = r_config_get (core->config, "http.port"); char *allow = (char *)r_config_get (core->config, "http.allow"); if (core->http_up) { eprintf ("http server is already running\n"); return 1; } if (r_sandbox_enable (0)) { eprintf ("sandbox: connect disabled\n"); return 1; } if (path && atoi (path)) { port = path; path = NULL; } if (!strcmp (port, "0")) { r_num_irand (); iport = 1024+r_num_rand (45256); snprintf (buf, sizeof (buf), "%d", iport); port = buf; } s = r_socket_new (R_FALSE); s->local = !r_config_get_i (core->config, "http.public"); if (!r_socket_listen (s, port, NULL)) { eprintf ("Cannot listen on http.port\n"); return 1; } if (launch) { char cmd[128]; const char *browser = r_config_get (core->config, "http.browser"); snprintf (cmd, sizeof (cmd)-1, "%s http://localhost:%d/%s &", browser, atoi (port), path?path:""); r_sys_cmd (cmd); } r_config_set (core->config, "asm.cmtright", "false"); r_config_set (core->config, "scr.html", "true"); r_config_set (core->config, "scr.color", "false"); r_config_set (core->config, "asm.bytes", "false"); r_config_set (core->config, "scr.interactive", "false"); if (r_config_get_i (core->config, "http.sandbox")) { oldsandbox = r_config_get_i (core->config, "cfg.sandbox"); r_config_set (core->config, "cfg.sandbox", "true"); } eprintf ("Starting http server...\n"); eprintf ("http://localhost:%d/\n", atoi (port)); core->http_up = R_TRUE; while (!r_cons_singleton ()->breaked) { r_cons_break ((RConsBreak)http_break, core); rs = r_socket_http_accept (s, timeout); if (!rs) { if (!s) break; r_sys_usleep (100); continue; } if (allow && *allow) { int accepted = R_FALSE; const char *host; char *p, *peer = r_socket_to_string (rs->s); char *allows = strdup (allow); //eprintf ("Firewall (%s)\n", allows); int i, count = r_str_split (allows, ','); p = strchr (peer, ':'); if (p) *p = 0; for (i=0; i<count; i++) { host = r_str_word_get0 (allows, i); //eprintf ("--- (%s) (%s)\n", host, peer); if (!strcmp (host, peer)) { accepted = R_TRUE; break; } } free (peer); free (allows); if (!accepted) { r_socket_http_close (rs); continue; } } if (!rs->method || !rs->path) { eprintf ("Invalid http headers received from client\n"); r_socket_http_close (rs); continue; } char *dir = NULL; if (r_config_get_i (core->config, "http.dirlist")) if (r_file_is_directory (rs->path)) dir = strdup (rs->path); if (!strcmp (rs->method, "GET")) { if (!memcmp (rs->path, "/up", 3)) { if (r_config_get_i (core->config, "http.upget")) { const char *uproot = r_config_get (core->config, "http.uproot"); if (!rs->path[3] || (rs->path[3]=='/'&&!rs->path[4])) { char *ptr = rtr_dir_files (uproot); r_socket_http_response (rs, 200, ptr, 0, NULL); free (ptr); } else { char *path = r_file_root (uproot, rs->path + 4); if (r_file_exists (path)) { int sz = 0; char *f = r_file_slurp (path, &sz); if (f) { r_socket_http_response (rs, 200, f, sz, NULL); free (f); } else { r_socket_http_response (rs, 403, "Permission denied", 0, NULL); eprintf ("http: Cannot open '%s'\n", path); } } else { if (dir) { char *resp = rtr_dir_files (dir); r_socket_http_response (rs, 404, resp, 0, NULL); free (resp); } else { eprintf ("File '%s' not found\n", path); r_socket_http_response (rs, 404, "File not found\n", 0, NULL); } } free (path); } } else { r_socket_http_response (rs, 403, "Permission denied\n", 0, NULL); } } else if (!memcmp (rs->path, "/cmd/", 5)) { char *cmd = rs->path +5; char foo[32]; const char *httpcmd = r_config_get (core->config, "http.uri"); while (*cmd=='/') cmd++; if (httpcmd && *httpcmd) { int len; char *res; // do remote http query and proxy response snprintf (foo, sizeof (foo), "%s/%s", httpcmd, cmd); res = r_socket_http_get (foo, NULL, &len); if (res) { res[len]=0; r_cons_printf ("%s\n", res); } } else { char *out, *cmd = rs->path+5; r_str_uri_decode (cmd); // eprintf ("CMD (%s)\n", cmd); out = r_core_cmd_str_pipe (core, cmd); // eprintf ("\nOUT LEN = %d\n", strlen (out)); if (out) { char *res = r_str_uri_encode (out); r_socket_http_response (rs, 200, out, 0, "Content-Type: text/plain\n"); free (out); free (res); } else r_socket_http_response (rs, 200, "", 0, NULL); } } else { const char *root = r_config_get (core->config, "http.root"); char *path = r_file_root (root, rs->path); // FD IS OK HERE if (rs->path [strlen (rs->path)-1] == '/') { path = r_str_concat (path, "index.html"); //rs->path = r_str_concat (rs->path, "index.html"); } else { //snprintf (path, sizeof (path), "%s/%s", root, rs->path); if (r_file_is_directory (path)) { char res[128]; snprintf (res, sizeof (res), "Location: %s/\n", rs->path); r_socket_http_response (rs, 302, NULL, 0, res); r_socket_http_close (rs); free (path); free (dir); dir = NULL; continue; } } if (r_file_exists (path)) { int sz = 0; char *f = r_file_slurp (path, &sz); if (f) { const char *contenttype = NULL; if (strstr (path, ".js")) contenttype = "Content-Type: application/javascript\n"; if (strstr (path, ".css")) contenttype = "Content-Type: text/css\n"; if (strstr (path, ".html")) contenttype = "Content-Type: text/html\n"; r_socket_http_response (rs, 200, f, sz, contenttype); free (f); } else { r_socket_http_response (rs, 403, "Permission denied", 0, NULL); eprintf ("http: Cannot open '%s'\n", path); } } else { if (dir) { char *resp = rtr_dir_files (dir); eprintf ("Dirlisting %s\n", dir); r_socket_http_response (rs, 404, resp, 0, NULL); free (resp); } else { eprintf ("File '%s' not found\n", path); r_socket_http_response (rs, 404, "File not found\n", 0, NULL); } } free (path); } } else if (!strcmp (rs->method, "POST")) { ut8 *ret; int retlen; char buf[128]; if (r_config_get_i (core->config, "http.upload")) { ret = r_socket_http_handle_upload ( rs->data, rs->data_length, &retlen); if (ret) { ut64 size = r_config_get_i (core->config, "http.maxsize"); if (size && retlen > size) { r_socket_http_response (rs, 403, "403 File too big\n", 0, NULL); } else { char *filename = r_file_root ( r_config_get (core->config, "http.uproot"), rs->path + 4); eprintf ("UPLOADED '%s'\n", filename); r_file_dump (filename, ret, retlen); free (filename); snprintf (buf, sizeof (buf), "<html><body><h2>uploaded %d bytes. Thanks</h2>\n", retlen); r_socket_http_response (rs, 200, buf, 0, NULL); } free (ret); } } else { r_socket_http_response (rs, 403, "403 Forbidden\n", 0, NULL); } } else { r_socket_http_response (rs, 404, "Invalid protocol", 0, NULL); } r_socket_http_close (rs); free (dir); } core->http_up = R_FALSE; r_socket_free (s); r_cons_break_end (); r_config_set_i (core->config, "scr.html", x); r_config_set_i (core->config, "scr.color", y); r_config_set_i (core->config, "asm.bytes", z); r_config_set_i (core->config, "scr.interactive", u); r_config_set_i (core->config, "asm.cmtright", v); if (oldsandbox != -1) r_config_set_i (core->config, "cfg.sandbox", oldsandbox); return 0; }