static bool rtti_itanium_read_class_type_info (RVTableContext *context, ut64 addr, class_type_info *cti) { ut64 at; if (addr == UT64_MAX) { return false; } if (!context->read_addr (context->anal, addr, &at)) { return false; } cti->vtable_addr = at; if (!context->read_addr (context->anal, addr + context->word_size, &at)) { return false; } cti->name_addr = at; ut8 buf[NAME_BUF_SIZE]; if (!context->anal->iob.read_at (context->anal->iob.io, at, buf, sizeof(buf))) { return false; } size_t name_len = r_str_len_utf8 ((const char *)buf) + 1; cti->name = malloc (name_len); if (!cti->name) { return false; } memcpy (cti->name, buf, name_len); return true; }
static int real_strlen(const char *ptr, int len) { int utf8len = r_str_len_utf8 (ptr); int ansilen = r_str_ansi_len (ptr); int diff = len-utf8len; if (diff) diff--; return ansilen - diff; }
/* ansi helpers */ R_API int r_str_ansi_len(const char *str) { int ch, ch2, i=0, len = 0, sub = 0; while (str[i]) { ch = str[i]; ch2 = str[i+1]; if (ch == 0x1b) { if (ch2 == '\\') { i++; } else if (ch2 == ']') { if (!strncmp (str+2+5, "rgb:", 4)) i += 18; } else if (ch2 == '[') { for (++i; str[i]&&str[i]!='J'&& str[i]!='m'&&str[i]!='H';i++); } } else { len++; #if 0 int olen = strlen (str); int ulen = r_str_len_utf8 (str); if (olen != ulen) { len += (olen-ulen); } else len++; //sub -= (r_str_len_utf8char (str+i, 4))-2; #endif }//len++; i++; } return len-sub; }
static bool rtti_itanium_read_vmi_class_type_info (RVTableContext *context, ut64 addr, vmi_class_type_info *vmi_cti) { ut64 at; if (addr == UT64_MAX) { return false; } if (!context->read_addr (context->anal, addr, &at)) { return false; } vmi_cti->vtable_addr = at; addr += context->word_size; if (!context->read_addr (context->anal, addr, &at)) { return false; } vmi_cti->name_addr = at; ut8 buf[NAME_BUF_SIZE]; if (!context->anal->iob.read_at (context->anal->iob.io, at, buf, sizeof(buf))) { return false; } size_t name_len = r_str_len_utf8 ((const char *)buf) + 1; vmi_cti->name = malloc (name_len); if (!vmi_cti->name) { return false; } memcpy (vmi_cti->name, buf, name_len); addr += context->word_size; if (!context->read_addr (context->anal, addr, &at)) { return false; } vmi_cti->vmi_flags = at; addr += 0x4; if (!context->read_addr (context->anal, addr, &at)) { return false; } if (at < 1 || at > 0xfffff) { eprintf ("Error reading vmi_base_count\n"); return false; } vmi_cti->vmi_base_count = at; vmi_cti->vmi_bases = calloc (sizeof (base_class_type_info), vmi_cti->vmi_base_count); if (!vmi_cti->vmi_bases) { return false; } ut64 tmp_addr = addr + 0x4; int i; for (i = 0; i < vmi_cti->vmi_base_count; i++) { if (!context->read_addr (context->anal, tmp_addr, &at)) { return false; } vmi_cti->vmi_bases[i].base_class_addr = at; tmp_addr += context->word_size; if (!context->read_addr (context->anal, tmp_addr, &at)) { return false; } vmi_cti->vmi_bases[i].flags = at; tmp_addr += context->word_size; } return true; }
R_API void r_cons_visual_write (char *buffer) { char white[1024]; int cols = I.columns; int alen, lines = I.rows; const char *endptr; char *nl, *ptr = buffer; memset (&white, ' ', sizeof (white)); while ((nl = strchr (ptr, '\n'))) { int len = ((int)(size_t)(nl-ptr))+1; *nl = 0; //alen = r_str_ansi_len (ptr); // handle ansi chars { int utf8len = r_str_len_utf8 (ptr); int ansilen = r_str_ansi_len (ptr); int diff = len-utf8len; if (diff) diff--; alen = ansilen - diff; } *nl = '\n'; if (alen>cols) { endptr = r_str_ansi_chrn (ptr, cols); endptr++; len = (endptr-ptr); if (lines>0) { r_cons_write (ptr, len); } } else { if (lines>0) { int w = cols-alen; if (ptr>buffer) r_cons_write (ptr-1, len); else r_cons_write (ptr, len-1); if (I.blankline && w>0) { if (w>sizeof (white)-1) w = sizeof (white)-1; r_cons_write (white, w); } } // TRICK to empty columns.. maybe buggy in w32 if (r_mem_mem ((const ut8*)ptr, len, (const ut8*)"\x1b[0;0H", 6)) { lines = I.rows; r_cons_write (ptr, len); } } lines--; // do not use last line ptr = nl+1; } /* fill the rest of screen */ if (lines>0) { if (cols>sizeof (white)) cols = sizeof (white); while (lines-->0) r_cons_write (white, cols); } }
static bool rtti_itanium_print_class_type_info_recurse(RVTableContext *context, ut64 atAddress, int mode) { bool use_json = mode == 'j'; ut64 colRefAddr = atAddress - context->word_size; //Vtable: Type Info ut64 colAddr; //Type Info ut64 class_type_offset; if (!context->read_addr (context->anal, colRefAddr, &colAddr)) { return false; } if (!context->read_addr (context->anal, colAddr, &class_type_offset)) { return false; } RCore *core = context->anal->coreb.core; if (!core) { return false; } class_type_offset -= 2 * context->word_size; RFlagItem *flag; flag = r_flag_get_i(core->flags, class_type_offset); if (!flag) { eprintf ("No RTTI found\n"); return false; } if (!r_str_cmp (flag->name, vmi_class_type_info_name, r_str_len_utf8 (flag->name))) { vmi_class_type_info vmi_cti; if (!rtti_itanium_read_vmi_class_type_info (context, colAddr, &vmi_cti)) { eprintf ("Failed to parse Type Info at 0x%08"PFMT64x" (referenced from 0x%08"PFMT64x")\n", colAddr, colRefAddr); return false; } if (use_json) { rtti_itanium_print_vmi_class_type_info_json (&vmi_cti, colAddr); } else { rtti_itanium_print_vmi_class_type_info (&vmi_cti, colAddr, ""); } } if (!r_str_cmp (flag->name, si_class_type_info_name, r_str_len_utf8 (flag->name))) { si_class_type_info si_cti; if (!rtti_itanium_read_si_class_type_info (context, colAddr, &si_cti)) { eprintf ("Failed to parse Type Info at 0x%08"PFMT64x" (referenced from 0x%08"PFMT64x")\n", colAddr, colRefAddr); return false; } if (use_json) { rtti_itanium_print_si_class_type_info_json (&si_cti, colAddr); } else { rtti_itanium_print_si_class_type_info (&si_cti, colAddr, ""); } } if (!r_str_cmp (flag->name, class_type_info_name, r_str_len_utf8 (flag->name))) { class_type_info cti; if (!rtti_itanium_read_class_type_info (context, colAddr, &cti)) { eprintf ("Failed to parse Type Info at 0x%08"PFMT64x" (referenced from 0x%08"PFMT64x")\n", colAddr, colRefAddr); return false; } if (use_json) { rtti_itanium_print_class_type_info_json (&cti, colAddr); } else { rtti_itanium_print_class_type_info (&cti, colAddr, ""); } } return true; }
// TODO: move into another file // TODO: this is TOO SLOW. do not iterate over all reflines or gtfo R_API char* r_anal_reflines_str(void *core, ut64 addr, int opts) { int l, linestyle = opts & R_ANAL_REFLINE_TYPE_STYLE; int dir = 0, wide = opts & R_ANAL_REFLINE_TYPE_WIDE; char ch = ' ', *str = NULL; struct list_head *pos; RAnalRefline *ref, *list = ((RCore*)core)->reflines; if (!list) return NULL; str = r_str_concat (str, " "); for (pos = linestyle?(&(list->list))->next:(&(list->list))->prev; pos != (&(list->list)); pos = linestyle?pos->next:pos->prev) { ref = list_entry (pos, RAnalRefline, list); dir = (addr == ref->to)? 1: (addr == ref->from)? 2: dir; if (addr == ref->to) { str = r_str_concat (str, (ref->from>ref->to)? "." : "`"); ch = '-'; } else if (addr == ref->from) { str = r_str_concat (str, (ref->from>ref->to)? "`" : "," ); ch = '='; } else if (ref->from < ref->to) { if (addr > ref->from && addr < ref->to) { if (ch=='-' || ch=='=') str = r_str_concatch (str, ch); //else str = r_str_concat (str, ((RCore*)core)->cons->vline[LINE_VERT]); else str = r_str_concatch (str, '|'); } else str = r_str_concatch (str, ch); } else { if (addr < ref->from && addr > ref->to) { if (ch=='-' || ch=='=') str = r_str_concatch (str, ch); //else str = r_str_concat (str, ((RCore*)core)->cons->vline[LINE_VERT]); else str = r_str_concatch (str, '|'); } else str = r_str_concatch (str, ch); } if (wide) str = r_str_concatch (str, (ch=='=' || ch=='-')? ch : ' '); } //str = r_str_concat (str, (dir==1)?"-> ":(dir==2)?"=< ":" "); str = r_str_concat (str, (dir==1)? "-> " :(dir==2)? "=< " : " "); if (((RCore*)core)->anal->lineswidth>0) { l = r_str_len_utf8 (str); if (l > ((RCore*)core)->anal->lineswidth) r_str_cpy (str, str + l - ((RCore*)core)->anal->lineswidth); } /* HACK */ if (((RCore*)core)->utf8 && ((RCore*)core)->cons->vline) { RCons *cons = ((RCore*)core)->cons; //str = r_str_replace (str, "=", "-", 1); str = r_str_replace (str, "<", cons->vline[ARROW_LEFT], 1); str = r_str_replace (str, ">", cons->vline[ARROW_RIGHT], 1); str = r_str_replace (str, "|", cons->vline[LINE_VERT], 1); str = r_str_replace (str, "=", cons->vline[LINE_HORIZ], 1); str = r_str_replace (str, "-", cons->vline[LINE_HORIZ], 1); //str = r_str_replace (str, ".", "\xe2\x94\x8c", 1); str = r_str_replace (str, ",", cons->vline[LUP_CORNER], 1); str = r_str_replace (str, ".", cons->vline[LUP_CORNER], 1); str = r_str_replace (str, "`", cons->vline[LDWN_CORNER], 1); } if (((RCore*)core)->anal->lineswidth>0) { char pfx[128]; int l = ((RCore*)core)->anal->lineswidth-r_str_len_utf8 (str); memset (pfx, ' ', sizeof (pfx)); if (l>=sizeof(pfx)) l = sizeof (pfx)-1; pfx[l] = 0; str = r_str_prefix (str, pfx); } return str; }