R_API void r_core_print_func_args(RCore *core) { RListIter *iter; bool color = r_config_get_i (core->config, "scr.color"); if (!core->anal) { return; } if (!core->anal->reg) { return; } const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC); ut64 cur_addr = r_reg_getv (core->anal->reg, pc); RAnalOp *op = r_core_anal_op (core, cur_addr, R_ANAL_OP_MASK_BASIC); if (!op) { return; } if (op->type == R_ANAL_OP_TYPE_CALL) { RAnalFunction *fcn; RAnalFuncArg *arg; int i; int nargs = 0; bool onstack = false; const char *fcn_name = NULL; ut64 pcv = op->jump; if (pcv == UT64_MAX) { pcv = op->ptr; } fcn = r_anal_get_fcn_at (core->anal, pcv, 0); if (fcn) { fcn_name = fcn->name; } else { if (core->flags) { RFlagItem *item = r_flag_get_i (core->flags, pcv); if (item) { fcn_name = item->name; } } } RList *list = r_core_get_func_args (core, fcn_name); if (!r_list_empty (list)) { int argcnt = 0; r_list_foreach (list, iter, arg) { if (arg->cc_source && !strncmp (arg->cc_source, "stack", 5)) { onstack = true; } print_arg_str (argcnt, arg->name, color); print_format_values (core, arg->fmt, onstack, arg->src, color); argcnt++; } } else {
static int filter(RParse *p, RFlag *f, char *data, char *str, int len) { char *ptr = data, *ptr2; //RListIter *iter; RFlagItem *flag; ut64 off; ptr2 = NULL; while ((ptr = strstr (ptr, "0x"))) { for (ptr2 = ptr; *ptr2 && !isx86separator (*ptr2); ptr2++); off = r_num_math (NULL, ptr); if (!off) { ptr = ptr2; continue; } flag = r_flag_get_i (f, off); if (flag && strchr (flag->name, '.')) { // XXX. tooslow but correct //r_list_foreach (f->flags, iter, flag) { if (flag->offset == off && strchr (flag->name, '.')) { if (p->notin_flagspace != -1) { if (p->flagspace == flag->space) continue; } else if (p->flagspace != -1 && \ (p->flagspace != flag->space)) { continue; } *ptr = 0; snprintf (str, len, "%s%s%s", data, flag->name, ptr2!=ptr? ptr2: ""); return R_TRUE; } //} ptr = ptr2; } strncpy (str, data, len); return R_FALSE; }
static int cmd_meta(void *data, const char *input) { RCore *core = (RCore*)data; int i; RAnalFunction *f; switch (*input) { case 'j': case '*': r_meta_list (core->anal, R_META_TYPE_ANY, *input); break; case 'L': cmd_meta_lineinfo (core, input + 1); break; case 'C': cmd_meta_comment (core, input); break; case 'h': /* comment */ case 's': /* string */ case 'd': /* data */ case 'm': /* magic */ case 'f': /* formatted */ cmd_meta_hsdmf (core, input); break; case '-': if (input[1]!='*') { i = r_num_math (core->num, input+((input[1]==' ')?2:1)); r_meta_del (core->anal, R_META_TYPE_ANY, core->offset, i, ""); } else r_meta_cleanup (core->anal, 0LL, UT64_MAX); break; case '\0': case '?':{ const char* help_msg[] = { "Usage:", "C[-LCvsdfm?] [...]", " # Metadata management", "C*", "", "list meta info in r2 commands", "C-", " [len] [[@]addr]", "delete metadata at given address range", "CL", "[-][*] [file:line] [addr]", "show or add 'code line' information (bininfo)", "CS", "[-][space]", "manage meta-spaces to filter comments, etc..", "CC", "[-] [comment-text] [@addr]", "add/remove comment", "CC!", " [@addr]", "edit comment with $EDITOR", "CCa", "[-at]|[at] [text] [@addr]", "add/remove comment at given address", "CCu", " [comment-text] [@addr]", "add unique comment", "Cs", "[-] [size] [@addr]", "add string", "Ch", "[-] [size] [@addr]", "hide data", "Cd", "[-] [size] [@addr]", "hexdump data", "Cf", "[-] [sz] [fmt..] [@addr]", "format memory (see pf?)", "Cm", "[-] [sz] [fmt..] [@addr]", "magic parse (see pm?)", NULL}; r_core_cmd_help (core, help_msg); } break; case 'F': f = r_anal_get_fcn_in (core->anal, core->offset, R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM); if (f) r_anal_str_to_fcn (core->anal, f, input+2); else eprintf ("Cannot find function here\n"); break; case 'S': { RSpaces *ms = &core->anal->meta_spaces; /** copypasta from `fs`.. this must be refactorized to be shared */ switch (input[1]) { case '?': { const char *help_msg[] = { "Usage: CS","[*] [+-][metaspace|addr]", " # Manage metaspaces", "CS","","display metaspaces", "CS"," *","select all metaspaces", "CS"," metaspace","select metaspace or create if it doesn't exist", "CS","-metaspace","remove metaspace", "CS","-*","remove all metaspaces", "CS","+foo","push previous metaspace and set", "CS","-","pop to the previous metaspace", // "CSm"," [addr]","move metas at given address to the current metaspace", "CSr"," newname","rename selected metaspace", NULL}; r_core_cmd_help (core, help_msg); } break; case '+': r_space_push (ms, input+2); break; case 'r': if (input[2]==' ') r_space_rename (ms, NULL, input+2); else eprintf ("Usage: CSr [newname]\n"); break; case '-': if (input[2]) { if (input[2]=='*') { r_space_unset (ms, NULL); } else { r_space_unset (ms, input+2); } } else { r_space_pop (ms); } break; case 'j': case '\0': case '*': r_space_list (ms, input[1]); break; case ' ': r_space_set (ms, input+2); break; #if 0 case 'm': { RFlagItem *f; ut64 off = core->offset; if (input[2] == ' ') off = r_num_math (core->num, input+2); f = r_flag_get_i (core->flags, off); if (f) { f->space = core->flags->space_idx; } else eprintf ("Cannot find any flag at 0x%"PFMT64x".\n", off); } break; #endif default: { int i, j = 0; for (i=0; i<R_FLAG_SPACES_MAX; i++) { if (ms->spaces[i]) r_cons_printf ("%02d %c %s\n", j++, (i==ms->space_idx)?'*':' ', ms->spaces[i]); } } break; } } break; } return R_TRUE; }
static int cmd_meta_hsdmf (RCore *core, const char *input) { int n, type = input[0]; char *t = 0, *p, name[256]; ut64 addr_end = 0LL, addr = core->offset; switch (input[1]) { case '?': eprintf ("See C?\n"); break; case '-': switch (input[2]) { case '*': core->num->value = r_meta_del (core->anal, input[0], 0, UT64_MAX, NULL); break; case ' ': addr = r_num_math (core->num, input+3); default: core->num->value = r_meta_del (core->anal, input[0], addr, 1, NULL); break; } break; case '*': r_meta_list (core->anal, input[0], 1); break; case '!': { char *out, *comment = r_meta_get_string ( core->anal, R_META_TYPE_COMMENT, addr); out = r_core_editor (core, NULL, comment); if (out) { //r_meta_add (core->anal->meta, R_META_TYPE_COMMENT, addr, 0, out); r_core_cmdf (core, "CC-@0x%08"PFMT64x, addr); //r_meta_del (core->anal->meta, input[0], addr, addr+1, NULL); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, out); free (out); } free (comment); } break; case ' ': case '\0': if (type!='z' && !input[1]) { r_meta_list (core->anal, type, 0); break; } t = strdup (input+2); p = NULL; n = 0; strncpy (name, t, sizeof (name)-1); if (*input != 'C') { n = r_num_math (core->num, t); if (type == 'f') { p = strchr (t, ' '); if (p) n = r_print_format (core->print, addr, core->block, core->blocksize, p+1, -1, NULL, NULL); } if (type == 's') { /* This is kept for compatibility with old projects. * Somewhat broken, but project will get corrected on * save and reload. */ p = strchr (t, ' '); if (p) addr = r_num_math (core->num, p+1); } if (!*t || n>0) { RFlagItem *fi; p = strchr (t, ' '); if (p) { *p = '\0'; strncpy (name, p+1, sizeof (name)-1); } else switch (type) { case 'z': type='s'; case 's': // TODO: filter \n and so on :) strncpy (name, t, sizeof (name)-1); name[sizeof (name)-1] = '\0'; r_core_read_at (core, addr, (ut8*)name, sizeof (name)-1); if (n < sizeof(name)) name[n] = '\0'; else name[sizeof (name)-1] = '\0'; break; default: fi = r_flag_get_i (core->flags, addr); if (fi) strncpy (name, fi->name, sizeof (name)-1); } } else if (n<1) { eprintf ("Invalid length %d\n", n); return R_FALSE; } } if (!n) n++; addr_end = addr + n; r_meta_add (core->anal, type, addr, addr_end, name); free (t); //r_meta_cleanup (core->anal->meta, 0LL, UT64_MAX); break; default: eprintf ("Missing space after CC\n"); break; } return R_TRUE; }
static bool rtti_itanium_print_class_type_info_recurse(RVTableContext *context, ut64 atAddress, int mode) { bool use_json = mode == 'j'; ut64 colRefAddr = atAddress - context->word_size; //Vtable: Type Info ut64 colAddr; //Type Info ut64 class_type_offset; if (!context->read_addr (context->anal, colRefAddr, &colAddr)) { return false; } if (!context->read_addr (context->anal, colAddr, &class_type_offset)) { return false; } RCore *core = context->anal->coreb.core; if (!core) { return false; } class_type_offset -= 2 * context->word_size; RFlagItem *flag; flag = r_flag_get_i(core->flags, class_type_offset); if (!flag) { eprintf ("No RTTI found\n"); return false; } if (!r_str_cmp (flag->name, vmi_class_type_info_name, r_str_len_utf8 (flag->name))) { vmi_class_type_info vmi_cti; if (!rtti_itanium_read_vmi_class_type_info (context, colAddr, &vmi_cti)) { eprintf ("Failed to parse Type Info at 0x%08"PFMT64x" (referenced from 0x%08"PFMT64x")\n", colAddr, colRefAddr); return false; } if (use_json) { rtti_itanium_print_vmi_class_type_info_json (&vmi_cti, colAddr); } else { rtti_itanium_print_vmi_class_type_info (&vmi_cti, colAddr, ""); } } if (!r_str_cmp (flag->name, si_class_type_info_name, r_str_len_utf8 (flag->name))) { si_class_type_info si_cti; if (!rtti_itanium_read_si_class_type_info (context, colAddr, &si_cti)) { eprintf ("Failed to parse Type Info at 0x%08"PFMT64x" (referenced from 0x%08"PFMT64x")\n", colAddr, colRefAddr); return false; } if (use_json) { rtti_itanium_print_si_class_type_info_json (&si_cti, colAddr); } else { rtti_itanium_print_si_class_type_info (&si_cti, colAddr, ""); } } if (!r_str_cmp (flag->name, class_type_info_name, r_str_len_utf8 (flag->name))) { class_type_info cti; if (!rtti_itanium_read_class_type_info (context, colAddr, &cti)) { eprintf ("Failed to parse Type Info at 0x%08"PFMT64x" (referenced from 0x%08"PFMT64x")\n", colAddr, colRefAddr); return false; } if (use_json) { rtti_itanium_print_class_type_info_json (&cti, colAddr); } else { rtti_itanium_print_class_type_info (&cti, colAddr, ""); } } return true; }
static int cmd_meta_hsdmf(RCore *core, const char *input) { int n, type = input[0]; char *t = 0, *p, name[256]; int repeat = 1; ut64 addr_end = 0LL, addr = core->offset; switch (input[1]) { case '?': eprintf ("See C?\n"); break; case '-': switch (input[2]) { case '*': core->num->value = r_meta_del (core->anal, input[0], 0, UT64_MAX, NULL); break; case ' ': addr = r_num_math (core->num, input+3); /* fallthrough */ default: core->num->value = r_meta_del (core->anal, input[0], addr, 1, NULL); break; } break; case '*': r_meta_list (core->anal, input[0], 1); break; case '!': { char *out, *comment = r_meta_get_string ( core->anal, R_META_TYPE_COMMENT, addr); out = r_core_editor (core, NULL, comment); if (out) { //r_meta_add (core->anal->meta, R_META_TYPE_COMMENT, addr, 0, out); r_core_cmdf (core, "CC-@0x%08"PFMT64x, addr); //r_meta_del (core->anal->meta, input[0], addr, addr+1, NULL); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, out); free (out); } free (comment); } break; case ' ': case '\0': if (type!='z' && input[1] == '*') { r_meta_list (core->anal, type, 0); break; } if (type == 'z') { type = 's'; } if (strlen (input) > 2) { char *rep = strchr (input + 2, '['); if (!rep) rep = strchr (input + 2, ' '); if (rep) { repeat = r_num_get (core->num, rep + 1); } } int repcnt = 0; if (repeat < 1) repeat = 1; while (repcnt < repeat) { t = strdup (r_str_chop_ro (input + 1)); p = NULL; n = 0; strncpy (name, t, sizeof (name) - 1); if (type != 'C') { n = r_num_math (core->num, t); if (type == 'f') { p = strchr (t, ' '); if (p) { n = r_print_format (core->print, addr, core->block, core->blocksize, p + 1, 0, NULL, NULL); } } if (type == 's') { strncpy (name, t, sizeof (name) - 1); (void)r_core_read_at (core, addr, (ut8*)name, sizeof (name) - 1); name[sizeof (name) - 1] = '\0'; int name_len = strlen (name); if (n == 0) { n = name_len + 1; } else { if (n > 0 && n < name_len) { name[n] = 0; } } } if (!*t || n > 0) { RFlagItem *fi; p = strchr (t, ' '); if (p) { *p = '\0'; strncpy (name, p + 1, sizeof (name)-1); } else { if (type != 's') { fi = r_flag_get_i (core->flags, addr); if (fi) strncpy (name, fi->name, sizeof (name)-1); } } } else if (n < 1) { eprintf ("Invalid length %d\n", n); return false; } } if (!n) n++; addr_end = addr + n; r_meta_add (core->anal, type, addr, addr_end, name); free (t); repcnt ++; addr = addr_end; } //r_meta_cleanup (core->anal->meta, 0LL, UT64_MAX); break; default: eprintf ("Missing space after CC\n"); break; } return true; }
static int cmd_meta_hsdmf(RCore *core, const char *input) { int n, type = input[0]; char *t = 0, *p, name[256]; int repeat = 1; ut64 addr_end = 0LL, addr = core->offset; switch (input[1]) { case '?': eprintf ("See C?\n"); break; case '-': switch (input[2]) { case '*': core->num->value = r_meta_del (core->anal, input[0], 0, UT64_MAX, NULL); break; case ' ': addr = r_num_math (core->num, input+3); /* fallthrough */ default: core->num->value = r_meta_del (core->anal, input[0], addr, 1, NULL); break; } break; case '*': r_meta_list (core->anal, input[0], 1); break; case '!': { char *out, *comment = r_meta_get_string ( core->anal, R_META_TYPE_COMMENT, addr); out = r_core_editor (core, NULL, comment); if (out) { //r_meta_add (core->anal->meta, R_META_TYPE_COMMENT, addr, 0, out); r_core_cmdf (core, "CC-@0x%08"PFMT64x, addr); //r_meta_del (core->anal->meta, input[0], addr, addr+1, NULL); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, out); free (out); } free (comment); } break; case ' ': case '\0': if (type != 'z' && input[1] == '*') { r_meta_list (core->anal, type, 0); break; } if (type == 'z') { type = 's'; } if (strlen (input) > 2) { char *rep = strchr (input + 2, '['); if (!rep) rep = strchr (input + 2, ' '); if (rep) { repeat = r_num_get (core->num, rep + 1); } } int repcnt = 0; if (repeat < 1) { repeat = 1; } while (repcnt < repeat) { t = strdup (r_str_chop_ro (input + 1)); p = NULL; n = 0; strncpy (name, t, sizeof (name) - 1); if (type != 'C') { n = r_num_math (core->num, t); if (type == 'f') { // "Cf" p = strchr (t, ' '); if (p) { if (n < 1) { n = r_print_format_struct_size (p + 1, core->print, 0); if (n < 1) { eprintf ("Cannot resolve struct size\n"); n = 32; // } } int r = r_print_format (core->print, addr, core->block, n, p + 1, 0, NULL, NULL); if (r < 0) { n = -1; } } else { eprintf ("Usage: Cf [size] [pf-format-string]\n"); break; } } else if (type == 's') { //Cs char tmp[256] = {0}; int i, j, name_len = 0; (void)r_core_read_at (core, addr, (ut8*)tmp, sizeof (tmp) - 1); name_len = r_str_nlen_w (tmp, sizeof (tmp)); //handle wide strings for (i = 0, j = 0; i < sizeof (name); i++, j++) { name[i] = tmp[j]; if (!tmp[j]) { break; } if (!tmp[j + 1]) { if (j + 3 < sizeof (tmp)) { if (tmp[j + 3]) { break; } } j++; } } name[sizeof (name) - 1] = '\0'; if (n == 0) { n = name_len + 1; } else { if (n > 0 && n < name_len) { name[n] = 0; } } } if (n < 1) { /* invalid length, do not insert into db */ return false; } if (!*t || n > 0) { RFlagItem *fi; p = strchr (t, ' '); if (p) { *p = '\0'; strncpy (name, p + 1, sizeof (name)-1); } else { if (type != 's') { fi = r_flag_get_i (core->flags, addr); if (fi) strncpy (name, fi->name, sizeof (name)-1); } } } } if (!n) { n++; } addr_end = addr + n; r_meta_add (core->anal, type, addr, addr_end, name); free (t); repcnt ++; addr = addr_end; } //r_meta_cleanup (core->anal->meta, 0LL, UT64_MAX); break; default: eprintf ("Missing space after CC\n"); break; } return true; }