static RList *r_debug_native_modules_get (RDebug *dbg) { char *lastname = NULL; RDebugMap *map; RListIter *iter, *iter2; RList *list, *last; int must_delete; #if __APPLE__ list = xnu_dbg_maps (dbg, 1); if (list && !r_list_empty (list)) { return list; } #endif #if __WINDOWS__ list = w32_dbg_modules (dbg); if (list && !r_list_empty (list)) { return list; } #endif list = r_debug_native_map_get (dbg); if (!list) { return NULL; } last = r_list_newf ((RListFree)r_debug_map_free); if (!last) { r_list_free (list); return NULL; } r_list_foreach_safe (list, iter, iter2, map) { const char *file = map->file; if (!map->file) { file = map->file = strdup (map->name); } must_delete = 1; if (file && *file) { if (file[0] == '/') { if (lastname) { if (strcmp (lastname, file)) { must_delete = 0; } } else { must_delete = 0; } } } if (must_delete) { r_list_delete (list, iter); } else { r_list_append (last, map); free (lastname); lastname = strdup (file); } } list->free = NULL; free (lastname); r_list_free (list); return last; }
R_API ut64 r_io_seek(RIO *io, ut64 offset, int whence) { int posix_whence = SEEK_SET; ut64 ret = UT64_MAX; if (io->buffer_enabled) { io->off = offset; return offset; } switch (whence) { case R_IO_SEEK_SET: posix_whence = SEEK_SET; ret = offset; break; case R_IO_SEEK_CUR: // offset += io->off; posix_whence = SEEK_CUR; ret = offset+io->off; break; case R_IO_SEEK_END: //offset = UT64_MAX; // XXX: depending on io bits? ret = UT64_MAX; posix_whence = SEEK_END; break; } if (io == NULL) return ret; // XXX: list_empty trick must be done in r_io_set_va(); //eprintf ("-(seek)-> 0x%08llx\n", offset); if (!io->debug && io->va && !r_list_empty (io->sections)) { ut64 o = r_io_section_vaddr_to_offset (io, offset); if (o != UT64_MAX) offset = o; // eprintf ("-(vadd)-> 0x%08llx\n", offset); } // if resolution fails... just return as invalid address if (offset==UT64_MAX) return UT64_MAX; if (io->fd != NULL) { if (io->plugin && io->plugin->lseek) ret = io->plugin->lseek (io, io->fd, offset, whence); // XXX can be problematic on w32..so no 64 bit offset? else ret = (ut64)lseek (io->fd->fd, offset, posix_whence); if (ret != UT64_MAX) { io->off = ret; // XXX this can be tricky.. better not to use this .. must be deprecated // r_io_sundo_push (io); ret = (!io->debug && io->va && !r_list_empty (io->sections))? r_io_section_offset_to_vaddr (io, io->off) : io->off; } //else eprintf ("r_io_seek: cannot seek to %"PFMT64x"\n", offset); } //else { eprintf ("r_io_seek: null fd\n"); } return ret; }
R_API int r_core_visual_xrefs_x (RCore *core) { int ret = 0; #if FCN_OLD char ch; int count = 0; RList *xrefs = NULL; RAnalRef *refi; RListIter *iter; RAnalFunction *fun; if ((xrefs = r_anal_xref_get (core->anal, core->offset))) { r_cons_gotoxy (1, 1); r_cons_printf ("[GOTO XREF]> \n"); if (r_list_empty (xrefs)) { r_cons_printf ("\tNo XREF found at 0x%"PFMT64x"\n", core->offset); r_cons_any_key (NULL); r_cons_clear00 (); } else { r_list_foreach (xrefs, iter, refi) { fun = r_anal_get_fcn_in (core->anal, refi->addr, R_ANAL_FCN_TYPE_NULL); r_cons_printf (" [%i] 0x%08"PFMT64x" %s XREF 0x%08"PFMT64x" (%s) \n", count, refi->at, refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)": refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr, fun?fun->name:"unk"); if (++count > 9) break; } }
R_API void *r_mixed_get0 (RMixed *m, int key, ut64 value) { RList *list = r_mixed_get (m, key, value); if (list && !r_list_empty (list)) { RListIter *head = r_list_head (list); if (head) return head->data; } return NULL; }
R_API int r_list_join (RList *list1, RList *list2) { if (!list1 || !list2) return 0; if (r_list_empty (list2)) return 0; if (r_list_empty (list1)) { list1->head = list2->head; list1->tail = list2->tail; } else if (list1->tail == NULL) { list1->tail = list2->head; } else if (list2->head != NULL) { list1->tail->n = list2->head; list2->head->p = list1->tail; } list2->head = list2->tail = NULL; /* the caller must free list2 */ return 1; }
r_mapnode_t *r_map_node(rmap_t *map, unsigned long index) { r_mapnode_t *node; if (index >= r_carray_length(map->data)) return NULL; node = (r_mapnode_t*)r_carray_slot(map->data, index); if (r_list_empty(&node->hash)) return NULL; return node; }
R_API bool r_mixed_change_end(RMixed *m, void *p) { int i; void *q; for (i=0; i<RMIXED_MAXKEYS; i++) { if (m->keys[i]) { RHashTable *ht = m->keys[i]->hash.ht; RHashTable64 *ht64 = m->keys[i]->hash.ht64; ut64 newstate = r_mixed_get_value (i, m->keys[i]->size, p); if (newstate != m->state[i]) { // rehash this pointer RListIter *iter; RList *list = r_mixed_get (m, i, m->state[i]); if (list == NULL) { eprintf ("RMixed internal corruption?\n"); return false; } /* No _safe loop necessary because we return immediately after the delete. */ r_list_foreach (list, iter, q) { if (q == p) { r_list_delete (list, iter); break; } } if (r_list_empty (list)) { // delete hash entry r_list_free (list); switch (m->keys[i]->size) { case 1: case 2: case 4: r_hashtable_remove (ht, m->state[i]); break; case 8: r_hashtable64_remove (ht64, m->state[i]); break; } } switch (m->keys[i]->size) { case 1: case 2: case 4: list = r_hashtable_lookup (ht, (ut32)newstate); if (!list) { list = r_list_new (); r_hashtable_insert (ht, (ut32)newstate, list); } r_list_append (list, p); break; case 8: list = r_hashtable64_lookup (ht64, newstate); if (!list) { list = r_list_new (); r_hashtable64_insert (ht64, newstate, list); } r_list_append (list, p); break; } } }
void r_map_cleanup(robject_t *obj) { r_mapnode_t *node; rmap_t *map = (rmap_t*)obj; while (!r_list_empty(&map->active)) { node = r_list_entry(r_list_first(&map->active), r_mapnode_t, active); if (!r_object_gcget((robject_t*)node->key)) r_string_destroy(node->key); r_list_del(&node->active); } while (!r_list_empty(&map->inactive)) { node = r_list_entry(r_list_first(&map->inactive), r_mapnode_t, active); r_list_del(&node->active); } r_carray_destroy(map->data); r_free(map->hash); r_object_cleanup(&map->obj); }
R_API RList *r_anal_xrefs_get_from(RAnal *anal, ut64 to) { RList *list = r_anal_ref_list_new (); if (!list) { return NULL; } listxrefs (anal->dict_refs, to, list); if (r_list_empty (list)) { r_list_free (list); list = NULL; } return list; }
void r_gc_deallocateall(rgc_t *gc) { robject_t *obj; rhead_t *head = r_gc_head(gc); while (!r_list_empty(head)) { obj = r_list_entry(r_list_first(head), robject_t, lnk); r_list_del(&obj->lnk); obj->gc = NULL; r_object_destroy(obj); } }
R_API int r_list_join(RList *list1, RList *list2) { if (!list1 || !list2) { return 0; } if (r_list_empty (list2)) { return 0; } if (r_list_empty (list1)) { list1->head = list2->head; list1->tail = list2->tail; } else if (!list1->tail) { list1->tail = list2->head; } else if (list2->head != NULL) { list1->tail->n = list2->head; list2->head->p = list1->tail; } list1->length += list2->length; list2->head = list2->tail = NULL; list1->sorted = true; /* the caller must free list2 */ return 1; }
/* Idea: At first, get all sections in vrange, meanwhile record all unsectioned area and store it via RIORange in a list, read all sections via mread, resolve maps for unsectioned areas and fill the gaps. last point must always prefere using io->desc*/ R_API int r_io_vread (RIO *io, ut64 vaddr, ut8 *buf, int len) { int tmp_len = len; ut8 *tmp_buf = buf; ut64 vendaddr, maddr, tmp_vaddr = vaddr; RIOMap *map; RIOSection *section; RIORange *range; RList *sections, *ranges = NULL, *maps; RListIter *iter, *ator; if (!io->desc) { eprintf ("r_io_vread: desc is NULL, WTF!\n"); return R_ERROR; } if (len < 0) { eprintf ("r_io_vread: wrong usage; len is smaller than 0. len: %i\n", len); return R_FAIL; } sections = r_io_section_get_in_vaddr_range (io, vaddr, vaddr+len); if (!r_list_empty (sections)) { //check if there is any section ranges = r_list_new(); ranges->free = free; r_list_foreach (sections, iter, section) { if (section->vaddr==0) continue; if (section->vaddr > tmp_vaddr) { range = r_io_range_new(); //create a new range range->from = tmp_vaddr; //record unsectioned area range->to = section->vaddr; r_list_append (ranges, range); //store the range tmp_vaddr = section->vaddr; //prepare for resolving the maddr tmp_len -= (tmp_vaddr - vaddr); tmp_buf += (tmp_vaddr - vaddr); //adjust buffer } vendaddr = tmp_vaddr + tmp_len; //calculate the virtual end address if (vendaddr > (section->vaddr + section->vsize)) //check if the virual end address is in the section too vendaddr = section->vaddr + section->vsize; //if not, size it down maddr = tmp_vaddr - section->vaddr + section->offset; //calculate the map address (address inside the map) if (maddr > ( section->offset + section->size)) { //check if the maddr is inside the physical section, if not, skip some things } else { if ((vendaddr - section->vaddr + section->offset) > (section->offset + section->size)) { //check if the virtual part of the section fits into the physical part r_io_mread (io, section->fd, maddr, tmp_buf, (section->offset + section->size) - maddr);//if not, read as far as possible } else { r_io_mread (io, section->fd, maddr, tmp_buf, vendaddr - tmp_vaddr); //read from the sections fd } } tmp_buf += (vendaddr - tmp_vaddr); //adjust buffer tmp_len -= (vendaddr - tmp_vaddr); //adjust length tmp_vaddr = vendaddr; //adjust address } }
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 {
r_mapnode_t *r_map_getfreenode(rmap_t *map, const char *key, unsigned long size) { r_mapnode_t *node = NULL; if (r_list_empty(&map->inactive)) { long index = r_carray_add(map->data, NULL); node = (r_mapnode_t*)r_carray_slot(map->data, index); r_mapnode_init(node, key, size); node->index = index; } else { node = r_list_entry(r_list_first(&map->inactive), r_mapnode_t, active); r_list_del(&node->active); r_mapnode_init(node, key, size); } return node; }
R_API RList *r_anal_refs_get (RAnal *anal, ut64 from) { RList *list = r_list_new (); if (!list) { return NULL; } r_anal_xrefs_from (anal, list, "ref", R_ANAL_REF_TYPE_NULL, from); r_anal_xrefs_from (anal, list, "ref", R_ANAL_REF_TYPE_CODE, from); r_anal_xrefs_from (anal, list, "ref", R_ANAL_REF_TYPE_CALL, from); r_anal_xrefs_from (anal, list, "ref", R_ANAL_REF_TYPE_DATA, from); r_anal_xrefs_from (anal, list, "ref", R_ANAL_REF_TYPE_STRING, from); if (r_list_empty (list)) { r_list_free (list); list = NULL; } return list; }
R_API RList *r_anal_xrefs_get (RAnal *anal, ut64 to) { RList *list = r_list_new (); if (!list) { return NULL; } list->free = NULL; // XXX r_anal_xrefs_from (anal, list, "xref", R_ANAL_REF_TYPE_NULL, to); r_anal_xrefs_from (anal, list, "xref", R_ANAL_REF_TYPE_CODE, to); r_anal_xrefs_from (anal, list, "xref", R_ANAL_REF_TYPE_CALL, to); r_anal_xrefs_from (anal, list, "xref", R_ANAL_REF_TYPE_DATA, to); r_anal_xrefs_from (anal, list, "xref", R_ANAL_REF_TYPE_STRING, to); if (r_list_empty (list)) { r_list_free (list); list = NULL; } return list; }
static void nextpal(RCore *core, int mode) { RList *files; RListIter *iter; const char *fn; char *home = r_str_home (".config/radare2/cons/"); getNext = false; if (home) { files = r_sys_dir (home); r_list_foreach (files, iter, fn) { if (*fn && *fn != '.') { if (!nextpal_item (core, mode, fn)) { r_list_free (files); R_FREE (home); goto done; } } } r_list_free (files); R_FREE (home); } files = r_sys_dir (R2_DATDIR"/radare2/"R2_VERSION"/cons/"); r_list_foreach (files, iter, fn) { if (*fn && *fn != '.') { if (!nextpal_item (core, mode, fn)) goto done; } } done: if (getNext) { R_FREE (curtheme); nextpal (core, mode); return; } if (mode == 'l' && !curtheme && !r_list_empty (files)) { nextpal (core, mode); // beware infinite loop here return; } r_list_free (files); if (curtheme) { r_core_cmdf (core, "eco %s", curtheme); } }
R_API int r_debug_esil_watch_empty(RDebug *dbg) { return r_list_empty (EWPS); }
/* * Recursively go over array data to unref any GC managed * objects. We need this because when GC is destroying arrays, * array's oncleanup might try to destroy the data, that should really * be destroyed by the GC. To avoid any attempts the same data * to be destroyed twice we remove the references of all GC managed * data from the arrays and leave the destruction of such data to * the GC. */ void rvm_reg_array_unref_gcdata(robject_t *obj) { unsigned long i, size; rvmreg_t *r; if (obj->type == R_OBJECT_ARRAY) { rarray_t *array = (rarray_t*)obj; if ((size = r_array_length(array)) > 0) { /* * set the size to 0, to prevent circular references to come back here */ r_array_setlength(array, 0); for (i = 0; i < size; i++) { r = (rvmreg_t*) r_array_slot(array, i); if (rvm_reg_tstflag(r, RVM_INFOBIT_ROBJECT)) { robject_t *p = RVM_REG_GETP(r); if (!r_list_empty(&p->lnk)) { /* * if this entry is robject_t that is on GC * list, it can be RVM_REG_CLEARed. It will be * cleaned up by the GC. */ rvm_reg_array_unref_gcdata(p); RVM_REG_CLEAR(r); } } } /* * Restore the size */ r_array_setlength(array, size); } } else if (obj->type == R_OBJECT_CARRAY || obj->type == R_OBJECT_HARRAY) { rcarray_t *array = (rcarray_t*)obj; if (obj->type == R_OBJECT_HARRAY) array = ((rharray_t*)obj)->members; if ((size = r_carray_length(array)) > 0) { /* * set the size to 0, to prevent circular references to come back here */ array->alloc_size = 0; for (i = 0; i < size; i++) { r = (rvmreg_t*) r_carray_slot(array, i); if (rvm_reg_tstflag(r, RVM_INFOBIT_ROBJECT)) { robject_t *p = RVM_REG_GETP(r); if (!r_list_empty(&p->lnk)) { /* * if this entry is robject_t that is on GC * list, it can be RVM_REG_CLEARed. It will be * cleaned up by the GC. */ rvm_reg_array_unref_gcdata(p); RVM_REG_CLEAR(r); } } } /* * Restore the size */ array->alloc_size = size; } } }
R_API int r_core_visual_cmd(RCore *core, int ch) { RAsmOp op; ut64 offset = core->offset; char buf[4096]; int i, ret, offscreen, cols = core->print->cols, delta = 0; ch = r_cons_arrow_to_hjkl (ch); ch = visual_nkey (core, ch); if (ch<2) return 1; // do we need hotkeys for data references? not only calls? if (ch>='0'&& ch<='9') { ut64 off = core->asmqjmps[ch-'0']; if (off != UT64_MAX) { int delta = R_ABS ((st64)off-(st64)offset); r_io_sundo_push (core->io, offset); if (curset && delta<100) { cursor = delta; } else { r_core_visual_seek_animation (core, off); //r_core_seek (core, off, 1); } r_core_block_read (core, 1); } } else switch (ch) { case 0x0d: { r_cons_enable_mouse (R_TRUE); RAnalOp *op = r_core_anal_op (core, core->offset+cursor); if (op) { if (op->type == R_ANAL_OP_TYPE_JMP || op->type == R_ANAL_OP_TYPE_CJMP || op->type == R_ANAL_OP_TYPE_CALL) { r_io_sundo_push (core->io, offset); r_core_visual_seek_animation(core, op->jump); } } r_anal_op_free (op); } break; case 90: // shift+tab if (!strcmp (printfmt[0], "x")) printfmt[0] = "pxa"; else printfmt[0] = "x"; break; case 9: // tab { // XXX: unify diff mode detection ut64 f = r_config_get_i (core->config, "diff.from"); ut64 t = r_config_get_i (core->config, "diff.to"); if (f == t && f == 0) { core->print->col = core->print->col==1? 2: 1; } else { ut64 delta = offset - f; r_core_seek (core, t+delta, 1); r_config_set_i (core->config, "diff.from", t); r_config_set_i (core->config, "diff.to", f); } } break; case 'a': if (core->file && !(core->file->rwx & 2)) { r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n"); r_cons_any_key (); return R_TRUE; } r_cons_printf ("Enter assembler opcodes separated with ';':\n"); showcursor (core, R_TRUE); r_cons_flush (); r_cons_set_raw (R_FALSE); strcpy (buf, "wa "); r_line_set_prompt (":> "); if (r_cons_fgets (buf+3, 1000, 0, NULL) <0) buf[0]='\0'; if (*buf) { if (curset) r_core_seek (core, core->offset + cursor, 0); r_core_cmd (core, buf, R_TRUE); if (curset) r_core_seek (core, core->offset - cursor, 1); } showcursor (core, R_FALSE); r_cons_set_raw (R_TRUE); break; case '!': r_cons_2048(); break; case 'o': visual_offset (core); break; case 'A': { int oc = curset; ut64 off = curset? core->offset+cursor : core->offset; curset = 0; r_core_visual_asm (core, off); curset = oc; } break; case 'c': setcursor (core, curset?0:1); break; case 'C': color = color? 0: 1; r_config_set_i (core->config, "scr.color", color); break; case 'd': r_core_visual_define (core); break; case 'D': setdiff (core); break; case 'f': { int range, min, max; char name[256], *n; r_line_set_prompt ("flag name: "); showcursor (core, R_TRUE); if (r_cons_fgets (name, sizeof (name), 0, NULL) >=0 && *name) { n = r_str_chop (name); if (*name=='-') { if (*n) r_flag_unset (core->flags, n+1, NULL); } else { if (ocursor != -1) { min = R_MIN (cursor, ocursor); max = R_MAX (cursor, ocursor); } else { min = max = cursor; } range = max-min+1; if (range<1) range = 1; if (*n) r_flag_set (core->flags, n, core->offset + min, range, 1); } } } showcursor (core, R_FALSE); break; case 'F': r_flag_unset_i (core->flags, core->offset + cursor, NULL); break; case 'n': r_core_seek_next (core, r_config_get (core->config, "scr.nkey")); break; case 'N': r_core_seek_previous (core, r_config_get (core->config, "scr.nkey")); break; case 'i': case 'I': if (core->file && !(core->file->rwx & 2)) { r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n"); r_cons_any_key (); return R_TRUE; } showcursor (core, R_TRUE); r_cons_flush (); r_cons_set_raw (0); if (ch=='I') { strcpy (buf, "wow "); r_line_set_prompt ("insert hexpair block: "); if (r_cons_fgets (buf+4, sizeof (buf)-5, 0, NULL) <0) buf[0]='\0'; char *p = strdup (buf); int cur = core->print->cur; if (cur>=core->blocksize) cur = core->print->cur-1; snprintf (buf, sizeof (buf), "%s @ $$0!%i", p, core->blocksize-cursor); r_core_cmd (core, buf, 0); free (p); break; } delta = (ocursor!=-1)? R_MIN (cursor, ocursor): cursor; if (core->print->col==2) { strcpy (buf, "\"w "); r_line_set_prompt ("insert string: "); if (r_cons_fgets (buf+3, sizeof (buf)-4, 0, NULL) <0) buf[0]='\0'; strcat (buf, "\""); } else { r_line_set_prompt ("insert hex: "); if (ocursor != -1) { int bs = R_ABS (cursor-ocursor)+1; core->blocksize = bs; strcpy (buf, "wow "); } else { strcpy (buf, "wx "); } if (r_cons_fgets (buf+strlen (buf), sizeof (buf)-strlen (buf), 0, NULL) <0) buf[0]='\0'; } if (curset) r_core_seek (core, core->offset + delta, 0); r_core_cmd (core, buf, 1); if (curset) r_core_seek (core, offset, 1); r_cons_set_raw (1); showcursor (core, R_FALSE); break; case 'R': r_core_cmd0 (core, "ecr"); break; case 'e': r_core_visual_config (core); break; case 'E': r_core_visual_colors (core); break; case 'M': r_core_visual_mounts (core); break; case 't': r_core_visual_trackflags (core); break; case 'x': { int count = 0; RList *xrefs = NULL; RAnalRef *refi; RListIter *iter; RAnalFunction *fun; if ((xrefs = r_anal_xref_get (core->anal, core->offset))) { r_cons_gotoxy (1, 1); r_cons_printf ("[GOTO XREF]> \n"); if (r_list_empty (xrefs)) { r_cons_printf ("\tNo XREF found at 0x%"PFMT64x"\n", core->offset); r_cons_any_key (); r_cons_clear00 (); } else { r_list_foreach (xrefs, iter, refi) { fun = r_anal_fcn_find (core->anal, refi->addr, R_ANAL_FCN_TYPE_NULL); r_cons_printf (" [%i] 0x%08"PFMT64x" %s XREF 0x%08"PFMT64x" (%s) \n", count, refi->at, refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)": refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr, fun?fun->name:"unk"); if (++count > 9) break; } } } else xrefs = NULL;
R_API int r_debug_reg_list(RDebug *dbg, int type, int size, int rad, const char *use_color) { int i, delta, from, to, cols, n = 0; const char *fmt, *fmt2, *kwhites; RPrint *pr = NULL; int colwidth = 20; RListIter *iter; RRegItem *item; RList *head; ut64 diff; char strvalue[256]; if (!dbg || !dbg->reg) { return false; } if (dbg->corebind.core) { pr = ((RCore*)dbg->corebind.core)->print; } if (size != 0 && !(dbg->reg->bits & size)) { // TODO: verify if 32bit exists, otherwise use 64 or 8? size = 32; } if (dbg->bits & R_SYS_BITS_64) { //fmt = "%s = 0x%08"PFMT64x"%s"; fmt = "%s = %s%s"; fmt2 = "%s%4s%s %s%s"; kwhites = " "; colwidth = dbg->regcols? 20: 25; cols = 3; } else { //fmt = "%s = 0x%08"PFMT64x"%s"; fmt = "%s = %s%s"; fmt2 = "%s%4s%s %s%s"; kwhites = " "; colwidth = 20; cols = 4; } if (dbg->regcols) { cols = dbg->regcols; } if (rad == 'j') { dbg->cb_printf ("{"); } // with the new field "arena" into reg items why need // to get all arenas. from = 0; to = R_REG_TYPE_LAST; int itmidx = -1; dbg->creg = NULL; for (i = from; i < to; i++) { head = r_reg_get_list (dbg->reg, i); if (!head) { continue; } r_list_foreach (head, iter, item) { ut64 value; utX valueBig; if (type != -1) { if (type != item->type && R_REG_TYPE_FLG != item->type) { continue; } if (size != 0 && size != item->size) { continue; } } // Is this register being asked? if (dbg->q_regs) { if (!r_list_empty (dbg->q_regs)) { RListIter *iterreg; RList *q_reg = dbg->q_regs; char *q_name; bool found = false; r_list_foreach (q_reg, iterreg, q_name) { if (!strcmp (item->name, q_name)) { found = true; break; } } if (!found) { continue; } r_list_delete (q_reg, iterreg); } else { // List is empty, all requested regs were taken, no need to go further goto beach; } }
static void nextpal(RCore *core, int mode) { // TODO: use r_core_list_themes() here instead of rewalking all the time RList *files = NULL; RListIter *iter; const char *fn; int ctr = 0; char *home = r_str_home (".config/radare2/cons/"); getNext = false; if (mode == 'j') { r_cons_printf ("["); } if (home) { files = r_sys_dir (home); r_list_foreach (files, iter, fn) { if (*fn && *fn != '.') { if (mode == 'p') { const char *nfn = iter->n? iter->n->data: NULL; if (!curtheme) { free (home); r_list_free (files); return; } eprintf ("%s %s %s\n", nfn, curtheme, fn); if (nfn && !strcmp (nfn, curtheme)) { r_list_free (files); files = NULL; free (curtheme); curtheme = strdup (fn); R_FREE (home); goto done; } } else { if (!nextpal_item (core, mode, fn, ctr++)) { r_list_free (files); files = NULL; R_FREE (home); goto done; } } } } r_list_free (files); R_FREE (home); } files = r_sys_dir (R2_DATDIR"/radare2/"R2_VERSION"/cons/"); r_list_foreach (files, iter, fn) { if (*fn && *fn != '.') { if (mode == 'p') { const char *nfn = iter->n? iter->n->data: NULL; if (!curtheme) { free (home); r_list_free (files); return; } eprintf ("%s %s %s\n", nfn, curtheme, fn); if (nfn && !strcmp (nfn, curtheme)) { free (curtheme); curtheme = strdup (fn); goto done; } } else { if (!nextpal_item (core, mode, fn, ctr++)) { goto done; } } } } done: if (getNext) { R_FREE (curtheme); nextpal (core, mode); return; } if (mode == 'l' && !curtheme && !r_list_empty (files)) { //nextpal (core, mode); } else { if (curtheme) { r_core_cmdf (core, "eco %s", curtheme); } } r_list_free (files); files = NULL; if (mode == 'j') { r_cons_printf ("]\n"); } }
R_API int r_core_visual_cmd(RCore *core, int ch) { RAsmOp op; char buf[4096]; int i, ret, offscreen, cols = core->print->cols; ch = r_cons_arrow_to_hjkl (ch); ch = visual_nkey (core, ch); if (ch<2) return 1; // do we need hotkeys for data references? not only calls? if (ch>='0'&& ch<='9') { r_io_sundo_push (core->io, core->offset); r_core_seek (core, core->asmqjmps[ch-'0'], 1); r_core_block_read (core, 1); } else switch (ch) { case 9: // tab { // XXX: unify diff mode detection ut64 f = r_config_get_i (core->config, "diff.from"); ut64 t = r_config_get_i (core->config, "diff.to"); if (f == t && f == 0) { core->print->col = core->print->col==1? 2: 1; } else { ut64 delta = core->offset - f; r_core_seek (core, t+delta, 1); r_config_set_i (core->config, "diff.from", t); r_config_set_i (core->config, "diff.to", f); } } break; case 'c': // XXX dupped flag imho setcursor (core, curset ^ 1); break; case 'd': r_core_visual_define (core); break; case 'D': setdiff (core); break; case 'C': color ^= 1; if (color) flags |= R_PRINT_FLAGS_COLOR; else flags &= ~(flags&R_PRINT_FLAGS_COLOR); r_config_set_i (core->config, "scr.color", color); r_print_set_flags (core->print, flags); break; case 'f': { int range; char name[256], *n; r_line_set_prompt ("flag name: "); if (r_cons_fgets (name, sizeof (name), 0, NULL) >=0 && *name) { n = r_str_chop (name); if (*name=='-') { if (*n) r_flag_unset (core->flags, n+1, NULL); } else { range = curset? (R_ABS (cursor-ocursor)+1): 1; if (range<1) range = 1; if (*n) r_flag_set (core->flags, n, core->offset + cursor, range, 1); } } } break; case 'F': r_flag_unset_i (core->flags, core->offset + cursor, NULL); break; case 'n': r_core_seek_next (core, r_config_get (core->config, "scr.nkey")); break; case 'N': r_core_seek_previous (core, r_config_get (core->config, "scr.nkey")); break; case 'A': { int oc = curset; ut64 off = curset? core->offset+cursor : core->offset; curset = 0; r_core_visual_asm (core, off); curset = oc; } break; case 'a': if (core->file && !(core->file->rwx & 2)) { r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n"); r_cons_any_key (); return R_TRUE; } r_cons_printf ("Enter assembler opcodes separated with ';':\n"); r_cons_show_cursor (R_TRUE); r_cons_flush (); r_cons_set_raw (R_FALSE); strcpy (buf, "wa "); r_line_set_prompt (":> "); if (r_cons_fgets (buf+3, 1000, 0, NULL) <0) buf[0]='\0'; if (*buf) { if (curset) r_core_seek (core, core->offset + cursor, 0); r_core_cmd (core, buf, R_TRUE); if (curset) r_core_seek (core, core->offset - cursor, 1); } r_cons_show_cursor (R_FALSE); r_cons_set_raw (R_TRUE); break; case 'i': case 'I': if (core->file && !(core->file->rwx & 2)) { r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n"); r_cons_any_key (); return R_TRUE; } r_cons_show_cursor (R_TRUE); r_cons_flush (); r_cons_set_raw (0); if (ch=='I') { strcpy (buf, "wow "); r_line_set_prompt ("insert hexpair block: "); if (r_cons_fgets (buf+4, sizeof (buf)-3, 0, NULL) <0) buf[0]='\0'; char *p = strdup (buf); int cur = core->print->cur; if (cur>=core->blocksize) cur = core->print->cur-1; snprintf (buf, sizeof (buf), "%s @ $$0!%i", p, core->blocksize-cursor); r_core_cmd (core, buf, 0); free (p); break; } if (core->print->col==2) { strcpy (buf, "w "); r_line_set_prompt ("insert string: "); if (r_cons_fgets (buf+2, sizeof (buf)-3, 0, NULL) <0) buf[0]='\0'; } else { strcpy (buf, "wx "); r_line_set_prompt ("insert hex: "); if (r_cons_fgets (buf+3, sizeof (buf)-4, 0, NULL) <0) buf[0]='\0'; } if (curset) r_core_seek (core, core->offset + cursor, 0); r_core_cmd (core, buf, 1); if (curset) r_core_seek (core, core->offset - cursor, 1); r_cons_set_raw (1); r_cons_show_cursor (R_FALSE); break; case 'e': r_core_visual_config (core); break; case 'M': r_core_visual_mounts (core); break; case 't': r_core_visual_trackflags (core); break; case 'x': { int count = 0; RList *xrefs = NULL; RAnalRef *refi; RListIter *iter; RAnalFunction *fun; if ((xrefs = r_anal_xref_get (core->anal, core->offset))) { r_cons_printf ("XREFS:\n"); if (r_list_empty (xrefs)) { r_cons_printf ("\tNo XREF found at 0x%"PFMT64x"\n", core->offset); r_cons_any_key (); r_cons_clear00 (); } else { r_list_foreach (xrefs, iter, refi) { fun = r_anal_fcn_find (core->anal, refi->addr, R_ANAL_FCN_TYPE_NULL); r_cons_printf ("\t[%i] %s XREF 0x%08"PFMT64x" (%s)\n", count, refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)": refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr, fun?fun->name:"unk"); if (++count > 9) break; } } } else xrefs = NULL;