R_API void r_anal_type_match(RCore *core, RAnalFunction *fcn) { bool esil_var[STATES_SIZE] = {false}; if (!core ) { return; } if (!r_anal_emul_init (core, esil_var) || !fcn ) { r_anal_emul_restore (core, esil_var); return; } const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC); ut64 addr = fcn->addr; r_reg_setv (core->dbg->reg, pc, fcn->addr); r_debug_reg_sync (core->dbg, -1, true); r_cons_break (NULL, NULL); while (!r_cons_is_breaked ()) { RAnalOp *op = r_core_anal_op (core, addr); int loop_count = sdb_num_get ( core->anal->esil->db_trace, sdb_fmt (-1, "0x%"PFMT64x".count", addr), 0); if (loop_count > LOOP_MAX) { eprintf ("Unfortunately your evilly engineered %s function trapped my most innocent `aftm` in an infinite loop.\n", fcn->name); eprintf ("I kept trace log for you to review and find out how bad things were going to happen by yourself.\n"); eprintf ("You can view this log by `ate`. Meanwhile, I will train on how to behave with such behaviour without bothering you.\n"); return; } sdb_num_set (core->anal->esil->db_trace, sdb_fmt (-1, "0x%"PFMT64x".count", addr), loop_count + 1, 0); if (!op || op->type == R_ANAL_OP_TYPE_RET) { r_anal_emul_restore (core, esil_var); return; } if (op->type == R_ANAL_OP_TYPE_CALL) { RAnalFunction *fcn_call = r_anal_get_fcn_in (core->anal, op->jump, -1); //eprintf ("in the middle of %s\n", fcn_call->name); if (fcn_call) { type_match (core, addr, fcn_call->name); } else { eprintf ("Cannot find function at 0x%08"PFMT64x"\n", op->jump); } addr += op->size; r_anal_op_free (op); r_reg_setv (core->dbg->reg, pc, addr); r_debug_reg_sync (core->dbg, -1, true); r_anal_esil_set_pc (core->anal->esil, addr); addr += stack_clean (core, addr, fcn); r_reg_setv (core->dbg->reg, pc, addr); r_debug_reg_sync (core->dbg, -1, true); r_anal_esil_set_pc (core->anal->esil, addr); continue; } else { r_core_esil_step (core, UT64_MAX, NULL); r_anal_op_free (op); } r_core_cmd0 (core, ".ar*"); addr = r_reg_getv (core->anal->reg, pc); } r_cons_break_end (); r_anal_emul_restore (core, esil_var); }
static int r_debug_native_drx (RDebug *dbg, int n, ut64 addr, int sz, int rwx, int g) { #if __i386__ || __x86_64__ drxt regs[8] = {0}; // sync drx regs #define R dbg->reg regs[0] = r_reg_getv (R, "dr0"); regs[1] = r_reg_getv (R, "dr1"); regs[2] = r_reg_getv (R, "dr2"); regs[3] = r_reg_getv (R, "dr3"); /* RESERVED regs[4] = r_reg_getv (R, "dr4"); regs[5] = r_reg_getv (R, "dr5"); */ regs[6] = r_reg_getv (R, "dr6"); regs[7] = r_reg_getv (R, "dr7"); if (sz == 0) { drx_list ((drxt*)®s); return false; } if (sz<0) { // remove drx_set (regs, n, addr, -1, 0, 0); } else { drx_set (regs, n, addr, sz, rwx, g); } r_reg_setv (R, "dr0", regs[0]); r_reg_setv (R, "dr1", regs[1]); r_reg_setv (R, "dr2", regs[2]); r_reg_setv (R, "dr3", regs[3]); r_reg_setv (R, "dr6", regs[6]); r_reg_setv (R, "dr7", regs[7]); return true; #else eprintf ("drx: Unsupported platform\n"); #endif return false; }
int gb_interrupts (emu *e) //needs a lot of more love { ut8 ien, ifl, tac, tma, tima, ly; ut16 pc = r_reg_getv (e->reg, "pc"), sp = r_reg_getv (e->reg, "sp") - 2; GBCpuStats *cpu = (GBCpuStats *)e->data; gb_read (e, 0xff07, &tac, 1); gb_read (e, 0xff06, &tma, 1); gb_read (e, 0xff05, &tima, 1); gb_read (e, 0xff0f, &ifl, 1); gb_read (e, 0xffff, &ien, 1); gb_read (e, 0xff44, &ly, 1); if (ly != cpu->ly) ly = 0; cpu->render_ccl += cpu->cycles - cpu->prev_cycles; if (cpu->render_ccl >= 456) { cpu->render_ccl -= 456; ly++; if (ly == 153) ly = 0; cpu->ly = ly; } gb_write (e, 0xff44, &ly, 1); if ((tac&3) != (cpu->tac&3)) { cpu->timer_ccl = 0; //XXX cpu->tac = tac; } if (tac & 4) { cpu->timer_ccl += cpu->cycles - cpu->prev_cycles; switch (tac & 3) { case 0: while (cpu->timer_ccl >= 256) { tima = (tima + 1) & 0xff; cpu->timer_ccl -= 256; } break; case 1: while (cpu->timer_ccl >= 4) { //check below, if he new value is smaler than the new one, if so, add the content of tma and throw interrupt tima = (tima + 1) & 0xff; cpu->timer_ccl -= 4; } break; case 2: while (cpu->timer_ccl >= 16) { tima = (tima + 1) & 0xff; cpu->timer_ccl -= 16; } break; case 3: while (cpu->timer_ccl >= 64) { tima = (tima +1) & 0xff; cpu->timer_ccl -= 64; } } } if (cpu->input != cpu->prev_input) { if ((ien & 16) && r_reg_getv (e->reg, "ime")) { ifl = 16; gb_write (e, 0xff0f, &ifl, 1); //how to reset this? r_reg_setv (e->reg, "ime", R_FALSE); gb_write (e, (ut64)sp, (ut8 *)&pc, 2); //manual push r_reg_setv (e->reg, "mpc", GB_INT_JP); r_reg_setv (e->reg, "sp", sp); cpu->interruptlevel++; } cpu->input = cpu->prev_input; } if (cpu->tima > tima) { tima = (tima+tma) & 0xff; if ((ien & 4) && r_reg_getv (e->reg, "ime")) { ifl = 4; gb_write (e, 0xff0f, &ifl, 1); r_reg_setv (e->reg, "ime", R_FALSE); gb_write (e, (ut64)sp, (ut8 *)&pc, 2); r_reg_setv (e->reg, "mpc", GB_INT_TIM); r_reg_setv (e->reg, "sp", sp); cpu->interruptlevel++; } } if (ly > 144) { //vblank if ((ien & 1) && r_reg_getv (e->reg, "ime")) { ifl = 1; gb_write (e, 0xff0f, &ifl, 1); r_reg_setv (e->reg, "ime", R_FALSE); gb_write (e, (ut64)sp, (ut8 *)&pc, 2); r_reg_setv (e->reg, "mpc", GB_INT_VBL); r_reg_setv (e->reg, "sp", sp); cpu->interruptlevel++; } } cpu->tima = tima; gb_write (e, 0xff05, &tima, 1); return R_TRUE; }