R_API void r_cons_pal_list(int rad, const char *arg) { char *name, **color; const char *hasnext; int i; if (rad == 'j') { r_cons_print ("{"); } for (i = 0; keys[i].name; i++) { RColor *rcolor = RCOLOR_AT (i); color = COLOR_AT (i); switch (rad) { case 'j': hasnext = (keys[i + 1].name) ? "," : ""; r_cons_printf ("\"%s\":[%d,%d,%d]%s", keys[i].name, rcolor->r, rcolor->g, rcolor->b, hasnext); break; case 'c': { const char *prefix = r_str_trim_ro (arg); if (!prefix) { prefix = ""; } hasnext = (keys[i + 1].name) ? "\n" : ""; // TODO Need to replace the '.' char because this is not valid CSS char *name = strdup (keys[i].name); int j, len = strlen (name); for (j = 0; j < len; j++) { if (name[j] == '.') { name[j] = '_'; } } r_cons_printf (".%s%s { color: rgb(%d, %d, %d); }%s", prefix, name, rcolor->r, rcolor->g, rcolor->b, hasnext); free (name); } break; case 'h': name = strdup (keys[i].name); r_str_replace_char (name, '.', '_'); r_cons_printf (".%s { color:#%02x%02x%02x }\n", name, rcolor->r, rcolor->g, rcolor->b); free (name); break; case '*': case 'r': case 1: r_cons_printf ("ec %s rgb:%02x%02x%02x\n", keys[i].name, rcolor->r, rcolor->g, rcolor->b); break; default: r_cons_printf (" %s##"Color_RESET" %s\n", *color, keys[i].name); } } if (rad == 'j') { r_cons_print ("}\n"); } }
int main() { int i,j ,k; //char *str = "\x1b[38;5;231mpop\x1b[0m"; //char *str ="\x1b]4;%d;rgb:30/20/24pop\x1b[0m"; char *str ="\x1b\\pop\x1b[0m"; i=j=k =0; r_cons_new (); // r_cons_rgb_init (); printf ("3 == %d\n", r_str_ansi_len (str)); for (i=0;i<255;i+=40) { for (j=0;j<255;j+=40) { for (k=0;k<255;k+=40) { r_cons_rgb (i, j, k, 0); r_cons_rgb (i, j, k, 1); r_cons_print ("__"); r_cons_reset_colors (); r_cons_rgb (i, j, k, 0); // r_cons_rgb (155, 200, 200, 1); r_cons_printf (" RGB %d %d %d", i, j, k); r_cons_reset_colors (); r_cons_newline (); } }} r_cons_flush (); return 0; }
static void r_cons_pal_show_rgb() { const int inc = 3; int i, j, k, n = 0; RColor rc = RColor_BLACK; r_cons_print ("\n\nRGB:\n"); for (i = n = 0; i <= 0xf; i += inc) { for (k = 0; k <= 0xf; k += inc) { for (j = 0; j <= 0xf; j += inc) { char fg[32], bg[32]; rc.r = i * 16; rc.g = j * 16; rc.b = k * 16; strcpy (fg, ((i < 6) && (j < 5)) ? Color_WHITE: Color_BLACK); r_cons_rgb_str (bg, sizeof (bg), &rc); r_cons_printf ("%s%s rgb:%02x%02x%02x " Color_RESET, fg, bg, rc.r, rc.g, rc.b); if (n ++== 5) { n = 0; r_cons_newline (); } } } } }
static void r_cons_pal_show_rgb () { const int inc = 3; int i, j, k, n = 0; r_cons_print ("\n\nRGB:\n"); for (i = n = 0; i <= 0xf; i += inc) { for (k = 0; k <= 0xf; k += inc) { for (j = 0; j <= 0xf; j += inc) { char fg[32], bg[32]; int r = i * 16; int g = j * 16; int b = k * 16; strcpy (fg, ((i < 6) && (j < 5)) ? Color_WHITE: Color_BLACK); r_cons_rgb_str (bg, r, g, b, 1); r_cons_printf ("%s%s rgb:%02x%02x%02x " Color_RESET, fg, bg, r, g, b); //if (n++==7) { if (n ++== 5) { n = 0; r_cons_newline (); } } } } }
static void r_cons_pal_show_256() { RColor rc = RColor_BLACK; r_cons_print ("\n\nXTerm colors:\n"); int r = 0; int g = 0; int b = 0; for (r = 0x00; r <= 0xff; r += 0x28) { rc.r = r; if (rc.r == 0x28) { rc.r = 0x5f; } for (b = 0x00; b <= 0xff; b += 0x28) { rc.b = b; if (rc.b == 0x28) { rc.b = 0x5f; } for (g = 0x00; g <= 0xff; g += 0x28) { rc.g = g; char bg[32]; if (rc.g == 0x28) { rc.g = 0x5f; } const char *fg = ((rc.r <= 0x5f) && (rc.g <= 0x5f)) ? Color_WHITE: Color_BLACK; r_cons_rgb_str (bg, sizeof (bg), &rc); r_cons_printf ("%s%s rgb:%02x%02x%02x " Color_RESET, fg, bg, rc.r, rc.g, rc.b); } r_cons_newline (); } } }
static void r_cons_pal_show_256 () { int r, g, b; r_cons_print ("\n\nXTerm colors:\n"); for (r = 0x00; r <= 0xff; r += 0x28) { if (r == 0x28) { r = 0x5f; } for (b = 0x00; b <= 0xff; b += 0x28) { if (b == 0x28) { b = 0x5f; } for (g = 0x00; g <= 0xff; g += 0x28) { char fg[32], bg[32]; if (g == 0x28) { g = 0x5f; } if ((r <= 0x5f) && (g <= 0x5f)) { strcpy (fg, Color_WHITE); } else { strcpy (fg, Color_BLACK); } r_cons_rgb_str (bg, r, g, b, 1); r_cons_printf ("%s%s rgb:%02x%02x%02x " Color_RESET, fg, bg, r, g, b); if (g == 0xff) { r_cons_newline (); } } } } }
R_API int r_cons_any_key(const char *msg) { if (msg && *msg) { r_cons_printf ("\n-- %s --\n", msg); } else { r_cons_print ("\n--press any key--\n"); } r_cons_flush (); return r_cons_readchar (); //r_cons_strcat ("\x1b[2J\x1b[0;0H"); // wtf? }
static void r_cons_pal_show_gs () { int i, n; r_cons_print ("\nGreyscale:\n"); for (i = 0x08, n = 0; i <= 0xee; i += 0xa) { char fg[32], bg[32]; if (i < 0x76) strcpy (fg, Color_WHITE); else strcpy (fg, Color_BLACK); r_cons_rgb_str (bg, i, i, i, 1); r_cons_printf ("%s%s rgb:%02x%02x%02x "Color_RESET, fg, bg, i, i, i); if (n++ == 5) { n = 0; r_cons_newline (); } } }
static void rtti_msvc_print_all(RVTableContext *context, int mode) { r_cons_break_push (NULL, NULL); RList *vtables = r_anal_vtable_search (context); RListIter *vtableIter; RVTableInfo *table; if (vtables) { r_list_foreach (vtables, vtableIter, table) { if (r_cons_is_breaked ()) { break; } r_anal_rtti_msvc_print_at_vtable (context, table->saddr, mode); r_cons_print ("\n"); } } r_list_free (vtables); r_cons_break_pop (); }
static void r_cons_pal_show_gs() { int i, n; r_cons_print ("\nGreyscale:\n"); RColor rcolor = RColor_BLACK; for (i = 0x08, n = 0; i <= 0xee; i += 0xa) { char fg[32], bg[32]; rcolor.r = i; rcolor.g = i; rcolor.b = i; if (i < 0x76) { strcpy (fg, Color_WHITE); } else { strcpy (fg, Color_BLACK); } r_cons_rgb_str (bg, sizeof (bg), &rcolor); r_cons_printf ("%s%s rgb:%02x%02x%02x "Color_RESET, fg, bg, i, i, i); if (n++ == 5) { n = 0; r_cons_newline (); } } }
R_API void r_cons_pal_list (int rad, const char *arg) { RConsPalette *pal = & (r_cons_singleton ()->pal); ut8 r, g, b, *p = (ut8*)pal; char *name, **color, rgbstr[32]; const char *hasnext; int i; if (rad == 'j') r_cons_print ("{"); for (i = 0; keys[i].name; i++) { color = (char**) (p + keys[i].off); switch (rad) { case 'j': r = g = b = 0; r_cons_rgb_parse (*color, &r, &g, &b, NULL); hasnext = (keys[i + 1].name) ? "," : ""; r_cons_printf ("\"%s\":[%d,%d,%d]%s", keys[i].name, r, g, b, hasnext); break; case 'c': { const char *prefix = r_str_chop_ro (arg); if (!prefix) { prefix = ""; } r = g = b = 0; r_cons_rgb_parse (*color, &r, &g, &b, NULL); hasnext = (keys[i + 1].name) ? "\n" : ""; //Need to replace the '.' char because this is not //valid CSS char *name = strdup (keys[i].name); int j, len = strlen (name); for (j = 0; j < len; j++) { if (name[j] == '.') { name[j] = '_'; } } r_cons_printf (".%s%s { color: rgb(%d, %d, %d); }%s", prefix, name, r, g, b, hasnext); free (name); } break; case 'h': r = g = b = 0; r_cons_rgb_parse (*color, &r, &g, &b, NULL); rgbstr[0] = 0; name = strdup (keys[i].name); r_str_replace_char (name, '.', '_'); r_cons_printf (".%s { color:#%02x%02x%02x }\n", name, r, g, b); free (name); break; case '*': case 'r': case 1: r = g = b = 0; r_cons_rgb_parse (*color, &r, &g, &b, NULL); rgbstr[0] = 0; r_cons_rgb_str (rgbstr, r, g, b, 0); r_cons_printf ("ec %s rgb:%02x%02x%02x\n", keys[i].name, r, g, b); break; default: r_cons_printf (" %s##"Color_RESET" %s\n", *color, keys[i].name); } } if (rad == 'j') r_cons_print ("}\n"); }
R_API void r_cons_println(const char* str) { r_cons_print (str); r_cons_newline (); }
static void print_format_values(RCore *core, const char *fmt, bool onstack, ut64 src, bool color) { char opt; ut64 bval = src; int i; int endian = core->print->big_endian; int width = (core->anal->bits == 64)? 8: 4; int bsize = R_MIN (64, core->blocksize); ut8 *buf = malloc (bsize); if (!buf) { eprintf ("Cannot allocate %d byte(s)\n", bsize); free (buf); return; } if (fmt) { opt = *fmt; } else { opt = 'p'; // void *ptr } if (onstack || ((opt != 'd' && opt != 'x') && !onstack)) { if (color) { r_cons_printf (Color_BGREEN"0x%08"PFMT64x Color_RESET" --> ", bval); } else { r_cons_printf ("0x%08"PFMT64x" --> ", bval); } r_io_read_at (core->io, bval, buf, bsize); } if (onstack) { // Fetch value from stack bval = get_buf_val (buf, endian, width); if (opt != 'd' && opt != 'x') { r_io_read_at (core->io, bval, buf, bsize); // update buf with val from stack } } r_cons_print (color? Color_BGREEN: ""); switch (opt) { case 'z' : // Null terminated string r_cons_print (color ?Color_RESET Color_BWHITE:""); r_cons_print ("\""); for (i = 0; i < MAXSTRLEN; i++) { if (buf[i] == '\0') { break; } ut8 b = buf[i]; if (IS_PRINTABLE (b)) { r_cons_printf ("%c", b); } else { r_cons_printf ("\\x%02x", b); } if (i == MAXSTRLEN - 1) { r_cons_print ("..."); // To show string is truncated } } r_cons_print ("\""); r_cons_newline (); break; case 'd' : // integer case 'x' : r_cons_printf ("0x%08" PFMT64x, bval); r_cons_newline (); break; case 'c' : // char r_cons_print ("\'"); ut8 ch = buf[0]; if (IS_PRINTABLE (ch)) { r_cons_printf ("%c", ch); } else { r_cons_printf ("\\x%02x", ch); } r_cons_print ("\'"); r_cons_newline (); break; case 'p' : // pointer { // Try to deref the pointer once again r_cons_printf ("0x%08"PFMT64x, get_buf_val (buf, endian, width)); r_cons_newline (); break; } default: //TODO: support types like structs and unions r_cons_println ("unk_format"); } r_cons_print (Color_RESET); free (buf); }
R_API void r_cons_println(const char* str) { r_cons_print (str); r_cons_print ("\n"); }
static int cmd_type(void *data, const char *input) { RCore *core = (RCore *)data; char *res; const char *help_message[] = { "USAGE tu[...]", "", "", "tu", "", "List all loaded unions", "tu?", "", "show this help", NULL }; switch (input[0]) { case 'n': // "tn" cmd_type_noreturn (core, input + 1); break; // t [typename] - show given type in C syntax case 'u': // "tu" switch (input[1]) { case '?': r_core_cmd_help (core, help_message); break; case 0: sdb_foreach (core->anal->sdb_types, stdprintifunion, core); break; } break; case 'k': // "tk" res = (input[1] == ' ') ? sdb_querys (core->anal->sdb_types, NULL, -1, input + 2) : sdb_querys (core->anal->sdb_types, NULL, -1, "*"); if (res) { r_cons_print (res); } break; case 's': // "ts" switch (input[1]) { case '?': { const char *help_message[] = { "USAGE ts[...]", "", "", "ts", "", "List all loaded structs", "ts?", "", "show this help", NULL }; r_core_cmd_help (core, help_message); } break; case 0: sdb_foreach (core->anal->sdb_types, stdprintifstruct, core); break; } break; case 'b': { char *p, *s = (strlen (input) > 1)? strdup (input + 2): NULL; const char *isenum; p = s? strchr (s, ' '): NULL; if (p) { *p++ = 0; // dupp in core.c (see getbitfield()) isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strcmp (isenum, "enum")) { *--p = '.'; const char *res = sdb_const_get (core->anal->sdb_types, s, 0); if (res) r_cons_println (res); else eprintf ("Invalid enum member\n"); } else { eprintf ("This is not an enum\n"); } } else { eprintf ("Missing value\n"); } free (s); } break; case 'e': { if (!input[1]) { char *name = NULL; SdbKv *kv; SdbListIter *iter; SdbList *l = sdb_foreach_list (core->anal->sdb_types); ls_foreach (l, iter, kv) { if (!strcmp (kv->value, "enum")) { if (!name || strcmp (kv->value, name)) { free (name); name = strdup (kv->key); r_cons_println (name); } } } free (name); ls_free (l); break; } if (input[1] == '?') { const char *help_message[] = { "USAGE te[...]", "", "", "te", "", "List all loaded enums", "te", " <enum> <value>", "Show name for given enum number", "te?", "", "show this help", NULL }; r_core_cmd_help (core, help_message); break; } char *p, *s = strdup (input + 2); const char *isenum; p = strchr (s, ' '); if (p) { *p++ = 0; isenum = sdb_const_get (core->anal->sdb_types, s, 0); if (isenum && !strncmp (isenum, "enum", 4)) { const char *q = sdb_fmt (0, "%s.0x%x", s, (ut32)r_num_math (core->num, p)); const char *res = sdb_const_get (core->anal->sdb_types, q, 0); if (res) r_cons_println (res); } else { eprintf ("This is not an enum\n"); } } else { //eprintf ("Missing value\n"); r_core_cmdf (core, "t~&%s,=0x", s); } free (s); } break; case ' ': { const char *isenum = sdb_const_get (core->anal->sdb_types, input + 1, 0); if (isenum && !strcmp (isenum, "enum")) { eprintf ("IS ENUM! \n"); } else { char *fmt = r_anal_type_format (core->anal, input + 1); if (fmt) { r_str_chop (fmt); r_cons_printf ("pf %s\n", fmt); free (fmt); } else eprintf ("Cannot find '%s' type\n", input + 1); } } break; // t* - list all types in 'pf' syntax case '*': sdb_foreach (core->anal->sdb_types, typelist, core); break; case 0: sdb_foreach (core->anal->sdb_types, sdbforcb, core); break; case 'o': if (!r_sandbox_enable (0)) { if (input[1] == ' ') { const char *filename = input + 2; char *homefile = NULL; if (*filename == '~') { if (filename[1] && filename[2]) { homefile = r_str_home (filename + 2); filename = homefile; } } if (!strcmp (filename, "-")) { char *out, *tmp; tmp = r_core_editor (core, NULL, ""); if (tmp) { out = r_parse_c_string (tmp); if (out) { // r_cons_strcat (out); save_parsed_type (core, out); free (out); } free (tmp); } } else { char *out = r_parse_c_file (filename); if (out) { //r_cons_strcat (out); save_parsed_type (core, out); free (out); } //r_anal_type_loadfile (core->anal, filename); } free (homefile); } else if (input[1] == 's') { const char *dbpath = input + 3; if (r_file_exists (dbpath)) { Sdb *db_tmp = sdb_new (0, dbpath, 0); sdb_merge (core->anal->sdb_types, db_tmp); sdb_close (db_tmp); sdb_free (db_tmp); } } } else { eprintf ("Sandbox: system call disabled\n"); } break; // td - parse string with cparse engine and load types from it case 'd': if (input[1] == '?') { const char *help_message[] = { "Usage:", "\"td [...]\"", "", "td", "[string]", "Load types from string", NULL }; r_core_cmd_help (core, help_message); r_cons_printf ("Note: The td command should be put between double quotes\n" "Example: \" td struct foo {int bar;int cow};\"" "\nt"); } else if (input[1] == ' ') { char tmp[8192]; snprintf (tmp, sizeof (tmp) - 1, "%s;", input + 2); //const char *string = input + 2; //r_anal_str_to_type (core->anal, string); char *out = r_parse_c_string (tmp); if (out) { //r_cons_strcat (out); save_parsed_type (core, out); free (out); } } else { eprintf ("Invalid use of td. See td? for help\n"); } break; // tl - link a type to an address case 'l': switch (input[1]) { case '?': { const char *help_message[] = { "Usage:", "", "", "tl", "", "list all links in readable format", "tl", "[typename]", "link a type to current adress.", "tl", "[typename] = [address]", "link type to given address.", "tls", "[address]", "show link at given address", "tl-*", "", "delete all links.", "tl-", "[address]", "delete link at given address.", "tl*", "", "list all links in radare2 command format", "tl?", "", "print this help.", NULL }; r_core_cmd_help (core, help_message); } break; case ' ': { char *type = strdup (input + 2); char *ptr = strchr (type, '='); ut64 addr; if (ptr) { *ptr++ = 0; r_str_chop (ptr); if (ptr && *ptr) { addr = r_num_math (core->num, ptr); } else { eprintf ("address is unvalid\n"); free (type); break; } } else { addr = core->offset; } r_str_chop (type); char *tmp = sdb_get (core->anal->sdb_types, type, 0); if (tmp && *tmp) { r_anal_type_link (core->anal, type, addr); free (tmp); } else { eprintf ("unknown type %s\n", type); } free (type); } break; case 's': { int ptr; char *addr = strdup (input + 2); SdbKv *kv; SdbListIter *sdb_iter; SdbList *sdb_list = sdb_foreach_list (core->anal->sdb_types); r_str_chop (addr); ptr = r_num_math (NULL, addr); //r_core_cmdf (core, "tl~0x%08"PFMT64x" = ", addr); ls_foreach (sdb_list, sdb_iter, kv) { char *linkptr; if (strncmp (kv->key, "link.", strlen ("link."))) { continue; } linkptr = sdb_fmt (-1,"0x%s", kv->key + strlen ("link.")); if (ptr == r_num_math (NULL, linkptr)) { linklist_readable (core, kv->key, kv->value); } } free (addr); ls_free (sdb_list); } break; case '-': switch (input[2]) { case '*': sdb_foreach (core->anal->sdb_types, sdbdeletelink, core); break; case ' ': { const char *ptr = input + 3; ut64 addr = r_num_math (core->num, ptr); r_anal_type_unlink (core->anal, addr); } break; } break; case '*': sdb_foreach (core->anal->sdb_types, linklist, core); break; case '\0': sdb_foreach (core->anal->sdb_types, linklist_readable, core); break; }
// Display a list of entries in the hud, filtered and emphasized based // on the user input. R_API char *r_cons_hud(RList *list, const char *prompt) { const int buf_size = 128; int ch, nch, first_line, current_entry_n, j, i = 0; char *p, *x, user_input[buf_size], mask[buf_size]; int last_color_change, top_entry_n = 0; char *selected_entry = NULL; char tmp, last_mask = 0; void *current_entry; RListIter *iter; user_input[0] = 0; r_cons_clear (); // Repeat until the user exits the hud for (;;) { first_line = 1; r_cons_gotoxy (0, 0); current_entry_n = 0; if (top_entry_n < 0) { top_entry_n = 0; } selected_entry = NULL; if (prompt && *prompt) { r_cons_print (">> "); r_cons_println (prompt); } r_cons_printf ("%d> %s|\n", top_entry_n, user_input); int counter = 0; int rows; (void)r_cons_get_size (&rows); // Iterate over each entry in the list r_list_foreach (list, iter, current_entry) { memset (mask, 0, buf_size); if (!user_input[0] || strmatch (current_entry, user_input, mask, buf_size)) { counter++; if (counter == rows + top_entry_n) { break; } // if the user scrolled down the list, do not print the first entries if (!top_entry_n || current_entry_n >= top_entry_n) { // remove everything after a tab (in ??, it contains the commands) x = strchr (current_entry, '\t'); if (x) { *x = 0; } p = strdup (current_entry); // if the filter is empty, print the entry and move on if (!user_input[0]) { r_cons_printf (" %c %s\n", first_line? '-': ' ', current_entry); } else { // otherwise we need to emphasize the matching part if (I(use_color)) { last_color_change = 0; last_mask = 0; r_cons_printf (" %c ", first_line? '-': ' '); // Instead of printing one char at the time // (which would be slow), we group substrings of the same color for (j = 0; p[j] && j < buf_size; j++) { if (mask[j] != last_mask) { tmp = p[j]; p[j] = 0; if (mask[j]) { r_cons_printf (Color_RESET"%s", p + last_color_change); } else { r_cons_printf (Color_GREEN"%s", p + last_color_change); } p[j] = tmp; last_color_change = j; last_mask = mask[j]; } } if (last_mask) { r_cons_printf (Color_GREEN"%s\n"Color_RESET, p + last_color_change); } else { r_cons_printf (Color_RESET"%s\n", p + last_color_change); } } else { // Otherwise we print the matching characters uppercase for (j = 0; p[j]; j++) { if (mask[j]) p[j] = toupper ((unsigned char)p[j]); } r_cons_printf (" %c %s\n", first_line? '-': ' ', p); } } // Clean up and restore the tab character (if any) free (p); if (x) { *x = '\t'; } if (first_line) { selected_entry = current_entry; } first_line = 0; } current_entry_n++; } } r_cons_visual_flush (); ch = r_cons_readchar (); nch = r_cons_arrow_to_hjkl (ch); (void)r_cons_get_size (&rows); if (nch == 'J' && ch != 'J') { top_entry_n += (rows - 1); if (top_entry_n + 1 >= current_entry_n) { top_entry_n = current_entry_n; } } else if (nch == 'K' && ch != 'K') { top_entry_n -= (rows - 1); if (top_entry_n < 0) { top_entry_n = 0; } } else if (nch == 'j' && ch != 'j') { if (top_entry_n + 1 < current_entry_n) { top_entry_n++; } } else if (nch == 'k' && ch != 'k') { if (top_entry_n >= 0) { top_entry_n--; } } else { switch (ch) { case 9: // \t if (top_entry_n + 1 < current_entry_n) { top_entry_n++; } else { top_entry_n = 0; } break; case 10: // \n case 13: // \r top_entry_n = 0; // if (!*buf) // return NULL; if (current_entry_n >= 1) { //eprintf ("%s\n", buf); //i = buf[0] = 0; return strdup (selected_entry); } // no match! break; case 23: // ^w top_entry_n = 0; i = user_input[0] = 0; break; case 0x1b: // ESC return NULL; case 8: // bs case 127: // bs top_entry_n = 0; if (i < 1) return NULL; user_input[--i] = 0; break; default: if (IS_PRINTABLE (ch)) { if (i >= buf_size) { break; } top_entry_n = 0; if (i + 1 >= buf_size) { // too many break; } user_input[i++] = ch; user_input[i] = 0; } break; } } }