// TODO: move somewhere else R_API RAsmOp *r_core_disassemble (RCore *core, ut64 addr) { int delta; ut8 buf[128]; static RBuffer *b = NULL; // XXX: never freed and non-thread safe. move to RCore RAsmOp *op; if (b == NULL) { b = r_buf_new (); if (!r_core_read_at (core, addr, buf, sizeof (buf))) return NULL; b->base = addr; r_buf_set_bytes (b, buf, sizeof (buf)); } else { if ((addr < b->base) || addr > (b->base+b->length-32)) { if (!r_core_read_at (core, addr, buf, sizeof (buf))) return NULL; b->base = addr; r_buf_set_bytes (b, buf, sizeof (buf)); } } delta = addr - b->base; op = R_NEW (RAsmOp); r_asm_set_pc (core->assembler, addr); if (r_asm_disassemble (core->assembler, op, b->buf+delta, b->length)<1) { free (op); return NULL; } return op; }
/* Copy a zero terminated string to the clipboard. Clamp to maxlen or blocksize. */ R_API int r_core_yank_string(RCore *core, ut64 addr, int maxlen) { ut64 curseek = core->offset; ut8 *buf = NULL; if (maxlen<0) { eprintf ("r_core_yank_string: cannot yank negative bytes\n"); return R_FALSE; } if (addr != core->offset) r_core_seek (core, addr, 1); /* Ensure space and safe termination for largest possible string allowed */ buf = malloc (core->blocksize + 1); if (!buf) return R_FALSE; buf[core->blocksize] = 0; r_core_read_at (core, addr, buf, core->blocksize); if (maxlen == 0) { maxlen = strnlen ((const char*)buf, core->blocksize); } else if (maxlen > core->blocksize) { maxlen = core->blocksize; } r_core_yank_set (core, addr, buf, maxlen); if (curseek != addr) r_core_seek (core, curseek, 1); free (buf); return R_TRUE; }
/* Copy a zero terminated string to the clipboard. Clamp to maxlen or blocksize. */ R_API int r_core_yank_string(RCore *core, ut64 addr, int maxlen) { ut64 curseek = core->offset; ut8 *buf = NULL; if (maxlen<0) { eprintf ("r_core_yank_string: cannot yank negative bytes\n"); return false; } if (addr != core->offset) r_core_seek (core, addr, 1); /* Ensure space and safe termination for largest possible string allowed */ buf = malloc (core->blocksize + 1); if (!buf) return false; buf[core->blocksize] = 0; r_core_read_at (core, addr, buf, core->blocksize); if (maxlen == 0) { maxlen = r_str_nlen ((const char*)buf, core->blocksize); //Don't use strnlen, see: http://sourceforge.net/p/mingw/bugs/1912/ } else if (maxlen > core->blocksize) { maxlen = core->blocksize; } r_core_yank_set (core, addr, buf, maxlen); if (curseek != addr) r_core_seek (core, curseek, 1); free (buf); return true; }
static void cmd_write_bits(RCore *core, int set, ut64 val) { ut64 ret, orig; // used to set/unset bit in current address r_core_read_at (core, core->offset, (ut8*)&orig, sizeof (orig)); if (set) { ret = orig | val; } else { ret = orig & (~(val)); } r_core_write_at (core, core->offset, (const ut8*)&ret, sizeof (ret)); }
static int prevopsz (RCore *core, ut64 addr) { ut64 target = addr; ut64 base = target-OPDELTA; int len, ret, i; ut8 buf[OPDELTA*2]; RAnalOp op; r_core_read_at (core, base, buf, sizeof (buf)); for (i=0; i<sizeof (buf); i++) { ret = r_anal_op (core->anal, &op, base+i, buf+i, sizeof (buf)-i); if (!ret) continue; len = op.size; r_anal_op_fini (&op); // XXX if (len<1) continue; i += len-1; if (target == base+i+1) return len; } return 4; }
R_API int r_core_yank(struct r_core_t *core, ut64 addr, int len) { ut64 curseek = core->offset; ut8 *buf = NULL; if (len<0) { eprintf ("r_core_yank: cannot yank negative bytes\n"); return R_FALSE; } if (len == 0) len = core->blocksize; //free (core->yank_buf); buf = malloc (len); //core->yank_buf = (ut8 *)malloc (len); if (addr != core->offset) r_core_seek (core, addr, 1); r_core_read_at (core, addr, buf, len); r_core_yank_set (core, addr, buf, len); if (curseek != addr) r_core_seek (core, curseek, 1); free (buf); return R_TRUE; }
static int prevopsz (RCore *core, ut64 addr) { const int delta = 32; ut64 target = addr; ut64 base = target-delta; int len, ret, i; ut8 buf[delta*2]; RAnalOp op; r_core_read_at (core, base, buf, sizeof (buf)); for (i=0; i<sizeof (buf); i++) { ret = r_anal_op (core->anal, &op, addr+i, buf+i, sizeof (buf)-i); if (!ret) continue; len = op.length; r_anal_op_fini (&op); if (len<1) continue; i += len-1; if (target == base+i+1) return len; } return 4; }
R_API int r_core_yank_to(RCore *core, const char *_arg) { ut64 src = core->offset; ut64 len = 0; ut64 pos = -1; char *str, *arg; ut8 *buf; while (*_arg==' ') _arg++; arg = strdup (_arg); str = strchr (arg, ' '); if (str) { str[0]='\0'; len = r_num_math (core->num, arg); pos = r_num_math (core->num, str+1); str[0]=' '; } if ((str == NULL) || (pos == -1) || (len == 0)) { eprintf ("Usage: yt [len] [dst-addr]\n"); free (arg); return 1; } #if 0 if (!config_get("file.write")) { eprintf("You are not in read-write mode.\n"); return 1; } #endif buf = (ut8*)malloc (len); r_core_read_at (core, src, buf, len); r_core_write_at (core, pos, buf, len); free (buf); core->offset = src; r_core_block_read (core, 0); free (arg); return 0; }
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_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; }