void dbg_hard_release() { if(dbg_hard_brk_enabled() || dbg_hard_stp_enabled()) return; if(!(info->vmm.ctrl.dbg.excp & (1<<DB_EXCP))) return; info->vmm.ctrl.dbg.excp &= ~(1<<DB_EXCP); ctrl_traps_set_update(1); debug(DBG_HARD, "removed #DB intercept (%d|%d)\n" ,dbg_hard_stp_enabled() ,dbg_hard_brk_enabled()); }
void dbg_hard_protect() { if(!dbg_hard_brk_enabled() && !dbg_hard_stp_enabled()) return; if(info->vmm.ctrl.dbg.excp & (1<<DB_EXCP)) return; info->vmm.ctrl.dbg.excp |= (1<<DB_EXCP); ctrl_traps_set_update(1); debug(DBG_HARD, "installed #DB intercept (%d|%d)\n" ,dbg_hard_stp_enabled() ,dbg_hard_brk_enabled()); }
int dbg_hard_stp_event() { offset_t addr; int mode; dbg_evt_t *evt; if(!dbg_hard_stp_enabled()) return CTRL_EVT_IGNORE; debug(DBG_HARD_STP, "sstep event\n"); if(dbg_soft_resuming()) dbg_soft_resume_post(&__hstp_ctx.cr3); dbg_hard_set_dr6_dirty(1); dbg_hard_stp_disable(); if(dbg_hard_stp_requestor() == DBG_REQ_VMM) { debug(DBG_HARD_STP, "internal sstep event\n"); return CTRL_EVT_INTERN; } vm_get_code_addr(&addr, 0, &mode); evt = &info->vmm.ctrl.dbg.evt; evt->type = DBG_EVT_TYPE_HARD_SSTEP; evt->addr = addr; debug(DBG_HARD_STP, "prepared sstep ctrl event for 0x%X\n", evt->addr); return CTRL_EVT_DONE; }
/* ** Hardware Single-step Services */ int dbg_hard_stp_event_gp() { ud_t disasm; int rc; if(!dbg_hard_stp_enabled()) return CTRL_EVT_IGNORE; debug(DBG_HARD_STP, "sstep #GP event\n"); dbg_hard_stp_restore_context(); if(!disassemble(&disasm)) return CTRL_EVT_FAIL; rc = __emulate_insn(&disasm); dbg_hard_stp_setup_context(); switch(rc) { case EMU_FAULT: return CTRL_EVT_FAULT; case EMU_UNSUPPORTED: return CTRL_EVT_IGNORE; case EMU_FAIL: return CTRL_EVT_FAIL; } if(disasm.mnemonic == UD_Isysenter) return dbg_hard_stp_event_sysenter(); if(disasm.mnemonic == UD_Isysexit) return dbg_hard_stp_event_sysexit(); return CTRL_EVT_IGNORE; }
/* ** Hardware Single-step Services */ int dbg_hard_stp_event_gp() { size_t mn; int rc; if(!dbg_hard_stp_enabled()) return VM_IGNORE; debug(DBG_HARD_STP, "sstep #GP event\n"); __db_show_pending(); rc = disassemble(&info->vm.cpu.disasm); if(rc != VM_DONE) return rc; mn = info->vm.cpu.disasm.mnemonic; switch(mn) { case UD_Isysenter: return dbg_hard_stp_event_fast_syscall(0); case UD_Isysexit: return dbg_hard_stp_event_fast_syscall(1); } return VM_IGNORE; }
int dbg_hard_stp_event() { offset_t addr; int mode; dbg_evt_t *evt; if(!dbg_hard_stp_enabled()) return VM_IGNORE; debug(DBG_HARD_STP, "sstep event [req %s]\n" ,dbg_hard_stp_requestor()?"vmm":"usr"); if(dbg_soft_resuming()) dbg_soft_resume_post(); dbg_hard_stp_disable(); if(dbg_hard_stp_requestor() == DBG_REQ_VMM) { dbg_hard_dr6_clean(); return VM_INTERN; } dbg_hard_set_dr6_dirty(1); vm_get_code_addr(&addr, 0, &mode); evt = &info->vmm.ctrl.dbg.evt; evt->type = DBG_EVT_TYPE_HARD_SSTEP; evt->addr = addr; debug(DBG_HARD_STP, "prepared sstep ctrl event for 0x%X\n", evt->addr); return VM_DONE; }
void dbg_hard_stp_disable() { if(!dbg_hard_stp_enabled()) return; debug(DBG_HARD_STP, "hard stp disable\n"); dbg_hard_stp_set_enable(0); dbg_hard_stp_release(); }
void dbg_hard_stp_enable(uint8_t req) { if(dbg_hard_stp_enabled()) return; debug(DBG_HARD_STP, "hard stp enable\n"); dbg_hard_stp_set_enable(1); dbg_hard_stp_set_req(req); dbg_hard_stp_protect(); }
static void dbg_hard_stp_release() { if(dbg_hard_stp_enabled()) return; debug(DBG_HARD_STP, "hard stp release\n"); dbg_hard_stp_restore_context(); __rflags.tf = dbg_hard_stp_saved_tf(); __post_access(__rflags); /* XXX */ /* if(!dbg_hard_brk_enabled()) */ /* __release_rflags(); */ info->vmm.ctrl.dbg.excp &= ~(1<<GP_EXCP); dbg_hard_release(); }
static void dbg_hard_stp_protect() { if(!dbg_hard_stp_enabled()) return; debug(DBG_HARD_STP, "hard stp protect\n"); dbg_hard_stp_save_context(); dbg_hard_stp_save_tf(__rflags.tf); __rflags.tf = 1; __post_access(__rflags); /* XXX */ /* __protect_rflags(); */ info->vmm.ctrl.dbg.excp |= 1<<GP_EXCP; dbg_hard_protect(); }
/* ** Hardware Single-step Services */ int dbg_hard_stp_event_gp() { size_t mn; if(!dbg_hard_stp_enabled()) return VM_IGNORE; debug(DBG_HARD_STP, "sstep #GP event\n"); if(!disassemble(&info->vm.cpu.disasm)) return VM_FAIL; mn = info->vm.cpu.disasm.mnemonic; switch(mn) { case UD_Isysenter: return dbg_hard_stp_event_fast_syscall(0); case UD_Isysexit: return dbg_hard_stp_event_fast_syscall(1); } return VM_IGNORE; }
int emulate_rmode_interrupt(uint8_t vector, uint16_t insn_sz) { ivt_e_t *ivt; fptr_t fptr; debug(EMU_RMODE_INT, "int 0x%x (ax 0x%x)\n" , vector, info->vm.cpu.gpr->rax.wlow); if(vector == BIOS_MISC_INTERRUPT) { int rc = emulate_int15(); if(rc != VM_DONE_LET_RIP) return rc; } ivt = (ivt_e_t*)0; fptr.segment = ivt[vector].cs; fptr.offset.wlow = ivt[vector].ip; fptr.offset.whigh = 0; emulate_rmode_push(__rflags.wlow); __rflags.IF = 0; __rflags.ac = 0; /* XXX for controlled singlestep */ if(!dbg_hard_stp_enabled()) __rflags.tf = 0; /* XXX for controlled hardware BP */ if(!dbg_hard_brk_insn_enabled()) __rflags.rf = 0; emulate_rmode_far_call(&fptr, insn_sz); __post_access(__rflags); return VM_DONE_LET_RIP; }