fix VM inside VM inside VM
This commit is contained in:
parent
735da7d8dd
commit
c46cba8d3a
@ -1,6 +1,6 @@
|
||||
#SERIALPORT is the port to communicate with the debugger, usually 0x3f8, on db's system it's 0xef00
|
||||
SERIALPORT=0 #release/no serialport build
|
||||
#SERIALPORT=0x3f8 #bochs (gigabyte test system)
|
||||
#SERIALPORT=0 #release/no serialport build
|
||||
SERIALPORT=0x3f8 #bochs (gigabyte test system)
|
||||
#SERIALPORT=0xbf00 #intel
|
||||
#SERIALPORT=0xec00 #amd
|
||||
#SERIALPORT=0xd010 #16 core test system
|
||||
|
@ -18,6 +18,7 @@ typedef struct _criticalSection
|
||||
int locked;
|
||||
int apicid;
|
||||
int lockcount;
|
||||
|
||||
} criticalSection, *PcriticalSection;
|
||||
|
||||
extern int debugzeromem;
|
||||
|
@ -1026,6 +1026,11 @@ void mrewEndWrite(Pmultireadexclusivewritesychronizer MREW)
|
||||
|
||||
void csEnter(PcriticalSection CS)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (CS->ignorelock)
|
||||
return;
|
||||
#endif
|
||||
|
||||
int apicid=getAPICID()+1; //+1 so it never returns 0
|
||||
|
||||
if ((CS->locked) && (CS->apicid==apicid))
|
||||
@ -1046,6 +1051,11 @@ void csEnter(PcriticalSection CS)
|
||||
|
||||
void csLeave(PcriticalSection CS)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (CS->ignorelock)
|
||||
return;
|
||||
#endif
|
||||
|
||||
int apicid=getAPICID()+1; //+1 so it never returns 0
|
||||
|
||||
|
||||
|
@ -12,11 +12,13 @@
|
||||
#if (defined SERIALPORT) && (SERIALPORT != 0)
|
||||
#define DEBUG //comment for release
|
||||
#define DEBUGINTHANDLER //comment for release
|
||||
#define CHECKAPICID
|
||||
#endif
|
||||
|
||||
#if (DISPLAYDEBUG==1)
|
||||
#define DEBUG
|
||||
#define DEBUGINTHANDLER
|
||||
#define CHECKAPICID
|
||||
#endif
|
||||
|
||||
#define ULTIMAPDEBUG //for debugging ultimap (I seem to have misplaced my serial port...)
|
||||
@ -80,6 +82,9 @@ typedef volatile struct _criticalSection
|
||||
volatile int locked;
|
||||
volatile int apicid;
|
||||
int lockcount;
|
||||
#ifdef DEBUG
|
||||
int ignorelock;
|
||||
#endif
|
||||
} criticalSection, *PcriticalSection;
|
||||
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "vmcall.h"
|
||||
#include "maps.h"
|
||||
#include "list.h"
|
||||
#include "vmeventhandler.h"
|
||||
|
||||
QWORD EPTMapPhysicalMemory(pcpuinfo currentcpuinfo, QWORD physicalAddress, int forcesmallpage);
|
||||
|
||||
|
@ -117,6 +117,11 @@ int cinthandler(unsigned long long *stack, int intnr) //todo: move to it's own s
|
||||
DWORD thisAPICID;
|
||||
int cpunr=0;
|
||||
|
||||
#ifdef DEBUG
|
||||
sendstringCS.ignorelock=1;
|
||||
sendstringfCS.ignorelock=1;
|
||||
#endif
|
||||
|
||||
if (readMSRSafe(IA32_FS_BASE_MSR)==0)
|
||||
{
|
||||
sendstringf("Invalid FS base during exception\n");
|
||||
@ -146,6 +151,18 @@ int cinthandler(unsigned long long *stack, int intnr) //todo: move to it's own s
|
||||
|
||||
thisAPICID=getAPICID();
|
||||
|
||||
#ifdef CHECKAPICID
|
||||
if (thisAPICID!=cpuinfo->apicid)
|
||||
{
|
||||
sendstringCS.ignorelock=1;
|
||||
sendstringfCS.ignorelock=1;
|
||||
sendstringf("Interrupt %d. Invalid cpuinfo", intnr);
|
||||
while(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
sendstringCS.lockcount=0;
|
||||
sendstringCS.locked=0;
|
||||
sendstringfCS.lockcount=0;
|
||||
@ -154,7 +171,7 @@ int cinthandler(unsigned long long *stack, int intnr) //todo: move to it's own s
|
||||
|
||||
// sendstringf("interrupt fired : %d (%x)\n\r", intnr,intnr);
|
||||
|
||||
sendstringf("cpunr=%d\n\r",cpunr);
|
||||
sendstringf("cpunr=%d (apicid=%d)\n\r",cpunr, thisAPICID);
|
||||
sendstringf("intnr=%d\n\r",intnr);
|
||||
sendstringf("rsp=%x\n\r",getRSP());
|
||||
sendstringf("cr2=%6\n\r",getCR2());
|
||||
|
@ -71,7 +71,9 @@ extern ULONG setCR8(UINT64 newcr8);
|
||||
extern void _invlpg(UINT64 address);
|
||||
extern void _invpcid(int type, PINVPCIDDESCRIPTOR datablock);
|
||||
extern void _invept(int type, PINVEPTDESCRIPTOR datablock);
|
||||
extern int _invept2(int type, PINVEPTDESCRIPTOR datablock);
|
||||
extern void _invvpid(int type, PINVVPIDDESCRIPTOR datablock);
|
||||
extern int _invvpid2(int type, PINVVPIDDESCRIPTOR datablock);
|
||||
extern void _wbinvd(void);
|
||||
extern void _invd(void);
|
||||
|
||||
|
@ -4198,7 +4198,9 @@ int handleVMEvent(pcpuinfo currentcpuinfo, VMRegisters *vmregisters, FXSAVE64 *f
|
||||
case 50:
|
||||
{
|
||||
sendstring("INVEPT\n\r");
|
||||
return 1;
|
||||
return handleIntelVMXInstruction(currentcpuinfo, vmregisters);
|
||||
|
||||
//return 1;
|
||||
}
|
||||
|
||||
case 51:
|
||||
@ -4239,12 +4241,20 @@ int handleVMEvent(pcpuinfo currentcpuinfo, VMRegisters *vmregisters, FXSAVE64 *f
|
||||
return 0;
|
||||
}
|
||||
|
||||
case 53:
|
||||
case vm_exit_invvpid:
|
||||
{
|
||||
sendstring("INVVPID\n\r");
|
||||
return handleIntelVMXInstruction(currentcpuinfo, vmregisters);
|
||||
|
||||
#ifdef DEBUG
|
||||
while (1);
|
||||
#endif
|
||||
// return 1;
|
||||
}
|
||||
|
||||
case vm_exit_invpcid:
|
||||
{
|
||||
while(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1481,6 +1481,27 @@ invept rdi,[rsi]
|
||||
ret
|
||||
|
||||
|
||||
global _invept2
|
||||
;---------------------------;
|
||||
;_invept2(int type, 128data); type must be either 1(local for specific ept pointer) or 2(global for all vpids)
|
||||
;---------------------------;
|
||||
_invept2:
|
||||
invept rdi,[rsi]
|
||||
jc _invept2_err1
|
||||
jz _invept2_err2
|
||||
xor rax,rax
|
||||
ret
|
||||
|
||||
_invept2_err1:
|
||||
mov eax,1
|
||||
ret
|
||||
|
||||
_invept2_err2:
|
||||
mov eax,2
|
||||
ret
|
||||
|
||||
|
||||
|
||||
global _invvpid
|
||||
;--------------------------;
|
||||
;_invvpid(int type, 128data); type must be either 0(specific linear address for specific vpid) 1(local for specific vpid) or 2(global for all vpids)
|
||||
@ -1489,6 +1510,26 @@ _invvpid:
|
||||
invvpid rdi,[rsi]
|
||||
ret
|
||||
|
||||
global _invvpid2
|
||||
;----------------------------;
|
||||
;_invvpid2(int type, 128data); type must be either 0(specific linear address for specific vpid) 1(local for specific vpid) or 2(global for all vpids)
|
||||
;----------------------------;
|
||||
_invvpid2:
|
||||
invvpid rdi,[rsi]
|
||||
jc _vmread2_err1
|
||||
jz _vmread2_err2
|
||||
xor rax,rax
|
||||
ret
|
||||
|
||||
_invvpid2_err1:
|
||||
mov eax,1
|
||||
ret
|
||||
|
||||
_invvpid2_err2:
|
||||
mov eax,2
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
global _invlpg
|
||||
|
@ -118,7 +118,7 @@ char * getVMExitReassonString(void)
|
||||
{
|
||||
case 0: return "Exception or NMI";
|
||||
case 1: return "External interrupt";
|
||||
case 2: return "Tripple fault";
|
||||
case 2: return "Triple fault";
|
||||
case 3: return "INIT Signal";
|
||||
case 4: return "Start-up IPI (SIPI)";
|
||||
case 5: return "SMI interrupt";
|
||||
@ -132,8 +132,10 @@ char * getVMExitReassonString(void)
|
||||
case 17: return "VMREAD";
|
||||
case 18: return "VMCALL";
|
||||
case 19: return "VMCLEAR";
|
||||
case 20: return "VMLAUNCH";
|
||||
case 21: return "VMPTRLD";
|
||||
case 23: return "VMREAD";
|
||||
case 24: return "VMRESUME";
|
||||
case 25: return "VMWRITE";
|
||||
case 27: return "VMXON"; //or: omg it's one bee
|
||||
case 28: return "Controlregister access";
|
||||
@ -145,8 +147,10 @@ char * getVMExitReassonString(void)
|
||||
case 37: return "Monitor trap flag";
|
||||
case vm_exit_ept_violation: return "EPT Violation";
|
||||
case vm_exit_ept_misconfiguration: return "EPT Misconfiguration";
|
||||
case 50: return "INVEPT";
|
||||
case 51: return "RDTSCP";
|
||||
case 52: return "Preemption timer";
|
||||
case 53: return "INVVPID";
|
||||
case 55: return "XSETBV";
|
||||
default :return "NYI";
|
||||
}
|
||||
@ -694,6 +698,9 @@ int vmexit_amd(pcpuinfo currentcpuinfo, UINT64 *registers, void *fxsave UNUSED)
|
||||
return result;
|
||||
}
|
||||
|
||||
int lastexits[10];
|
||||
int lastexitsindex=0;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
QWORD lastbeat=0;
|
||||
@ -752,8 +759,7 @@ int vmexit(pcpuinfo currentcpuinfo, UINT64 *registers, void *fxsave)
|
||||
int vmexit2(pcpuinfo currentcpuinfo, UINT64 *registers, void *fxsave)
|
||||
#else
|
||||
|
||||
int lastexits[10];
|
||||
int lastexitsindex=0;
|
||||
|
||||
|
||||
int vmexit(pcpuinfo currentcpuinfo, UINT64 *registers, void *fxsave)
|
||||
#endif
|
||||
@ -768,6 +774,25 @@ int vmexit(pcpuinfo currentcpuinfo, UINT64 *registers, void *fxsave)
|
||||
lastexitsindex++;
|
||||
lastexitsindex=lastexitsindex % 10;
|
||||
|
||||
#ifdef CHECKAPICID
|
||||
if (currentcpuinfo)
|
||||
{
|
||||
if (getAPICID()!=currentcpuinfo->apicid)
|
||||
{
|
||||
sendstring("FUCK\n");
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sendstring("WTFOMG\n");
|
||||
while (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if (dbvm_plugin_exit_pre)
|
||||
{
|
||||
@ -1050,9 +1075,13 @@ int vmexit(pcpuinfo currentcpuinfo, UINT64 *registers, void *fxsave)
|
||||
// skip=0;
|
||||
// break;
|
||||
//
|
||||
case vm_exit_vmlaunch:
|
||||
verbosity=10;
|
||||
skip=0;
|
||||
break;
|
||||
|
||||
case vm_exit_vmresume:
|
||||
//skip=1;
|
||||
skip=currentcpuinfo->cpunr!=0;
|
||||
break;
|
||||
|
||||
case vm_exit_vmcall:
|
||||
@ -1062,7 +1091,11 @@ int vmexit(pcpuinfo currentcpuinfo, UINT64 *registers, void *fxsave)
|
||||
break;
|
||||
|
||||
case vm_exit_vmread:
|
||||
//skip=1;
|
||||
skip=1;
|
||||
break;
|
||||
|
||||
case vm_exit_vmwrite:
|
||||
skip=1;
|
||||
break;
|
||||
|
||||
case vm_exit_vmptrld:
|
||||
@ -1070,10 +1103,15 @@ int vmexit(pcpuinfo currentcpuinfo, UINT64 *registers, void *fxsave)
|
||||
|
||||
break;
|
||||
|
||||
case vm_exit_vmwrite:
|
||||
//skip=1;
|
||||
case vm_exit_invept:
|
||||
skip=1;
|
||||
break;
|
||||
|
||||
case vm_exit_invvpid:
|
||||
skip=1;
|
||||
break;
|
||||
|
||||
|
||||
case vm_exit_cpuid:
|
||||
skip=2; //REALLY verbose
|
||||
break;
|
||||
@ -1177,6 +1215,7 @@ int vmexit(pcpuinfo currentcpuinfo, UINT64 *registers, void *fxsave)
|
||||
VMRegisters* r=(VMRegisters*)registers;
|
||||
switch (r->rcx)
|
||||
{
|
||||
case 0x10:
|
||||
case 0x176:
|
||||
case 0x175:
|
||||
case 0x174:
|
||||
@ -1195,6 +1234,7 @@ int vmexit(pcpuinfo currentcpuinfo, UINT64 *registers, void *fxsave)
|
||||
VMRegisters* r=(VMRegisters*)registers;
|
||||
switch (r->rcx)
|
||||
{
|
||||
case 0x10:
|
||||
case 0x3a:
|
||||
case 0xc0000080:
|
||||
skip=1;
|
||||
@ -1209,6 +1249,10 @@ int vmexit(pcpuinfo currentcpuinfo, UINT64 *registers, void *fxsave)
|
||||
skip=1;
|
||||
break;
|
||||
|
||||
case vm_exit_rdtsc:
|
||||
skip=1;
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case vm_exit_invalid_guest_state:
|
||||
|
@ -573,6 +573,7 @@ typedef volatile struct tcpuinfo
|
||||
|
||||
int currenterrorcode; //if not 0, return this errorcode on vmread
|
||||
vmxhoststate originalhoststate;
|
||||
vmxhoststate dbvmhoststate;
|
||||
int runningvmx; //1 if the previous call was a vmlaunch/vmresume and no vmexit happened yet
|
||||
|
||||
} vmxdata;
|
||||
|
@ -79,7 +79,9 @@
|
||||
#define vm_exit_taskswitch 9
|
||||
#define vm_exit_cpuid 10
|
||||
#define vm_exit_invlpg 14
|
||||
#define vm_exit_rdtsc 16
|
||||
#define vm_exit_vmcall 18
|
||||
#define vm_exit_vmlaunch 20
|
||||
#define vm_exit_vmptrld 21
|
||||
#define vm_exit_vmread 23
|
||||
#define vm_exit_vmresume 24
|
||||
@ -91,8 +93,11 @@
|
||||
#define vm_exit_monitor_trap_flag 37
|
||||
#define vm_exit_ept_violation 48
|
||||
#define vm_exit_ept_misconfiguration 49
|
||||
#define vm_exit_invept 50
|
||||
#define vm_exit_vmx_preemptiontimer_reachedzero 52
|
||||
#define vm_exit_invvpid 53
|
||||
#define vm_exit_xsetbv 55
|
||||
#define vm_exit_invpcid 58
|
||||
#define vm_exit_invalid_guest_state 0x80000021
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
int emulatevmx=1;
|
||||
|
||||
vmxhoststate *dbvm_originalhoststate;
|
||||
//todo: vmcs link pointer implementation
|
||||
|
||||
|
||||
void setHostState(vmxhoststate *hoststate)
|
||||
@ -585,6 +585,174 @@ int handle_vmresume(pcpuinfo currentcpuinfo, VMRegisters *vmregisters UNUSED)
|
||||
return 0xce01; //launch with the last entrystate and do a resume
|
||||
}
|
||||
|
||||
int handle_invept(pcpuinfo currentcpuinfo, VMRegisters *vmregisters)
|
||||
{
|
||||
int vmcsinvepterror=0;
|
||||
int vmcsinvepterrorcode=0;
|
||||
|
||||
sendstringf("handle_invept\n");
|
||||
if (currentcpuinfo->vmxdata.insideVMXRootMode==0)
|
||||
return raiseInvalidOpcodeException(currentcpuinfo);
|
||||
|
||||
instruction_info_vm ii;
|
||||
ii.instructioninfo=vmread(vm_instruction_information); //e.g: 7361d130 for invept rdi,[rsi]
|
||||
/* 0111 0 0110 1 1000 011 1010 0 010 0110 0 00
|
||||
*
|
||||
* scaling=00 (0)
|
||||
* reserved=0 (0)
|
||||
* reg1=0110 (6)
|
||||
* addresSize=010 (2)
|
||||
* usesreg = 0 (0)
|
||||
* undefined =1010
|
||||
* segmentreg: 011 (3)
|
||||
* indexreg: 1000 (10)
|
||||
* indexreginvalid: 1
|
||||
* basereg: 0110 (6)
|
||||
* basereginvalid: 0
|
||||
* reg2: 0111 (7)
|
||||
*
|
||||
*reg1=rsi
|
||||
*basereg=rsi
|
||||
*reg2=rdi
|
||||
*/
|
||||
int invepttype=regToVal(ii.reg2, vmregisters);
|
||||
QWORD inveptdataaddress=getDestinationAddressFromInstructionInfo(vmregisters);
|
||||
|
||||
//read the pointerinfo
|
||||
int error;
|
||||
QWORD pagefault;
|
||||
|
||||
sendstringf("invept: Type=%d data=%6\n", invepttype, inveptdataaddress);
|
||||
|
||||
|
||||
PINVEPTDESCRIPTOR inveptdescriptor=mapVMmemory(currentcpuinfo, inveptdataaddress, 16, &error, &pagefault);
|
||||
if (error==2)
|
||||
return raisePagefault(currentcpuinfo, pagefault);
|
||||
|
||||
|
||||
|
||||
|
||||
if (vmptrld(currentcpuinfo->vmxdata.guest_activeVMCS))
|
||||
{
|
||||
sendstringf("Failure to load guest active vmcs state");
|
||||
VMfailInvalid();
|
||||
unmapVMmemory(inveptdescriptor, 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//do the invept instruction
|
||||
|
||||
vmcsinvepterror=_invept2(invepttype, inveptdescriptor);
|
||||
if (vmcsinvepterror==2) //error happened and it had an errorcode
|
||||
vmcsinvepterrorcode=vmread(vm_errorcode);
|
||||
|
||||
//back to the original state
|
||||
vmptrld(currentcpuinfo->vmcs_regionPA);
|
||||
|
||||
unmapVMmemory(inveptdescriptor, 16);
|
||||
|
||||
vmwrite(vm_guest_rip,vmread(vm_guest_rip)+vmread(vm_exit_instructionlength));
|
||||
|
||||
if (vmcsinvepterror)
|
||||
{
|
||||
if (vmcsinvepterror==1)
|
||||
VMfailInvalid();
|
||||
else
|
||||
VMfailValid(currentcpuinfo, vmcsinvepterrorcode);
|
||||
}
|
||||
else
|
||||
vmsucceed();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle_invvpid(pcpuinfo currentcpuinfo, VMRegisters *vmregisters)
|
||||
{
|
||||
int vmcsinvvpiderror=0;
|
||||
int vmcsinvvpiderrorcode=0;
|
||||
|
||||
sendstringf("handle_invept\n");
|
||||
if (currentcpuinfo->vmxdata.insideVMXRootMode==0)
|
||||
return raiseInvalidOpcodeException(currentcpuinfo);
|
||||
|
||||
instruction_info_vm ii;
|
||||
ii.instructioninfo=vmread(vm_instruction_information); //e.g: 7361d130 for invept rdi,[rsi]
|
||||
/* 0111 0 0110 1 1000 011 1010 0 010 0110 0 00
|
||||
*
|
||||
* scaling=00 (0)
|
||||
* reserved=0 (0)
|
||||
* reg1=0110 (6)
|
||||
* addresSize=010 (2)
|
||||
* usesreg = 0 (0)
|
||||
* undefined =1010
|
||||
* segmentreg: 011 (3)
|
||||
* indexreg: 1000 (10)
|
||||
* indexreginvalid: 1
|
||||
* basereg: 0110 (6)
|
||||
* basereginvalid: 0
|
||||
* reg2: 0111 (7)
|
||||
*
|
||||
*reg1=rsi
|
||||
*basereg=rsi
|
||||
*reg2=rdi
|
||||
*/
|
||||
int invvpidtype=regToVal(ii.reg2, vmregisters);
|
||||
QWORD invvpiddataaddress=getDestinationAddressFromInstructionInfo(vmregisters);
|
||||
|
||||
//read the pointerinfo
|
||||
int error;
|
||||
QWORD pagefault;
|
||||
|
||||
sendstringf("invvpid: Type=%d data=%6\n", invvpidtype, invvpiddataaddress);
|
||||
|
||||
|
||||
PINVVPIDDESCRIPTOR invvpiddescriptor=mapVMmemory(currentcpuinfo, invvpiddataaddress, 16, &error, &pagefault);
|
||||
if (error==2)
|
||||
return raisePagefault(currentcpuinfo, pagefault);
|
||||
|
||||
|
||||
|
||||
|
||||
if (vmptrld(currentcpuinfo->vmxdata.guest_activeVMCS))
|
||||
{
|
||||
sendstringf("Failure to load guest active vmcs state");
|
||||
VMfailInvalid();
|
||||
unmapVMmemory(invvpiddescriptor, 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//do the invept instruction
|
||||
|
||||
vmcsinvvpiderror=_invvpid2(invvpidtype, invvpiddescriptor);
|
||||
if (vmcsinvvpiderror==2) //error happened and it had an errorcode
|
||||
vmcsinvvpiderrorcode=vmread(vm_errorcode);
|
||||
|
||||
//back to the original state
|
||||
vmptrld(currentcpuinfo->vmcs_regionPA);
|
||||
|
||||
unmapVMmemory(invvpiddescriptor, 16);
|
||||
|
||||
vmwrite(vm_guest_rip,vmread(vm_guest_rip)+vmread(vm_exit_instructionlength));
|
||||
|
||||
if (vmcsinvvpiderror)
|
||||
{
|
||||
sendstringf("invept error");
|
||||
if (vmcsinvvpiderrorcode==1)
|
||||
VMfailInvalid();
|
||||
else
|
||||
{
|
||||
VMfailValid(currentcpuinfo, vmcsinvvpiderrorcode);
|
||||
sendstringf("%d", vmcsinvvpiderrorcode);
|
||||
}
|
||||
|
||||
sendstring("\n");
|
||||
}
|
||||
else
|
||||
vmsucceed();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int handle_vmread(pcpuinfo currentcpuinfo, VMRegisters *vmregisters)
|
||||
@ -953,14 +1121,8 @@ int handle_vmptrld(pcpuinfo currentcpuinfo, VMRegisters *vmregisters)
|
||||
unmapVMmemory(mapped, 8);
|
||||
|
||||
|
||||
if (dbvm_originalhoststate==NULL) //one time init
|
||||
{
|
||||
sendstring("generating dbvm_originalhoststate\n");
|
||||
dbvm_originalhoststate=malloc2(sizeof(vmxhoststate)); //no free ever
|
||||
getHostState(dbvm_originalhoststate);
|
||||
|
||||
sendstringf("CR3=%6\n", dbvm_originalhoststate->CR3);
|
||||
}
|
||||
if (currentcpuinfo->vmxdata.dbvmhoststate.FS_BASE==0) //only needs one time init
|
||||
getHostState((vmxhoststate *)¤tcpuinfo->vmxdata.dbvmhoststate);
|
||||
|
||||
vmwrite(vm_guest_rip,vmread(vm_guest_rip)+vmread(vm_exit_instructionlength));
|
||||
|
||||
@ -987,8 +1149,9 @@ int handle_vmptrld(pcpuinfo currentcpuinfo, VMRegisters *vmregisters)
|
||||
else
|
||||
{
|
||||
sendstringf("restore: vmptrld failed: %d (error=%d)\n", vmread(vm_errorcode));
|
||||
VMfailInvalid();
|
||||
return 0;
|
||||
//VMfailInvalid();
|
||||
//return 0;
|
||||
//it's a load, the old state could have been deleted
|
||||
}
|
||||
}
|
||||
|
||||
@ -1032,8 +1195,9 @@ int handle_vmptrld(pcpuinfo currentcpuinfo, VMRegisters *vmregisters)
|
||||
|
||||
//change the hoststate so it exits on dbvm
|
||||
sendstring("Editing the guest vmcs state so it exits on this host\n");
|
||||
setHostState(dbvm_originalhoststate);
|
||||
setHostState((vmxhoststate *)¤tcpuinfo->vmxdata.dbvmhoststate);
|
||||
|
||||
//debug code, can go
|
||||
vmxhoststate debugstate;
|
||||
getHostState(&debugstate);
|
||||
|
||||
@ -1143,49 +1307,70 @@ int handle_vmxoff(pcpuinfo currentcpuinfo, VMRegisters *vmregisters UNUSED)
|
||||
|
||||
|
||||
|
||||
|
||||
int handleIntelVMXInstruction(pcpuinfo currentcpuinfo, VMRegisters *vmregisters)
|
||||
{
|
||||
|
||||
int r;
|
||||
sendstringf("handleIntelVMXInstruction. emulatevmx=%d\n", emulatevmx);
|
||||
if (emulatevmx==0)
|
||||
return raiseInvalidOpcodeException(currentcpuinfo);
|
||||
else
|
||||
{
|
||||
//try to handle it
|
||||
|
||||
int exit_reason=currentcpuinfo->guest_error?currentcpuinfo->guest_error:vmread(vm_exit_reason) & 0x7fffffff;
|
||||
currentcpuinfo->guest_error=0;
|
||||
currentcpuinfo->vmxdata.currenterrorcode=0;
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
switch (exit_reason)
|
||||
{
|
||||
/*
|
||||
19 VMCLEAR. Guest software attempted to execute VMCLEAR.
|
||||
20 VMLAUNCH. Guest software attempted to execute VMLAUNCH.
|
||||
21 VMPTRLD. Guest software attempted to execute VMPTRLD.
|
||||
22 VMPTRST. Guest software attempted to execute VMPTRST.
|
||||
23 VMREAD. Guest software attempted to execute VMREAD.
|
||||
24 VMRESUME. Guest software attempted to execute VMRESUME.
|
||||
25 VMWRITE. Guest software attempted to execute VMWRITE.
|
||||
26 VMXOFF. Guest software attempted to execute VMXOFF.
|
||||
27 VMXON. Guest software attempted to execute VMXON.
|
||||
19 VMCLEAR. Guest software attempted to execute VMCLEAR.
|
||||
20 VMLAUNCH. Guest software attempted to execute VMLAUNCH.
|
||||
21 VMPTRLD. Guest software attempted to execute VMPTRLD.
|
||||
22 VMPTRST. Guest software attempted to execute VMPTRST.
|
||||
23 VMREAD. Guest software attempted to execute VMREAD.
|
||||
24 VMRESUME. Guest software attempted to execute VMRESUME.
|
||||
25 VMWRITE. Guest software attempted to execute VMWRITE.
|
||||
26 VMXOFF. Guest software attempted to execute VMXOFF.
|
||||
27 VMXON. Guest software attempted to execute VMXON.
|
||||
*/
|
||||
case 19: return handle_vmclear(currentcpuinfo, vmregisters);
|
||||
case 20: return handle_vmlaunch(currentcpuinfo, vmregisters);
|
||||
case 0xce00: return handle_vmlaunchFail(currentcpuinfo);
|
||||
case 21: return handle_vmptrld(currentcpuinfo, vmregisters);
|
||||
case 22: return handle_vmptrst(currentcpuinfo, vmregisters);
|
||||
case 23: return handle_vmread(currentcpuinfo, vmregisters);
|
||||
case 24: return handle_vmresume(currentcpuinfo, vmregisters);
|
||||
case 0xce01: return handle_vmresumeFail(currentcpuinfo);
|
||||
case 25: return handle_vmwrite(currentcpuinfo, vmregisters);
|
||||
case 26: return handle_vmxoff(currentcpuinfo, vmregisters);
|
||||
case 27: return handle_vmxon(currentcpuinfo, vmregisters);
|
||||
case 19: r=handle_vmclear(currentcpuinfo, vmregisters); break;
|
||||
case 20: r=handle_vmlaunch(currentcpuinfo, vmregisters); break;
|
||||
case 0xce00: r=handle_vmlaunchFail(currentcpuinfo); break;
|
||||
case 21: r=handle_vmptrld(currentcpuinfo, vmregisters); break;
|
||||
case 22: r=handle_vmptrst(currentcpuinfo, vmregisters); break;
|
||||
case 23: r=handle_vmread(currentcpuinfo, vmregisters); break;
|
||||
case 24: r=handle_vmresume(currentcpuinfo, vmregisters); break;
|
||||
case 0xce01: r=handle_vmresumeFail(currentcpuinfo); break;
|
||||
case 25: r=handle_vmwrite(currentcpuinfo, vmregisters); break;
|
||||
case 26: r=handle_vmxoff(currentcpuinfo, vmregisters); break;
|
||||
case 27: r=handle_vmxon(currentcpuinfo, vmregisters); break;
|
||||
case vm_exit_invept: r=handle_invept(currentcpuinfo, vmregisters); break;
|
||||
case vm_exit_invvpid: r=handle_invvpid(currentcpuinfo, vmregisters); break;
|
||||
default:
|
||||
{
|
||||
sendstringf("vmxemu.c: Invalid exit_reason: %d\n", exit_reason);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
except
|
||||
{
|
||||
int err=lastexception;
|
||||
|
||||
sendstringf("Something shitty happened when emulating VMX (%6: %d)\n", ExceptionRIP, err);
|
||||
|
||||
while (1);
|
||||
}
|
||||
tryend
|
||||
|
||||
return r;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,9 @@ typedef struct _instruction_info_vm
|
||||
struct {
|
||||
unsigned scaling :2; //0-1 scaling
|
||||
unsigned reserved1 :1; //2
|
||||
unsigned reg1 :4; //3-6
|
||||
unsigned reg1 :4; //3-6 //invalid for INVEPT, INVPCID, and INVVPID
|
||||
unsigned addressSize:3; //7-9
|
||||
unsigned usesreg :1; //10
|
||||
unsigned usesreg :1; //10 //0 for INVEPT, INVPCID, and INVVPID
|
||||
unsigned undefined :4; //11-14
|
||||
unsigned segmentReg :3; //15-17
|
||||
unsigned indexReg :4; //18-21
|
||||
|
Loading…
Reference in New Issue
Block a user