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)", "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; } return R_TRUE; }
static int cmd_meta(void *data, const char *input) { RCore *core = (RCore*)data; int i; char *t = 0; 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 '?': r_cons_strcat ( "|Usage: C[-LCvsdfm?] [...]\n" "| C* List meta info in r2 commands\n" "| C- [len] [@][ addr] delete metadata at given address range\n" "| CL[-][*] [file:line] [addr] show or add 'code line' information (bininfo)\n" "| CC[-] [comment-text] add/remove comment. Use CC! to edit with $EDITOR\n" "| CCa[-at]|[at] [text] add/remove comment at given address\n" "| Cs[-] [size] [[addr]] add string\n" "| Ch[-] [size] [@addr] hide data\n" "| Cd[-] [size] hexdump data\n" "| Cf[-] [sz] [fmt..] format memory (see pf?)\n" "| Cm[-] [sz] [fmt..] magic parse (see pm?)\n"); break; case 'F': f = r_anal_fcn_find (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; } if (t) free (t); return R_TRUE; }
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 int cmd_meta_comment(RCore *core, const char *input) { ut64 addr = core->offset; switch (input[1]) { case '?': { const char* help_msg[] = { "Usage:", "CC[-+!*au] [base64:..|str] @ addr", "", "CC", "", "list all comments in human friednly form", "CC*", "", "list all comments in r2 commands", "CC.", "", "show comment at current offset", "CC", " or maybe not", "append comment at current address", "CC+", " same as above", "append comment at current address", "CC!", "", "edit comment using cfg.editor (vim, ..)", "CC-", " @ cmt_addr", "remove comment at given address", "CCu", " good boy @ addr", "add good boy comment at given address", "CCu", " base64:AA== @ addr", "add comment in base64", NULL}; r_core_cmd_help (core, help_msg); } break; case '.': { char *comment = r_meta_get_string ( core->anal, R_META_TYPE_COMMENT, addr); if (comment) { r_cons_printf ("%s\n", comment); free (comment); } } break; case 0: r_meta_list (core->anal, R_META_TYPE_COMMENT, 0); 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 ' ': { const char* newcomment = input+2; char *text, *nc; while (*newcomment==' ') newcomment++; char *comment = r_meta_get_string ( core->anal, R_META_TYPE_COMMENT, addr); nc = strdup (newcomment); r_str_unescape (nc); if (comment) { text = malloc (strlen (comment)+strlen (newcomment)+2); strcpy (text, comment); strcat (text, "\n"); strcat (text, nc); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, text); free (text); } else { r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, nc); } free (nc); } break; case '*': r_meta_list (core->anal, R_META_TYPE_COMMENT, 1); break; case '-': r_meta_del (core->anal, R_META_TYPE_COMMENT, core->offset, 1, NULL); break; case 'u': // { char *newcomment; const char *arg = input+2; while (*arg && *arg == ' ') arg++; if (!strncmp (arg, "base64:", 7)) { char *s = (char *)sdb_decode (arg+7, NULL); if (s) { newcomment = s; } else { newcomment = NULL; } } else { newcomment = strdup (arg); } if (newcomment) { char *comment = r_meta_get_string ( core->anal, R_META_TYPE_COMMENT, addr); if (!comment || (comment && !strstr (comment, newcomment))) { r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, newcomment); } free (comment); free (newcomment); } } break; case 'a': { char *s, *p; s = strchr (input, ' '); if (s) { s = strdup (s+1); } else { eprintf ("Usage\n"); return R_FALSE; } p = strchr (s, ' '); if (p) *p++ = 0; ut64 addr; if (input[2]=='-') { if (input[3]) { addr = r_num_math (core->num, input+3); r_meta_del (core->anal, R_META_TYPE_COMMENT, addr, 1, NULL); } else eprintf ("Usage: CCa-[address]\n"); free (s); return R_TRUE; } addr = r_num_math (core->num, s); // Comment at if (p) { if (input[2]=='+') { char *text = p; char *comment = r_meta_get_string ( core->anal, R_META_TYPE_COMMENT, addr); if (comment) { text = malloc (strlen (comment) + strlen (p)+2); strcpy (text, comment); strcat (text, "\n"); strcat (text, p); r_meta_add (core->anal, R_META_TYPE_COMMENT, addr, addr+1, text); free (text); } else { r_meta_add (core->anal, R_META_TYPE_COMMENT, addr, addr+1, p); } } else { r_meta_add (core->anal, R_META_TYPE_COMMENT, addr, addr+1, p); } } else eprintf ("Usage: CCa [address] [comment]\n"); free (s); return R_TRUE; } } return R_TRUE; }
static int cmd_meta_comment(RCore *core, const char *input) { ut64 addr = core->offset; if (input[1] == '+' || input[1] == ' ') { const char* newcomment = input+2; char *text; while (*newcomment==' ') newcomment++; char *comment = r_meta_get_string ( core->anal, R_META_TYPE_COMMENT, addr); if (comment) { text = malloc (strlen (comment)+strlen (newcomment)+2); strcpy (text, comment); strcat (text, "\n"); strcat (text, newcomment); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, text); free (text); } else { r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, newcomment); } return R_TRUE; } else if (input[1] == 'a') { char *s, *p; s = strchr (input, ' '); if (s) { s = strdup (s+1); } else { eprintf ("Usage\n"); return R_FALSE; } p = strchr (s, ' '); if (p) *p++ = 0; ut64 addr; if (input[2]=='-') { if (input[3]) { addr = r_num_math (core->num, input+3); r_meta_del (core->anal, R_META_TYPE_COMMENT, addr, 1, NULL); } else eprintf ("Usage: CCa-[address]\n"); free (s); return R_TRUE; } addr = r_num_math (core->num, s); // Comment at if (p) { if (input[2]=='+') { char *text = p; char *comment = r_meta_get_string ( core->anal, R_META_TYPE_COMMENT, addr); if (comment) { text = malloc (strlen (comment) + strlen (p)+2); strcpy (text, comment); strcat (text, "\n"); strcat (text, p); r_meta_add (core->anal, R_META_TYPE_COMMENT, addr, addr+1, text); free (text); } else { r_meta_add (core->anal, R_META_TYPE_COMMENT, addr, addr+1, p); } } else { r_meta_add (core->anal, R_META_TYPE_COMMENT, addr, addr+1, p); } } else eprintf ("Usage: CCa [address] [comment]\n"); free (s); return R_TRUE; } else if (input[1] == '*') { r_meta_list (core->anal, R_META_TYPE_COMMENT, 1); } else if (input[1] == '-') { r_meta_del (core->anal, R_META_TYPE_COMMENT, core->offset, 1, NULL); } return R_TRUE; }
static int cmd_meta_comment(RCore *core, const char *input) { ut64 addr = core->offset; switch (input[1]) { 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 ' ': { const char* newcomment = input+2; char *text; while (*newcomment==' ') newcomment++; char *comment = r_meta_get_string ( core->anal, R_META_TYPE_COMMENT, addr); if (comment) { text = malloc (strlen (comment)+strlen (newcomment)+2); strcpy (text, comment); strcat (text, "\n"); strcat (text, newcomment); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, text); free (text); } else { r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, newcomment); } } break; case '*': r_meta_list (core->anal, R_META_TYPE_COMMENT, 1); break; case '-': r_meta_del (core->anal, R_META_TYPE_COMMENT, core->offset, 1, NULL); break; case 'u': // { const char* newcomment = input+2; while (*newcomment==' ') newcomment++; char *comment = r_meta_get_string ( core->anal, R_META_TYPE_COMMENT, addr); if (!comment || (comment && !strstr (comment, newcomment))) { r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, newcomment); } free (comment); } break; case 'a': { char *s, *p; s = strchr (input, ' '); if (s) { s = strdup (s+1); } else { eprintf ("Usage\n"); return R_FALSE; } p = strchr (s, ' '); if (p) *p++ = 0; ut64 addr; if (input[2]=='-') { if (input[3]) { addr = r_num_math (core->num, input+3); r_meta_del (core->anal, R_META_TYPE_COMMENT, addr, 1, NULL); } else eprintf ("Usage: CCa-[address]\n"); free (s); return R_TRUE; } addr = r_num_math (core->num, s); // Comment at if (p) { if (input[2]=='+') { char *text = p; char *comment = r_meta_get_string ( core->anal, R_META_TYPE_COMMENT, addr); if (comment) { text = malloc (strlen (comment) + strlen (p)+2); strcpy (text, comment); strcat (text, "\n"); strcat (text, p); r_meta_add (core->anal, R_META_TYPE_COMMENT, addr, addr+1, text); free (text); } else { r_meta_add (core->anal, R_META_TYPE_COMMENT, addr, addr+1, p); } } else { r_meta_add (core->anal, R_META_TYPE_COMMENT, addr, addr+1, p); } } else eprintf ("Usage: CCa [address] [comment]\n"); free (s); return R_TRUE; } } return R_TRUE; }
R_API int r_meta_cleanup(RAnal *a, ut64 from, ut64 to) { return r_meta_del (a, R_META_TYPE_ANY, from, (to-from), NULL); }
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; }
static int cmd_meta_comment(RCore *core, const char *input) { ut64 addr = core->offset; switch (input[1]) { case '?': { const char* help_msg[] = { "Usage:", "CC[-+!*au] [base64:..|str] @ addr", "", "CC", "", "list all comments in human friendly form", "CC*", "", "list all comments in r2 commands", "CC.", "", "show comment at current offset", "CC,", " [file]", "show or set comment file", "CC", " [text]", "append comment at current address", "CCf", "", "list comments in function", "CC+", " [text]", "append comment at current address", "CC!", "", "edit comment using cfg.editor (vim, ..)", "CC-", " @ cmt_addr", "remove comment at given address", "CCu", " good boy @ addr", "add good boy comment at given address", "CCu", " base64:AA== @ addr", "add comment in base64", NULL}; r_core_cmd_help (core, help_msg); } break; case ',': // "CC," if (input[2]=='?') { eprintf ("Usage: CC, [file]\n"); } else if (input[2]==' ') { const char *fn = input+2; char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr); while (*fn== ' ')fn++; if (comment && *comment) { // append filename in current comment char *nc = r_str_newf ("%s ,(%s)", comment, fn); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, nc); free (nc); } else { char *comment = r_str_newf (",(%s)", fn); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, comment); free (comment); } } else { char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr); if (comment && *comment) { char *cmtfile = r_str_between (comment, ",(", ")"); if (cmtfile && *cmtfile) { char *getcommapath(RCore *core); char *cwd = getcommapath (core); r_cons_printf ("%s"R_SYS_DIR"%s\n", cwd, cmtfile); free (cwd); } free (cmtfile); } free (comment); } break; case '.': { char *comment = r_meta_get_string ( core->anal, R_META_TYPE_COMMENT, addr); if (comment) { r_cons_println (comment); free (comment); } } break; case 0: // "CC" r_meta_list (core->anal, R_META_TYPE_COMMENT, 0); break; case 'f': // "CCf" r_meta_list_at (core->anal, R_META_TYPE_COMMENT, 'f', core->offset); break; case 'j': // "CCj" r_meta_list (core->anal, R_META_TYPE_COMMENT, 'j'); 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 ' ': { const char* newcomment = r_str_chop_ro (input + 2); char *text, *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr); char *nc = strdup (newcomment); r_str_unescape (nc); if (comment) { text = malloc (strlen (comment)+strlen (newcomment)+2); if (text) { strcpy (text, comment); strcat (text, "\n"); strcat (text, nc); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, text); free (text); } else { r_sys_perror ("malloc"); } } else { r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, nc); } free (nc); } break; case '*': r_meta_list (core->anal, R_META_TYPE_COMMENT, 1); break; case '-': // "CC-" r_meta_del (core->anal, R_META_TYPE_COMMENT, core->offset, 1, NULL); break; case 'u': // { char *newcomment; const char *arg = input + 2; while (*arg && *arg == ' ') arg++; if (!strncmp (arg, "base64:", 7)) { char *s = (char *)sdb_decode (arg+7, NULL); if (s) { newcomment = s; } else { newcomment = NULL; } } else { newcomment = strdup (arg); } if (newcomment) { char *comment = r_meta_get_string ( core->anal, R_META_TYPE_COMMENT, addr); if (!comment || (comment && !strstr (comment, newcomment))) { r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, newcomment); } free (comment); free (newcomment); } } break; case 'a': { char *s, *p; s = strchr (input, ' '); if (s) { s = strdup (s + 1); } else { eprintf ("Usage\n"); return false; } p = strchr (s, ' '); if (p) { *p++ = 0; } ut64 addr; if (input[2]=='-') { if (input[3]) { addr = r_num_math (core->num, input+3); r_meta_del (core->anal, R_META_TYPE_COMMENT, addr, 1, NULL); } else eprintf ("Usage: CCa-[address]\n"); free (s); return true; } addr = r_num_math (core->num, s); // Comment at if (p) { if (input[2]=='+') { char *comment = r_meta_get_string ( core->anal, R_META_TYPE_COMMENT, addr); if (comment) { char* text = r_str_newf ("%s\n%s", comment, p); r_meta_add (core->anal, R_META_TYPE_COMMENT, addr, addr+1, text); free (text); } else { r_meta_add (core->anal, R_META_TYPE_COMMENT, addr, addr+1, p); } } else { r_meta_add (core->anal, R_META_TYPE_COMMENT, addr, addr + 1, p); } } else { eprintf ("Usage: CCa [address] [comment]\n"); } free (s); return true; } } return true; }
R_API int r_meta_del(RAnal *a, int type, ut64 addr, ut64 size) { char key[100], *dtr, *s, *p, *next; const char *val; int i; if (size == UT64_MAX) { // FULL CLEANUP // XXX: this thing ignores the type if (type == R_META_TYPE_ANY) { sdb_reset (DB); } else { snprintf (key, sizeof (key)-1, "meta.%c.count", type); int last = (ut64)sdb_num_get (DB, key, NULL)/K; for (i=0; i<last; i++) { snprintf (key, sizeof (key)-1, "meta.%c.%d", type, i); dtr = sdb_get (DB, key, 0); for (p = dtr; p; p = next) { s = sdb_anext (p, &next); snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, type, sdb_atoi (s)); sdb_unset (DB, key, 0); if (!next) break; } free (dtr); } } return false; } if (type == R_META_TYPE_ANY) { /* special case */ r_meta_del (a, R_META_TYPE_COMMENT, addr, size); r_meta_del (a, R_META_TYPE_VARTYPE, addr, size); } if (type == R_META_TYPE_COMMENT || type == R_META_TYPE_VARTYPE) { snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, type, addr); } else { snprintf (key, sizeof (key)-1, "meta.0x%"PFMT64x, addr); } meta_inrange_del (a, addr, size); val = sdb_const_get (DB, key, 0); if (val) { if (type == R_META_TYPE_ANY) { char item_key[100]; const char *ptr = val; while (*ptr) { snprintf (item_key, sizeof (item_key), "meta.%c.0x%" PFMT64x, *ptr, addr); sdb_unset (DB, item_key, 0); ptr++; if (*ptr) { ptr++; } } sdb_unset (DB, key, 0); return false; } if (strchr (val, ',')) { char type_fld[] = "##"; if (val[0] == type) { type_fld[0] = type; type_fld[1] = ','; } else { type_fld[0] = ','; type_fld[1] = type; } sdb_uncat (DB, key, type_fld, 0); } else { sdb_unset (DB, key, 0); } snprintf (key, sizeof (key), "meta.%c.0x%" PFMT64x, type, addr); sdb_unset (DB, key, 0); } sdb_unset (DB, key, 0); return false; }