大家好,这几天在研究VT,目前只处理了CPUID VMCALL CR和DR,在没处理DR前,VT运行正常,系统也不会卡死,也没有任务切换发生VM-EXIT,但是当拦截DR的时候,每次都会虚拟机卡死,看了下ExitReason是9,ExitQualifiction是0xC0000050, 发现每次都是由于任务切换造成系统卡死的,我学了下joen牛中DdvpDbg的处理,没有对任务切换进行处理,直接GuestEIP+指令长度,然后VmResume,虚拟机照样卡死,这是我的HOST入口点的代码:
//////////////// 虚拟机处理系统 ///////
__declspec( naked ) VOID VMMEntryPoint( )
{
_asm
{
CLI
PUSHAD
// 保存通用寄存器
MOV GuestEAX, EAX
MOV GuestEBX, EBX
MOV GuestECX, ECX
MOV GuestEDX, EDX
MOV GuestESI, ESI
MOV GuestEDI, EDI
MOV GuestEBP, EBP
}
ReadGuestState();
GuestResumeEIP = GuestEIP + ExitInstructionLength;
VMWRITE(GUEST_RIP,(ULONG)GuestResumeEIP ); //0x0000681E
if(ExitReason==0xA) // CPUID
{
if(GuestEAX==0x123)
{
_asm{
POPAD
MOV EBX,0x11111111
MOV ECX,0x22222222
MOV EDX,0x33333333
JMP Resume
}
}
else{
_asm{
POPAD
CPUID
JMP Resume
}
}
}
if(ExitReason==0x12) // VMCALL
{
if(GuestEAX==0x1234) //Unload Handler
{
VMXOFF();
_asm{
POPAD
MOV ESP, GuestESP
STI
JMP GuestResumeEIP
}
}
else
{
_asm
{
POPAD
JMP Resume
}
}
}
if(ExitReason==0x1C) // Control Register
{
if( HandlerLogging ) Log( "Control Register Access detected.", 0 );
movcrControlRegister= (ExitQualification & 0x0000000F); // bit0-bit3
movcrAccessType= ( (ExitQualification>>4) & 0x00000003); // bit4-bit5
movcrOprandType= ( (ExitQualification>>6) & 0x00000001); // bit6
movcrGeneralPurposeRegister= ( (ExitQualification>>8) &0xF);// bit8-bit11
movcrLmswSourceData= ( (ExitQualification>>16) &0xFFFF); // bit16-bit31
if( HandlerLogging )
{
Log("movcrControlRegister", movcrControlRegister);
Log("movcrAccessType", movcrAccessType);
Log("movcrOprandType", movcrOprandType);
Log("movcrGeneralPurposeRegister", movcrGeneralPurposeRegister);
Log("movcrLmswSourceData", movcrLmswSourceData);
}
// MOV CR3,Register
if( movcrControlRegister==0x3 && movcrAccessType==0 && movcrOprandType==0 && movcrGeneralPurposeRegister==0)
{
VMWRITE(GUEST_CR3, GuestEAX);
_asm POPAD
_asm JMP Resume
}
if( movcrControlRegister==0x3 && movcrAccessType==0 && movcrOprandType==0 && movcrGeneralPurposeRegister==1)
{
VMWRITE(GUEST_CR3, GuestECX);
_asm POPAD
_asm JMP Resume
}
if( movcrControlRegister==0x3 && movcrAccessType==0 && movcrOprandType==0 && movcrGeneralPurposeRegister==2)
{
VMWRITE(GUEST_CR3, GuestEDX);
_asm POPAD
_asm JMP Resume
}
if( movcrControlRegister==0x3 && movcrAccessType==0 && movcrOprandType==0 && movcrGeneralPurposeRegister==3)
{
VMWRITE(GUEST_CR3, GuestEBX);
_asm POPAD
_asm JMP Resume
}
if( movcrControlRegister==0x3 && movcrAccessType==0 && movcrOprandType==0 && movcrGeneralPurposeRegister==4)
{
VMWRITE(GUEST_CR3, GuestESP);
_asm POPAD
_asm JMP Resume
}
if( movcrControlRegister==0x3 && movcrAccessType==0 && movcrOprandType==0 && movcrGeneralPurposeRegister==5)
{
VMWRITE(GUEST_CR3, GuestEBP);
_asm POPAD
_asm JMP Resume
}
if( movcrControlRegister==0x3 && movcrAccessType==0 && movcrOprandType==0 && movcrGeneralPurposeRegister==6)
{
VMWRITE(GUEST_CR3, GuestESI);
_asm POPAD
_asm JMP Resume
}
if( movcrControlRegister==0x3 && movcrAccessType==0 && movcrOprandType==0 && movcrGeneralPurposeRegister==7)
{
VMWRITE(GUEST_CR3, GuestEDI);
_asm POPAD
_asm JMP Resume
}
// MOV Register,CR3
if( movcrControlRegister==0x3 && movcrAccessType==1 && movcrOprandType==0 && movcrGeneralPurposeRegister==0)
{
_asm POPAD
_asm MOV EAX, GuestCR3
_asm JMP Resume
}
if( movcrControlRegister==0x3 && movcrAccessType==1 && movcrOprandType==0 && movcrGeneralPurposeRegister==1)
{
_asm POPAD
_asm MOV ECX, GuestCR3
_asm JMP Resume
}
if( movcrControlRegister==0x3 && movcrAccessType==1 && movcrOprandType==0 && movcrGeneralPurposeRegister==2)
{
_asm POPAD
_asm MOV EDX, GuestCR3
_asm JMP Resume
}
if( movcrControlRegister==0x3 && movcrAccessType==1 && movcrOprandType==0 && movcrGeneralPurposeRegister==3)
{
_asm POPAD
_asm MOV EBX, GuestCR3
_asm JMP Resume
}
if( movcrControlRegister==0x3 && movcrAccessType==1 && movcrOprandType==0 && movcrGeneralPurposeRegister==4)
{
_asm POPAD
_asm MOV ESP, GuestCR3
_asm JMP Resume
}
if( movcrControlRegister==0x3 && movcrAccessType==1 && movcrOprandType==0 && movcrGeneralPurposeRegister==5)
{
_asm POPAD
_asm MOV EBP, GuestCR3
_asm JMP Resume
}
if( movcrControlRegister==0x3 && movcrAccessType==1 && movcrOprandType==0 && movcrGeneralPurposeRegister==6)
{
_asm POPAD
_asm MOV ESI, GuestCR3
_asm JMP Resume
}
if( movcrControlRegister==0x3 && movcrAccessType==1 && movcrOprandType==0 && movcrGeneralPurposeRegister==7)
{
_asm POPAD
_asm MOV EDI, GuestCR3
_asm JMP Resume
}
}
if(ExitReason==0x1D) // DR
{
PrintGuestState();
DispatchDrHandler();
}
if(ExitReason==0x9)
{
_asm{
POPAD
JMP Resume
}
}
PrintGuestState();
Resume:
_asm
{
STI
_emit 0x0F // VMRESUME
_emit 0x01
_emit 0xC3
}
}
VOID ReadGuestState()
{
HandlerLogging=0;
ExitInstructionLength = VMREAD(VM_EXIT_INSTRUCTION_LEN);
ExitReason = VMREAD(VM_EXIT_REASON);
ExitQualification=VMREAD(EXIT_QUALIFICATION);
GuestEIP = VMREAD(GUEST_RIP);
GuestESP = VMREAD(GUEST_RSP);
GuestCR3 = VMREAD(GUEST_CR3);
GuestDR7 = VMREAD(GUEST_DR7);
}
VOID PrintGuestState()
{
Log( "----- VMM Guest -----", 0 );
Log("The GuestEAX:",GuestEAX);
Log("The GuestECX:",GuestECX);
Log("The GuestEDX:",GuestEDX);
Log("The GuestEBX:",GuestEBX);
Log("The GuestESP:",GuestESP);
Log("The GuestEBP:",GuestEBP);
Log("The GuestESI:",GuestESI);
Log("The GuestEDI:",GuestEDI);
Log("The GuestDR7:",GuestDR7);
Log("The ExitReason:",ExitReason);
Log("The ExitQualification:",ExitQualification);
}
这是我对DR的处理:
VOID DispatchDrHandler()
{
movdrRegister = ( (ExitQualification) & 0x7); // bit0-bit2
movdrDirection = ( (ExitQualification>>4) & 0x1); // bit4
movdrGeneralPurposeRegister = ( (ExitQualification>>8) & 0xF); // bit8-bit11
SourceReg=0;
DR=0;
// MOV DR, Reg
if(movdrDirection==0){
if(movdrGeneralPurposeRegister==0){
SourceReg=GuestEAX;
}
if(movdrGeneralPurposeRegister==1){
SourceReg=GuestECX;
}
if(movdrGeneralPurposeRegister==2){
SourceReg=GuestEDX;
}
if(movdrGeneralPurposeRegister==3){
SourceReg=GuestEBX;
}
if(movdrGeneralPurposeRegister==4){
SourceReg=GuestESP;
}
if(movdrGeneralPurposeRegister==5){
SourceReg=GuestEBP;
}
if(movdrGeneralPurposeRegister==6){
SourceReg=GuestESI;
}
if(movdrGeneralPurposeRegister==7){
SourceReg=GuestEDI;
}
if(movdrRegister==0){
_asm{
MOV EAX, SourceReg
MOV DR0, EAX
POPAD
JMP Resume
}
}
if(movdrRegister==1){
_asm{
MOV EAX, SourceReg
MOV DR1, EAX
POPAD
JMP Resume
}
}
if(movdrRegister==2){
_asm{
MOV EAX, SourceReg
MOV DR2, EAX
POPAD
JMP Resume
}
}
if(movdrRegister==3){
_asm{
MOV EAX, SourceReg
MOV DR3, EAX
POPAD
JMP Resume
}
}
if(movdrRegister==4){
_asm xchg sp, sp
}
if(movdrRegister==5){
_asm xchg sp, sp
}
if(movdrRegister==6){
_asm{
MOV EAX, SourceReg
MOV DR6, EAX
POPAD
JMP Resume
}
}
if(movdrRegister==7){
VMWRITE(GUEST_DR7, SourceReg);
_asm{
POPAD
JMP Resume
}
}
}
// MOV Reg,DR
if(movdrDirection==1){
if(movdrRegister==0){
_asm{
MOV EAX, DR0
MOV DR, EAX
}
}
if(movdrRegister==1){
_asm{
MOV EAX, DR1
MOV DR, EAX
}
}
if(movdrRegister==2){
_asm{
MOV EAX, DR2
MOV DR, EAX
}
}
if(movdrRegister==3){
_asm{
MOV EAX, DR3
MOV DR, EAX
}
}
if(movdrRegister==4){
_asm xchg sp, sp
}
if(movdrRegister==5){
_asm xchg sp, sp
}
if(movdrRegister==6){
_asm{
MOV EAX, DR6
MOV DR, EAX
}
}
if(movdrRegister==7){
DR=VMREAD(GUEST_DR7);
}
if(movdrGeneralPurposeRegister==0){
_asm POPAD
_asm MOV EAX, DR
_asm JMP Resume
}
if(movdrGeneralPurposeRegister==1){
_asm POPAD
_asm MOV ECX, DR
_asm JMP Resume
}
if(movdrGeneralPurposeRegister==2){
_asm POPAD
_asm MOV EDX, DR
_asm JMP Resume
}
if(movdrGeneralPurposeRegister==3){
_asm POPAD
_asm MOV EBX, DR
_asm JMP Resume
}
if(movdrGeneralPurposeRegister==4){
_asm POPAD
_asm MOV ESP, DR
_asm JMP Resume
}
if(movdrGeneralPurposeRegister==5){
_asm POPAD
_asm MOV EBP, DR
_asm JMP Resume
}
if(movdrGeneralPurposeRegister==6){
_asm POPAD
_asm MOV ESI, DR
_asm JMP Resume
}
if(movdrGeneralPurposeRegister==7){
_asm POPAD
_asm MOV EDI, DR
_asm JMP Resume
}
}
//LogDrHandler();
Resume:
_asm
{
STI
_emit 0x0F // VMRESUME
_emit 0x01
_emit 0xC3
}
}
这是我的文件
VtTest.rar
非常感谢了!!!
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课