Beispiel #1
0
static int emulate_sysexit()
{
   seg_sel_t cs;

   __pre_access(__sysenter_cs);

   cs.raw = __sysenter_cs.wlow;

   if(__cpl || !__cr0.pe || !cs.index)
   {
      debug(EMU_INSN, "sysexit fault: cpl %d cr0.pe %d cs.index %d\n"
	    , __cpl, __cr0.pe, cs.index);
      __inject_exception(GP_EXCP, 0, 0);
      return VM_FAULT;
   }

   __cs.selector.raw = __sysenter_cs.wlow + 16;
   __cs.selector.rpl = 3;
   __cs.base.raw = 0ULL;
   __cs.limit.raw = 0xffffffff;
   __cs.attributes.g = 1;
   __cs.attributes.s = 1;
   __cs.attributes.type = SEG_DESC_CODE_XRA;
   __cs.attributes.d = 1;
   __cs.attributes.dpl = 3;
   __cs.attributes.p = 1;
   __cpl = 3;

   __ss.selector.raw = __sysenter_cs.wlow + 24;
   __ss.selector.rpl = 3;
   __ss.base.raw = 0ULL;
   __ss.limit.raw = 0xffffffff;
   __ss.attributes.g = 1;
   __ss.attributes.s = 1;
   __ss.attributes.type = SEG_DESC_DATA_RWA;
   __ss.attributes.d = 1;
   __ss.attributes.dpl = 3;
   __ss.attributes.p = 1;

   info->vm.cpu.gpr->rsp.low = info->vm.cpu.gpr->rcx.low;
   __rip.low = info->vm.cpu.gpr->rdx.low;

   __post_access(__rip);

   __post_access(__cs.selector);
   __post_access(__cs.base);
   __post_access(__cs.limit);
   __post_access(__cs.attributes);

   __post_access(__ss.selector);
   __post_access(__ss.base);
   __post_access(__ss.limit);
   __post_access(__ss.attributes);

   return VM_DONE_LET_RIP;
}
Beispiel #2
0
static void emulate_rmode_far_jump(fptr_t *fptr)
{
   __cs.selector.raw = fptr->segment;
   __cs.base.low = (__cs.selector.raw)<<4;

   /* on op16, eip high is cleared */
   __rip.low = fptr->offset.raw;

   debug(EMU_RMODE_FAR, "far jump to 0x%x:0x%x\n",
         __cs.selector.raw, __rip.wlow);

   __post_access(__cs.selector);
   __post_access(__cs.base);
   __post_access(__rip);
}
Beispiel #3
0
static void emulate_rmode_far_ret(uint16_t add_sp)
{
   __rip.wlow        = emulate_rmode_pop();
   __cs.selector.raw = emulate_rmode_pop();
   __cs.base.low     = (__cs.selector.raw)<<4;

   debug(EMU_RMODE_FAR, "far ret to 0x%x:0x%x\n", __cs.selector.raw, __rip.wlow);

   if(add_sp)
      info->vm.cpu.gpr->rsp.wlow += add_sp;

   __post_access(__rip);
   __post_access(__cs.base);
   __post_access(__cs.selector);
}
Beispiel #4
0
void dbg_hard_brk_rearm()
{
   dbg_hard_brk_set_disarm(0);

   __dr7.low = info->vmm.ctrl.dbg.hard.brk.dr7.low;
   __post_access(__dr7);
}
Beispiel #5
0
void dbg_hard_brk_disarm()
{
   dbg_hard_brk_set_disarm(1);

   __dr7.low &= 0x100;
   __post_access(__dr7);
}
Beispiel #6
0
int emulate_rmode_iret()
{
   emulate_rmode_far_ret(0);
   __rflags.wlow = emulate_rmode_pop();
   __post_access(__rflags);

   debug(EMU_RMODE_IRET, "iret\n");
   return VM_DONE_LET_RIP;
}
Beispiel #7
0
/*
** if we filter #DB, vmx_exit_excp() will update dr6
** if we don't, the cpu will do it as normal
*/
static int vmx_db_check_pending_stp()
{
   if(!vm_state.rflags.tf)
      return VM_IGNORE;

   __rflags.tf = 0;
   __post_access(__rflags);

   return VM_DONE;
}
Beispiel #8
0
/*
** A20 gate support: AX = 2403h
** CF clear if successful
** AH = 00h
** BX = status of A20 gate support
**     0 supported on keyboard controller
**     1 supported with bit 1 of I/O port 92h
**  14-2 reserved
**    15 additional data is available (location not yet defined)
** CF set on error
** AH = status 01h keyboard controller is in secure mode
** 86h function not supported
*/
static int emulate_int15_a20_support()
{
   info->vm.cpu.gpr->rax.bhigh = 0;
   info->vm.cpu.gpr->rbx.wlow  = 2;

   __rflags.cf = 0;
   __post_access(__rflags);

   return VM_DONE;
}
Beispiel #9
0
static void dbg_hard_brk_insn_protect()
{
   if(!dbg_hard_brk_insn_enabled())
      return;

   dbg_hard_brk_save_rf(__rflags.rf);
   __rflags.rf = 0;
   __post_access(__rflags);
   /* XXX */
   /* __protect_rflags(); */
}
Beispiel #10
0
/*
** A20 gate status: AX = 2402h
** CF clear if successful
** AH = 00h
** AL = current state (00h disabled, 01h enabled)
** CX = ??? (set to 0000h-000Bh or FFFFh by AMI BIOS v1.00.03.AV0M)
**      FFFFh if keyboard controller does not become ready
**      within C000h read attempts
** CF set on error
** AH = status 01h
** keyboard controller is in secure mode
** 86h function not supported
*/
static int emulate_int15_a20_status()
{
   info->vm.cpu.gpr->rax.blow  = info->vm.dev.mem.a20;
   info->vm.cpu.gpr->rax.bhigh = 0;
   info->vm.cpu.gpr->rcx.wlow  = 0;

   __rflags.cf = 0;
   __post_access(__rflags);

   return VM_DONE;
}
Beispiel #11
0
/*
** A20 gate enable: AX = 2401h
** CF clear if successful
** AH = 00h
** CF set on error
** AH = status
** 01h  keyboard controller is in secure mode
** 86h function not supported
*/
static int emulate_int15_a20_enable()
{
   info->vm.cpu.gpr->rax.bhigh = 0;

   __rflags.cf = 0;
   __post_access(__rflags);

    dev_a20_set(1);

   return VM_DONE;
}
Beispiel #12
0
/*
** A20 gate disable: AX = 2400h
** CF clear if successful
** AH = 00h
** CF set on error
** AH = status
** 01h keyboard controller is in secure mode
** 86h function not supported 
*/
static int emulate_int15_a20_disable()
{
   info->vm.cpu.gpr->rax.bhigh = 0;

   __rflags.cf = 0;
   __post_access(__rflags);

   dev_a20_set(0);

   return EMU_SUCCESS;
}
Beispiel #13
0
void vm_rewind_rip(offset_t offset)
{
   if(__lmode64())
      __rip.raw -= (uint64_t)offset;
   else if(__pmode32())
      __rip.low -= (uint32_t)offset;
   else
      __rip.wlow -= (uint16_t)offset;

   __post_access(__rip);
}
Beispiel #14
0
static void dbg_hard_release_dr()
{
   debug(DBG_HARD_BRK, "hard release dr\n");

   /* XXX: release DBG_CTL_MSR */

   /* XXX: vmm area check ? */
   set_dr0(info->vm.dr_shadow[0].raw);
   set_dr1(info->vm.dr_shadow[1].raw);
   set_dr2(info->vm.dr_shadow[2].raw);
   set_dr3(info->vm.dr_shadow[3].raw);

   __dr6.low = info->vm.dr_shadow[4].low;
   __dr7.low = info->vm.dr_shadow[5].low;

   dbg_hard_set_dr6_dirty(0);

   __post_access(__dr6);
   __post_access(__dr7);
   __allow_dr_access();
}
Beispiel #15
0
int resolve_exception()
{
   if(__exception_vector == PF_EXCP)
   {
      __cr2.raw = __exception_fault;
      __post_access(__cr2);
   }

   return __resolve_exception(__exception_vector,
                              __exception_error.raw,
                              __exception_fault);
}
Beispiel #16
0
static void dbg_hard_brk_insn_release()
{
   if(dbg_hard_brk_insn_enabled())
      return;

   __rflags.rf = dbg_hard_brk_saved_rf();
   __post_access(__rflags);

   /* XXX */
   /* if(!dbg_hard_stp_enabled()) */
   /*    __release_rflags(); */
}
Beispiel #17
0
int dbg_hard_brk_resume()
{
   uint8_t n = info->vmm.ctrl.dbg.evt.hard;

   if(info->vmm.ctrl.dbg.evt.type != DBG_EVT_TYPE_HARD_BRK_X || !__hbrk_enabled(n))
      return 0;

   __rflags.rf = 1;
   __post_access(__rflags);
   /* XXX protect rflags ? */

   return 1;
}
Beispiel #18
0
static int dbg_hard_stp_event_fast_syscall(int tf)
{
   int rc;

   dbg_hard_stp_restore_context();
   rc = emulate_insn(&info->vm.cpu.disasm);
   dbg_hard_stp_setup_context();

   if(rc == VM_DONE_LET_RIP)
   {
      __rflags.tf = tf;
      __post_access(__rflags);
   }

   return rc;
}
Beispiel #19
0
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();
}
Beispiel #20
0
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();
}
Beispiel #21
0
static int dbg_hard_stp_event_fast_syscall(int tf)
{
   int    rc;
   size_t sz;

   dbg_hard_stp_restore_context();

   sz = ud_insn_len(&info->vm.cpu.disasm);
   rc = emulate_done(emulate_insn(&info->vm.cpu.disasm), sz);
   info->vm.cpu.emu_sts = EMU_STS_AVL; /* stealth for db_pending() */

   dbg_hard_stp_setup_context();

   if(rc == VM_DONE_LET_RIP)
   {
      __rflags.tf = tf;
      __post_access(__rflags);
   }

   return rc;
}
Beispiel #22
0
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;
}
Beispiel #23
0
static int dbg_hard_stp_event_sysexit()
{
   __rflags.tf = 1;
   __post_access(__rflags);
   return CTRL_EVT_DONE;
}
Beispiel #24
0
void dbg_hard_stp_restore_context()
{
   debug(DBG_HARD_STP, "stp restored sysenter\n");
   __sysenter_cs.raw = __hstp_ctx.sysenter_cs.raw;
   __post_access(__sysenter_cs);
}
Beispiel #25
0
void dbg_hard_stp_setup_context()
{
   debug(DBG_HARD_STP, "stp install sysenter\n");
   __sysenter_cs.raw = 0;
   __post_access(__sysenter_cs);
}