static int emulate_mov(ud_t *disasm) { struct ud_operand *op1, *op2; uint8_t gpr; op1 = &disasm->operand[0]; op2 = &disasm->operand[1]; if(op2->type != UD_OP_REG || op1->type != UD_OP_REG) return VM_FAIL; /* read cr */ if(range(op2->base, UD_R_CR0, UD_R_CR4)) { uint8_t cr = op2->base - UD_R_CR0; if(disasm->pfx_lock != UD_NONE || disasm->pfx_rex != UD_NONE) return VM_FAIL; gpr = __emulate_get_gpr(op1); return __resolve_cr(0, cr, gpr); } /* write cr */ else if(range(op1->base, UD_R_CR0, UD_R_CR4)) { uint8_t cr = op1->base - UD_R_CR0; if(disasm->pfx_lock != UD_NONE || disasm->pfx_rex != UD_NONE) return VM_FAIL; gpr = __emulate_get_gpr(op2); return __resolve_cr(1, cr, gpr); } /* read dr */ else if(range(op2->base, UD_R_DR0, UD_R_DR7)) { uint8_t dr = op2->base - UD_R_DR0; gpr = __emulate_get_gpr(op1); return __resolve_dr(0, dr, gpr); } /* write dr */ else if(range(op1->base, UD_R_DR0, UD_R_DR7)) { uint8_t dr = op1->base - UD_R_DR0; gpr = __emulate_get_gpr(op2); return __resolve_dr(1, dr, gpr); } return VM_FAIL; }
int vmx_vmexit_resolve_dr_access() { vmcs_exit_info_dr_t *access; uint8_t gpr; vmcs_read(vm_exit_info.qualification); access = &vm_exit_info.qualification.dr; gpr = GPR64_RAX - (access->gpr & GPR64_RAX); if(__resolve_dr(!access->dir, access->nr, gpr) == DR_SUCCESS) { info->vm.cpu.emu_done = 1; vmcs_read(vm_exit_info.insn_len); vm_update_rip(vm_exit_info.insn_len.raw); return 1; } return 0; }