基本信息
源码名称:vt开发源码
源码大小:0.53M
文件格式:.rar
开发语言:C/C++
更新时间:2015-07-04
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300

本次赞助数额为: 2 元 
   源码介绍

extern "C"
{
#include <ntddk.h>
}




#include "ntiologc.h"
#include <windef.h>
#include <stdio.h>
#include <string.h>
#include "stdarg.h"
#include "ntimage.h"
#include "ntiologc.h"
#include <windef.h>
#include "jeinSysBase.H"
//////////////////////////////////////////////////////////////////////////
#define SEC_IMAGE 0x01000000
//////////////////////////////////////////////////////////////////////////
#define IOCTL_EVENT_MSG   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x927, METHOD_BUFFERED , FILE_ANY_ACCESS)
#pragma warning(disable: 4047 4018)
#ifdef __cplusplus
extern "C"
#endif

char buf_gmifo[]= {0xBB,0xB6,0xD3,0xAD,0xBC,0xBC,0xCA,0xF5,0xBD,0xBB,0xC1,0xF7,0x20,0xCE,0xD2,0xB5, 0xC4,0x51,0x51,0x20,};

void ShowInfo()
{
    DbgPrint("代码无卸载部分,驱动加载前请要保存好文档! \n");
    DbgPrint("只支持单核测试,请在boot.ini中添加  /numproc=1  \n");
    DbgPrint("%s %d\n\n",buf_gmifo,HOST_QQ_GM);
}



//////////////////////////////////////////////////////////////////////////

#pragma pack(1)
typedef struct
{
    unsigned short LowOffset;
    unsigned short selector;
    unsigned char unused_lo;
    unsigned char segment_type:4;	//0x0E is an interrupt gate
    unsigned char system_segment_flag:1;
    unsigned char DPL:2;	// descriptor privilege level
    unsigned char P:1; /* present */
    unsigned short HiOffset;
} IDTENTRY;

/* sidt returns idt in this format */
typedef struct
{
    unsigned short IDTLimit;
    unsigned short LowIDTbase;
    unsigned short HiIDTbase;
} IDTINFO;
#define IDT_INFO IDTINFO
#define IDT_ENTRY IDTENTRY
#pragma pack()

//////////////////////////////////////////////////////////////////////////

VOID	  UnloadDriver(IN PDRIVER_OBJECT DriverObject);
NTSTATUS  DCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS  Dclose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS  HideProcess_IoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS JeinIOControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp);
//////////////////////////////////////////////////////////////////////////
#define		HIDE_PROCESS_WIN32_DEV_NAME    L"\\Device\\VT"
#define		HIDE_PROCESS_DEV_NAME	       L"\\DosDevices\\VT"

#define FILE_DEVICE_EXTNDDRV  0x00008300
#define EXTNDDRV_IOCTL_INDEX  0x830
#define IOCTL_EXTNDDRV_GET_STARTING_SERVICEID      CTL_CODE(FILE_DEVICE_EXTNDDRV,  \
	EXTNDDRV_IOCTL_INDEX,  \
	METHOD_BUFFERED,       \
FILE_ANY_ACCESS)


UNICODE_STRING DeviceNameString;
UNICODE_STRING LinkDeviceNameString;
CCHAR     outBuf[1024];
int * PRecvinteger;
//////////////////////////////////////////////////////////////////////////


NTSTATUS DCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{

    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return Irp->IoStatus.Status;
}

NTSTATUS Dclose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{

    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return Irp->IoStatus.Status;
}


VOID UnloadDriver(IN PDRIVER_OBJECT DriverObject)
{

    DbgPrint("UnloadDriver ! ");
    PDEVICE_OBJECT deviceObject;
    deviceObject= DriverObject->DeviceObject;
    IoDeleteSymbolicLink(&LinkDeviceNameString);
    ASSERT(!deviceObject->AttachedDevice);
    if (deviceObject != NULL )
    {
        IoDeleteDevice( deviceObject );
    }
}

NTSTATUS JeinIOControl(IN PDEVICE_OBJECT pDevObj,
                       IN PIRP pIrp)
{
    NTSTATUS status = STATUS_SUCCESS;
    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
    ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
    ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
    ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
    ULONG info = 0;

    pIrp->IoStatus.Status = status;
    pIrp->IoStatus.Information = info;	// bytes xfered
    IoCompleteRequest( pIrp, IO_NO_INCREMENT );
    return status;
}


#define Log( message, value ) { DbgPrint("[vmm] %-40s [%08X]\n", message, value ); }

///////////////
//           //
//  SET BIT  //
//           //
///////////////
VOID SetBit( ULONG * dword, ULONG bit )
{
    ULONG mask = ( 1 << bit );
    *dword = *dword | mask;
}
VOID ClearBit( ULONG * dword, ULONG bit )
{
    ULONG mask = 0xFFFFFFFF;
    ULONG sub = ( 1 << bit );
    mask = mask - sub;
    *dword = *dword & mask;
}

VOID ClearBit( VOID * dword_, ULONG bit )
{
    ULONG mask = 0xFFFFFFFF;
    ULONG sub = ( 1 << bit );
    mask = mask - sub;
    ULONG * dword = (ULONG*)dword_;
    *dword = *dword & mask;
}



ULONG			*pVMXONRegion		= NULL;		// Memory address of VMXON region.
ULONG			*pVMCSRegion		= NULL;		// Memory address of VMCS region.
ULONG			VMXONRegionSize		= 0;		// Size of of VMXON region.
ULONG			VMCSRegionSize		= 0;		// Size of of VMCS region.
ULONG			ErrorCode			= 0;

EFLAGS			eFlags				= {0};
MSR				msr					= {0};
PVOID			FakeStack				= NULL;

ULONG			HandlerLogging		= 0;
ULONG			ScrubTheLaunch		= 0;
ULONG			VMXIsActive			= 0;


VOID WriteVMCS( ULONG encoding, ULONG value )
{
    __asm
    {
        PUSHAD

        PUSH	value
        MOV		EAX, encoding

        _emit	0x0F				// VMWRITE EAX, [ESP]
        _emit	0x79
        _emit	0x04
        _emit	0x24

        POP EAX

        POPAD
    }
}

DWORD VmxRead(DWORD in_code)
{
    DWORD m_vmread = 0;
    __asm
    {
        PUSHAD

        MOV		EAX, in_code			//ExitInterruptionInformation

        _emit	0x0F	// VMREAD  EBX, EAX
        _emit	0x78
        _emit	0xC3

        MOV		m_vmread, EBX
        POPAD
    }
    return m_vmread;
}



//	Loads the contents of a 64-bit model specific register (MSR) specified
//	in the ECX register into registers EDX:EAX. The EDX register is loaded
//	with the high-order 32 bits of the MSR and the EAX register is loaded
//	with the low-order 32 bits.
//		msr.Hi --> EDX
//		msr.Lo --> EAX
//
VOID ReadMSR( ULONG msrEncoding )
{
    __asm
    {
        PUSHAD

        MOV		ECX, msrEncoding

        RDMSR

        MOV		msr.Hi, EDX
        MOV		msr.Lo, EAX

        POPAD
    }
}


////////////////////////////////////
//                                //
//  SEGMENT DESCRIPTOR OPERATORS  //
//                                //
////////////////////////////////////
ULONG GetSegmentDescriptorBase( ULONG gdt_base , USHORT seg_selector )
{
    ULONG			base = 0;
    SEG_DESCRIPTOR	segDescriptor = {0};

    RtlCopyBytes( &segDescriptor, (ULONG *)(gdt_base   (seg_selector >> 3) * 8), 8 );
    base = segDescriptor.BaseHi;
    base <<= 8;
    base |= segDescriptor.BaseMid;
    base <<= 16;
    base |= segDescriptor.BaseLo;

    return base;
}

ULONG GetSegmentDescriptorDPL( ULONG gdt_base , USHORT seg_selector )
{
    SEG_DESCRIPTOR	segDescriptor = {0};

    RtlCopyBytes( &segDescriptor, (ULONG *)(gdt_base   (seg_selector >> 3) * 8), 8 );

    return segDescriptor.DPL;
}

ULONG GetSegmentDescriptorLimit( ULONG gdt_base , USHORT seg_selector )
{
    SEG_DESCRIPTOR	segDescriptor = {0};
    RtlCopyBytes( &segDescriptor, (ULONG *)(gdt_base   (seg_selector >> 3) * 8), 8 );
    return ( (segDescriptor.LimitHi << 16) | segDescriptor.LimitLo );
}


PHYSICAL_ADDRESS			PhysicalVMXONRegionPtr;
PHYSICAL_ADDRESS			PhysicalVMCSRegionPtr;

VMX_FEATURES				vmxFeatures;
IA32_VMX_BASIC_MSR			vmxBasicMsr ;
IA32_FEATURE_CONTROL_MSR	vmxFeatureControl ;

CR0_REG						cr0_reg = {0};
CR4_REG						cr4_reg = {0};

ULONG						temp32 = 0;
USHORT						temp16 = 0;

GDTR						gdt_reg = {0};
IDTR						idt_reg = {0};

ULONG						gdt_base = 0;
ULONG						idt_base = 0;

USHORT						mLDT = 0;
USHORT						seg_selector = 0;

SEG_DESCRIPTOR				segDescriptor = {0};
MISC_DATA					misc_data = {0};

PVOID						GuestReturn = NULL;
ULONG						GuestStack = 0;


NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{

    NTSTATUS status;
    PDEVICE_OBJECT   deviceObject;
    RtlInitUnicodeString( &DeviceNameString,    HIDE_PROCESS_WIN32_DEV_NAME );
    RtlInitUnicodeString( &LinkDeviceNameString,HIDE_PROCESS_DEV_NAME );

    DbgPrint("--------------------------------- Intel VT ---------------------\n ");
    status = IoCreateDevice(
                 DriverObject,
                 0,
                 &DeviceNameString,
                 FILE_DEVICE_DISK_FILE_SYSTEM,
                 FILE_DEVICE_SECURE_OPEN,
                 FALSE,
                 & deviceObject );

    if (!NT_SUCCESS( status ))
    {

        DbgPrint("Error creating control device object");
        return status;
    }

    status = IoCreateSymbolicLink(
                 (PUNICODE_STRING) &LinkDeviceNameString,
                 (PUNICODE_STRING) &DeviceNameString
             );

    if (!NT_SUCCESS(status))
    {

        IoDeleteDevice(deviceObject);
        return status;
    }
    ShowInfo();

    DriverObject->MajorFunction[IRP_MJ_CREATE] = DCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = Dclose;

    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = JeinIOControl;
    DriverObject->DriverUnload = UnloadDriver;
    //////////////////////////////////////////////////////////////////////////


    ULONG		EntryEFlags = 0;
    ULONG		cr4 = 0;
    ULONG		EntryEAX = 0;
    ULONG		EntryECX = 0;
    ULONG		EntryEDX = 0;
    ULONG		EntryEBX = 0;
    ULONG		EntryESP = 0;
    ULONG		EntryEBP = 0;
    ULONG		EntryESI = 0;
    ULONG		EntryEDI = 0;

    __asm
    {
        PUSHAD

        MOV		EAX, 1
        CPUID

        // ECX contains the VMX_FEATURES FLAGS (VMX supported if bit 5 equals 1)
        MOV		vmxFeatures, ECX

        MOV		EAX, 0x80000008
        CPUID
        MOV		temp32, EAX

        POPAD
    }
    if( vmxFeatures.VMX == 0 )
    {
        Log( "CPU不支持!" , vmxFeatures );
        return STATUS_UNSUCCESSFUL;
    }
    else
    {
        Log( "CPU支持VT!" , vmxFeatures );
    }
    //////////////////////////////////////////////////////////////////////////
    __asm
    {
        PUSH	EAX

        _emit	0x0F	// MOV	EAX, CR4
        _emit	0x20
        _emit	0xE0

        MOV		cr4, EAX

        POP		EAX
    }

    //////////////////////////////////////////////////////////////////////////

    pVMXONRegion = (ULONG*)MmAllocateNonCachedMemory( 4096 );
    if( pVMXONRegion == NULL )
    {
        Log( "ERROR : Allocating VMXON Region memory." , 0 );
        return STATUS_UNSUCCESSFUL;
    }
    Log( "VMXONRegion virtual address" , pVMXONRegion );
    RtlZeroMemory( pVMXONRegion, 4096 );
    PhysicalVMXONRegionPtr = MmGetPhysicalAddress( pVMXONRegion );
    Log( "VMXONRegion physical address" , PhysicalVMXONRegionPtr.LowPart );

    //	Allocate the VMCS region memory.
    //
    pVMCSRegion = (ULONG*)MmAllocateNonCachedMemory( 4096 );
    if( pVMCSRegion == NULL )
    {
        Log( "ERROR : Allocating VMCS Region memory." , 0 );
        MmFreeNonCachedMemory( pVMXONRegion , 4096 );
        return STATUS_UNSUCCESSFUL;
    }
    Log( "VMCSRegion virtual address" , pVMCSRegion );
    RtlZeroMemory( pVMCSRegion, 4096 );
    PhysicalVMCSRegionPtr = MmGetPhysicalAddress( pVMCSRegion );
    Log( "VMCSRegion physical address" , PhysicalVMCSRegionPtr.LowPart );

    //	Allocate stack for the VM Exit Handler.
    //
    FakeStack = ExAllocatePoolWithTag( NonPagedPool , 0x2000, 'vmcs' );
    if( FakeStack == NULL )
    {
        Log( "ERROR : Allocating VM Exit Handler stack memory." , 0 );
        MmFreeNonCachedMemory( pVMXONRegion , 4096 );
        MmFreeNonCachedMemory( pVMCSRegion , 4096 );
        return STATUS_UNSUCCESSFUL;
    }
    Log( "FakeStack" , FakeStack );

    //////////////////////////////////////////////////////////////////////////
    __asm
    {
        CLI
        MOV		GuestStack, ESP
    }

    //	Save the state of the architecture.
    //
    __asm
    {
        PUSHAD
        POP		EntryEDI
        POP		EntryESI
        POP		EntryEBP
        POP		EntryESP
        POP		EntryEBX
        POP		EntryEDX
        POP		EntryECX
        POP		EntryEAX
        PUSHFD
        POP		EntryEFlags
    }
    //////////////////////////////////////////////////////////////////////////
    DbgPrint("StartVMX() == %08X " , StartVMX );
    //启动
    StartVMX( );

    //	Restore the state of the architecture.
    //
    __asm
    {
        PUSH	EntryEFlags
        POPFD
        PUSH	EntryEAX
        PUSH	EntryECX
        PUSH	EntryEDX
        PUSH	EntryEBX
        PUSH	EntryESP
        PUSH	EntryEBP
        PUSH	EntryESI
        PUSH	EntryEDI
        POPAD
    }

    __asm
    {
        STI
        MOV		ESP, GuestStack
    }



    if( ScrubTheLaunch == 1 )
    {
        Log( "ERROR : Launch aborted." , 0 );
        MmFreeNonCachedMemory( pVMXONRegion , 4096 );
        MmFreeNonCachedMemory( pVMCSRegion , 4096 );
        //堆栈
        ExFreePoolWithTag( FakeStack, 'vmcs' );
        return STATUS_UNSUCCESSFUL;
    }

    Log( "VM is now executing." , 0 );
    return STATUS_SUCCESS;

}
__declspec( naked ) VOID StartVMX( )
{
    //
    //	Get the Guest Return EIP.
    //
    //
    //	Hi	|			|
    //		 ----------- 
    //		|	 EIP	|
    //		 -----------  <--	ESP after the CALL
    //	Lo	|			|
    //
    //

    __asm	POP	GuestReturn

    Log("Guest Return EIP" , GuestReturn );

    ///////////////////////////
    //                       //
    //	SET THREAD AFFINITY  //
    //                       //
    ///////////////////////////
    //	Log( "Enabling VMX mode on CPU 0", 0 );
    //	KeSetSystemAffinityThread( (KAFFINITY) 0x00000001 );
    //	Log( "Running on Processor" , KeGetCurrentProcessorNumber() );

    ////////////////
    //            //
    //  GDT Info  //
    //            //
    ////////////////
    __asm
    {
        SGDT	gdt_reg
    }

    temp32 = 0;
    temp32 = gdt_reg.BaseHi;
    temp32 <<= 16;
    temp32 |= gdt_reg.BaseLo;
    gdt_base = temp32;
    Log( "GDT Base", gdt_base );
    Log( "GDT Limit", gdt_reg.Limit );

    ////////////////////////////
    //                        //
    //  IDT Segment Selector  //
    //                        //
    ////////////////////////////
    __asm	SIDT	idt_reg

    temp32 = 0;
    temp32 = idt_reg.BaseHi;
    temp32 <<= 16;
    temp32 |= idt_reg.BaseLo;
    idt_base = temp32;
    /*
    [vmm] GDT Base                                 [8003F000]
    [vmm] GDT Limit                                [000003FF]
    [vmm] IDT Base                                 [8003F400]

    */

    Log( "IDT Base", idt_base );
    Log( "IDT Limit", idt_reg.Limit );

    //	(1)	Check VMX support in processor using CPUID.
    __asm
    {
        PUSHAD

        MOV		EAX, 1
        CPUID

        // ECX contains the VMX_FEATURES FLAGS (VMX supported if bit 5 equals 1)
        MOV		vmxFeatures, ECX

        MOV		EAX, 0x80000008
        CPUID
        MOV		temp32, EAX

        POPAD
    }

    if( vmxFeatures.VMX == 0 )
    {
        Log( "VMX Support Not Present." , vmxFeatures );
        goto Abort;
    }

    Log( "VMX Support Present." , vmxFeatures );

    //	(2)	Determine the VMX capabilities supported by the processor through
    //		the VMX capability MSRs.
    __asm
    {
        PUSHAD

        MOV		ECX, IA32_VMX_BASIC_MSR_CODE
        RDMSR
        LEA		EBX, vmxBasicMsr
        MOV		[EBX 4], EDX
        MOV		[EBX], EAX

        MOV		ECX, IA32_FEATURE_CONTROL_CODE
        RDMSR
        LEA		EBX, vmxFeatureControl
        MOV		[EBX 4], EDX
        MOV		[EBX], EAX

        POPAD
    };

    //	(3)	Create a VMXON region in non-pageable memory of a size specified by
    //		IA32_VMX_BASIC_MSR and aligned to a 4-byte boundary. The VMXON region
    //		must be hosted in cache-coherent memory.
    Log( "VMXON Region Size" , vmxBasicMsr.szVmxOnRegion ) ;
    Log( "VMXON Access Width Bit" , vmxBasicMsr.PhyAddrWidth );
    Log( "      [   1] --> 32-bit" , 0 );
    Log( "      [   0] --> 64-bit" , 0 );
    Log( "VMXON Memory Type", vmxBasicMsr.MemType );
    Log( "      [   0]  --> Strong Uncacheable" , 0 );
    Log( "      [ 1-5]  --> Unused" , 0 );
    Log( "      [   6]  --> Write Back" , 0 );
    Log( "      [7-15]  --> Unused" , 0 );

    VMXONRegionSize = vmxBasicMsr.szVmxOnRegion;

    switch( vmxBasicMsr.MemType )
    {
    case 0:
        Log( "Unsupported memory type." , vmxBasicMsr.MemType );
        goto Abort;
        break;
    case 6:
        break;
    default:
        Log( "ERROR : Unknown VMXON Region memory type." , 0);
        goto Abort;
        break;
    }

    //	(4)	Initialize the version identifier in the VMXON region (first 32 bits)
    //		with the VMCS revision identifier reported by capability MSRs.
    *(pVMXONRegion) = vmxBasicMsr.RevId;

    Log( "vmxBasicMsr.RevId" , vmxBasicMsr.RevId );

    //	(5)	Ensure the current processor operating mode meets the required CR0
    //		fixed bits (CR0.PE=1, CR0.PG=1). Other required CR0 fixed bits can
    //		be detected through the IA32_VMX_CR0_FIXED0 and IA32_VMX_CR0_FIXED1
    //		MSRs.
    __asm
    {
        PUSH	EAX

        MOV		EAX, CR0
        MOV		cr0_reg, EAX

        POP		EAX
    }
    if( cr0_reg.PE != 1 )
    {
        Log( "ERROR : Protected Mode not enabled." , 0 );
        Log( "Value of CR0" , cr0_reg );
        goto Abort;
    }

    Log( "Protected Mode enabled." , 0 );

    if( cr0_reg.PG != 1 )
    {
        Log( "ERROR : Paging not enabled." , 0 );
        Log( "Value of CR0" , cr0_reg );
        goto Abort;
    }

    Log( "Paging enabled." , 0 );

    cr0_reg.NE = 1;

    __asm
    {
        PUSH	EAX

        MOV		EAX, cr0_reg
        MOV		CR0, EAX

        POP		EAX
    }

    //	(6)	Enable VMX operation by setting CR4.VMXE=1 [bit 13]. Ensure the
    //		resultant CR4 value supports all the CR4 fixed bits reported in
    //		the IA32_VMX_CR4_FIXED0 and IA32_VMX_CR4_FIXED1 MSRs.
    __asm
    {
        PUSH	EAX

        _emit	0x0F	// MOV	EAX, CR4
        _emit	0x20
        _emit	0xE0

        MOV		cr4_reg, EAX

        POP		EAX
    }

    Log( "CR4" , cr4_reg );
    cr4_reg.VMXE = 1;
    Log( "CR4" , cr4_reg );

    __asm
    {
        PUSH	EAX

        MOV		EAX, cr4_reg

        _emit	0x0F	// MOV	CR4, EAX
        _emit	0x22
        _emit	0xE0

        POP		EAX
    }

    //	(7)	Ensure that the IA32_FEATURE_CONTROL_MSR (MSR index 0x3A) has been
    //		properly programmed and that its lock bit is set (bit 0=1). This MSR
    //		is generally configured by the BIOS using WRMSR.
    Log( "IA32_FEATURE_CONTROL Lock Bit" , vmxFeatureControl.Lock );
    if( vmxFeatureControl.Lock != 1 )
    {
        Log( "ERROR : Feature Control Lock Bit != 1." , 0 );
        goto Abort;
    }

    //	(8)	Execute VMXON with the physical address of the VMXON region as the
    //		operand. Check successful execution of VMXON by checking if
    //		RFLAGS.CF=0.
    __asm
    {
        PUSH	 0
        PUSH	 PhysicalVMXONRegionPtr.LowPart

        _emit	0xF3	// VMXON [ESP]
        _emit	0x0F
        _emit	0xC7
        _emit	0x34
        _emit	0x24

        PUSHFD
        POP		eFlags

        ADD		ESP, 8
    }
    if( eFlags.CF == 1 )
    {
        Log( "ERROR : VMXON operation failed." , 0 );
        goto Abort;
    }

    Log( "SUCCESS : VMXON operation completed." , 0 );
    Log( "VMM is now running." , 0 );

    VMXIsActive = 1;

    //
    //	***	The processor is now in VMX root operation!
    //

    //	(1)	Create a VMCS region in non-pageable memory of size specified by
    //		the VMX capability MSR IA32_VMX_BASIC and aligned to 4-KBytes.
    //		Software should read the capability MSRs to determine width of the
    //		physical addresses that may be used for a VMCS region and ensure
    //		the entire VMCS region can be addressed by addresses with that width.
    //		The term "guest-VMCS address" refers to the physical address of the
    //		new VMCS region for the following steps.
    VMCSRegionSize = vmxBasicMsr.szVmxOnRegion;

    switch( vmxBasicMsr.MemType )
    {
    case 0:
        Log( "Unsupported memory type." , vmxBasicMsr.MemType );
        goto Abort;
        break;
    case 6:
        break;
    default:
        Log( "ERROR : Unknown VMCS Region memory type." , 0 );
        goto Abort;
        break;
    }

    //	(2)	Initialize the version identifier in the VMCS (first 32 bits)
    //		with the VMCS revision identifier reported by the VMX
    //		capability MSR IA32_VMX_BASIC.
    *(pVMCSRegion) = vmxBasicMsr.RevId;

    //	(3)	Execute the VMCLEAR instruction by supplying the guest-VMCS address.
    //		This will initialize the new VMCS region in memory and set the launch
    //		state of the VMCS to "clear". This action also invalidates the
    //		working-VMCS pointer register to FFFFFFFF_FFFFFFFFH. Software should
    //		verify successful execution of VMCLEAR by checking if RFLAGS.CF = 0
    //		and RFLAGS.ZF = 0.

    __asm
    {
        PUSH	  0
        PUSH	  PhysicalVMCSRegionPtr.LowPart

        _emit	0x66	// VMCLEAR [ESP]
        _emit	0x0F
        _emit	0xc7
        _emit	0x34
        _emit	0x24

        ADD		ESP, 8

        PUSHFD
        POP		eFlags
    }
    if( eFlags.CF != 0 || eFlags.ZF != 0 )
    {
        Log( "ERROR : VMCLEAR operation failed." , 0 );
        goto Abort;
    }

    Log( "SUCCESS : VMCLEAR operation completed." , 0 );

    //	(4)	Execute the VMPTRLD instruction by supplying the guest-VMCS address.
    //		This initializes the working-VMCS pointer with the new VMCS region抯
    //		physical address.
    __asm
    {
        PUSH	 0
        PUSH	 PhysicalVMCSRegionPtr.LowPart

        _emit	0x0F	// VMPTRLD [ESP]
        _emit	0xC7
        _emit	0x34
        _emit	0x24

        ADD		ESP, 8
    }

    //
    //	***************************************
    //  *                                     *
    //	*	H.1.1 16-Bit Guest-State Fields   *
    //  *                                     *
    //	***************************************
    //
    //			Guest ES selector									00000800H
    __asm	MOV		seg_selector, ES
    Log( "Setting Guest ES Selector" , seg_selector );
    WriteVMCS( 0x00000800, seg_selector );

    //			Guest CS selector									00000802H
    __asm	MOV		seg_selector, CS
    Log( "Setting Guest CS Selector" , seg_selector );
    WriteVMCS( 0x00000802, seg_selector );

    //			Guest SS selector									00000804H
    __asm	MOV		seg_selector, SS
    Log( "Setting Guest SS Selector" , seg_selector );
    WriteVMCS( 0x00000804, seg_selector );

    //			Guest DS selector									00000806H
    __asm	MOV		seg_selector, DS
    Log( "Setting Guest DS Selector" , seg_selector );
    WriteVMCS( 0x00000806, seg_selector );

    //			Guest FS selector									00000808H
    __asm	MOV		seg_selector, FS
    Log( "Setting Guest FS Selector" , seg_selector );
    WriteVMCS( 0x00000808, seg_selector );

    //			Guest GS selector									0000080AH
    __asm	MOV		seg_selector, GS
    Log( "Setting Guest GS Selector" , seg_selector );
    WriteVMCS( 0x0000080A, seg_selector );

    //			Guest TR selector									0000080EH
    __asm	STR		seg_selector
    ClearBit( &seg_selector, 2 );						// TI Flag
    Log( "Setting Guest TR Selector" , seg_selector );
    WriteVMCS( 0x0000080E, seg_selector );

    //	**************************************
    //  *                                    *
    //	*	H.1.2 16-Bit Host-State Fields   *
    //  *                                    *
    //	**************************************
    //
    //			Host ES selector									00000C00H
    __asm	MOV		seg_selector, ES
    seg_selector &= 0xFFFC;
    Log( "Setting Host ES Selector" , seg_selector );
    WriteVMCS( 0x00000C00, seg_selector );

    //			Host CS selector									00000C02H
    __asm	MOV		seg_selector, CS
    Log( "Setting Host CS Selector" , seg_selector );
    WriteVMCS( 0x00000C02, seg_selector );

    //			Host SS selector									00000C04H
    __asm	MOV		seg_selector, SS
    Log( "Setting Host SS Selector" , seg_selector );
    WriteVMCS( 0x00000C04, seg_selector );

    //			Host DS selector									00000C06H
    __asm	MOV		seg_selector, DS
    seg_selector &= 0xFFFC;
    Log( "Setting Host DS Selector" , seg_selector );
    WriteVMCS( 0x00000C06, seg_selector );

    //			Host FS selector									00000C08H
    __asm	MOV		seg_selector, FS
    Log( "Setting Host FS Selector" , seg_selector );
    WriteVMCS( 0x00000C08, seg_selector );

    //			Host GS selector									00000C0AH
    __asm	MOV		seg_selector, GS
    seg_selector &= 0xFFFC;
    Log( "Setting Host GS Selector" , seg_selector );
    WriteVMCS( 0x00000C0A, seg_selector );

    //			Host TR selector									00000C0CH
    __asm	STR		seg_selector
    Log( "Setting Host TR Selector" , seg_selector );
    WriteVMCS( 0x00000C0C, seg_selector );

    //	***************************************
    //  *                                     *
    //	*	H.2.2 64-Bit Guest-State Fields   *
    //  *                                     *
    //	***************************************
    //
    //			VMCS Link Pointer (full)							00002800H
    temp32 = 0xFFFFFFFF;
    Log( "Setting VMCS Link Pointer (full)" , temp32 );
    WriteVMCS( 0x00002800, temp32 );

    //			VMCS link pointer (high)							00002801H
    temp32 = 0xFFFFFFFF;
    Log( "Setting VMCS Link Pointer (high)" , temp32 );
    WriteVMCS( 0x00002801, temp32 );

    //			Reserved Bits of IA32_DEBUGCTL MSR must be 0
    //			(1D9H)
    ReadMSR( 0x000001D9 );
    Log( "IA32_DEBUGCTL MSR" , msr.Lo );

    //			Guest IA32_DEBUGCTL (full)							00002802H
    temp32 = msr.Lo;
    Log( "Setting Guest IA32_DEBUGCTL (full)" , temp32 );
    WriteVMCS( 0x00002802, temp32 );

    //			Guest IA32_DEBUGCTL (high)							00002803H
    temp32 = msr.Hi;
    Log( "Setting Guest IA32_DEBUGCTL (high)" , temp32 );
    WriteVMCS( 0x00002803, temp32 );

    //	***********************************
    //  *                                 *
    //	*	H.3.1 32-Bit Control Fields   *
    //  *                                 *
    //	***********************************
    //
    //			Pin-based VM-execution controls						00004000H
    //			IA32_VMX_PINBASED_CTLS MSR (index 481H)

    ReadMSR( 0x481 );
    Log( "Pin-based allowed-0" , msr.Lo );
    Log( "Pin-based allowed-1" , msr.Hi );
    temp32 = 0;
    temp32 |= msr.Lo;
    temp32 &= msr.Hi;

    Log( "Setting Pin-Based Controls Mask" , temp32 );
    WriteVMCS( 0x00004000, temp32 );

    //			Primary processor-based VM-execution controls		00004002H
    //			IA32_VMX_PROCBASED_CTLS MSR (index 482H)
    ReadMSR( 0x482 );
    Log( "Proc-based allowed-0" , msr.Lo );
    Log( "Proc-based allowed-1" , msr.Hi );
    temp32 = 0;
    temp32 |= msr.Lo;
    temp32 &= msr.Hi;
    Log( "Setting Pri Proc-Based Controls Mask" , temp32 );
    WriteVMCS( CPU_BASED_VM_EXEC_CONTROL, temp32 );	//4002

    //异常位设置
    //Exception bitmap	 	00004004H
    temp32 = 0x00000000;

    //SetBit( &temp32, 14 );						// Page Fault
    //SetBit( &temp32, 3 );							// Software Interrupt (INT 3)

    //SetBit( &temp32, 7 );							// No Math Co-Processor
    //SetBit( &temp32, 8 );							// Doudle Fault

    WriteVMCS( EXCEPTION_BITMAP, temp32 );			//0x00004004

    //			Page-fault error-code mask							00004006H
    Log( "Page-Fault Error-Code Mask" , 0 );
    WriteVMCS( PAGE_FAULT_ERROR_CODE_MASK, 0 );

    //			Page-fault error-code match							00004008H
    Log( "Page-Fault Error-Code Match" , 0 );
    WriteVMCS( PAGE_FAULT_ERROR_CODE_MATCH, 0 );

    //	Get the CR3-target count, MSR store/load counts, et cetera
    //
    //	IA32_VMX_MISC MSR (index 485H)
    ReadMSR( 0x485 );
    //Log( "Misc Data" , msr.Lo );
    //Log( "Misc Data" , msr.Hi );
    RtlCopyBytes( &misc_data, &msr.Lo, 4 );
    //	Log( "   ActivityStates" , misc_data.ActivityStates );
    //	Log( "   CR3Targets" , misc_data.CR3Targets );
    //	Log( "   MaxMSRs" , misc_data.MaxMSRs );

    //			VM-exit controls									0000400CH
    //			IA32_VMX_EXIT_CTLS MSR (index 483H)
    ReadMSR( 0x483 );
    Log( "Exit controls allowed-0" , msr.Lo );
    Log( "Exit controls allowed-1" , msr.Hi );
    temp32 = 0;
    temp32 |= msr.Lo;
    temp32 &= msr.Hi;
    SetBit( &temp32, 15 );								// Acknowledge Interrupt On Exit
    Log( "Setting VM-Exit Controls Mask" , temp32 );
    WriteVMCS( VM_EXIT_CONTROLS, temp32 );

    //			VM-entry controls									00004012H
    //			IA32_VMX_ENTRY_CTLS MSR (index 484H)
    ReadMSR( 0x484 );
    Log( "VMX Entry allowed-0" , msr.Lo );
    Log( "VMX Entry allowed-1" , msr.Hi );
    temp32 = 0;
    temp32 |= msr.Lo;
    temp32 &= msr.Hi;
    ClearBit( &temp32 , 9 );							// IA-32e Mode Guest Disable
    Log( "Setting VM-Entry Controls Mask" , temp32 );
    WriteVMCS( 0x00004012, temp32 );

    //	***************************************
    //  *                                     *
    //	*	H.3.3 32-Bit Guest-State Fields   *
    //  *                                     *
    //	***************************************
    //
    //			Guest ES limit										00004800H
    __asm	MOV seg_selector, ES
    temp32 = 0;
    temp32 = GetSegmentDescriptorLimit( gdt_base, seg_selector );
    Log( "Setting Guest ES limit" , 0xFFFFFFFF );
    WriteVMCS( 0x00004800, 0xFFFFFFFF );

    //			Guest CS limit										00004802H
    __asm	MOV seg_selector, CS
    temp32 = 0;
    temp32 = GetSegmentDescriptorLimit( gdt_base, seg_selector );
    Log( "Setting Guest CS limit" , 0xFFFFFFFF );
    WriteVMCS( 0x00004802, 0xFFFFFFFF );

    //			Guest SS limit										00004804H
    __asm	MOV seg_selector, SS
    temp32 = 0;
    temp32 = GetSegmentDescriptorLimit( gdt_base, seg_selector );
    Log( "Setting Guest SS limit" , 0xFFFFFFFF );
    WriteVMCS( 0x00004804, 0xFFFFFFFF );

    //			Guest DS limit										00004806H
    __asm	MOV seg_selector, DS
    temp32 = 0;
    temp32 = GetSegmentDescriptorLimit( gdt_base, seg_selector );
    Log( "Setting Guest DS limit" , 0xFFFFFFFF );
    WriteVMCS( 0x00004806, 0xFFFFFFFF );

    //			Guest FS limit										00004808H
    __asm	MOV seg_selector, FS
    temp32 = 0;
    temp32 = GetSegmentDescriptorLimit( gdt_base, seg_selector );
    Log( "Setting Guest FS limit" , 0x00001000 );
    WriteVMCS( 0x00004808, 0x00001000 );

    //			Guest GS limit										0000480AH
    __asm	MOV seg_selector, GS
    temp32 = 0;
    temp32 = GetSegmentDescriptorLimit( gdt_base, seg_selector );
    Log( "Setting Guest GS limit" , 0xFFFFFFFF );
    WriteVMCS( 0x0000480A, 0xFFFFFFFF );

    //			Guest TR limit										0000480EH
    __asm
    {
        PUSH	EAX

        STR		AX
        MOV		mLDT, AX

        POP		EAX
    }
    temp32 = 0;
    temp32 = GetSegmentDescriptorLimit( gdt_base, mLDT );
    Log( "Setting Guest TR limit" , temp32 );
    WriteVMCS( 0x0000480E, temp32 );

    //			Guest GDTR limit									00004810H
    Log( "Setting Guest GDTR limit" , gdt_reg.Limit );
    WriteVMCS( 0x00004810, gdt_reg.Limit );

    //			Guest IDTR limit									00004812H
    Log( "Setting Guest IDTR limit" , idt_reg.Limit );
    WriteVMCS( GUEST_IDTR_LIMIT, idt_reg.Limit );			//0X4812

    __asm	MOV		seg_selector, CS
    temp32 = seg_selector;
    temp32 >>= 3;
    temp32 *= 8;
    temp32  = (gdt_base   5);			// CS Segment Descriptor
    __asm
    {
        PUSHAD
        MOV		EAX, temp32
        MOV		EBX, [EAX]
        MOV		temp32, EBX
        POPAD
    }
    temp32 &= 0x0000F0FF;
    Log( "Setting Guest CS access rights" , temp32 );
    WriteVMCS( 0x00004816, temp32 );

    __asm	MOV		seg_selector, DS
    temp32 = seg_selector;
    temp32 >>= 3;
    temp32 *= 8;
    temp32  = (gdt_base   5);			// DS Segment Descriptor
    __asm
    {
        PUSHAD
        MOV		EAX, temp32
        MOV		EBX, [EAX]
        MOV		temp32, EBX
        POPAD
    }
    temp32 &= 0x0000F0FF;
    Log( "Setting Guest DS access rights" , temp32 );
    WriteVMCS( 0x0000481A, temp32 );

    __asm	MOV		seg_selector, ES
    temp32 = seg_selector;
    temp32 >>= 3;
    temp32 *= 8;
    temp32  = (gdt_base   5);			// ES Segment Descriptor
    __asm
    {
        PUSHAD
        MOV		EAX, temp32
        MOV		EBX, [EAX]
        MOV		temp32, EBX
        POPAD
    }
    temp32 &= 0x0000F0FF;
    Log( "Setting Guest ES access rights" , temp32 );
    WriteVMCS( 0x00004814, temp32 );

    __asm	MOV		seg_selector, FS
    temp32 = seg_selector;
    temp32 >>= 3;
    temp32 *= 8;
    temp32  = (gdt_base   5);			// FS Segment Descriptor
    __asm
    {
        PUSHAD
        MOV		EAX, temp32
        MOV		EBX, [EAX]
        MOV		temp32, EBX
        POPAD
    }
    temp32 &= 0x0000F0FF;
    temp32 &= 0xFFFF7FFF;				// Granularity Bit = 0
    Log( "Setting Guest FS access rights" , temp32 );
    WriteVMCS( 0x0000481C, temp32 );

    __asm	MOV		seg_selector, GS
    temp32 = seg_selector;
    temp32 >>= 3;
    temp32 *= 8;
    temp32  = (gdt_base   5);			// GS Segment Descriptor
    __asm
    {
        PUSHAD
        MOV		EAX, temp32
        MOV		EBX, [EAX]
        MOV		temp32, EBX
        POPAD
    }
    temp32 &= 0x0000F0FF;
    SetBit( &temp32, 16 );				// Unusable
    Log( "Setting Guest GS access rights" , temp32 );
    WriteVMCS( 0x0000481E, temp32 );

    __asm	MOV		seg_selector, SS
    temp32 = seg_selector;
    temp32 >>= 3;
    temp32 *= 8;
    temp32  = (gdt_base   5);			// SS Segment Descriptor
    __asm
    {
        PUSHAD
        MOV		EAX, temp32
        MOV		EBX, [EAX]
        MOV		temp32, EBX
        POPAD
    }
    temp32 &= 0x0000F0FF;
    Log( "Setting Guest SS access rights" , temp32 );
    WriteVMCS( 0x00004818, temp32 );

    __asm	STR		seg_selector
    temp32 = seg_selector;
    temp32 >>= 3;
    temp32 *= 8;
    temp32  = (gdt_base   5);			// TR Segment Descriptor
    __asm
    {
        PUSHAD
        MOV		EAX, temp32
        MOV		EBX, [EAX]
        MOV		temp32, EBX
        POPAD
    }
    temp32 &= 0x0000F0FF;
    Log( "Setting Guest TR access rights" , temp32 );
    WriteVMCS( 0x00004822, temp32 );

    //			Guest LDTR access rights							00004820H
    temp32 = 0;
    SetBit( &temp32, 16 );			// Unusable
    Log( "Setting Guest LDTR access rights" , temp32 );
    WriteVMCS( 0x00004820, temp32 );

    //			Guest IA32_SYSENTER_CS								0000482AH
    //			(174H)
    ReadMSR( 0x174 );
    Log( "Setting Guest IA32_SYSENTER_CS" , (ULONG)msr.Lo );
    WriteVMCS( 0x0000482A, msr.Lo );

    //	**************************************
    //  *                                    *
    //	*	H.3.4 32-Bit Host-State Fields   *
    //  *                                    *
    //	**************************************
    //
    //			Host IA32_SYSENTER_CS								00004C00H
    //			(174H)
    ReadMSR( 0x174 );
    Log( "Setting Host IA32_SYSENTER_CS" , (ULONG)msr.Lo );
    WriteVMCS( 0x00004C00, msr.Lo );

    //	**********************************************
    //  *                                            *
    //	*	H.4.3 Natural-Width Guest-State Fields   *
    //  *                                            *
    //	**********************************************
    //
    //			Guest CR0											00006800H
    __asm
    {
        PUSH	EAX
        MOV		EAX, CR0
        MOV		temp32, EAX
        POP		EAX
    }

    ReadMSR( 0x486 );							// IA32_VMX_CR0_FIXED0
    Log( "IA32_VMX_CR0_FIXED0" , msr.Lo );

    ReadMSR( 0x487 );							// IA32_VMX_CR0_FIXED1
    Log( "IA32_VMX_CR0_FIXED1" , msr.Lo );

    SetBit( &temp32, 0 );		// PE
    SetBit( &temp32, 5 );		// NE
    SetBit( &temp32, 31 );		// PG
    Log( "Setting Guest CR0" , temp32 );
    WriteVMCS( 0x00006800, temp32 );

    //			Guest CR3											00006802H
    __asm
    {
        PUSH	EAX

        _emit	0x0F	// MOV EAX, CR3
        _emit	0x20
        _emit	0xD8

        MOV		temp32, EAX

        POP		EAX
    }
    Log( "Setting Guest CR3" , temp32 );
    WriteVMCS( GUEST_CR3, temp32 );

    //			Guest CR4											00006804H
    __asm
    {
        PUSH	EAX

        _emit	0x0F	// MOV EAX, CR4
        _emit	0x20
        _emit	0xE0

        MOV		temp32, EAX

        POP		EAX
    }

    ReadMSR( 0x488 );							// IA32_VMX_CR4_FIXED0
    Log( "IA32_VMX_CR4_FIXED0" , msr.Lo );

    ReadMSR( 0x489 );							// IA32_VMX_CR4_FIXED1
    Log( "IA32_VMX_CR4_FIXED1" , msr.Lo );

    SetBit( &temp32, 13 );		// VMXE
    Log( "Setting Guest CR4" , temp32 );
    WriteVMCS( 0x00006804, temp32 );

    //			Guest ES base										00006806H
    __asm	MOV		seg_selector, ES
    temp32 = 0;
    temp32 = GetSegmentDescriptorBase( gdt_base , seg_selector );
    Log( "Setting Guest ES Base" , temp32 );
    WriteVMCS( 0x00006806, temp32 );

    //			Guest CS base										00006808H
    __asm	MOV		seg_selector, CS
    temp32 = 0;
    temp32 = GetSegmentDescriptorBase( gdt_base , seg_selector );
    Log( "Setting Guest CS Base" , temp32 );
    WriteVMCS( 0x00006808, temp32 );

    //			Guest SS base										0000680AH
    __asm	MOV		seg_selector, SS
    temp32 = 0;
    temp32 = GetSegmentDescriptorBase( gdt_base , seg_selector );
    Log( "Setting Guest SS Base" , temp32 );
    WriteVMCS( 0x0000680A, temp32 );

    //			Guest DS base										0000680CH
    __asm	MOV		seg_selector, DS
    temp32 = 0;
    temp32 = GetSegmentDescriptorBase( gdt_base , seg_selector );
    Log( "Setting Guest DS Base" , temp32 );
    WriteVMCS( 0x0000680C, temp32 );

    //			Guest FS base										0000680EH
    __asm	MOV		seg_selector, FS
    temp32 = 0;
    temp32 = GetSegmentDescriptorBase( gdt_base , seg_selector );
    Log( "Setting Guest FS Base" , temp32 );
    WriteVMCS( 0x0000680E, temp32 );

    //			Guest TR base										00006814H
    __asm
    {
        PUSH	EAX

        STR		AX
        MOV		mLDT, AX

        POP		EAX
    }
    temp32 = 0;
    temp32 = GetSegmentDescriptorBase( gdt_base , mLDT );
    Log( "Setting Guest TR Base" , temp32 );
    WriteVMCS( 0x00006814, temp32 );

    //			Guest GDTR base										00006816H
    __asm
    {
        SGDT	gdt_reg
    }
    temp32 = 0;
    temp32 = gdt_reg.BaseHi;
    temp32 <<= 16;
    temp32 |= gdt_reg.BaseLo;
    Log( "Setting Guest GDTR Base" , temp32 );
    WriteVMCS( GUEST_GDTR_BASE, temp32 );

    //			Guest IDTR base										00006818H
    __asm
    {
        SIDT	idt_reg
    }
    temp32 = 0;
    temp32 = idt_reg.BaseHi;
    temp32 <<= 16;
    temp32 |= idt_reg.BaseLo;
    Log( "Setting Guest IDTR Base" , temp32 );
    WriteVMCS( GUEST_IDTR_BASE, temp32 );

    //			Guest RFLAGS										00006820H
    __asm
    {
        PUSHAD

        PUSHFD

        MOV		EAX, 0x00006820

        // VMWRITE	EAX, [ESP]
        _emit	0x0F
        _emit	0x79
        _emit	0x04
        _emit	0x24

        POP		eFlags

        POPAD
    }
    Log( "Guest EFLAGS" , eFlags );

    //			Guest IA32_SYSENTER_ESP								00006824H
    //			MSR (175H)
    ReadMSR( 0x175 );
    Log( "Setting Guest IA32_SYSENTER_ESP" , msr.Lo );
    WriteVMCS( GUEST_SYSENTER_ESP, msr.Lo );

    //			Guest IA32_SYSENTER_EIP								00006826H
    //			MSR (176H)
    ReadMSR( 0x176 );
    Log( "Setting Guest IA32_SYSENTER_EIP" , msr.Lo );
    WriteVMCS( GUEST_SYSENTER_EIP, msr.Lo );		//0x00006826


    //	*********************************************
    //  *                                           *
    //	*	H.4.4 Natural-Width Host-State Fields   *
    //  *                                           *
    //	*********************************************
    //
    //			Host CR0											00006C00H
    __asm
    {
        PUSH	EAX
        MOV		EAX, CR0
        MOV		temp32, EAX
        POP		EAX
    }
    SetBit( &temp32, 5 );								// Set NE Bit
    Log( "Setting Host CR0" , temp32 );
    WriteVMCS( 0x00006C00, temp32 );

    //			Host CR3											00006C02H
    __asm
    {
        PUSH	EAX

        _emit	0x0F	// MOV EAX, CR3
        _emit	0x20
        _emit	0xD8

        MOV		temp32, EAX

        POP		EAX
    }
    Log( "Setting Host CR3" , temp32 );
    WriteVMCS( 0x00006C02, temp32 );

    //			Host CR4											00006C04H
    __asm
    {
        PUSH	EAX

        _emit	0x0F	// MOV EAX, CR4
        _emit	0x20
        _emit	0xE0

        MOV		temp32, EAX

        POP		EAX
    }
    Log( "Setting Host CR4" , temp32 );
    WriteVMCS( 0x00006C04, temp32 );

    //			Host FS base										00006C06H
    __asm	MOV		seg_selector, FS
    temp32 = 0;
    temp32 = GetSegmentDescriptorBase( gdt_base , seg_selector );
    Log( "Setting Host FS Base" , temp32 );
    WriteVMCS( 0x00006C06, temp32 );

    //			Host TR base										00006C0AH
    __asm
    {
        PUSH	EAX

        STR		AX
        MOV		mLDT, AX

        POP		EAX
    }
    temp32 = 0;
    temp32 = GetSegmentDescriptorBase( gdt_base , mLDT );
    Log( "Setting Host TR Base" , temp32 );
    WriteVMCS( 0x00006C0A, temp32 );

    //			Host GDTR base										00006C0CH
    __asm
    {
        SGDT	gdt_reg
    }
    temp32 = 0;
    temp32 = gdt_reg.BaseHi;
    temp32 <<= 16;
    temp32 |= gdt_reg.BaseLo;
    Log( "Setting Host GDTR Base" , temp32 );
    WriteVMCS( HOST_GDTR_BASE, temp32 );

    //			Host IDTR base										00006C0EH
    __asm
    {
        SIDT	idt_reg
    }
    temp32 = 0;
    temp32 = idt_reg.BaseHi;
    temp32 <<= 16;
    temp32 |= idt_reg.BaseLo;

    Log( "Setting Host IDTR Base" , temp32 );
    WriteVMCS( HOST_IDTR_BASE, temp32 );

    //			Host IA32_SYSENTER_ESP								00006C10H
    //			MSR (175H)
    ReadMSR( 0x175 );
    Log( "Setting Host IA32_SYSENTER_ESP" , msr.Lo );
    WriteVMCS( 0x00006C10, msr.Lo );

    //			Host IA32_SYSENTER_EIP								00006C12H
    //			MSR (176H)
    ReadMSR( 0x176 );
    Log( "Setting Host IA32_SYSENTER_EIP" , msr.Lo );
    WriteVMCS( 0x00006C12, msr.Lo );

    //	(5)	Issue a sequence of VMWRITEs to initialize various host-state area
    //		fields in the working VMCS. The initialization sets up the context
    //		and entry-points to the VMM VIRTUAL-MACHINE MONITOR PROGRAMMING
    //		CONSIDERATIONS upon subsequent VM exits from the guest. Host-state
    //		fields include control registers (CR0, CR3 and CR4), selector fields
    //		for the segment registers (CS, SS, DS, ES, FS, GS and TR), and base-
    //		address fields (for FS, GS, TR, GDTR and IDTR; RSP, RIP and the MSRs
    //		that control fast system calls).
    //

    //	(6)	Use VMWRITEs to set up the various VM-exit control fields, VM-entry
    //		control fields, and VM-execution control fields in the VMCS. Care
    //		should be taken to make sure the settings of individual fields match
    //		the allowed 0 and 1 settings for the respective controls as reported
    //		by the VMX capability MSRs (see Appendix G). Any settings inconsistent
    //		with the settings reported by the capability MSRs will cause VM
    //		entries to fail.

    //	(7)	Use VMWRITE to initialize various guest-state area fields in the
    //		working VMCS. This sets up the context and entry-point for guest
    //		execution upon VM entry. Chapter 22 describes the guest-state loading
    //		and checking done by the processor for VM entries to protected and
    //		virtual-8086 guest execution.
    //

    // Clear the VMX Abort Error Code prior to VMLAUNCH
    //
    RtlZeroMemory( (pVMCSRegion   4), 4 );
    Log( "Clearing VMX Abort Error Code" , *(pVMCSRegion   4) );

    //	Set EIP, ESP for the Guest right before calling VMLAUNCH
    // G、Guest的ESP和EIP
    Log( "Setting Guest ESP" , GuestStack );
    WriteVMCS( 0x0000681C, (ULONG)GuestStack );

    Log( "Setting Guest EIP" , GuestReturn );
    WriteVMCS( 0x0000681E, (ULONG)GuestReturn );

    /*
    //	Allocate some stack space for the VMEntry and VMMHandler.
    //
    HighestAcceptableAddress.QuadPart = 0xFFFFFFFF;
    FakeStack = MmAllocateContiguousMemory( 0x2000, HighestAcceptableAddress );
    Log( "FakeStack" , FakeStack );
    */

    //	Set EIP, ESP for the Host right before calling VMLAUNCH
    //
    Log( "Setting Host ESP" , ((ULONG)FakeStack   0x1FFF) );


    WriteVMCS( HOST_RSP, ((ULONG)FakeStack   0x1FFF) );//0x00006C14
    Log( "Setting Host EIP" , VMMEntryPoint );
    // 入口
    WriteVMCS( HOST_RIP, (ULONG)VMMEntryPoint );		//6C16

    ////////////////
    //            //
    //	VMLAUNCH //
    //            //
    ////////////////
    __asm
    {
        _emit	0x0F
        _emit	0x01
        _emit	0xC2
    }

    Log( "成功后不会在这里玩! \n" , 1907 );
    __asm
    {
        PUSHFD
        POP		eFlags
    }



    Log( "VMLAUNCH 失败啦 !" , 0xDEADF00D );
    /* Get the error number from VMCS */
    ErrorCode = VmxRead(VM_INSTRUCTION_ERROR);
    Log("VM Instruction Error", ErrorCode);

Abort:

    ScrubTheLaunch = 1;
    __asm
    {
        MOV		ESP, GuestStack
        JMP		GuestReturn
    }
}

//////////////////////////////////////////////////////////////////////////


ULONG		ExitReason;
ULONG		ExitQualification;
ULONG		ExitInterruptionInformation;
ULONG		ExitInterruptionErrorCode;
ULONG		IDTVectoringInformationField;
ULONG		IDTVectoringErrorCode;
ULONG		ExitInstructionLength;
ULONG		ExitInstructionInformation;

ULONG		GuestEIP;
ULONG		GuestResumeEIP;
ULONG		GuestESP;
ULONG		GuestCR3;

ULONG		GuestEAX;
ULONG		GuestEBX;
ULONG		GuestECX;
ULONG		GuestEDX;
ULONG		GuestEDI;
ULONG		GuestESI;
ULONG		GuestEBP;

ULONG		movcrControlRegister;
ULONG		movcrAccessType;
ULONG		movcrOperandType;
ULONG		movcrGeneralPurposeRegister;
ULONG		movcrLMSWSourceData;

////////////////虚拟机处理系统 ///////
__declspec( naked ) VOID VMMEntryPoint( )
{

    //如果不关中断,则有可能在执行了mov ss之后,mov sp之前发生中断,会破坏此时ss:sp指向的数据。
    __asm
    {
        CLI		//屏蔽中断
        PUSHAD
        //	保存通用寄存器
        MOV GuestEAX, EAX
        MOV GuestEBX, EBX
        MOV GuestECX, ECX
        MOV GuestEDX, EDX
        MOV GuestEDI, EDI
        MOV GuestESI, ESI
        MOV GuestEBP, EBP
    }

    VMMReadGuestState();
    //////////////////////////////////////////////////////////////////////////
    if (0 == ExitReason )
    {
        int IntrNo = ExitInterruptionInformation & 0xFF;
        if ( 3 == IntrNo )
        {

        }
    }//end if 0 reason
    //////////////////////////////////////////////////////////////////////////

    //	Writing the Guest VMCS EIP uses general registers.
    //	Must complete this before setting general registers
    //	for guest return state.
    //
    GuestResumeEIP = GuestEIP   ExitInstructionLength;
    WriteVMCS(GUEST_RIP,(ULONG)GuestResumeEIP );		//0x0000681E
    //////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////
    //                                         //
    //  *** EXIT REASON CHECKS START HERE ***  //
    //                                         //
    /////////////////////////////////////////////

    /////////////////////////////////////////////////////////////////////////////////////
    //                                                                                 //
    //  VMCLEAR, VMLAUNCH, VMPTRLD, VMPTRST, VMREAD, VMWRITE, VMRESUME, VMXOFF, VMXON  //
    //                                                                                 //
    /////////////////////////////////////////////////////////////////////////////////////
    if( ExitReason > 0x00000012 && ExitReason < 0x0000001C )
    {
        Log( "Request has been denied - CPU0", ExitReason );

        __asm
        {
            POPAD
            JMP		Resume
        }
    }
    //处理 CPUID 指令
    if( ExitReason == VMX_EXIT_CPUID )
    {
        if( GuestEAX == 0 )
        {

            DbgPrint("CPUID EIP == %08X \n" ,  GuestEIP );
            //ShowGuestState();
            //0x34EC2B
            __asm
            {
                POPAD
                MOV		EAX, 0
                CPUID

                //修改返回值
                MOV		EBX, 0x80808080
                MOV		ECX, 0x90909090
                MOV		EDX, 0x10101010

                JMP		Resume
            }
        }
        else
        {
            __asm
            {
                POPAD
                MOV		EAX, GuestEAX
                CPUID
                JMP		Resume
            }
        }
    }//end if VMX_EXIT_CPUID

    if( ExitReason == VMX_EXIT_VMCALL )	//VMCALL	//0X12
    {
        Log( "VMCALL detected - CPU0" , 0 );

        if( GuestEAX == 0x12345678 )
        {
            //	Switch off VMX mode.
            //
            Log( "- Terminating VMX Mode.", 0xDEADDEAD );
            __asm
            {
                _emit	0x0F	// VMXOFF
                _emit	0x01
                _emit	0xC4
            }

            Log( "- Flow Control Return to Address" , GuestResumeEIP );

            __asm
            {
                POPAD
                MOV	ESP, GuestESP
                STI
                JMP	GuestResumeEIP
            }
        }

        Log( "- Request has been denied." , ExitReason );

        __asm
        {
            POPAD
            JMP	Resume
        }
    }


    if( ExitReason == VMX_EXIT_INVD )		//0XD
    {
        Log( "INVD detected - CPU0" , 0 );

        __asm
        {
            _emit 0x0F
            _emit 0x08

            POPAD
            JMP		Resume
        }
    }

    if( ExitReason == VMX_EXIT_RDMSR )	//0X1F
    {

        __asm
        {
            POPAD

            MOV		ECX, GuestECX

            _emit	0x0F
            _emit	0x32

            JMP		Resume
        }
    }

    if( ExitReason == VMX_EXIT_WRMSR )	//0x20
    {

        __asm
        {
            POPAD

            MOV		ECX, GuestECX
            MOV		EAX, GuestEAX
            MOV		EDX, GuestEDX

            _emit	0x0F
            _emit	0x30

            JMP		Resume
        }
    }

    ///////////////////////////////
    //                           //
    //  Control Register Access  //
    //                           //
    ///////////////////////////////
    if( ExitReason == VMX_EXIT_CRX_MOVE )	//0x1c
    {
        if( HandlerLogging ) Log( "Control Register Access detected.", 0 );

        movcrControlRegister = ( ExitQualification & 0x0000000F );
        movcrAccessType = ( ( ExitQualification & 0x00000030 ) >> 4 );
        movcrOperandType = ( ( ExitQualification & 0x00000040 ) >> 6 );
        movcrGeneralPurposeRegister = ( ( ExitQualification & 0x00000F00 ) >> 8 );

        if( HandlerLogging )
        {
            Log( "- movcrControlRegister", movcrControlRegister );
            Log( "- movcrAccessType", movcrAccessType );
            Log( "- movcrOperandType", movcrOperandType );
            Log( "- movcrGeneralPurposeRegister", movcrGeneralPurposeRegister );
        }

        //	Control Register Access (CR3 <-- reg32)
        //
        if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 0 )
        {
            WriteVMCS( GUEST_CR3, GuestEAX );
            __asm POPAD
            goto Resume;
        }
        if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 1 )
        {
            WriteVMCS( GUEST_CR3, GuestECX );
            __asm POPAD
            goto Resume;
        }
        if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 2 )
        {
            WriteVMCS( GUEST_CR3, GuestEDX );
            __asm POPAD
            goto Resume;
        }
        if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 3 )
        {
            WriteVMCS( GUEST_CR3, GuestEBX );
            __asm POPAD
            goto Resume;
        }
        if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 4 )
        {
            WriteVMCS( GUEST_CR3, GuestESP );
            __asm POPAD
            goto Resume;
        }
        if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 5 )
        {
            WriteVMCS( GUEST_CR3, GuestEBP );
            __asm POPAD
            goto Resume;
        }
        if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 6 )
        {
            WriteVMCS( GUEST_CR3, GuestESI );
            __asm POPAD
            goto Resume;
        }
        if( movcrControlRegister == 3 && movcrAccessType == 0 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 7 )
        {
            WriteVMCS( GUEST_CR3, GuestEDI );
            __asm POPAD
            goto Resume;
        }
        //	Control Register Access (reg32 <-- CR3)
        //
        if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 0 )
        {
            __asm	POPAD
            __asm	MOV EAX, GuestCR3
            goto Resume;
        }
        if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 1 )
        {
            __asm	POPAD
            __asm	MOV ECX, GuestCR3
            goto Resume;
        }
        if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 2 )
        {
            __asm	POPAD
            __asm	MOV EDX, GuestCR3
            goto Resume;
        }
        if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 3 )
        {
            __asm	POPAD
            __asm	MOV EBX, GuestCR3
            goto Resume;
        }
        if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 4 )
        {
            __asm	POPAD
            __asm	MOV ESP, GuestCR3
            goto Resume;
        }
        if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 5 )
        {
            __asm	POPAD
            __asm	MOV EBP, GuestCR3
            goto Resume;
        }
        if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 6 )
        {
            __asm	POPAD
            __asm	MOV ESI, GuestCR3
            goto Resume;
        }
        if( movcrControlRegister == 3 && movcrAccessType == 1 && movcrOperandType == 0 && movcrGeneralPurposeRegister == 7 )
        {
            __asm	POPAD
            __asm	MOV EDI, GuestCR3
            goto Resume;
        }
    }//end VMX_EXIT_CRX_MOVE



Exit:

    __asm
    {
        _emit	0x0F	// VMXOFF
        _emit	0x01
        _emit	0xC4
    }

    VMXIsActive = 0;

    Log( "Flow Control Return to Address" , GuestEIP );

    __asm
    {
        POPAD
        MOV		ESP, GuestESP
        STI
        JMP		GuestEIP
    }

Resume:
    //恢复

    //	Need to execute the VMRESUME without having changed
    //	the state of the GPR and ESP et cetera.

    __asm
    {
        STI

        _emit	0x0F	// VMRESUME
        _emit	0x01
        _emit	0xC3
    }
}


VOID VMMReadGuestState( )
{
    HandlerLogging = 0;
    ExitReason =						VmxRead(VM_EXIT_REASON);			//0x4402
    ExitInterruptionInformation		=	VmxRead( VM_EXIT_INTR_INFO);		//0x4404
    ExitInstructionLength			=	VmxRead(VM_EXIT_INSTRUCTION_LEN);	//0x440c
    ExitQualification				=	VmxRead(EXIT_QUALIFICATION) ;		//0x6400
    ExitInterruptionInformation		=	VmxRead(VM_EXIT_INTR_INFO);			//0x4404
    ExitInterruptionErrorCode		=	VmxRead(VM_EXIT_INTR_ERROR_CODE);	//0x4406

    IDTVectoringInformationField = VmxRead(IDT_VECTORING_INFO);				//0X00004408	// IDT-Vectoring Information Field
    IDTVectoringErrorCode		 = VmxRead(IDT_VECTORING_ERROR_CODE);		//0X0000440A	// IDT-Vectoring Error Code
    ExitInstructionLength		 = VmxRead(VM_EXIT_INSTRUCTION_LEN);		//0x0000440C	// VM-Exit Instruction Length
    ExitInstructionInformation   = VmxRead(VMX_INSTRUCTION_INFO) ;	//0x0000440E	//VM-Exit Instruction Information
    GuestEIP = VmxRead(GUEST_RIP);									//0x0000681E;	//GuestEIP
    GuestESP = VmxRead(GUEST_RSP);									//0x0000681c	//esp
    GuestCR3 = VmxRead(GUEST_CR3);									//0X6802	GuestCR3

}

void ShowGuestState()
{

    Log( "----- VMM  Guest  -----", 0 );
    Log( "Guest EAX" , GuestEAX );
    Log( "Guest EBX" , GuestEBX );
    Log( "Guest ECX" , GuestECX );
    Log( "Guest EDX" , GuestEDX );
    Log( "Guest EDI" , GuestEDI );
    Log( "Guest ESI" , GuestESI );
    Log( "Guest EBP" , GuestEBP );

    Log( "Exit Reason" , ExitReason );


    Log( "Exit Qualification" , ExitQualification );
    Log( "Exit Interruption Information" , ExitInterruptionInformation );
    Log( "Exit Interruption Error Code" , ExitInterruptionErrorCode );
    Log( "IDT-Vectoring Information Field" , IDTVectoringInformationField );
    Log( "IDT-Vectoring Error Code" , IDTVectoringErrorCode );
    Log( "VM Exit CR3" , GuestCR3 );
    Log( "VM Exit EIP" , GuestEIP );
    Log( "VM Exit ESP" , GuestESP );
    Log( "VM-Exit Instruction Information" , ExitInstructionInformation );
    Log( "VM-Exit Instruction Length" , ExitInstructionLength );

}