static int bin_dwarf(RCore *core, int mode) { RBinDwarfRow *row; RListIter *iter; RList *list = NULL; RBinFile *binfile = r_core_bin_cur (core); RBinPlugin * plugin = r_bin_file_cur_plugin (binfile); if (!binfile) return false; if (plugin && plugin->lines) { list = plugin->lines (binfile); } else if (core->bin) { // TODO: complete and speed-up support for dwarf if (r_config_get_i (core->config, "bin.dwarf")) { RBinDwarfDebugAbbrev *da = NULL; da = r_bin_dwarf_parse_abbrev (core->bin, mode); r_bin_dwarf_parse_info (da, core->bin, mode); r_bin_dwarf_parse_aranges (core->bin, mode); list = r_bin_dwarf_parse_line (core->bin, mode); r_bin_dwarf_free_debug_abbrev (da); free (da); } } if (!list) return false; r_cons_break (NULL, NULL); r_list_foreach (list, iter, row) { if (r_cons_singleton()->breaked) break; if (mode) { // TODO: use 'Cl' instead of CC const char *path = row->file; char *line = r_file_slurp_line (path, row->line-1, 0); if (line) { r_str_filter (line, strlen (line)); line = r_str_replace (line, "\"", "\\\"", 1); line = r_str_replace (line, "\\\\", "\\", 1); } // TODO: implement internal : if ((mode & R_CORE_BIN_SET)) if ((mode & R_CORE_BIN_SET)) { char *cmt = r_str_newf ("%s:%d %s", row->file, row->line, line?line:""); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, row->address, cmt); free (cmt); } else { r_cons_printf ("\"CC %s:%d %s\"@0x%"PFMT64x"\n", row->file, row->line, line?line:"", row->address); } free (line); } else { r_cons_printf ("0x%08"PFMT64x"\t%s\t%d\n", row->address, row->file, row->line); } } r_cons_break_end (); r_list_free (list); return true; }
void gb_bankswitch_detect(RMeta *m, RIOBind iob, ut64 addr, ut16 ldarg) { ut8 rt; if(addr > 0x3fff) return; iob.read_at(iob.io, 0x147, &rt, 1); //xxx: it won't change switch(gb_mbc_resolve(rt)) { case -1: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "unknown MBC!!!"); case 0: return; default: meta_gb_bankswitch_cmt(m, addr, ldarg, (ut8)gb_mbc_resolve(rt)); } }
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; }
void meta_gb_bankswitch_cmt(RMeta *m, ut64 addr, ut16 ldarg, ut8 rmbc) { if(rmbc>4) //todo return; if(mbc[rmbc-1].from<ldarg && ldarg<mbc[rmbc-1].to) r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "Bankswitch"); }
void meta_gb_hardware_cmt(RMeta *m, const ut8 hw, ut64 addr) { switch(hw) { case 0: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "JOYPAD"); //Moar context for this (which Key is affected) break; case 1: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "Serial tranfer data"); break; case 2: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "Serial tranfer data - Ctl"); break; case 4: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "DIV"); break; case 5: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "TIMA"); break; case 6: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "TMA"); break; case 7: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "TAC"); break; case 0x0f: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "Interrupt Flag"); //TODO: save in sdb for halt break; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "SOUND"); break; case 0x30: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "Wave Pattern RAM/SOUND"); break; case 0x40: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "LCDC"); break; case 0x41: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "LCDC - STAT"); break; case 0x42: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "LCDC - Scroll y"); break; case 0x43: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "LCDC - Scroll x"); break; case 0x44: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "LCDC - y cord"); break; case 0x45: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "LCDC - y cord cmp"); break; case 0x46: r_meta_set_string(m, R_META_TYPE_COMMENT, addr, "DMA"); break; } }
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; }
void meta_gb_bankswitch_cmt(RAnal *a, ut64 addr, ut16 ldarg) { if(0x1fff <ldarg && ldarg < 0x4000 && addr < 0x4000) r_meta_set_string (a, R_META_TYPE_COMMENT, addr, "Bankswitch"); if(0x6000 > ldarg && ldarg > 0x3fff) r_meta_set_string(a, R_META_TYPE_COMMENT, addr, "Ramswitch"); }
static int ws_anal(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) { RAsmOp *aop; memset (op, '\0', sizeof(RAnalOp)); op->addr = addr; op->type = R_ANAL_OP_TYPE_UNK; aop = R_NEW0(RAsmOp); op->size = wsdis(aop, data, len); if(op->size) { switch(aop->buf_asm[0]) { case 'n': op->type = R_ANAL_OP_TYPE_NOP; break; case 'e': op->type = R_ANAL_OP_TYPE_TRAP; break; case 'd': if(aop->buf_asm[1] == 'u') op->type = R_ANAL_OP_TYPE_UPUSH; else op->type = R_ANAL_OP_TYPE_DIV; break; case 'i': op->type = R_ANAL_OP_TYPE_ILL; break; case 'a': op->type = R_ANAL_OP_TYPE_ADD; break; case 'm': if(aop->buf_asm[1] == 'o') op->type = R_ANAL_OP_TYPE_MOD; else op->type = R_ANAL_OP_TYPE_MUL; break; case 'r': op->type = R_ANAL_OP_TYPE_RET; break; case 'l': op->type = R_ANAL_OP_TYPE_LOAD; break; case 'c': if(aop->buf_asm[1] == 'a') { op->type = R_ANAL_OP_TYPE_CALL; op->fail = addr + aop->size; op->jump = ws_find_label(atoi(&aop->buf_asm[5]), anal->iob); } else { op->type = R_ANAL_OP_TYPE_UPUSH; } break; case 'j': if(aop->buf_asm[1] == 'm') { op->type = R_ANAL_OP_TYPE_JMP; op->jump = ws_find_label(atoi(&aop->buf_asm[4]), anal->iob); } else { op->type = R_ANAL_OP_TYPE_CJMP; op->jump = ws_find_label(atoi(&aop->buf_asm[3]), anal->iob); } op->fail = addr + aop->size; break; case 'g': op->type = R_ANAL_OP_TYPE_IO; break; case 'p': if(aop->buf_asm[1] == 'o') { op->type = R_ANAL_OP_TYPE_POP; } else { if(aop->buf_asm[2] == 's') { op->type = R_ANAL_OP_TYPE_PUSH; if(127 > atoi(&aop->buf_asm[5]) && atoi(&aop->buf_asm[5]) >= 33) { char c[4]; c[3] = '\0'; c[0] = c[2] = '\''; c[1] = (char) atoi(&aop->buf_asm[5]); r_meta_set_string(anal, R_META_TYPE_COMMENT, addr, c); } } else { op->type = R_ANAL_OP_TYPE_IO; } } break; case 's': switch (aop->buf_asm[1]) { case 'u': op->type = R_ANAL_OP_TYPE_SUB; break; case 't': op->type = R_ANAL_OP_TYPE_STORE; break; case 'l': op->type = R_ANAL_OP_TYPE_LOAD; // XXX break; case 'w': op->type = R_ANAL_OP_TYPE_ROR; } break; } } r_asm_op_free(aop); return op->size; }
static void type_match(RCore *core, ut64 addr, char *name) { Sdb *trace = core->anal->esil->db_trace; RAnal *anal = core->anal; RAnalVar *v; char *fcn_name; if (r_anal_type_func_exist (anal, name)) { fcn_name = strdup (name); } else if (!(fcn_name = r_anal_type_func_guess (anal, name))) { eprintf ("can't find function prototype for %s\n", name); return; } const char* cc = r_anal_type_func_cc (anal, fcn_name); if (!cc || !r_anal_cc_exist (anal, cc)) { eprintf ("can't find %s calling convention %s\n", fcn_name, cc); return; } int i, j, max = r_anal_type_func_args_count (anal, fcn_name); int size = 0, idx = sdb_num_get (trace, "idx", 0); const char *sp_name = r_reg_get_name (anal->reg, R_REG_NAME_SP); const char *bp_name = r_reg_get_name (anal->reg, R_REG_NAME_BP); ut64 sp = r_reg_getv (anal->reg, sp_name); ut64 bp = r_reg_getv (anal->reg, bp_name); for (i = 0; i < max; i++) { char *type = r_anal_type_func_args_type (anal, fcn_name, i); const char *name =r_anal_type_func_args_name (anal, fcn_name, i); const char *place = r_anal_cc_arg (anal, cc, i + 1); if (!strcmp (place, "stack")) { // type_match_stack (); for (j = idx; j >= 0; j--) { ut64 write_addr = sdb_num_get (trace, sdb_fmt (-1, "%d.mem.write", j), 0); if (write_addr == sp + size) { ut64 instr_addr = sdb_num_get (trace, sdb_fmt (-1, "%d.addr", j), 0); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, instr_addr, sdb_fmt (-1, "%s %s", type, name)); char *tmp = sdb_fmt (-1, "%d.mem.read", j); int i2, array_size = sdb_array_size (trace, tmp); for (i2 = 0; i2 < array_size; i2++) { if (bp_name) { int bp_idx = sdb_array_get_num (trace, tmp, i2, 0) - bp; if ((v =r_anal_var_get (anal, addr, R_ANAL_VAR_KIND_BPV, 1, bp_idx))) { r_anal_var_retype (anal, addr, 1, bp_idx, R_ANAL_VAR_KIND_BPV, type, -1, v->name); r_anal_var_free (v); } } int sp_idx = sdb_array_get_num (trace, tmp, i2, 0) - sp; if ((v = r_anal_var_get (anal, addr, R_ANAL_VAR_KIND_SPV, 1, sp_idx))) { r_anal_var_retype (anal, addr, 1, sp_idx, R_ANAL_VAR_KIND_SPV, type, -1, v->name); r_anal_var_free (v); } } break; } } size += r_anal_type_get_size (anal, type) / 8; } else if (!strcmp (place , "stack_rev")) { // type_match_stack_rev (); free (type); int k; for ( k = max -1; k >=i; k--) { type = r_anal_type_func_args_type (anal, fcn_name, k); name =r_anal_type_func_args_name (anal, fcn_name, k); place = r_anal_cc_arg (anal, cc, k + 1); if (strcmp (place ,"stack_rev")) { break; } for (j = idx; j >= 0; j--) { ut64 write_addr = sdb_num_get (trace, sdb_fmt (-1, "%d.mem.write", j), 0); if (write_addr == sp + size) { ut64 instr_addr = sdb_num_get (trace, sdb_fmt (-1, "%d.addr", j), 0); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, instr_addr, sdb_fmt (-1, "%s %s", type, name)); char *tmp = sdb_fmt (-1, "%d.mem.read", j); int i2, array_size = sdb_array_size (trace, tmp); for (i2 = 0; i2 < array_size; i2++) { if (bp_name) { int bp_idx = sdb_array_get_num (trace, tmp, i2, 0) - bp; if ((v =r_anal_var_get (anal, addr, R_ANAL_VAR_KIND_BPV, 1, bp_idx))) { r_anal_var_retype (anal, addr, 1, bp_idx, R_ANAL_VAR_KIND_BPV, type, -1, v->name); r_anal_var_free (v); } } int sp_idx = sdb_array_get_num (trace, tmp, i2, 0) - sp; if ((v =r_anal_var_get (anal, addr, R_ANAL_VAR_KIND_SPV, 1, sp_idx))) { r_anal_var_retype (anal, addr, 1, sp_idx, R_ANAL_VAR_KIND_SPV, type, -1, v->name); r_anal_var_free (v); } } break; } } size += r_anal_type_get_size (anal, type) / 8; } break; } else { // type_match_reg (); for (j = idx; j >= 0; j--) { if (sdb_array_contains (trace, sdb_fmt (-1, "%d.reg.write", j), place, 0)) { ut64 instr_addr = sdb_num_get (trace, sdb_fmt (-1, "%d.addr", j), 0); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, instr_addr, sdb_fmt (-1, "%s %s", type, name)); char *tmp = sdb_fmt (-1, "%d.mem.read", j); int i2, array_size = sdb_array_size (trace, tmp); for (i2 = 0; i2 < array_size; i2++) { if (bp_name) { int bp_idx = sdb_array_get_num (trace, tmp, i2, 0) - bp; if ((v =r_anal_var_get (anal, addr, R_ANAL_VAR_KIND_BPV, 1, bp_idx))) { r_anal_var_retype (anal, addr, 1, bp_idx, R_ANAL_VAR_KIND_BPV, type, -1, v->name); r_anal_var_free (v); } } int sp_idx = sdb_array_get_num (trace, tmp, i2, 0) - sp; if ((v =r_anal_var_get (anal, addr, R_ANAL_VAR_KIND_SPV, 1, sp_idx))) { r_anal_var_retype (anal, addr, 1, sp_idx, R_ANAL_VAR_KIND_SPV, type, -1, v->name); r_anal_var_free (v); } } break; } } } free (type); } free (fcn_name); }
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_eval(void *data, const char *input) { char *p; RCore *core = (RCore *)data; switch (input[0]) { case 't': // env if (input[1] == 'a') { r_cons_printf ("%s\n", (r_num_rand (10) % 2)? "wen": "son"); } else if (input[1]==' ' && input[2]) { RConfigNode *node = r_config_node_get (core->config, input+2); if (node) { const char *type = r_config_node_type (node); if (type && *type) { r_cons_println (type); } } } else { eprintf ("Usage: et [varname] ; show type of eval var\n"); } break; case 'n': // env if (!strchr (input, '=')) { char *var, *p; var = strchr (input, ' '); if (var) while (*var==' ') var++; p = r_sys_getenv (var); if (p) { r_cons_println (p); free (p); } else { char **e = r_sys_get_environ (); while (e && *e) { r_cons_println (*e); e++; } } } else if (strlen (input)>3) { char *v, *k = strdup (input+3); if (!k) break; v = strchr (k, '='); if (v) { *v++ = 0; r_sys_setenv (k, v); } free (k); } return true; case 'x': // exit // XXX we need headers for the cmd_xxx files. return cmd_quit (data, ""); case 'j': // json r_config_list (core->config, NULL, 'j'); break; case 'v': // verbose r_config_list (core->config, input + 1, 'v'); break; case 'q': // quiet list of eval keys r_config_list (core->config, NULL, 'q'); break; case '\0': // "e" r_config_list (core->config, NULL, 0); break; case 'c': // "ec" switch (input[1]) { case 'd': r_cons_pal_init (NULL); break; case '?': { const char *helpmsg[] = { "Usage ec[s?] [key][[=| ]fg] [bg]","","", "ec","","list all color keys", "ec*","","same as above, but using r2 commands", "ecd","","set default palette", "ecr","","set random palette (see also scr.randpal)", "ecs","","show a colorful palette", "ecj","","show palette in JSON", "ecc"," [prefix]","show palette in CSS", "eco"," dark|white","load white color scheme template", "ecp","","load previous color theme", "ecn","","load next color theme", "ecH","[?]","highlight word or instruction", "ec"," prompt red","change color of prompt", "ec"," prompt red blue","change color and background of prompt", ""," ","", "colors:","","rgb:000, red, green, blue, ...", "e scr.rgbcolor","=1|0","for 256 color cube (boolean)", "e scr.truecolor","=1|0","for 256*256*256 colors (boolean)", "$DATADIR/radare2/cons","","~/.config/radare2/cons ./", NULL}; r_core_cmd_help (core, helpmsg); } break; case 'o': // "eco" if (input[2] == 'j') { nextpal (core, 'j'); } else if (input[2] == ' ') { bool failed = false; char *home, path[512]; snprintf (path, sizeof (path), ".config/radare2/cons/%s", input + 3); home = r_str_home (path); snprintf (path, sizeof (path), R2_DATDIR"/radare2/" R2_VERSION"/cons/%s", input + 3); if (!load_theme (core, home)) { if (load_theme (core, path)) { //curtheme = r_str_dup (curtheme, path); curtheme = r_str_dup (curtheme, input + 3); } else { if (load_theme (core, input + 3)) { curtheme = r_str_dup (curtheme, input + 3); } else { char *absfile = r_file_abspath (input + 3); eprintf ("eco: cannot open colorscheme profile (%s)\n", absfile); free (absfile); failed = true; } } } free (home); if (failed) { eprintf ("Something went wrong\n"); } } else if (input[2] == '?') { eprintf ("Usage: eco [themename] ;load theme from "R2_DATDIR"/radare2/"R2_VERSION"/cons/\n"); } else { nextpal (core, 'l'); } break; case 's': r_cons_pal_show (); break; // "ecs" case '*': r_cons_pal_list (1, NULL); break; // "ec*" case 'h': // echo if (( p = strchr (input, ' ') )) { r_cons_strcat (p+1); r_cons_newline (); } else { // "ech" r_cons_pal_list ('h', NULL); } break; case 'j': // "ecj" r_cons_pal_list ('j', NULL); break; case 'c': // "ecc" r_cons_pal_list ('c', input + 2); break; case '\0': // "ec" r_cons_pal_list (0, NULL); break; case 'r': // "ecr" r_cons_pal_random (); break; case 'n': // "ecn" nextpal (core, 'n'); break; case 'p': // "ecp" nextpal (core, 'p'); break; case 'H': { // "ecH" char *color_code = NULL; char *word = NULL; int argc = 0; char** argv = r_str_argv (input + 4, &argc); switch (input[2]) { case '?': { const char *helpmsg[] = { "Usage ecH[iw-?]","","", "ecHi","[color]","highlight current instruction with 'color' background", "ecHw","[word] [color]","highlight 'word ' in current instruction with 'color' background", "ecH-","","remove all highlights on current instruction", NULL }; r_core_cmd_help (core, helpmsg); } break; case '-': r_meta_set_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset, ""); return false; case '\0': case 'i': // "ecHi if (argc) { char *dup = r_str_newf ("bgonly %s", argv[0]); color_code = r_cons_pal_parse (dup); R_FREE (dup); } break; case 'w': // "ecHw" if (!argc) { eprintf ("Usage: echw word [color]\n"); r_str_argv_free (argv); return true; } word = strdup (argv[0]); if (argc > 1) { char *dup = r_str_newf ("bgonly %s", argv[1]); color_code = r_cons_pal_parse (dup); if (!color_code) { eprintf ("Unknown color %s\n", argv[1]); r_str_argv_free (argv); free (dup); free (word); return true; } R_FREE (dup); } break; default: eprintf ("See ecH?\n"); r_str_argv_free (argv); return true; } char *str = r_meta_get_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset); char *dup = r_str_newf ("%s \"%s%s\"", str?str:"", word?word:"", color_code?color_code:r_cons_pal_get ("highlight")); r_meta_set_string (core->anal, R_META_TYPE_HIGHLIGHT, core->offset, dup); r_str_argv_free (argv); R_FREE (word); R_FREE (dup); break; } default: { char *p = strdup (input + 2); char *q = strchr (p, '='); if (!q) { q = strchr (p, ' '); } if (q) { // set *q++ = 0; r_cons_pal_set (p, q); } else { const char *k = r_cons_pal_get (p); if (k) { eprintf ("(%s)(%sCOLOR"Color_RESET")\n", p, k); } } free (p); } } break; case 'e': if (input[1] == ' ') { char *p; const char *val, *input2 = strchr (input+2, ' '); if (input2) input2++; else input2 = input+2; val = r_config_get (core->config, input2); p = r_core_editor (core, NULL, val); if (p) { r_str_replace_char (p, '\n', ';'); r_config_set (core->config, input2, p); } } else { eprintf ("Usage: ee varname\n"); } break; case '!': input = r_str_chop_ro (input+1); if (!r_config_toggle (core->config, input)) eprintf ("r_config: '%s' is not a boolean variable.\n", input); break; case 's': r_config_list (core->config, (input[1])? input + 1: NULL, 's'); break; case '-': r_core_config_init (core); //eprintf ("BUG: 'e-' command locks the eval hashtable. patches are welcome :)\n"); break; case '*': r_config_list (core->config, NULL, 1); break; case '?': switch (input[1]) { case '?': r_config_list (core->config, input+2, 2); break; default: r_config_list (core->config, input+1, 2); break; case 0: r_core_cmd_help (core, help_msg_e); } break; case 'r': if (input[1]) { const char *key = input+((input[1]==' ')?2:1); if (!r_config_readonly (core->config, key)) { eprintf ("cannot find key '%s'\n", key); } } else { eprintf ("Usage: er [key]\n"); } break; case ' ': r_config_eval (core->config, input+1); break; default: r_config_eval (core->config, input); break; } return 0; }
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; }