R_API int r_core_project_save(RCore *core, const char *file) { int fd, tmp, ret = R_TRUE; char *prj; if (file == NULL || *file == '\0') return R_FALSE; prj = r_core_project_file (file); r_core_project_init (); fd = r_sandbox_open (prj, O_BINARY|O_RDWR|O_CREAT, 0644); if (fd != -1) { int fdold = r_cons_singleton ()->fdout; r_cons_singleton ()->fdout = fd; r_cons_singleton ()->is_interactive = R_FALSE; r_str_write (fd, "# r2 rdb project file\n"); //-- r_str_write (fd, "# flags\n"); tmp = core->flags->space_idx; core->flags->space_idx = -1; r_flag_list (core->flags, R_TRUE); core->flags->space_idx = tmp; r_cons_flush (); //-- r_str_write (fd, "# eval\n"); // TODO: r_str_writef (fd, "e asm.arch=%s", r_config_get ("asm.arch")); r_config_list (core->config, NULL, R_TRUE); r_cons_flush (); r_str_write (fd, "# sections\n"); r_io_section_list (core->io, core->offset, 1); r_cons_flush (); r_str_write (fd, "# meta\n"); r_meta_list (core->anal->meta, R_META_TYPE_ANY, 1); r_cons_flush (); r_core_cmd (core, "ar*", 0); r_cons_flush (); r_core_cmd (core, "af*", 0); r_cons_flush (); r_core_cmd (core, "ah*", 0); r_cons_flush (); r_str_write (fd, "# seek\n"); r_str_writef (fd, "s 0x%08"PFMT64x, core->offset); r_cons_flush (); close (fd); r_cons_singleton ()->fdout = fdold; r_cons_singleton ()->is_interactive = R_TRUE; } else { eprintf ("Cannot open '%s' for writing\n", prj); ret = R_FALSE; } free (prj); return ret; }
R_API char *r_cons_rgb_str (char *outstr, ut8 r, ut8 g, ut8 b, int is_bg) { int k, fgbg = is_bg? 48: 38; k = (r == g && g == b)? gs (r): rgb (r, g, b); //k = rgb (r, g, b); if (!outstr) outstr = malloc (32); switch (r_cons_singleton()->truecolor) { case 1: // 256 color palette sprintf (outstr, "\x1b[%d;5;%dm", fgbg, k); break; case 2: // 16M - xterm only sprintf (outstr, "\x1b[%d;2;%d;%d;%dm", fgbg, r&0xff, g&0xff, b&0xff); break; case 0: // ansi 16 colors default: { int k = (r+g+b)/3; r = (r>k)?1:0; g = (g>k)?1:0; b = (b>k)?1:0; k = (r?1:0) + (g? (b?6:2): (b?4:0)); sprintf (outstr, "\x1b[%dm", 30+k); } break; } return outstr; }
R_API void r_cons_pal_init(const char *foo) { RCons *cons = r_cons_singleton (); memset (&cons->pal, 0, sizeof (cons->pal)); cons->pal.prompt = Color_YELLOW; cons->pal.offset = Color_GREEN; cons->pal.input = Color_WHITE; cons->pal.comment = Color_CYAN; cons->pal.fname = Color_CYAN; cons->pal.fline = Color_CYAN; cons->pal.flag = Color_CYAN; cons->pal.label = Color_CYAN; cons->pal.flow = Color_CYAN; cons->pal.b0x00 = Color_GREEN; cons->pal.b0x7f = Color_CYAN; cons->pal.b0xff = Color_RED; cons->pal.other = Color_YELLOW; cons->pal.btext = Color_YELLOW; cons->pal.push = Color_MAGENTA; cons->pal.pop = Color_BMAGENTA; cons->pal.nop = Color_BLUE; cons->pal.jmp = Color_GREEN; cons->pal.cjmp = Color_GREEN; cons->pal.call = Color_BGREEN; cons->pal.cmp = Color_CYAN; cons->pal.swi = Color_MAGENTA; cons->pal.trap = Color_BRED; cons->pal.ret = Color_RED; cons->pal.num = Color_YELLOW; cons->pal.reg = Color_CYAN; cons->pal.reset = "\x1b[0m"; }
R_API void r_cons_pal_random () { RCons *cons = r_cons_singleton (); ut8 r, g, b; char val[32]; const char *k; int i; for (i = 0; ; i++) { k = r_cons_pal_get_i (i); if (!k) break; if (cons->truecolor > 0) { r = r_num_rand (0xff); g = r_num_rand (0xff); b = r_num_rand (0xff); sprintf (val, "rgb:%02x%02x%02x", r, g, b); r_cons_pal_set (k, val); } else { char *s = r_cons_color_random_string (0); if (s) { r_cons_pal_set (k, s); free (s); } else { r_cons_pal_set (k, "red"); } } } for (i = 0; i < R_CONS_PALETTE_LIST_SIZE; i++) { if (cons->pal.list[i]) R_FREE (cons->pal.list[i]); cons->pal.list[i] = r_cons_color_random (0); } }
R_API int r_core_dump(RCore *core, const char *file, ut64 addr, ut64 size) { ut64 i; ut8 *buf; int bs = core->blocksize; FILE *fd; r_sys_truncate (file, 0); fd = r_sandbox_fopen (file, "wb"); if (!fd) { eprintf ("Cannot open '%s' for writing\n", file); return R_FALSE; } buf = malloc (bs); r_cons_break (NULL, NULL); for (i=0; i<size; i+=bs) { if (r_cons_singleton ()->breaked) break; if ((i+bs)>size) bs = size-i; r_io_read_at (core->io, addr+i, buf, bs); if (fwrite (buf, bs, 1, fd) <1) { eprintf ("write error\n"); break; } } eprintf ("dumped 0x%"PFMT64x" bytes\n", i); r_cons_break_end (); fclose (fd); free (buf); return R_TRUE; }
R_API void r_cons_pal_free () { int i; RCons *cons = r_cons_singleton (); for (i = 0; i < R_CONS_PALETTE_LIST_SIZE; i++) { if (cons->pal.list[i]) R_FREE (cons->pal.list[i]); } }
static void apply_line_style(RConsCanvas *c, int x, int y, int x2, int y2, int style){ RCons *cons = r_cons_singleton (); switch (style) { case 0: // Unconditional jump //c->attr=Color_BLUE; c->attr = cons->pal.graph_trufae; //Color_GREEN; if (G (x, y)) W ("v"); if (G (x2, y2)) W ("V"); break; case 1: // Conditional jump, True branch c->attr = cons->pal.graph_true; //Color_GREEN; if (G (x, y)) W ("t"); //\\"); if (G (x2, y2)) W ("\\"); break; case 2: // Conditional jump, False branch c->attr = cons->pal.graph_false; //Color_RED; if (G (x, y)) W ("f"); if (G (x2, y2)) W ("/"); break; default: c->attr = cons->pal.graph_trufae; //Color_BLUE; break; } }
R_API void r_cons_pal_init(const char *foo) { RCons *cons = r_cons_singleton (); memset (&cons->pal, 0, sizeof (cons->pal)); cons->pal.b0x00 = Color_GREEN; cons->pal.b0x7f = Color_CYAN; cons->pal.b0xff = Color_RED; cons->pal.args = Color_YELLOW; cons->pal.bin = Color_YELLOW; cons->pal.btext = Color_WHITE; cons->pal.call = Color_BGREEN; cons->pal.cjmp = Color_GREEN; cons->pal.cmp = Color_CYAN; cons->pal.comment = Color_CYAN; // blue cons->pal.creg = Color_CYAN; cons->pal.flag = Color_CYAN; cons->pal.fline = Color_CYAN; cons->pal.floc = Color_CYAN; cons->pal.flow = Color_CYAN; cons->pal.fname = Color_RED; cons->pal.help = Color_GREEN; cons->pal.input = Color_WHITE; cons->pal.invalid = Color_BRED; cons->pal.jmp = Color_GREEN; cons->pal.label = Color_CYAN; cons->pal.math = Color_YELLOW; cons->pal.mov = Color_WHITE; cons->pal.nop = Color_BLUE; cons->pal.num = Color_YELLOW; cons->pal.offset = Color_GREEN; cons->pal.other = Color_WHITE; cons->pal.pop = Color_BMAGENTA; cons->pal.prompt = Color_YELLOW; cons->pal.push = Color_MAGENTA; cons->pal.reg = Color_CYAN; cons->pal.reset = Color_RESET; cons->pal.ret = Color_RED; cons->pal.swi = Color_MAGENTA; cons->pal.trap = Color_BRED; cons->pal.ai_read = Color_GREEN; cons->pal.ai_write = Color_BLUE; cons->pal.ai_exec = Color_RED; cons->pal.ai_seq = Color_MAGENTA; cons->pal.ai_ascii = Color_YELLOW; cons->pal.gui_cflow = Color_YELLOW; cons->pal.gui_dataoffset = Color_YELLOW; cons->pal.gui_background = Color_BLACK; cons->pal.gui_alt_background = Color_GRAY; cons->pal.gui_border = Color_BGGRAY; cons->pal.list[0] = strdup (Color_RED); cons->pal.list[1] = strdup (Color_YELLOW); cons->pal.list[2] = strdup (Color_BGREEN); cons->pal.list[3] = strdup (Color_CYAN); cons->pal.list[4] = strdup (Color_MAGENTA); cons->pal.list[5] = strdup (Color_GRAY); cons->pal.list[6] = strdup (Color_BLUE); cons->pal.list[7] = strdup (Color_GREEN); }
static void r_cons_pal_null (){ int i; RCons *cons = r_cons_singleton (); for (i = 0; i< R_CONS_PALETTE_LIST_SIZE; i++){ cons->pal.list[i] = NULL; } }
R_API RList *r_core_asm_bwdisassemble (RCore *core, ut64 addr, int n, int len) { RList *hits = r_core_asm_hit_list_new(); RAsmOp op; // len = n * 32; // if (n > core->blocksize) n = core->blocksize; ut8 *buf; ut64 instrlen = 0, at = 0; ut32 idx = 0, hit_count = 0; int numinstr, asmlen, ii; RAsmCode *c; if (len<1) return NULL; buf = (ut8 *)malloc (len); if (hits == NULL || buf == NULL ){ if (hits) { r_list_free (hits); } free (buf); return NULL; } if (r_io_read_at (core->io, addr-len, buf, len) != len) { if (hits) { r_list_free (hits); } free (buf); return NULL; } for (idx = 1; idx < len; ++idx) { if (r_cons_singleton ()->breaked) break; at = addr - idx; hit_count = 0; c = r_asm_mdisassemble (core->assembler, buf+(len-idx), idx); if (strstr(c->buf_asm, "invalid") || strstr(c->buf_asm, ".byte")) { r_asm_code_free(c); continue; } numinstr = 0; asmlen = strlen(c->buf_asm); for(ii = 0; ii < asmlen; ++ii) { if (c->buf_asm[ii] == '\n') ++numinstr; } r_asm_code_free(c); if (numinstr >= n || idx > 32 * n) { break; } } at = addr - idx; hit_count = 0; r_asm_set_pc (core->assembler, at); at = addr-idx; for ( hit_count = 0; hit_count < n; hit_count++) { instrlen = r_asm_disassemble (core->assembler, &op, buf+(len-(addr-at)), addr-at); add_hit_to_hits(hits, at, instrlen, true); at += instrlen; } free (buf); return hits; }
R_API RList *r_core_asm_bwdisassemble (RCore *core, ut64 addr, int n, int len) { RList *hits = r_core_asm_hit_list_new(); RCoreAsmHit dummy_value; RAsmOp op; ut8 *buf = (ut8 *)malloc (len); ut64 instrlen = 0, at = 0; ut32 idx = 0, hit_count = 0; memset (&dummy_value, 0, sizeof (RCoreAsmHit)); if (hits == NULL || buf == NULL ){ if (hits) r_list_destroy (hits); if (buf) free (buf); return NULL; } if (r_io_read_at (core->io, addr-len, buf, len) != len) { if (hits) r_list_destroy (hits); if (buf) free (buf); return NULL; } for (idx = 1; idx < len; idx++) { ut32 current_buf_pos; if (r_cons_singleton ()->breaked) break; at = addr - idx; hit_count = 0; // XXX - buf here. at may be greater than addr if near boundary. for (current_buf_pos = len - idx, hit_count = 0; current_buf_pos < len && hit_count <= n; current_buf_pos += instrlen, at += instrlen, hit_count++) { r_asm_set_pc (core->assembler, at); //XXX HACK We need another way to detect invalid disasm!! if (!(instrlen = r_asm_disassemble (core->assembler, &op, buf+(len-(addr-at)), addr-at)) || strstr (op.buf_asm, "invalid")) { break; } } if (hit_count >= n) break; } if (hit_count == n) { at = addr - idx; hit_count = 0; r_asm_set_pc (core->assembler, at); for ( hit_count = 0; hit_count < n; hit_count++) { instrlen = r_asm_disassemble (core->assembler, &op, buf+(len-(addr-at)), addr-at); add_hit_to_hits(hits, at, instrlen, R_TRUE); at += instrlen; } } r_asm_set_pc (core->assembler, addr); free (buf); return hits; }
DWORD WINAPI ThreadFunction(LPVOID lpParam) { RLang * lang = lpParam; CHAR buf[PIPE_BUF_SIZE]; BOOL bSuccess = FALSE; int i, res = 0; DWORD dwRead, dwWritten; r_cons_break (NULL, NULL); res = ConnectNamedPipe (hPipeInOut, NULL); if (!res) { eprintf ("ConnectNamedPipe failed\n"); return FALSE; } do { if (r_cons_singleton ()->breaked) { TerminateProcess(hproc,0); break; } memset (buf, 0, PIPE_BUF_SIZE); bSuccess = ReadFile (hPipeInOut, buf, PIPE_BUF_SIZE, &dwRead, NULL); if (bStopThread) break; if (bSuccess && dwRead>0) { buf[sizeof (buf)-1] = 0; char *res = lang->cmd_str ((RCore*)lang->user, buf); if (res) { int res_len = strlen (res) + 1; for (i = 0; i < res_len; i++) { memset (buf, 0, PIPE_BUF_SIZE); dwWritten = 0; int writelen=res_len - i; int rc = WriteFile (hPipeInOut, res + i, writelen>PIPE_BUF_SIZE?PIPE_BUF_SIZE:writelen, &dwWritten, 0); if (bStopThread) { free (res); break; } if (!rc) { eprintf ("WriteFile: failed 0x%x\n", (int)GetLastError()); } if (dwWritten > 0) { i += dwWritten - 1; } else { /* send null termination // chop */ eprintf ("w32-lang-pipe: 0x%x\n", (ut32)GetLastError ()); //WriteFile (hPipeInOut, "", 1, &dwWritten, NULL); //break; } } free (res); } else { WriteFile (hPipeInOut, "", 1, &dwWritten, NULL); } } } while(!bStopThread); r_cons_break_end (); return TRUE; }
static void apply_line_style(RConsCanvas *c, int x, int y, int x2, int y2, RCanvasLineStyle *style, int isvert) { RCons *cons = r_cons_singleton (); switch (style->color) { case LINE_UNCJMP: c->attr = cons->pal.graph_trufae; break; case LINE_TRUE: c->attr = cons->pal.graph_true; break; case LINE_FALSE: c->attr = cons->pal.graph_false; break; case LINE_NONE: default: c->attr = cons->pal.graph_trufae; break; } if (!c->color) { c->attr = Color_RESET; } switch (style->symbol) { case LINE_UNCJMP: if (G (x, y)) { if (isvert) { W ("v"); } else { W (">"); } } break; case LINE_TRUE: if (G (x, y)) { W ("t"); //\\"); } break; case LINE_FALSE: if (G (x, y)) { W ("f"); } break; case LINE_NOSYM_VERT: if (G (x, y)) { W (useUtf8 ? RUNECODESTR_LINE_VERT : "|"); } break; case LINE_NOSYM_HORIZ: if (G (x, y)) { W (useUtf8 ? RUNECODESTR_LINE_HORIZ : "-"); } break; case LINE_NONE: default: break; } }
static RList * r_core_asm_back_disassemble_all(RCore *core, ut64 addr, ut64 len, ut64 max_hit_count, ut32 extra_padding){ RList *hits = r_core_asm_hit_list_new (); RCoreAsmHit dummy_value; RCoreAsmHit *hit = NULL; RAsmOp op; ut8 *buf = (ut8 *)malloc (len + extra_padding); int current_instr_len = 0; ut64 current_instr_addr = addr, current_buf_pos = len - 1, hit_count = 0; memset (&dummy_value, 0, sizeof (RCoreAsmHit)); if (hits == NULL || buf == NULL ){ if (hits) { r_list_purge (hits); free (hits); } free (buf); return NULL; } if (r_io_read_at (core->io, addr-(len+extra_padding), buf, len+extra_padding) != len+extra_padding) { r_list_purge (hits); free (hits); free (buf); return NULL; } if (len == 0){ return hits; } current_buf_pos = len - 1; do { if (r_cons_singleton ()->breaked) break; // reset assembler r_asm_set_pc (core->assembler, current_instr_addr); current_instr_len = len - current_buf_pos + extra_padding; IFDBG eprintf("current_buf_pos: 0x%"PFMT64x", current_instr_len: %d\n", current_buf_pos, current_instr_len); current_instr_len = r_asm_disassemble (core->assembler, &op, buf+current_buf_pos, current_instr_len); hit = r_core_asm_hit_new (); hit->addr = current_instr_addr; hit->len = current_instr_len; hit->code = NULL; r_list_add_sorted (hits, hit, ((RListComparator)rcoreasm_address_comparator)); current_buf_pos--; current_instr_addr--; hit_count++; } while ( ((int) current_buf_pos >= 0) && (int)(len - current_buf_pos) >= 0 && hit_count <= max_hit_count); free(buf); return hits; }
R_API const char *r_cons_pal_get (const char *key) { int i; for (i = 0; keys[i].name; i++) { if (!strcmp (key, keys[i].name)) { char **p = (char **) ((char *)& (r_cons_singleton ()->pal) + keys[i].off); return p? *p: ""; } } return ""; }
R_API void r_cons_pal_list (int rad) { RConsPalette *pal = &(r_cons_singleton ()->pal); ut8 *p = (ut8*)pal; ut8 r, g, b; char **color, rgbstr[32]; const char *hasnext; int i; if (rad=='j') r_cons_printf ("{"); 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': { 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 { color: rgb(%d, %d, %d); }%s", name, r, g, b, hasnext); 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 >>= 4; g >>= 4; b >>= 4; r_cons_printf ("ec %s rgb:%x%x%x\n", keys[i].name, r&0xf, g&0xf, b&0xf); break; default: r_cons_printf (" %s##"Color_RESET" %s\n", *color, keys[i].name); } } if (rad=='j') r_cons_printf ("}\n"); }
R_API int r_cons_grepbuf(char *buf, int len) { RCons *cons = r_cons_singleton (); char *tline, *tbuf, *p, *out, *in = buf; int ret, buffer_len = 0, l = 0, tl = 0; if (!cons->buffer) { cons->buffer_len = len+20; cons->buffer = malloc (cons->buffer_len); cons->buffer[0] = 0; } out = tbuf = calloc (1, len); tline = malloc (len); cons->lines = 0; while (in-buf<len) { p = strchr (in, '\n'); if (!p) { free (tbuf); free (tline); return 0; } l = p-in; if (l > 0) { memcpy (tline, in, l); tl = r_str_ansi_filter (tline, l); if (tl < 0) ret = -1; else ret = r_cons_grep_line (tline, tl); if (ret > 0) { if (cons->grep.line == -1 || (cons->grep.line != -1 && cons->grep.line == cons->lines)) { memcpy (out, tline, ret); memcpy (out+ret, "\n", 1); out += ret+1; buffer_len += ret+1; } cons->lines++; } else if (ret < 0) { free (tbuf); free (tline); return 0; } in += l+1; } else in++; } memcpy (buf, tbuf, len); cons->buffer_len = buffer_len; free (tbuf); free (tline); if (cons->grep.counter) { if (cons->buffer_len<10) cons->buffer_len = 10; // HACK snprintf (cons->buffer, cons->buffer_len, "%d\n", cons->lines); cons->buffer_len = strlen (cons->buffer); } return cons->lines; }
static int bin_dwarf(RCore *core, int mode) { RBinDwarfRow *row; RListIter *iter; RList *list = NULL; RBinFile *binfile = r_core_bin_cur (core); RBinPlugin * plugin = r_bin_file_cur_plugin (binfile); if (!binfile) return false; if (plugin && plugin->lines) { list = plugin->lines (binfile); } else if (core->bin) { // TODO: complete and speed-up support for dwarf if (r_config_get_i (core->config, "bin.dwarf")) { RBinDwarfDebugAbbrev *da = NULL; da = r_bin_dwarf_parse_abbrev (core->bin, mode); r_bin_dwarf_parse_info (da, core->bin, mode); r_bin_dwarf_parse_aranges (core->bin, mode); list = r_bin_dwarf_parse_line (core->bin, mode); r_bin_dwarf_free_debug_abbrev (da); free (da); } } if (!list) return false; r_cons_break (NULL, NULL); r_list_foreach (list, iter, row) { if (r_cons_singleton()->breaked) break; if (mode) { // TODO: use 'Cl' instead of CC const char *path = row->file; char *line = r_file_slurp_line (path, row->line-1, 0); if (line) { r_str_filter (line, strlen (line)); line = r_str_replace (line, "\"", "\\\"", 1); line = r_str_replace (line, "\\\\", "\\", 1); } // TODO: implement internal : if ((mode & R_CORE_BIN_SET)) if ((mode & R_CORE_BIN_SET)) { char *cmt = r_str_newf ("%s:%d %s", row->file, row->line, line?line:""); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, row->address, cmt); free (cmt); } else { r_cons_printf ("\"CC %s:%d %s\"@0x%"PFMT64x"\n", row->file, row->line, line?line:"", row->address); } free (line); } else { r_cons_printf ("0x%08"PFMT64x"\t%s\t%d\n", row->address, row->file, row->line); } } r_cons_break_end (); r_list_free (list); return true; }
R_API void r_print_addr(RPrint *p, ut64 addr) { int mod = p->flags & R_PRINT_FLAGS_ADDRMOD; char ch = (p->addrmod&&mod)?((addr%p->addrmod)?' ':','):' '; if (p->flags & R_PRINT_FLAGS_COLOR) { #if 0 p->printf("%s0x%08"PFMT64x""Color_RESET"%c ", r_cons_singleton ()->palette[PAL_ADDRESS], addr, ch); #endif p->printf ("0x%08"PFMT64x"%c", addr, ch); } else r_cons_printf ("0x%08"PFMT64x"%c", addr, ch); }
R_API int r_cons_pal_set(const char *key, const char *val) { int i; char **p; for (i = 0; keys[i].name; i++) { if (!strcmp (key, keys[i].name)) { p = (char **) ((char *)& (r_cons_singleton ()->pal) + keys[i].off); *p = r_cons_pal_parse (val); return true; } } return false; }
R_API void r_cons_pal_list () { RConsPalette *pal = &(r_cons_singleton ()->pal); ut8 *p = (ut8*)pal; char **color; int i; for (i=0; keys[i].name; i++) { color = (char**)(p + keys[i].off); color = (char**)*color; r_cons_printf (" %s##"Color_RESET" %s\n", (color)? (char*)color: "", keys[i].name); } }
// XXX no control for max length here?!?! R_API int r_cons_fgets(char *buf, int len, int argc, const char **argv) { #define RETURN(x) { ret=x; goto beach; } RCons *cons = r_cons_singleton (); int ret = 0, color = cons->pal.input && *cons->pal.input; if (cons->echo) { r_cons_set_raw (0); r_cons_show_cursor (1); } #if 0 int mouse = r_cons_enable_mouse (false); r_cons_enable_mouse (false); r_cons_flush (); #endif if (cons->user_fgets) { RETURN (cons->user_fgets (buf, len)); } printf ("%s", cons->line->prompt); fflush (stdout); *buf = '\0'; fflush (cons->fdin); if (color) { const char *p = cons->pal.input; int len = p? strlen (p): 0; if (len>0) fwrite (p, len, 1, stdout); fflush (stdout); } if (!fgets (buf, len, cons->fdin)) { if (color) { printf (Color_RESET); fflush (stdout); } RETURN (-1); } if (feof (cons->fdin)) { if (color) { printf (Color_RESET); } RETURN (-2); } buf[strlen (buf)-1] = '\0'; if (color) printf (Color_RESET); ret = strlen (buf); beach: #if __UNIX__ if (errno == EINTR) { ret = 0; } #endif //r_cons_enable_mouse (mouse); return ret; }
// XXX no control for max length here?!?! R_API int r_cons_fgets(char *buf, int len, int argc, const char **argv) { RCons *cons = r_cons_singleton (); if (cons->user_fgets) return cons->user_fgets (buf, len); *buf = '\0'; fflush (cons->fdin); if (fgets (buf, len, cons->fdin) == NULL) return -1; if (feof (cons->fdin)) return -2; buf[strlen (buf)-1] = '\0'; return strlen (buf); }
R_API const char *r_cons_pal_get_color (int n) { RConsPalette *pal = & (r_cons_singleton ()->pal); ut8 *p = (ut8*)pal; int i; for (i = 0; keys[i].name; i++) { if (i >= n) { const char **color = (const char**) (p + keys[i].off); color = (const char**)*color; return (const char *)color; } } return NULL; }
R_API RList *r_core_asm_bwdisassemble (RCore *core, ut64 addr, int n, int len) { RCoreAsmHit *hit; RAsmOp op; RList *hits = NULL; ut8 *buf; ut64 at; int instrlen, ni, idx; if (!(hits = r_core_asm_hit_list_new ())) return NULL; buf = (ut8 *)malloc (len); if (!buf) { r_list_destroy (hits); return NULL; } if (r_io_read_at (core->io, addr-len, buf, len) != len) { r_list_destroy (hits); free (buf); return NULL; } for (idx = 1; idx < len; idx++) { if (r_cons_singleton ()->breaked) break; at = addr - idx; ni = 1; while (at < addr) { r_asm_set_pc (core->assembler, at); //XXX HACK We need another way to detect invalid disasm!! if (!(instrlen = r_asm_disassemble (core->assembler, &op, buf+(len-(addr-at)), addr-at)) || strstr (op.buf_asm, "invalid")) { break; } else { at += instrlen; if (at == addr) { if (ni == n) { if (!(hit = r_core_asm_hit_new ())) { r_list_destroy (hits); free (buf); return NULL; } hit->addr = addr-idx; hit->len = idx; hit->code = NULL; r_list_append (hits, hit); } } else ni++; } } } r_asm_set_pc (core->assembler, addr); free (buf); return hits; }
R_API int r_debug_continue_syscalls(RDebug *dbg, int *sc, int n_sc) { int i, reg, ret = R_FALSE; if (!dbg || !dbg->h || r_debug_is_dead (dbg)) return R_FALSE; if (!dbg->h->contsc) { /* user-level syscall tracing */ r_debug_continue_until_optype (dbg, R_ANAL_OP_TYPE_SWI, 0); return show_syscall (dbg, "a0"); } if (!r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_FALSE)) { eprintf ("--> cannot read registers\n"); return -1; } { int err; reg = (int)r_debug_reg_get_err (dbg, "sn", &err); if (err) { eprintf ("Cannot find 'sn' register for current arch-os.\n"); return -1; } } for (;;) { if (r_cons_singleton()->breaked) break; #if __linux__ // step is needed to avoid dupped contsc results r_debug_step (dbg, 1); #endif dbg->h->contsc (dbg, dbg->pid, 0); // TODO handle return value // wait until continuation r_debug_wait (dbg); if (!r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_FALSE)) { eprintf ("--> cannot sync regs, process is probably dead\n"); return -1; } reg = show_syscall (dbg, "sn"); if (n_sc == -1) continue; if (n_sc == 0) { break; } for (i=0; i<n_sc; i++) { if (sc[i] == reg) return reg; } // TODO: must use r_core_cmd(as)..import code from rcore } return ret; }
R_API int r_core_rtr_cmds (RCore *core, const char *port) { unsigned char buf[4097]; RSocket *ch, *s; int i, ret; char *str; if (!port || port[0]=='?') { r_cons_printf ("Usage: .:[tcp-port] run r2 commands for clients\n"); return R_FALSE; } s = r_socket_new (0); if (!r_socket_listen (s, port, NULL)) { eprintf ("Error listening on port %s\n", port); r_socket_free (s); return R_FALSE; } eprintf ("Listening for commands on port %s\n", port); listenport = port; for (;;) { r_cons_break ((RConsBreak)http_break, core); ch = r_socket_accept (s); buf[0] = 0; ret = r_socket_read (ch, buf, sizeof (buf) - 1); if (ret>0) { buf[ret] = 0; for (i=0; buf[i]; i++) if (buf[i] == '\n') buf[i] = buf[i+1]? ';': '\0'; if (!r_config_get_i (core->config, "scr.prompt") \ && !strcmp ((char*)buf, "q!")) break; str = r_core_cmd_str (core, (const char *)buf); if (str &&*str) { r_socket_write (ch, str, strlen (str)); } else r_socket_write (ch, "\n", 1); free (str); } if (r_cons_singleton()->breaked) break; r_socket_close (ch); r_cons_break_end (); } r_socket_free(s); r_socket_free(ch); return 0; }
R_API void r_cons_pal_random() { RCons *cons = r_cons_singleton (); ut8 r, g, b; char val[32]; const char *k; int i; for (i=0;;i++) { k = r_cons_pal_get_i (i); if (!k) break; r = r_num_rand (0xf); g = r_num_rand (0xf); b = r_num_rand (0xf); sprintf (val, "rgb:%x%x%x", r, g, b); r_cons_pal_set (k, val); } for (i=0; i<R_CONS_PALETTE_LIST_SIZE; i++) { cons->pal.list[i] = r_cons_color_random (0); } }
R_API void r_cons_pal_show() { int i; for (i = 0; colors[i].name; i++) { r_cons_printf ("%s%s__"Color_RESET" %s\n", colors[i].code, colors[i].bgcode, colors[i].name); } switch (r_cons_singleton ()->color) { case COLOR_MODE_256: // 256 color palette r_cons_pal_show_gs (); r_cons_pal_show_256 (); break; case COLOR_MODE_16M: // 16M (truecolor) r_cons_pal_show_gs (); r_cons_pal_show_rgb (); break; } }
R_API void r_cons_pal_list (int rad) { RConsPalette *pal = &(r_cons_singleton ()->pal); ut8 *p = (ut8*)pal; ut8 r, g, b; char **color, rgbstr[32];; int i; for (i=0; keys[i].name; i++) { color = (char**)(p + keys[i].off); if (rad) { 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 >>= 4; g >>= 4; b >>= 4; r_cons_printf ("ec %s rgb:%x%x%x\n", keys[i].name, r, g, b); } else r_cons_printf (" %s##"Color_RESET" %s\n", *color, keys[i].name); }