R_API void r_cons_grep_parsecmd(char *cmd, const char *quotestr) { char *ptr; if (!cmd) { return; } ptr = preprocess_filter_expr (cmd, quotestr); if (ptr) { r_str_chop (cmd); parse_grep_expression (ptr); free (ptr); } }
static RNumCalcValue prim(RNum *num, RNumCalc *nc, int get) { RNumCalcValue v = {0}; if (get) get_token (num, nc); switch (nc->curr_tok) { case RNCNUMBER: v = nc->number_value; get_token (num, nc); return v; case RNCNAME: //fprintf (stderr, "error: unknown keyword (%s)\n", nc->string_value); //double& v = table[nc->string_value]; r_str_chop (nc->string_value); v = Nset (r_num_get (num, nc->string_value)); get_token (num, nc); if (nc->curr_tok == RNCASSIGN) { v = expr (num, nc, 1); } if (nc->curr_tok == RNCINC) Naddi (v, 1); if (nc->curr_tok == RNCDEC) Nsubi (v, 1); return v; case RNCNEG: v = nc->number_value; get_token (num, nc); return Nneg (nc->number_value); //prim (num, nc, 1), 1); case RNCINC: return Naddi (prim (num, nc, 1), 1); case RNCDEC: return Naddi (prim (num, nc, 1), -1); case RNCORR: return Norr (v, prim (num, nc, 1)); case RNCMINUS: return Nsub (v, prim (num, nc, 1)); case RNCLEFTP: v = expr (num, nc, 1); if (nc->curr_tok == RNCRIGHTP) { get_token (num, nc); } else error (num, nc, " ')' expected"); case RNCEND: case RNCXOR: case RNCAND: case RNCPLUS: case RNCMOD: case RNCMUL: case RNCDIV: case RNCPRINT: case RNCASSIGN: case RNCRIGHTP: return v; //default: error (num, nc, "primary expected"); } return v; }
static bool cmd_wf(RCore *core, const char *input) { ut8 *buf; int size; const char *arg = input + ((input[1] == ' ') ? 2 : 1); int wseek = r_config_get_i (core->config, "cfg.wseek"); char *p, *a = r_str_chop (strdup (arg)); // XXX: file names cannot contain spaces p = strchr (a, ' '); if (p) *p++ = 0; if (*arg =='?' || !*arg) { eprintf ("Usage: wf [file] ([size] ([offset]))\n"); } if (!strcmp (arg, "-")) { char *out = r_core_editor (core, NULL, NULL); if (out) { r_io_write_at (core->io, core->offset, (ut8*)out, strlen (out)); r_core_block_read (core); free (out); } } if ((buf = (ut8*) r_file_slurp (a, &size))) { int u_size = size; int u_offset = 0; u_size = r_num_math (core->num, p); if (u_size < 1) u_size = size; if (p) { *p++ = 0; u_offset = r_num_math (core->num, p); if (u_offset > size) { eprintf ("Invalid offset\n"); free (buf); return false; } } r_io_use_desc (core->io, core->file->desc); r_io_write_at (core->io, core->offset, buf + u_offset, u_size); WSEEK (core, size); free (buf); r_core_block_read (core); } else { eprintf ("Cannot open file '%s'\n", arg); } return true; }
static NumValue prim(int get) { NumValue v = {0}; if (get) get_token (); switch (curr_tok) { case NUMBER: v = number_value; get_token (); return v; case NAME: //fprintf (stderr, "error: unknown keyword (%s)\n", string_value); //double& v = table[string_value]; r_str_chop (string_value); v = Nset (r_num_get (calc_num, string_value)); get_token (); if (curr_tok == ASSIGN) v = expr (1); if (curr_tok == INC) Naddi (v, 1); if (curr_tok == DEC) Nsubi (v, 1); return v; case INC: return Naddi (prim (1), 1); case DEC: return Naddi (prim (1), -1); case MINUS: return Nsub (v, prim (1)); case LEFTP: v = expr (1); if (curr_tok == RIGHTP) get_token (); else error (" ')' expected"); case END: case PLUS: case MUL: case DIV: case PRINT: case ASSIGN: case RIGHTP: return v; //default: error ("primary expected"); } return v; }
static char *swift_demangle_cmd(const char *s) { /* XXX: command injection issue here */ static char *swift_demangle = NULL; if (have_swift_demangle == -1) { if (!swift_demangle) { have_swift_demangle = 0; swift_demangle = r_file_path ("swift-demangle"); if (!swift_demangle || !strcmp (swift_demangle, "swift-demangle")) { char *xcrun = r_file_path ("xcrun"); if (xcrun) { if (strcmp (xcrun, "xcrun")) { free (swift_demangle); swift_demangle = r_str_newf ("%s swift-demangle", xcrun); have_swift_demangle = 1; } free (xcrun); } } } } if (swift_demangle) { if (strstr (s, "'") || strstr (s, "\\")) { /* nice try */ return NULL; } //char *res = r_sys_cmd_strf ("%s -compact -simplified '%s'", char *res = r_sys_cmd_strf ("%s -compact '%s'", swift_demangle, s); if (res && !*res) { free (res); res = NULL; } return r_str_chop (res); } return NULL; }
static int parse(RParse *p, const char *data, char *str) { int i, n; char w0[32]; char w1[32]; char w2[32]; char w3[32]; char *buf, *ptr, *optr, *num; // malloc can be slow here :? buf = strdup (data); r_str_trim_head (buf); ptr = strchr (buf, '#'); if (ptr) { *ptr = 0; r_str_chop (buf); } if (*buf == '.' || buf[strlen(buf)-1] == ':') { free (buf); strcpy (str, data); return R_TRUE; } r_str_replace_char (buf, '$', 0); r_str_replace_char (buf, '%', 0); r_str_replace_char (buf, '\t', ' '); r_str_replace_char (buf, '(', '['); r_str_replace_char (buf, ')', ']'); ptr = strchr (buf, '['); if (ptr) { *ptr = 0; num = (char*)r_str_lchr (buf, ' '); if (!num) num = (char*)r_str_lchr (buf, ','); if (num) { n = atoi (num+1); *ptr = '['; memmove (num+1, ptr, strlen (ptr)+1); ptr = (char*)r_str_lchr (buf, ']'); if (n && ptr) { char *rest = strdup (ptr+1); if(n>0) sprintf (ptr, "+%d]%s", n, rest); else sprintf (ptr, "%d]%s", n, rest); free (rest); } } else *ptr = '['; } if (*buf) { *w0 = *w1 = *w2 = *w3 = 0; ptr = strchr (buf, ' '); if (ptr == NULL) ptr = strchr (buf, '\t'); if (ptr) { *ptr = '\0'; for (++ptr; *ptr==' '; ptr++); strncpy (w0, buf, sizeof(w0) - 1); strncpy (w1, ptr, sizeof(w1) - 1); optr = ptr; ptr = strchr (ptr, ','); if (ptr) { *ptr = '\0'; for (++ptr; *ptr==' '; ptr++); strncpy (w1, optr, sizeof(w1)-1); strncpy (w2, ptr, sizeof(w2)-1); ptr = strchr (ptr, ','); if (ptr) { *ptr = '\0'; for (++ptr; *ptr==' '; ptr++); strncpy (w2, optr, sizeof(w2)-1); strncpy (w3, ptr, sizeof(w3)-1); } } } { const char *wa[] = { w0, w1, w2, w3 }; int nw = 0; for (i=0; i<4; i++) { if (wa[i][0] != '\0') nw++; } replace (nw, wa, str); } } free (buf); return R_TRUE; }
R_API int r_core_visual_cmd(RCore *core, int ch) { RAsmOp op; ut64 offset = core->offset; char buf[4096]; int i, ret, offscreen, cols = core->print->cols, delta = 0; ch = r_cons_arrow_to_hjkl (ch); ch = visual_nkey (core, ch); if (ch<2) return 1; // do we need hotkeys for data references? not only calls? if (ch>='0'&& ch<='9') { ut64 off = core->asmqjmps[ch-'0']; if (off != UT64_MAX) { int delta = R_ABS ((st64)off-(st64)offset); r_io_sundo_push (core->io, offset); if (curset && delta<100) { cursor = delta; } else { r_core_visual_seek_animation (core, off); //r_core_seek (core, off, 1); } r_core_block_read (core, 1); } } else switch (ch) { case 0x0d: { r_cons_enable_mouse (R_TRUE); RAnalOp *op = r_core_anal_op (core, core->offset+cursor); if (op) { if (op->type == R_ANAL_OP_TYPE_JMP || op->type == R_ANAL_OP_TYPE_CJMP || op->type == R_ANAL_OP_TYPE_CALL) { r_io_sundo_push (core->io, offset); r_core_visual_seek_animation(core, op->jump); } } r_anal_op_free (op); } break; case 90: // shift+tab if (!strcmp (printfmt[0], "x")) printfmt[0] = "pxa"; else printfmt[0] = "x"; break; case 9: // tab { // XXX: unify diff mode detection ut64 f = r_config_get_i (core->config, "diff.from"); ut64 t = r_config_get_i (core->config, "diff.to"); if (f == t && f == 0) { core->print->col = core->print->col==1? 2: 1; } else { ut64 delta = offset - f; r_core_seek (core, t+delta, 1); r_config_set_i (core->config, "diff.from", t); r_config_set_i (core->config, "diff.to", f); } } break; case 'a': if (core->file && !(core->file->rwx & 2)) { r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n"); r_cons_any_key (); return R_TRUE; } r_cons_printf ("Enter assembler opcodes separated with ';':\n"); showcursor (core, R_TRUE); r_cons_flush (); r_cons_set_raw (R_FALSE); strcpy (buf, "wa "); r_line_set_prompt (":> "); if (r_cons_fgets (buf+3, 1000, 0, NULL) <0) buf[0]='\0'; if (*buf) { if (curset) r_core_seek (core, core->offset + cursor, 0); r_core_cmd (core, buf, R_TRUE); if (curset) r_core_seek (core, core->offset - cursor, 1); } showcursor (core, R_FALSE); r_cons_set_raw (R_TRUE); break; case '!': r_cons_2048(); break; case 'o': visual_offset (core); break; case 'A': { int oc = curset; ut64 off = curset? core->offset+cursor : core->offset; curset = 0; r_core_visual_asm (core, off); curset = oc; } break; case 'c': setcursor (core, curset?0:1); break; case 'C': color = color? 0: 1; r_config_set_i (core->config, "scr.color", color); break; case 'd': r_core_visual_define (core); break; case 'D': setdiff (core); break; case 'f': { int range, min, max; char name[256], *n; r_line_set_prompt ("flag name: "); showcursor (core, R_TRUE); if (r_cons_fgets (name, sizeof (name), 0, NULL) >=0 && *name) { n = r_str_chop (name); if (*name=='-') { if (*n) r_flag_unset (core->flags, n+1, NULL); } else { if (ocursor != -1) { min = R_MIN (cursor, ocursor); max = R_MAX (cursor, ocursor); } else { min = max = cursor; } range = max-min+1; if (range<1) range = 1; if (*n) r_flag_set (core->flags, n, core->offset + min, range, 1); } } } showcursor (core, R_FALSE); break; case 'F': r_flag_unset_i (core->flags, core->offset + cursor, NULL); break; case 'n': r_core_seek_next (core, r_config_get (core->config, "scr.nkey")); break; case 'N': r_core_seek_previous (core, r_config_get (core->config, "scr.nkey")); break; case 'i': case 'I': if (core->file && !(core->file->rwx & 2)) { r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n"); r_cons_any_key (); return R_TRUE; } showcursor (core, R_TRUE); r_cons_flush (); r_cons_set_raw (0); if (ch=='I') { strcpy (buf, "wow "); r_line_set_prompt ("insert hexpair block: "); if (r_cons_fgets (buf+4, sizeof (buf)-5, 0, NULL) <0) buf[0]='\0'; char *p = strdup (buf); int cur = core->print->cur; if (cur>=core->blocksize) cur = core->print->cur-1; snprintf (buf, sizeof (buf), "%s @ $$0!%i", p, core->blocksize-cursor); r_core_cmd (core, buf, 0); free (p); break; } delta = (ocursor!=-1)? R_MIN (cursor, ocursor): cursor; if (core->print->col==2) { strcpy (buf, "\"w "); r_line_set_prompt ("insert string: "); if (r_cons_fgets (buf+3, sizeof (buf)-4, 0, NULL) <0) buf[0]='\0'; strcat (buf, "\""); } else { r_line_set_prompt ("insert hex: "); if (ocursor != -1) { int bs = R_ABS (cursor-ocursor)+1; core->blocksize = bs; strcpy (buf, "wow "); } else { strcpy (buf, "wx "); } if (r_cons_fgets (buf+strlen (buf), sizeof (buf)-strlen (buf), 0, NULL) <0) buf[0]='\0'; } if (curset) r_core_seek (core, core->offset + delta, 0); r_core_cmd (core, buf, 1); if (curset) r_core_seek (core, offset, 1); r_cons_set_raw (1); showcursor (core, R_FALSE); break; case 'R': r_core_cmd0 (core, "ecr"); break; case 'e': r_core_visual_config (core); break; case 'E': r_core_visual_colors (core); break; case 'M': r_core_visual_mounts (core); break; case 't': r_core_visual_trackflags (core); break; case 'x': { int count = 0; RList *xrefs = NULL; RAnalRef *refi; RListIter *iter; RAnalFunction *fun; if ((xrefs = r_anal_xref_get (core->anal, core->offset))) { r_cons_gotoxy (1, 1); r_cons_printf ("[GOTO XREF]> \n"); if (r_list_empty (xrefs)) { r_cons_printf ("\tNo XREF found at 0x%"PFMT64x"\n", core->offset); r_cons_any_key (); r_cons_clear00 (); } else { r_list_foreach (xrefs, iter, refi) { fun = r_anal_fcn_find (core->anal, refi->addr, R_ANAL_FCN_TYPE_NULL); r_cons_printf (" [%i] 0x%08"PFMT64x" %s XREF 0x%08"PFMT64x" (%s) \n", count, refi->at, refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)": refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr, fun?fun->name:"unk"); if (++count > 9) break; } } } else xrefs = NULL;
static int parse(RParse *p, const char *data, char *str) { int i, len = strlen (data); char *buf, *ptr, *optr, *ptr2; char w0[64]; char w1[64]; char w2[64]; char w3[64]; char w4[64]; // malloc can be slow here :? if ((buf = malloc (len+1)) == NULL) return R_FALSE; memcpy (buf, data, len+1); if (!strcmp (data, "invalid") || !strcmp (data, "nop") || !strcmp (data, "DEPRECATED")) { str[0] = 0; return R_TRUE; } r_str_chop (buf); if (*buf) { w0[0]='\0'; w1[0]='\0'; w2[0]='\0'; w3[0]='\0'; w4[0]='\0'; ptr = strchr (buf, ' '); if (ptr == NULL) ptr = strchr (buf, '\t'); if (ptr) { *ptr = '\0'; for (++ptr; *ptr==' '; ptr++); strcpy (w0, buf); strcpy (w1, ptr); optr=ptr; ptr2 = strchr (ptr, '}'); if (ptr2) ptr = ptr2+1; ptr = strchr (ptr, ','); if (ptr) { *ptr = '\0'; for (++ptr; *ptr==' '; ptr++); strcpy (w1, optr); strcpy (w2, ptr); optr=ptr; ptr = strchr (ptr, ','); if (ptr) { *ptr = '\0'; for (++ptr; *ptr==' '; ptr++); strcpy (w2, optr); strcpy (w3, ptr); optr=ptr; // bonus ptr = strchr (ptr, ','); if (ptr) { *ptr = '\0'; for (++ptr; *ptr==' '; ptr++); strcpy (w3, optr); strcpy (w4, ptr); } } } } { const char *wa[] = { w0, w1, w2, w3, w4 }; int nw = 0; for (i=0; i<4; i++) { if (wa[i][0] != '\0') nw++; } replace (nw, wa, str); { char *p = strdup (str); p = r_str_replace (p, "+ -", "- ", 0); #if EXPERIMENTAL_ZERO p = r_str_replace (p, "zero", "0", 0); if (!memcmp (p, "0 = ", 4)) *p = 0; // nop #endif if (!strcmp (w1, w2)) { char a[32], b[32]; #define REPLACE(x,y) \ sprintf (a, x, w1, w1); \ sprintf (b, y, w1); \ p = r_str_replace (p, a, b, 0); // TODO: optimize REPLACE ("%s = %s +", "%s +="); REPLACE ("%s = %s -", "%s -="); REPLACE ("%s = %s &", "%s &="); REPLACE ("%s = %s |", "%s |="); REPLACE ("%s = %s ^", "%s ^="); REPLACE ("%s = %s >>", "%s >>="); REPLACE ("%s = %s <<", "%s <<="); } strcpy (str, p); free (p); } } } free (buf); return R_TRUE; }
char *r_bin_demangle_swift(const char *s) { #define STRCAT_BOUNDS(x) if ((x+2+strlen (out))>sizeof (out)) break; static char *swift_demangle = NULL; char out[8192]; int i, len, is_generic = 0;; int is_first = 1; int is_last = 0; int retmode = 0; if (!strncmp (s, "__", 2)) s = s + 2; if (!strncmp (s, "imp.", 4)) s = s + 4; if (!strncmp (s, "reloc.", 6)) s = s + 6; #if 0 const char *element[] = { "module", "class", "method", NULL }; #endif const char *attr = NULL; const char *attr2 = NULL; const char *q, *p = s; if (strncmp (s, "_T", 2)) { return NULL; } if (strchr (s, '\'') || strchr (s, ' ')) return NULL; if (!swift_demangle) { swift_demangle = r_file_path ("swift-demangle"); if (!swift_demangle || !strcmp (swift_demangle, "swift-demangle")) { char *xcrun = r_file_path ("xcrun"); if (xcrun) { free (swift_demangle); swift_demangle = r_str_newf ("%s swift-demangle", xcrun); free (xcrun); } } } if (swift_demangle) { char *res = r_sys_cmd_strf ("%s -compact -simplified '%s'", swift_demangle, s); if (res && !*res) { free (res); res = NULL; } return r_str_chop (res); } out[0] = 0; p += 2; if (*p == 'F' || *p == 'W') { q = numpos (p); //printf ("(%s)\n", getstring (p, (q-p))); for (i=0, len = 1; len; q += len, i++) { if (*q=='P') { // printf ("PUBLIC: "); q++; } q = getnum (q, &len); if (!len) break; #if 0 printf ("%s %d %s\n", element[i], len, getstring (q, len)); #endif // push string if (*out) strcat (out, "."); STRCAT_BOUNDS (len); strcat (out, getstring (q, len)); } p = resolve (flags, q, &attr); if (!p && *q=='U') { p = resolve (metas, q, &attr); if (attr) { //printf ("Template (%s)\n", attr); } else { //printf ("Findus (%s)\n", q); } // return 0; } if (attr) { int len; const char *name; /* get field name and then type */ resolve (types, q, &attr); //printf ("Accessor: %s\n", attr); q = getnum (q+1, &len); name = getstring (q, len); #if 0 if (name && *name) { printf ("Field Name: %s\n", name); } #endif resolve (types, q+len, &attr2); // printf ("Field Type: %s\n", attr2); do { if (name && *name) { strcat (out, "."); STRCAT_BOUNDS (strlen (name)); strcat (out, name); } if (attr && *attr) { strcat (out, "."); STRCAT_BOUNDS (strlen (attr)); strcat (out, attr); } if (attr2 && *attr2) { strcat (out, "__"); STRCAT_BOUNDS (strlen (attr2)); strcat (out, attr2); } } while (0); } else { /* parse function parameters here */ // type len value for (i=0; q; i++) { switch (*q) { case 'B': case 'T': case 'I': case 'F': p = resolve (types, q+3, &attr); // type break; case 'G': q+=2; //printf ("GENERIC\n"); if (!strncmp (q, "_V", 2)) { q+=2; } p = resolve (types, q, &attr); // type break; case 'V': // printf ("VECTOR\n"); p = resolve (types, q+1, &attr); // type break; case '_': // it's return value time! p = resolve (types, q+1, &attr); // type //printf ("RETURN TYPE %s\n", attr); break; default: p = resolve (types, q, &attr); // type } if (p) { q = p; q = getnum (p, &len); if (!strcmp (attr, "generic")) is_generic = 1; //printf ("TYPE: %s LEN %d VALUE %s\n", // attr, len, getstring (q, len)); if (!len) { if (retmode) { p = resolve (types, q+1, &attr); // type //printf ("RETURN TYPE %s\n", attr); // printf ("RET %s\n", attr); strcat (out, " -> "); STRCAT_BOUNDS (strlen (attr)); strcat (out, attr); break; } retmode = 1; len++; } if (q[len]) { const char *s = getstring (q, len); if (s && *s) { if (is_first) { strcat (out, is_generic?"<":"("); is_first = 0; } //printf ("ISLAST (%s)\n", q+len); is_last = q[len]; STRCAT_BOUNDS (strlen (attr)); strcat (out, attr); strcat (out, " "); STRCAT_BOUNDS (strlen (s)); strcat (out, s); if (is_last) { strcat (out, is_generic?">":")"); is_first = 1; } else { strcat (out, ", "); } } else { strcat (out, " -> "); STRCAT_BOUNDS (strlen (attr)); strcat (out, attr); } } else { } q += len; } else { //printf ("void\n"); q++; break; } } } } else { //printf ("Unsupported type: %c\n", *p); } if (*out) { char *p, *outstr = strdup (out); p = outstr; for (;;) { p = strstr (p, ")("); if (p) { p[0] = '_'; p[1] = '_'; p+=2; } else break; } return outstr; } return NULL; }
static int cmd_type(void *data, const char *input) { RCore *core = (RCore *)data; switch (input[0]) { // t [typename] - show given type in C syntax case 'u': // "tu" switch (input[1]) { case '?': { const char *help_message[] = { "USAGE tu[...]", "", "", "tu", "", "List all loaded unions", "tu?", "", "show this help", NULL }; r_core_cmd_help (core, help_message); } break; case 0: sdb_foreach (core->anal->sdb_types, stdprintifunion, core); break; } break; case 'k': // "tk" if (input[1] == ' ') { sdb_query (core->anal->sdb_types, input + 2); } else sdb_query (core->anal->sdb_types, "*"); fflush (stdout); break; case 's': // "ts" switch (input[1]) { case '?': { const char *help_message[] = { "USAGE ts[...]", "", "", "ts", "", "List all loaded structs", "ts?", "", "show this help", NULL }; r_core_cmd_help (core, help_message); } break; case 0: sdb_foreach (core->anal->sdb_types, stdprintifstruct, core); break; } break; case 'b': { char *p, *s = (strlen (input) > 1)? strdup (input + 2): NULL; const char *isenum; p = s? strchr (s, ' '): NULL; if (p) { *p++ = 0; // dupp in core.c (see getbitfield()) isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strcmp (isenum, "enum")) { *--p = '.'; const char *res = sdb_const_get (core->anal->sdb_types, s, 0); if (res) r_cons_println (res); else eprintf ("Invalid enum member\n"); } else { eprintf ("This is not an enum\n"); } } else { eprintf ("Missing value\n"); } free (s); } break; case 'e': { if (!input[1]) { char *name = NULL; SdbKv *kv; SdbListIter *iter; SdbList *l = sdb_foreach_list (core->anal->sdb_types); ls_foreach (l, iter, kv) { if (!strcmp (kv->value, "enum")) { if (!name || strcmp (kv->value, name)) { free (name); name = strdup (kv->key); r_cons_println (name); } } } free (name); ls_free (l); break; } if (input[1] == '?') { const char *help_message[] = { "USAGE te[...]", "", "", "te", "", "List all loaded enums", "te", " <enum> <value>", "Show name for given enum number", "te?", "", "show this help", NULL }; r_core_cmd_help (core, help_message); break; } char *p, *s = strdup (input + 2); const char *isenum; p = strchr (s, ' '); if (p) { *p++ = 0; isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strncmp (isenum, "enum", 4)) { const char *q = sdb_fmt (0, "%s.0x%x", s, (ut32)r_num_math (core->num, p)); const char *res = sdb_const_get (core->anal->sdb_types, q, 0); if (res) r_cons_println (res); } else { eprintf ("This is not an enum\n"); } } else { //eprintf ("Missing value\n"); r_core_cmdf (core, "t~&%s,=0x", s); } free (s); } break; case ' ': { const char *isenum = sdb_const_get (core->anal->sdb_types, input + 1, 0); if (isenum && !strcmp (isenum, "enum")) { eprintf ("IS ENUM! \n"); } else { char *fmt = r_anal_type_format (core->anal, input + 1); if (fmt) { r_str_chop (fmt); r_cons_printf ("pf %s\n", fmt); free (fmt); } else eprintf ("Cannot find '%s' type\n", input + 1); } } break; // t* - list all types in 'pf' syntax case '*': sdb_foreach (core->anal->sdb_types, typelist, core); break; case 0: sdb_foreach (core->anal->sdb_types, sdbforcb, core); break; case 'o': if (!r_sandbox_enable (0)) { if (input[1] == ' ') { const char *filename = input + 2; char *homefile = NULL; if (*filename == '~') { if (filename[1] && filename[2]) { homefile = r_str_home (filename + 2); filename = homefile; } } if (!strcmp (filename, "-")) { char *out, *tmp; tmp = r_core_editor (core, NULL, ""); if (tmp) { out = r_parse_c_string (tmp); if (out) { // r_cons_strcat (out); save_parsed_type (core, out); free (out); } free (tmp); } } else { char *out = r_parse_c_file (filename); if (out) { //r_cons_strcat (out); save_parsed_type (core, out); free (out); } //r_anal_type_loadfile (core->anal, filename); } free (homefile); } else if (input[1] == 's') { const char *dbpath = input + 3; if (r_file_exists (dbpath)) { Sdb *db_tmp = sdb_new (0, dbpath, 0); sdb_merge (core->anal->sdb_types, db_tmp); sdb_close (db_tmp); sdb_free (db_tmp); } } } else { eprintf ("Sandbox: system call disabled\n"); } break; // td - parse string with cparse engine and load types from it case 'd': if (input[1] == '?') { const char *help_message[] = { "Usage:", "\"td [...]\"", "", "td", "[string]", "Load types from string", NULL }; r_core_cmd_help (core, help_message); r_cons_printf ("Note: The td command should be put between double quotes\n" "Example: \" td struct foo {int bar;int cow};\"" "\nt"); } else if (input[1] == ' ') { char tmp[8192]; snprintf (tmp, sizeof (tmp) - 1, "%s;", input + 2); //const char *string = input + 2; //r_anal_str_to_type (core->anal, string); char *out = r_parse_c_string (tmp); if (out) { //r_cons_strcat (out); save_parsed_type (core, out); free (out); } } else { eprintf ("Invalid use of td. See td? for help\n"); } break; // tl - link a type to an address case 'l': switch (input[1]) { case '?': { const char *help_message[] = { "Usage:", "", "", "tl", "", "list all links in readable format", "tl", "[typename]", "link a type to current adress.", "tl", "[typename] = [address]", "link type to given address.", "tls", "[address]", "show link at given address", "tl-*", "", "delete all links.", "tl-", "[address]", "delete link at given address.", "tl*", "", "list all links in radare2 command format", "tl?", "", "print this help.", NULL }; r_core_cmd_help (core, help_message); } break; case ' ': { char *type = strdup (input + 2); char *ptr = strchr (type, '='); ut64 addr; if (ptr) { *ptr++ = 0; r_str_chop (ptr); if (ptr && *ptr) { addr = r_num_math (core->num, ptr); } else { eprintf ("address is unvalid\n"); free (type); break; } } else { addr = core->offset; } r_str_chop (type); char *tmp = sdb_get (core->anal->sdb_types, type, 0); if (tmp && *tmp) { r_anal_type_link (core->anal, type, addr); free (tmp); } else { eprintf ("unknown type %s\n", type); } free (type); } break; case 's': { int ptr; char *addr = strdup (input + 2); SdbKv *kv; SdbListIter *sdb_iter; SdbList *sdb_list = sdb_foreach_list (core->anal->sdb_types); r_str_chop (addr); ptr = r_num_math (NULL, addr); //r_core_cmdf (core, "tl~0x%08"PFMT64x" = ", addr); ls_foreach (sdb_list, sdb_iter, kv) { char *linkptr; if (strncmp (kv->key, "link.", strlen ("link."))) { continue; } linkptr = sdb_fmt (-1,"0x%s", kv->key + strlen ("link.")); if (ptr == r_num_math (NULL, linkptr)) { linklist_readable (core, kv->key, kv->value); } } free (addr); ls_free (sdb_list); } break; case '-': switch (input[2]) { case '*': sdb_foreach (core->anal->sdb_types, sdbdeletelink, core); break; case ' ': { const char *ptr = input + 3; ut64 addr = r_num_math (core->num, ptr); r_anal_type_unlink (core->anal, addr); } break; } break; case '*': sdb_foreach (core->anal->sdb_types, linklist, core); break; case '\0': sdb_foreach (core->anal->sdb_types, linklist_readable, core); break; }
static int parse(RParse *p, const char *data, char *str) { int i, len = strlen (data); char w0[WSZ]; char w1[WSZ]; char w2[WSZ]; char w3[WSZ]; char w4[WSZ]; char *buf, *ptr, *optr; if (!strcmp (data, "jr ra")) { strcpy (str, "ret"); return true; } // malloc can be slow here :? if (!(buf = malloc (len+1))) return false; memcpy (buf, data, len+1); r_str_replace_char (buf, '(', ','); r_str_replace_char (buf, ')', ' '); r_str_chop (buf); if (*buf) { w0[0]='\0'; w1[0]='\0'; w2[0]='\0'; w3[0]='\0'; w4[0]='\0'; ptr = strchr (buf, ' '); if (!ptr) ptr = strchr (buf, '\t'); if (ptr) { *ptr = '\0'; for (++ptr; *ptr==' '; ptr++); strncpy (w0, buf, WSZ - 1); strncpy (w1, ptr, WSZ - 1); optr=ptr; ptr = strchr (ptr, ','); if (ptr) { *ptr = '\0'; for (++ptr; *ptr==' '; ptr++); strncpy (w1, optr, WSZ - 1); strncpy (w2, ptr, WSZ - 1); optr=ptr; ptr = strchr (ptr, ','); if (ptr) { *ptr = '\0'; for (++ptr; *ptr==' '; ptr++); strncpy (w2, optr, WSZ - 1); strncpy (w3, ptr, WSZ - 1); optr=ptr; // bonus ptr = strchr (ptr, ','); if (ptr) { *ptr = '\0'; for (++ptr; *ptr==' '; ptr++); strncpy (w3, optr, WSZ - 1); strncpy (w4, ptr, WSZ - 1); } } } } { const char *wa[] = { w0, w1, w2, w3, w4 }; int nw = 0; for (i=0; i<4; i++) { if (wa[i][0] != '\0') nw++; } replace (nw, wa, str); { char *p = strdup (str); p = r_str_replace (p, "+ -", "- ", 0); p = r_str_replace(p, " + ]", " + 0]", 0); #if EXPERIMENTAL_ZERO p = r_str_replace (p, "zero", "0", 0); if (!memcmp (p, "0 = ", 4)) *p = 0; // nop #endif if (!strcmp (w1, w2)) { char a[32], b[32]; #define REPLACE(x,y) \ sprintf (a, x, w1, w1); \ sprintf (b, y, w1); \ p = r_str_replace (p, a, b, 0); // TODO: optimize REPLACE ("%s = %s +", "%s +="); REPLACE ("%s = %s -", "%s -="); REPLACE ("%s = %s &", "%s &="); REPLACE ("%s = %s |", "%s |="); REPLACE ("%s = %s ^", "%s ^="); REPLACE ("%s = %s >>", "%s >>="); REPLACE ("%s = %s <<", "%s <<="); } p = r_str_replace (p, ":", "0000", 0); strcpy (str, p); free (p); } } } free (buf); return true; }
static int parse(RParse *p, const char *data, char *str) { int i, len = strlen (data); char w0[WSZ]; char w1[WSZ]; char w2[WSZ]; char w3[WSZ]; char w4[WSZ]; char *buf, *ptr, *optr, *par; // malloc can be slow here :? if (!(buf = malloc (len + 1))) { return false; } memcpy (buf, data, len + 1); r_str_chop (buf); if (*buf) { w0[0] = '\0'; w1[0] = '\0'; w2[0] = '\0'; w3[0] = '\0'; w4[0] = '\0'; ptr = strchr (buf, ' '); if (!ptr) { ptr = strchr (buf, '\t'); } if (ptr) { *ptr = '\0'; for (++ptr; *ptr == ' '; ptr++) { //nothing to see here } strncpy (w0, buf, WSZ - 1); strncpy (w1, ptr, WSZ - 1); optr = ptr; ptr = strchr (ptr, ','); if (ptr) { *ptr = '\0'; for (++ptr; *ptr == ' '; ptr++) { //nothing to see here } strncpy (w1, optr, WSZ - 1); strncpy (w2, ptr, WSZ - 1); optr = ptr; ptr = strchr (ptr, ','); if (ptr) { *ptr = '\0'; for (++ptr; *ptr == ' '; ptr++) { //nothing to see here } strncpy (w2, optr, WSZ - 1); strncpy (w3, ptr, WSZ - 1); optr = ptr; // bonus ptr = strchr (ptr, ','); if (ptr) { *ptr = '\0'; for (++ptr; *ptr == ' '; ptr++) { //nothing to see here } strncpy (w3, optr, WSZ - 1); strncpy (w4, ptr, WSZ - 1); } } } } else { strncpy (w0, buf, WSZ - 1); } { const char *wa[] = { w0, w1, w2, w3, w4 }; int nw = 0; for (i = 0; i < 5; i++) { if (wa[i][0] != '\0') { nw++; } } replace (nw, wa, str); } } free (buf); return true; }
R_API int r_core_visual_cmd(RCore *core, int ch) { RAsmOp op; char buf[4096]; int i, ret, offscreen, cols = core->print->cols; ch = r_cons_arrow_to_hjkl (ch); ch = visual_nkey (core, ch); if (ch<2) return 1; // do we need hotkeys for data references? not only calls? if (ch>='0'&& ch<='9') { r_io_sundo_push (core->io, core->offset); r_core_seek (core, core->asmqjmps[ch-'0'], 1); r_core_block_read (core, 1); } else switch (ch) { case 9: // tab { // XXX: unify diff mode detection ut64 f = r_config_get_i (core->config, "diff.from"); ut64 t = r_config_get_i (core->config, "diff.to"); if (f == t && f == 0) { core->print->col = core->print->col==1? 2: 1; } else { ut64 delta = core->offset - f; r_core_seek (core, t+delta, 1); r_config_set_i (core->config, "diff.from", t); r_config_set_i (core->config, "diff.to", f); } } break; case 'c': // XXX dupped flag imho setcursor (core, curset ^ 1); break; case 'd': r_core_visual_define (core); break; case 'D': setdiff (core); break; case 'C': color ^= 1; if (color) flags |= R_PRINT_FLAGS_COLOR; else flags &= ~(flags&R_PRINT_FLAGS_COLOR); r_config_set_i (core->config, "scr.color", color); r_print_set_flags (core->print, flags); break; case 'f': { int range; char name[256], *n; r_line_set_prompt ("flag name: "); if (r_cons_fgets (name, sizeof (name), 0, NULL) >=0 && *name) { n = r_str_chop (name); if (*name=='-') { if (*n) r_flag_unset (core->flags, n+1, NULL); } else { range = curset? (R_ABS (cursor-ocursor)+1): 1; if (range<1) range = 1; if (*n) r_flag_set (core->flags, n, core->offset + cursor, range, 1); } } } break; case 'F': r_flag_unset_i (core->flags, core->offset + cursor, NULL); break; case 'n': r_core_seek_next (core, r_config_get (core->config, "scr.nkey")); break; case 'N': r_core_seek_previous (core, r_config_get (core->config, "scr.nkey")); break; case 'A': { int oc = curset; ut64 off = curset? core->offset+cursor : core->offset; curset = 0; r_core_visual_asm (core, off); curset = oc; } break; case 'a': if (core->file && !(core->file->rwx & 2)) { r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n"); r_cons_any_key (); return R_TRUE; } r_cons_printf ("Enter assembler opcodes separated with ';':\n"); r_cons_show_cursor (R_TRUE); r_cons_flush (); r_cons_set_raw (R_FALSE); strcpy (buf, "wa "); r_line_set_prompt (":> "); if (r_cons_fgets (buf+3, 1000, 0, NULL) <0) buf[0]='\0'; if (*buf) { if (curset) r_core_seek (core, core->offset + cursor, 0); r_core_cmd (core, buf, R_TRUE); if (curset) r_core_seek (core, core->offset - cursor, 1); } r_cons_show_cursor (R_FALSE); r_cons_set_raw (R_TRUE); break; case 'i': case 'I': if (core->file && !(core->file->rwx & 2)) { r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n"); r_cons_any_key (); return R_TRUE; } r_cons_show_cursor (R_TRUE); r_cons_flush (); r_cons_set_raw (0); if (ch=='I') { strcpy (buf, "wow "); r_line_set_prompt ("insert hexpair block: "); if (r_cons_fgets (buf+4, sizeof (buf)-3, 0, NULL) <0) buf[0]='\0'; char *p = strdup (buf); int cur = core->print->cur; if (cur>=core->blocksize) cur = core->print->cur-1; snprintf (buf, sizeof (buf), "%s @ $$0!%i", p, core->blocksize-cursor); r_core_cmd (core, buf, 0); free (p); break; } if (core->print->col==2) { strcpy (buf, "w "); r_line_set_prompt ("insert string: "); if (r_cons_fgets (buf+2, sizeof (buf)-3, 0, NULL) <0) buf[0]='\0'; } else { strcpy (buf, "wx "); r_line_set_prompt ("insert hex: "); if (r_cons_fgets (buf+3, sizeof (buf)-4, 0, NULL) <0) buf[0]='\0'; } if (curset) r_core_seek (core, core->offset + cursor, 0); r_core_cmd (core, buf, 1); if (curset) r_core_seek (core, core->offset - cursor, 1); r_cons_set_raw (1); r_cons_show_cursor (R_FALSE); break; case 'e': r_core_visual_config (core); break; case 'M': r_core_visual_mounts (core); break; case 't': r_core_visual_trackflags (core); break; case 'x': { int count = 0; RList *xrefs = NULL; RAnalRef *refi; RListIter *iter; RAnalFunction *fun; if ((xrefs = r_anal_xref_get (core->anal, core->offset))) { r_cons_printf ("XREFS:\n"); if (r_list_empty (xrefs)) { r_cons_printf ("\tNo XREF found at 0x%"PFMT64x"\n", core->offset); r_cons_any_key (); r_cons_clear00 (); } else { r_list_foreach (xrefs, iter, refi) { fun = r_anal_fcn_find (core->anal, refi->addr, R_ANAL_FCN_TYPE_NULL); r_cons_printf ("\t[%i] %s XREF 0x%08"PFMT64x" (%s)\n", count, refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)": refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr, fun?fun->name:"unk"); if (++count > 9) break; } } } else xrefs = NULL;
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); }