static void dump_cols (ut8 *a, int as, ut8 *b, int bs, int w) { ut32 sz = R_MIN (as, bs); ut32 i, j; switch (w) { case 8: printf (" offset 0 1 2 3 4 5 6 7 01234567 0 1 2 3 4 5 6 7 01234567\n"); break; case 16: printf (" offset " "0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF " "0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\n"); break; default: eprintf ("Invalid column width\n"); return ; } for (i=0; i<sz; i+=w) { printf ("0x%08x%c ", i, (memcmp (a+i, b+i, 8))? ' ': '!'); for (j=0; j<w; j++) printf ("%02x", a[i+j]); printf (" "); for (j=0; j<w; j++) printf ("%c", IS_PRINTABLE (a[i+j])?a[i+j]:'.'); printf (" "); for (j=0; j<w; j++) printf ("%02x", b[i+j]); printf (" "); for (j=0; j<w; j++) printf ("%c", IS_PRINTABLE (b[i+j])? b[i+j]:'.'); printf ("\n"); } if (as != bs) printf ("...\n"); }
static void r_print_format_nulltermstring(const RPrint* p, const int len, int endian, int mode, const char* setval, ut64 seeki, ut8* buf, int i, int size) { if (MUSTSET) { int buflen = strlen ((const char *)buf+seeki), vallen = strlen(setval); char *newstring, *ons; newstring = ons = strdup(setval); if ((newstring[0] == '\"' && newstring[vallen-1] == '\"') || (newstring[0] == '\'' && newstring[vallen-1] == '\'')) { newstring[vallen-1] = '\0'; newstring++; vallen-=2; } if (vallen > buflen) { eprintf ("Warning: new string is longer than previous one\n"); } p->cb_printf ("wx "); for (i=0;i<vallen;i++) { if (i < vallen-3 && newstring[i] == '\\' && newstring[i+1] == 'x') { p->cb_printf ("%c%c", newstring[i+2], newstring[i+3]); i+=3; } else { p->cb_printf ("%2x", newstring[i]); } } p->cb_printf (" @ 0x%08"PFMT64x"\n", seeki); free(ons); } else if (mode & R_PRINT_DOT) { int j = i; p->cb_printf ("\\\"", seeki); for (; j<len && ((size==-1 || size-- >0) && buf[j]) ; j++) { char ch = buf[j]; if (ch == '"') { p->cb_printf ("\\\""); } else if (IS_PRINTABLE (ch)) { p->cb_printf ("%c", ch); } else p->cb_printf ("."); } p->cb_printf ("\\\""); } else if (MUSTSEE) { int j = i; if (!SEEVALUE) p->cb_printf ("0x%08"PFMT64x" = ", seeki); for (; j<len && ((size==-1 || size-- >0) && buf[j]) ; j++) { if (IS_PRINTABLE (buf[j])) p->cb_printf ("%c", buf[j]); else p->cb_printf ("."); } } else if (MUSTSEEJSON) { int j = i; p->cb_printf ("%d,\"string\":\"", seeki); for (; j<len && ((size==-1 || size-- >0) && buf[j]) ; j++) { if (IS_PRINTABLE (buf[j])) p->cb_printf ("%c", buf[j]); else p->cb_printf ("."); } p->cb_printf ("\"}"); } }
static void r_print_format_char(const RPrint* p, int endian, int mode, const char* setval, ut64 seeki, ut8* buf, int i, int size) { int elem = -1; if (size >= ARRAYINDEX_COEF) { elem = size/ARRAYINDEX_COEF-1; size %= ARRAYINDEX_COEF; } if (MUSTSET) { p->printf ("\"w %s\" @ 0x%08"PFMT64x"\n", setval, seeki); } else if (MUSTSEE) { p->printf ("0x%08"PFMT64x" = ", seeki); if (size==-1) p->printf (" %d ; '%c'", buf[i], buf[i], buf[i], IS_PRINTABLE (buf[i])?buf[i]:'.'); else { p->printf ("[ "); while (size--) { if (elem == -1 || elem == 0) { p->printf ("%d ; '%c'", buf[i], buf[i], buf[i], IS_PRINTABLE (buf[i])?buf[i]:'.'); if (elem == 0) elem = -2; } if (size != 0 && elem == -1) p->printf (", "); if (elem > -1) elem--; i++; } p->printf (" ]"); } } else if (MUSTSEEJSON) { if (size==-1) p->printf ("\"%c\"", buf[i]); else { p->printf ("[ "); while (size--) { if (elem == -1 || elem == 0) { p->printf ("\"%c\"", buf[i]); if (elem == 0) elem = -2; } if (size != 0 && elem == -1) p->printf (", "); if (elem > -1) elem--; i++; } p->printf (" ]"); } p->printf ("}"); } }
// move it out // r_diff maybe? static int radare_compare(RCore *core, const ut8 *f, const ut8 *d, int len) { int i, eq = 0; for (i=0; i<len; i++) { if (f[i]==d[i]) { eq++; continue; } r_cons_printf ("0x%08"PFMT64x" (byte=%.2d) %02x '%c' -> %02x '%c'\n", core->offset+i, i+1, f[i], (IS_PRINTABLE(f[i]))?f[i]:' ', d[i], (IS_PRINTABLE(d[i]))?d[i]:' '); } eprintf ("Compare %d/%d equal bytes\n", eq, len); return len-eq; }
static int is_string (const ut8 *buf, int size, int *len) { int i; if (size<1) return 0; if (size>3 && buf[0] &&!buf[1]&&buf[2]&&!buf[3]) { *len = 1; // XXX: TODO: Measure wide string length return 2; // is wide } for (i=0; i<size; i++) { if (!buf[i] && i>MINLEN) { *len = i; return 1; } if (buf[i]<32 || buf[i]>127) { // not ascii text return 0; } if (buf[i]==10||buf[i]==13||buf[i]==9) { continue; } if (!IS_PRINTABLE (buf[i])) { *len = i; return 0; } } *len = i; return 1; }
/* TODO: use a whitelist :) */ static int r_name_validate_char(const char ch) { if ((ch>='a' && ch<='z') || (ch>='A' && ch<='Z') || (ch>='0' && ch<='9')) return R_TRUE; switch (ch) { case '.': case '_': return R_TRUE; } return R_FALSE; #if 0 switch (ch) { case '!': case ':': case '{': case '}': case '$': case '=': case '*': case '/': case '+': case '|': case '&': case ';': case '~': case '"': case '>': case '<': case '#': case '%': case '(': case ')': case '`': case '\'': case '-': case ' ': case '\n': case '\t': case '[': case ']': case '@': return 0; default: if (((ch >= '0') && (ch <= '9'))) return R_TRUE; if (!IS_PRINTABLE (ch)) return R_FALSE; } return R_TRUE; #endif }
// Copy all printable characters from src to dst, copy all printable characters // as '.'. R_API void r_str_ncpy(char *dst, const char *src, int n) { int i; for (i = 0; src[i] && n > 0; i++, n--) { dst[i] = IS_PRINTABLE (src[i])? src[i]: '.'; } dst[i] = 0; }
R_API char *r_str_unscape(char *buf) { char *ptr, *ret; int len = strlen (buf); ptr = ret = malloc (1+len*2); if (ptr == NULL) return NULL; for (;*buf;buf++,ptr++) { if (*buf=='\n') { *ptr = '\\'; ptr++; *ptr = 'n'; } else if (*buf=='\t') { *ptr = '\\'; ptr++; *ptr = 't'; } else if (IS_PRINTABLE (*buf)) { *ptr = *buf; } else break; } *ptr = 0; r_str_sanitize (ret); return ret; }
static int r_print_format_hexpairs(const RPrint* p, int endian, int mode, const char* setval, ut64 seeki, ut8* buf, int size) { int j; if (MUSTSET) { p->printf ("?e pf X not yet implemented\n"); } else if (MUSTSEE) { size = (size < 1) ? 1 : size; p->printf ("0x%08"PFMT64x" = ", seeki); j=0; for (; j<10; j++) p->printf ("%02x ", buf[j]); p->printf (" ... ("); for (j=0; j<size; j++) if (IS_PRINTABLE (buf[j])) p->printf ("%c", buf[j]); else p->printf ("."); p->printf (")"); } else if (MUSTSEEJSON) { size = (size < 1) ? 1 : size; p->printf ("[ %d", buf[0]); j=1; for (; j<10; j++) p->printf (", %d", buf[j]); p->printf ("]}"); return size; } return size; }
static int r_print_format_10bytes(const RPrint* p, int mustset, const char* setval, ut64 seeki, ut64 addr, ut8* buf) { ut8 buffer[255]; int j; if (mustset) { realprintf ("?e pf B not yet implemented\n"); } else { if (!p->iob.read_at) { printf ("(cannot read memory)\n"); return -1; } else p->iob.read_at (p->iob.io, (ut64)addr, buffer, 248); p->printf ("0x%08"PFMT64x" = ", seeki); for (j=0; j<10; j++) p->printf ("%02x ", buf[j]); p->printf (" ... ("); for (j=0; j<10; j++) if (IS_PRINTABLE (buf[j])) p->printf ("%c", buf[j]); else p->printf ("."); p->printf (")"); } return 0; }
static void r_print_format_nulltermwidestring(const RPrint* p, const int len, int endian, int mode, const char* setval, ut64 seeki, ut8* buf, int i, int size) { if (MUSTSET) { int vallen = strlen(setval); char *newstring, *ons; newstring = ons = strdup(setval); if ((newstring[0] == '\"' && newstring[vallen-1] == '\"') || (newstring[0] == '\'' && newstring[vallen-1] == '\'')) { newstring[vallen-1] = '\0'; newstring++; vallen-=2; } if ((size = strlen (setval)) > r_wstr_clen((char*)(buf+seeki))) eprintf ("Warning: new string is longer than previous one\n"); p->printf ("ww %s @ 0x%08"PFMT64x"\n", newstring, seeki); free(ons); } else if (MUSTSEE) { int j = i; p->printf ("0x%08"PFMT64x" = ", seeki); for (; j<len && ((size || size==-1) && buf[j]) ; j+=2) { if (IS_PRINTABLE (buf[j])) p->printf ("%c", buf[j]); else p->printf ("."); } } }
/* returns 0-100 */ R_API int r_hash_pcprint(const ut8 *buffer, ut64 len) { const ut8 *end = buffer + len; int n; for (n=0; buffer<end; buffer++) if (IS_PRINTABLE (*buffer)) n++; return ((100*n)/len); }
R_API bool r_mem_is_printable(const ut8 *a, int la) { int i; for (i = 0; i < la; i++) { if (a[i] != '\n' && a[i] != '\t' && !IS_PRINTABLE (a[i])) { return false; } } return true; }
R_API void r_str_filter_zeroline(char *str, int len) { int i; for (i=0; str[i] && i<len; i++) { if (str[i]=='\n' || str[i]=='\r') break; if (!IS_PRINTABLE (str[i])) break; } str[i] = 0; }
/* there may be unprintable characters in string - should escape them when printing */ static void print_string_value(char *string) { int i; for (i = 0; string[i] != 0; i++) { if (IS_PRINTABLE(string[i])) printf("%c", string[i]); else printf("^%c", string[i] ^ 0x40); } }
R_API void r_core_visual_show_char (RCore *core, char ch) { if (r_config_get_i (core->config, "scr.feedback")<2) return; if (!IS_PRINTABLE (ch)) return; r_cons_gotoxy (1, 2); r_cons_printf (".---.\n"); r_cons_printf ("| %c |\n", ch); r_cons_printf ("'---'\n"); r_cons_flush (); r_sys_sleep (1); }
// XXX: redesign ? :) R_API char *r_print_hexpair(RPrint *p, const char *str, int n) { const char *s, *lastcol = Color_WHITE; char *d, *dst = (char *)malloc ((strlen (str)+2)*32); int colors = p->flags & R_PRINT_FLAGS_COLOR; /* XXX That's hacky as shit.. but partially works O:) */ /* TODO: Use r_print_set_cursor for win support */ int cur = R_MIN (p->cur, p->ocur); int ocur = R_MAX (p->cur, p->ocur); int ch, i; if (p->cur_enabled && cur==-1) cur = ocur; ocur++; #if CURDBG sprintf (dst, "(%d/%d/%d/%d)", p->cur_enabled, cur, ocur, n); d = dst+ strlen(dst); #else d = dst; #endif // XXX: overflow here // TODO: Use r_cons primitives here #define memcat(x,y) { memcpy(x,y,strlen(y));x+=strlen(y); } //for (s=str, d=dst; *s; s+=2, d+=2, i++) { for (s=str, i=0 ; *s; s+=2, d+=2, i++) { if (p->cur_enabled) { if (i==ocur-n) //memcat (d, "\x1b[27;47;30m"); //memcat (d, "\x1b[0m");//27;47;30m"); memcat (d, "\x1b[0m"); memcat (d, lastcol); if (i>=cur-n && i<ocur-n) memcat (d, "\x1b[7m"); } if (colors) { if (s[0]=='0' && s[1]=='0') lastcol = Color_GREEN; else if (s[0]=='7' && s[1]=='f') lastcol = Color_YELLOW; else if (s[0]=='f' && s[1]=='f') lastcol = Color_RED; else { ch = r_hex_pair2bin(s); //sscanf (s, "%02x", &ch); // XXX can be optimized if (IS_PRINTABLE (ch)) lastcol = Color_MAGENTA; } memcat (d, lastcol); } memcpy (d, s, 2); } if (colors || p->cur_enabled) memcpy (d, Color_RESET, strlen (Color_RESET)+1); else *d = 0; return dst; }
R_API void r_print_byte(RPrint *p, const char *fmt, int idx, ut8 ch) { ut8 rch = ch; if (!IS_PRINTABLE (ch) && fmt[0]=='%'&&fmt[1]=='c') rch = '.'; r_print_cursor (p, idx, 1); //if (p->flags & R_PRINT_FLAGS_CURSOR && idx == p->cur) { if (p->flags & R_PRINT_FLAGS_COLOR) { char *pre = NULL; switch (ch) { case 0x00: pre = Color_GREEN; break; case 0x7F: pre = Color_YELLOW; break; case 0xFF: pre = Color_RED; break; default: if (IS_PRINTABLE (ch)) pre = Color_MAGENTA; } if (pre) p->printf (pre); p->printf (fmt, rch); if (pre) p->printf (Color_RESET); } else p->printf (fmt, rch); r_print_cursor (p, idx, 0); }
/* returns 0-100 */ R_API int r_hash_pcprint(const ut8 *buffer, ut64 len) { const ut8 *end = buffer + len; int n; if (len < 1) { return 0; } for (n = 0; buffer < end; buffer++) { if (IS_PRINTABLE (*buffer)) { n++; } } return ((100 * n) / len); }
static void r_print_format_char(const RPrint* p, int endian, int mustset, const char* setval, ut64 seeki, ut8* buf, int i, int size) { if (mustset) { realprintf ("\"w %s\" @ 0x%08"PFMT64x"\n", setval, seeki); } else { p->printf ("0x%08"PFMT64x" = ", seeki); if (size==-1) p->printf ("%d ; %d ; '%c'", buf[i], buf[i], IS_PRINTABLE (buf[i])?buf[i]:0); else { p->printf ("[ %d ; %d ; '%c'", buf[i], buf[i], IS_PRINTABLE (buf[i])?buf[i]:0); size--; i++; while (size--) { p->printf (", %d ; %d ; '%c'", buf[i], buf[i], IS_PRINTABLE (buf[i])?buf[i]:0); i++; } p->printf (" ]"); } } }
static void dump_cols (ut8 *a, int as, ut8 *b, int bs) { ut32 sz = R_MIN (as, bs); ut32 i, j; printf (" offset 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8\n"); for (i=0; i<sz; i++) { char dch = (memcmp (a+i, b+i, 8))? ' ': '!'; printf ("0x%08x%c ", i, dch); for (j=0; j<8; j++) printf ("%02x", a[i+j]); printf (" "); for (j=0; j<8; j++) printf ("%c", IS_PRINTABLE (a[i+j])?a[i+j]:'.'); printf (" "); for (j=0; j<8; j++) printf ("%02x", b[i+j]); printf (" "); for (j=0; j<8; j++) printf ("%c", IS_PRINTABLE (b[i+j])? b[i+j]:'.'); printf ("\n"); } if (as != bs) printf ("...\n"); }
static PRBool IsPrintable(unsigned char *data, unsigned len) { unsigned char ch, *end; end = data + len; while (data < end) { ch = *data++; if (!IS_PRINTABLE(ch)) { return PR_FALSE; } } return PR_TRUE; }
R_API void bfvm_show_regs(BfvmCPU *c, int rad) { if (rad) { eprintf ("fs regs\n"); eprintf ("f eip @ 0x%08"PFMT64x"\n", (ut64)c->eip); eprintf ("f esp @ 0x%08"PFMT64x"\n", (ut64)c->esp); eprintf ("f ptr @ 0x%08"PFMT64x"\n", (ut64)c->ptr+c->base); eprintf ("fs *\n"); } else { ut8 ch = bfvm_get (c); eprintf (" eip 0x%08"PFMT64x" esp 0x%08"PFMT64x"\n", (ut64)c->eip, (ut64)c->esp); eprintf (" ptr 0x%08x [ptr] %d = 0x%02x '%c'\n", (ut32)c->ptr, ch, ch, IS_PRINTABLE (ch)? ch:' '); } }
static int r_print_format_10bytes(const RPrint* p, int mode, const char* setval, ut64 seeki, ut64 addr, ut8* buf) { ut8 buffer[255]; int j; if (MUSTSET) { p->cb_printf ("?e pf B not yet implemented\n"); } else if (mode & R_PRINT_DOT) { for (j = 0; j<10; j++) { p->cb_printf ("%02x ", buf[j]); } } else if (MUSTSEE) { if (!p->iob.read_at) { printf ("(cannot read memory)\n"); return -1; } p->iob.read_at (p->iob.io, (ut64)addr, buffer, 248); if (!SEEVALUE) p->cb_printf ("0x%08"PFMT64x" = ", seeki); for (j=0; j<10; j++) { p->cb_printf ("%02x ", buf[j]); } if (!SEEVALUE) p->cb_printf (" ... ("); for (j = 0; j < 10; j++) { if (!SEEVALUE) { if (IS_PRINTABLE (buf[j])) { p->cb_printf ("%c", buf[j]); } else { p->cb_printf ("."); } } } if (!SEEVALUE) p->cb_printf (")"); } else if (MUSTSEEJSON) { if (!p->iob.read_at) { printf ("(cannot read memory)\n"); return -1; } else { p->iob.read_at (p->iob.io, (ut64)addr, buffer, 248); } p->cb_printf ("[ %d", buf[0]); j = 1; for (; j < 10; j++) { p->cb_printf (", %d", buf[j]); } p->cb_printf ("]"); return 0; } return 0; }
static int hit(RSearchKeyword *kw, void *user, ut64 addr) { int delta = addr - cur; if (cur > addr && (cur - addr == kw->keyword_length - 1)) { // This case occurs when there is hit in search left over delta = cur - addr; } if (delta < 0 || delta >= bsize) { eprintf ("Invalid delta\n"); return 0; } if (rad) { printf ("f hit%d_%d 0x%08"PFMT64x" ; %s\n", 0, kw->count, addr, curfile); } else { if (showstr) { if (widestr) { char *str = calloc (1, bsize); int i, j = 0; for (i = delta; buf[i] && i < bsize; i++) { if (!IS_PRINTABLE (buf[i])) { break; } str[j++] = buf[i++]; if (j > 80) { strcpy (str + j, "..."); j += 3; break; } if (buf[i]) { break; } } str[j] = 0; printf ("0x%"PFMT64x" %s\n", addr, str); free (str); } else { printf ("0x%"PFMT64x" %s\n", addr, buf + delta); } } else { printf ("0x%"PFMT64x"\n", addr); if (pr) { r_print_hexdump (pr, addr, (ut8*)buf + delta, 78, 16, 1, 1); r_cons_flush (); } } } return 1; }
static char *hashify(char *s, ut64 vaddr) { r_return_val_if_fail (s, NULL); char *os = s; while (*s) { if (!IS_PRINTABLE (*s)) { if (vaddr && vaddr != UT64_MAX) { free (os); return r_str_newf ("_%" PFMT64d, vaddr); } ut32 hash = sdb_hash (s); free (os); return r_str_newf ("%x", hash); } s++; } return os; }
static int r_print_format_hexpairs(const RPrint* p, int endian, int mustset, const char* setval, ut64 seeki, ut8* buf, int size) { int j; if (mustset) { realprintf ("?e pf X not yet implemented\n"); } else { p->printf ("0x%08"PFMT64x" = ", seeki); size = (size < 1) ? 1 : size; for (j=0; j<size; j++) p->printf ("%02x ", (ut8)buf[j]); p->printf (" ... ("); for (j=0; j<size; j++) if (IS_PRINTABLE (buf[j])) p->printf ("%c", buf[j]); else p->printf ("."); p->printf (")"); } return size; }
R_API int r_print_string(RPrint *p, ut64 seek, const ut8 *buf, int len, int wide, int zeroend, int urlencode) { int i; //if (p->flags & R_PRINT_FLAGS_OFFSET) // r_print_addr(p, seek); p->interrupt = 0; for (i=0; !p->interrupt && i<len; i++) { if (zeroend && buf[i]=='\0') break; r_print_cursor (p, i, 1); if (urlencode) { // TODO: some ascii can be bypassed here p->printf ("%%%02x", buf[i]); } else { if (buf[i]=='\n' || IS_PRINTABLE (buf[i])) p->printf ("%c", buf[i]); else p->printf ("\\x%02x", buf[i]); } r_print_cursor (p, i, 0); if (wide) i++; } p->printf ("\n"); return i; }
static void display_block_data(t_block *block) { size_t i = 0; printf("[+] ASCII :\n"); while (i < block->size) { printf("%c", (IS_PRINTABLE(block->data[i]) ? block->data[i] : '.')); if (i % 10 == 0) printf("\n"); ++i; } printf("\n"); printf("[+] HEX :\n"); i = 0; while (i < block->size) { printf("%x ", block->data[i] > 0 ? block->data[i] : 255); if (i % 10 == 0) printf("\n"); ++i; } printf("\n"); }
/* Internal function. dot_nl specifies wheter to convert \n into the * graphiz-compatible newline \l */ static char *r_str_escape_(const char *buf, const int dot_nl) { char *new_buf, *q; const char *p; if (!buf) { return NULL; } /* Worst case scenario, we convert every byte */ new_buf = malloc (1 + (strlen (buf) * 4)); if (!new_buf) { return NULL; } p = buf; q = new_buf; while (*p) { switch (*p) { case '\n': *q++ = '\\'; *q++ = dot_nl? 'l': 'n'; break; case '\r': *q++ = '\\'; *q++ = 'r'; break; case '\\': *q++ = '\\'; *q++ = '\\'; break; case '\t': *q++ = '\\'; *q++ = 't'; break; case '"' : *q++ = '\\'; *q++ = '"'; break; case '\f': *q++ = '\\'; *q++ = 'f'; break; case '\b': *q++ = '\\'; *q++ = 'b'; break; case 0x1b: // ESC p++; /* Parse the ANSI code (only the graphic mode * set ones are supported) */ if (*p == '\0') goto out; if (*p == '[') for (p++; *p != 'm'; p++) { if (*p == '\0') goto out; } break; default: /* Outside the ASCII printable range */ if (!IS_PRINTABLE (*p)) { *q++ = '\\'; *q++ = 'x'; *q++ = '0'+((*p)>>4); *q++ = '0'+((*p)&0xf); } else { *q++ = *p; } }