基本信息
源码名称:vt开发源码
源码大小:0.53M
文件格式:.rar
开发语言:C/C++
更新时间:2015-07-04
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在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 ); }