R_API void r_cons_break_end() { I.breaked = false; I.timeout = 0; r_print_set_interrupted (I.breaked); #if __UNIX__ || __CYGWIN__ signal (SIGINT, SIG_IGN); #endif if (!r_stack_is_empty (I.break_stack)) { //free all the stack r_stack_free (I.break_stack); //create another one I.break_stack = r_stack_newf (6, break_stack_free); I.data = NULL; I.event_interrupt = NULL; } }
ut64 analyzeStackBased(RCore *core, Sdb *db, ut64 addr, RList *delayed_commands) { #define addCall(x) sdb_array_add_num (db, "calls", x, 0); #define addUcall(x) sdb_array_add_num (db, "ucalls", x, 0); #define addUjmp(x) sdb_array_add_num (db, "ujmps", x, 0); #define addCjmp(x) sdb_array_add_num (db, "cjmps", x, 0); #define addRet(x) sdb_array_add_num (db, "rets", x, 0); #define bbAddOpcode(x) sdb_array_insert_num (db, sdb_fmt ("bb.%"PFMT64x, addr+cur), -1, x, 0); ut64 oaddr = addr; ut64 *value = NULL; RAnalOp *op; int cur = 0; bool block_end = false; RStack *stack = r_stack_newf (10, free); addTarget (core, stack, db, addr); while (!r_stack_is_empty (stack)) { block_end = false; value = (ut64*) r_stack_pop (stack); if (!value) { eprintf ("Failed to pop next address from stack\n"); break; } addr = *value; free (value); cur = 0; while (!block_end) { op = r_core_anal_op (core, addr + cur, R_ANAL_OP_MASK_BASIC); if (!op || !op->mnemonic) { eprintf ("Cannot analyze opcode at %"PFMT64d"\n", addr+cur); oaddr = UT64_MAX; break; } if (op->mnemonic[0] == '?') { eprintf ("Cannot analyze opcode at %"PFMT64d"\n", addr+cur); oaddr = UT64_MAX; break; } bbAddOpcode (addr+cur); switch (op->type) { case R_ANAL_OP_TYPE_NOP: // skip nops if (cur == 0) { cur -= op->size; addr += op->size; oaddr += op->size; } break; case R_ANAL_OP_TYPE_CALL: /* A call instruction implies that the destination * is a new function unless the address is inside * the same range than the current function */ addCall (op->jump); r_list_append (delayed_commands, r_str_newf ("axC %"PFMT64d" %"PFMT64d, op->jump, addr + cur)); break; case R_ANAL_OP_TYPE_UCALL: case R_ANAL_OP_TYPE_ICALL: case R_ANAL_OP_TYPE_RCALL: case R_ANAL_OP_TYPE_IRCALL: /* unknown calls depend on ESIL or DEBUG tracing * information to know the destination, we can mark * those 'calls' for later adding tracepoints in * there to record all possible destinations */ addUcall (addr+cur); if (op->ptr != UT64_MAX) { r_list_append (delayed_commands, r_str_newf ("axC %"PFMT64d" %"PFMT64d, op->ptr, addr + cur)); } break; case R_ANAL_OP_TYPE_UJMP: case R_ANAL_OP_TYPE_RJMP: case R_ANAL_OP_TYPE_IJMP: case R_ANAL_OP_TYPE_IRJMP: /* an unknown jump use to go into computed destinations * outside the current function, but it may result * on an antidisasm trick */ addUjmp (addr + cur); /* An unknown jump breaks the basic blocks */ block_end = true; // XXX more investigation here break; case R_ANAL_OP_TYPE_TRAP: if (cur == 0) { // skip leading int3 cur -= op->size; addr += op->size; oaddr += op->size; } else { block_end = true; } break; case R_ANAL_OP_TYPE_RET: addRet (addr + cur); bbAdd (db, addr, addr + cur + op->size, UT64_MAX, UT64_MAX); block_end = true; break; case R_ANAL_OP_TYPE_CJMP: addCjmp (addr+cur); bbAdd (db, addr, addr + cur + op->size, op->jump, addr + cur + op->size); addTarget (core, stack, db, op->jump); addTarget (core, stack, db, addr + cur + op->size); block_end = true; r_list_append (delayed_commands, r_str_newf ("axc %"PFMT64d" %"PFMT64d, op->jump, addr + cur)); break; case R_ANAL_OP_TYPE_JMP: addUjmp (addr+cur); bbAdd (db, addr, addr + cur + op->size, op->jump, UT64_MAX); addTarget (core, stack, db, op->jump); block_end = true; r_list_append (delayed_commands, r_str_newf ("axc %"PFMT64d" %"PFMT64d, op->jump, addr + cur)); break; case R_ANAL_OP_TYPE_UNK: case R_ANAL_OP_TYPE_ILL: eprintf ("a2f: Invalid instruction\n"); block_end = true; break; default: if (op->ptr != UT64_MAX) { r_list_append (delayed_commands, r_str_newf ("axd %"PFMT64d" %"PFMT64d, op->ptr, addr + cur)); } break; } cur += op->size; r_anal_op_free (op); op = NULL; } } r_stack_free (stack); return oaddr; }
R_API RCons *r_cons_new() { I.refcnt++; if (I.refcnt != 1) { return &I; } I.line = r_line_new (); I.highlight = NULL; I.event_interrupt = NULL; I.is_wine = -1; I.fps = 0; I.use_color = false; I.blankline = true; I.teefile = NULL; I.fix_columns = 0; I.fix_rows = 0; I.mouse_event = 0; I.force_rows = 0; I.force_columns = 0; I.event_resize = NULL; I.data = NULL; I.event_data = NULL; I.is_interactive = true; I.noflush = false; I.linesleep = 0; I.fdin = stdin; I.fdout = 1; I.breaked = false; //I.lines = 0; I.buffer = NULL; I.buffer_sz = 0; I.buffer_len = 0; r_cons_get_size (&I.pagesize); I.num = NULL; I.null = 0; #if __WINDOWS__ && !__CYGWIN__ I.ansicon = r_sys_getenv ("ANSICON"); #endif #if EMSCRIPTEN /* do nothing here :? */ #elif __UNIX__ || __CYGWIN__ tcgetattr (0, &I.term_buf); memcpy (&I.term_raw, &I.term_buf, sizeof (I.term_raw)); I.term_raw.c_iflag &= ~(BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); I.term_raw.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); I.term_raw.c_cflag &= ~(CSIZE|PARENB); I.term_raw.c_cflag |= CS8; I.term_raw.c_cc[VMIN] = 1; // Solaris stuff hehe signal (SIGWINCH, resize); #elif __WINDOWS__ h = GetStdHandle (STD_INPUT_HANDLE); GetConsoleMode (h, (PDWORD) &I.term_buf); I.term_raw = 0; if (!SetConsoleCtrlHandler ((PHANDLER_ROUTINE)__w32_control, TRUE)) { eprintf ("r_cons: Cannot set control console handler\n"); } #endif I.pager = NULL; /* no pager by default */ I.truecolor = 0; I.mouse = 0; I.cons_stack = r_stack_newf (6, cons_stack_free); I.break_stack = r_stack_newf (6, break_stack_free); r_cons_pal_null (); r_cons_pal_init (NULL); r_cons_rgb_init (); r_cons_reset (); return &I; }