日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Intel VT学习笔记(六)—— VM-Exit Handler

發布時間:2025/3/21 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Intel VT学习笔记(六)—— VM-Exit Handler 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Intel VT學習筆記(六)—— VM-Exit Handler

  • Reutrn To DriverEntry
  • VM-Exit Handler
    • External interrupt
    • I/O instruction
    • Control-register accesses
    • CPUID
    • VMCALL
  • 完整代碼
  • 參考資料

Reutrn To DriverEntry

描述:當開啟VT后,就可以從DriverEntry中返回了,但應該怎么做呢?

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path) {DbgPrint("Driver load. \r\n");pDriver->DriverUnload = DriverUnload;StartVirtualTechnology(); //開啟VT//=========================================//how do I get here?//=========================================return STATUS_SUCCESS; }

實現思路

  • 在開啟VT前,將當前的CPU狀態保存在棧里,然后記錄ESP。
  • 使用類似于在StartVirtualTechnology函數下方打標簽的方式,保存其地址作為返回地址。
  • 開啟VT后,將EIP指向記錄的返回地址,并將ESP指向之前保存的CPU狀態。
  • 恢復CPU狀態,繼續向下執行。
  • 代碼實現(在Guest中執行INT 3或VMCALL都可以):

    //driver.c NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path) {DbgPrint("Driver load. \r\n");pDriver->DriverUnload = DriverUnload;__asm{pushadpushfdmov g_ret_esp, espmov g_ret_eip, offset RET_EIP}StartVirtualTechnology(); //開啟VTRET_EIP:__asm{popfdpopad}Log("Return To DriverEntry .", 0);return STATUS_SUCCESS; } //exithandler.c extern ULONG g_ret_esp; extern ULONG g_ret_eip;GUEST_REGS g_GuestRegs;static void VMMEntryPointEbd(void) {ULONG ExitReason;ExitReason = Vmx_VmRead(VM_EXIT_REASON);Log("ExitReason", ExitReason);g_GuestRegs.esp = Vmx_VmRead(GUEST_RSP);g_GuestRegs.eip = Vmx_VmRead(GUEST_RIP);Log("g_GuestRegs.esp", g_GuestRegs.esp);Log("g_GuestRegs.eip", g_GuestRegs.eip);__asm{mov esp, g_ret_espjmp g_ret_eip} }

    執行結果:

    可以看到,CPU已經成功回到了DriverEntry,并能夠關閉VT以及卸載驅動。

    VM-Exit Handler

    描述:當Guest觸發VM-Exit時,會進入Host進行處理。如果需要在Return To DriverEntry后使系統保持VT模式,則需要將返回代碼寫在Guest中,并在VM-Exit Handler中對各類VM-Exit事件進行處理。

    代碼實現:

    //vtsystem.c ... void __declspec(naked) GuestEntry() {__asm {mov ax, esmov es, axmov ax, dsmov ds, axmov ax, fsmov fs, axmov ax, gsmov gs, axmov ax, ssmov ss, axmov esp, g_ret_espjmp g_ret_eip} } ... //exithandler.c ... static void VMMEntryPointEbd(void) {ULONG ExitReason;ULONG ExitInstructionLength;ULONG GuestResumeEIP;ExitReason = Vmx_VmRead(VM_EXIT_REASON); //獲取退出碼ExitInstructionLength = Vmx_VmRead(VM_EXIT_INSTRUCTION_LEN); //獲取指令長度Log("ExitReason", ExitReason);g_GuestRegs.eflags = Vmx_VmRead(GUEST_RFLAGS);g_GuestRegs.esp = Vmx_VmRead(GUEST_RSP);g_GuestRegs.eip = Vmx_VmRead(GUEST_RIP);Log("g_GuestRegs.eflags", g_GuestRegs.eflags);Log("g_GuestRegs.esp", g_GuestRegs.esp);Log("g_GuestRegs.eip", g_GuestRegs.eip);switch(ExitReason){case ...: //需要處理的退出碼//處理程序break;...default:Log("not handled reason: %p", ExitReason);__asm int 3;break;}__asm INT 3; }void __declspec(naked) VMMEntryPoint(void) {__asm{//需要設置fs和gs,否則無法正常運行mov ax, fsmov fs, axmov ax, gsmov gs, ax}Log("VM Exit", 0);//盡量不要在裸函數中定義局部變量,或實現太多功能,最好封裝成函數VMMEntryPointEbd(); } ...

    External interrupt

    描述:通過設置,可以使外部中斷觸發VM-Exit。

    令人感到奇怪的是,明明在設置VMCS字段的時候已經將TF位置0了,卻仍然捕捉到了外部中斷。

    Vmx_VmWrite(GUEST_RFLAGS, Asm_GetEflags() & ~0x200); //cli

    運行結果:

    由于筆剛接觸這一塊,是跟著周壑老師的視頻做的實驗,而周壑老師做實驗的時候并沒有遇到01錯誤,因此一下子給筆者整不會了,折磨了很久,谷歌百度均無果,最終通過查手冊解決(手冊YYDS),原來是控制寄存器的設置出了問題。

    查手冊卷3附錄C,退出碼1對應的信息是外部中斷,原因是控制域中相應位被設置。

    翻閱控制域相關部分(詳見24.6.1),在「Pin-Based VM-Execution Controls」找到關于外部中斷的詳細說明。

    這里說,如果IA32_VMX_PINBASED_CTLS MSR的第0位為1,表示外部中斷將觸發VM-Exit,并且ELFAGS的TF位失效。

    找到原因了,那么接下來,只要在設置IA32_VMX_PINBASED_CTLS MSR的時候將第0位置0即可。

    當然,如果需要手動處理外部中斷,可以忽略這一步。

    static ULONG VmxAdjustControls(ULONG Ctl, ULONG Msr) {LARGE_INTEGER MsrValue;MsrValue.QuadPart = Asm_ReadMsr(Msr);Ctl &= MsrValue.HighPart; /* bit == 0 in high word ==> must be zero */Ctl |= MsrValue.LowPart; /* bit == 1 in low word ==> must be one */if (MSR_IA32_VMX_PINBASED_CTLS == Msr){Ctl &= ~1;} }

    運行結果:

    可以看到,退出碼01已經消失了,此時出現了一個新的退出碼1E。

    I/O instruction

    描述:訪問I/O時觸發了VM-Exit,對應退出碼1E。

    退出碼1E的出現也是在意料之外的,和01類似,也是由于MSR寄存器的設置出現了問題。

    從手冊對該退出碼的描述可以看到,除了訪問I/O,還需要滿足兩個條件。

  • 對應MSR的「use I/O bitmaps」位為0以及「unconditional I/O exiting」位為1
  • 「use I/O bitmaps」VM執行控制為1,與I/O指令訪問的一個端口相關的位圖中有一位為1。
  • 第二個條件不太理解是什么意思,但是第一個條件我們可以手動給他取消。

    關于「use I/O bitmaps」和「unconditional I/O exiting」標志位可查閱Intel手冊卷3第24.6.2小節,是IA32_VMX_PROCBASED_CTLS MSR寄存器的第24比特位和第25比特位。。

    目前無需了解其具體含義,把它們全部置0先。

    static ULONG VmxAdjustControls(ULONG Ctl, ULONG Msr) {LARGE_INTEGER MsrValue;MsrValue.QuadPart = Asm_ReadMsr(Msr);Ctl &= MsrValue.HighPart; /* bit == 0 in high word ==> must be zero */Ctl |= MsrValue.LowPart; /* bit == 1 in low word ==> must be one */if (MSR_IA32_VMX_PINBASED_CTLS == Msr) //關閉外部中斷信號{Ctl &= ~1;}if (MSR_IA32_VMX_PROCBASED_CTLS == Msr) //關閉I/O訪問信號{Ctl &= ~0x03000000;}return Ctl; }

    執行結果:

    好了,現在退出碼1E也消失了,捕獲到的退出碼變成了1C,總算可以進入正題了。

    Control-register accesses

    描述:當Guest試圖使用控制寄存器時會觸發該事件,對應的退出碼為0x1C。

    處理方式:當Guest試圖使用控制寄存器,并觸發VM-Exit來到Host后,Host通過讀取相應的信息,幫助Guest完成對應的功能,然后回到觸發該事件的下一句指令。

    ExitQualification = Vmx_VmRead(EXIT_QUALIFICATION);

    關于「Control-register accesses」錯誤的具體信息可參考Intel開發手冊卷3第27.2小節。


    值得注意的是,在實現Handler的過程中,只攔截Cr3即可。

    具體思路:

  • 如果分析錯誤信息后發現是操作的話,就把對應的值寫到VMCS相應的字段中。
  • 如果發現是操作的話,就先將其讀到g_GuestRegs全局變量的對應寄存器成員中,然后在Resume前將其寫到寄存器當中,調用Resume的時候會自動寫到VMCS相應的字段中。
  • 代碼實現:

    void HandleCrAccess() {ULONG movcrControlRegister;ULONG movcrAccessType;ULONG movcrOperandType; //只是讀了,沒有使用,通常都是寄存器ULONG movcrGeneralPurposeRegister;ULONG movcrLMSWSourceData;ULONG ExitQualification;ExitQualification = Vmx_VmRead(EXIT_QUALIFICATION); //獲取具體信息movcrControlRegister = (ExitQualification & 0x0000000F); //控制寄存器下標movcrAccessType = ((ExitQualification & 0x00000030) >> 4); //讀/寫movcrOperandType = ((ExitQualification & 0x00000040) >> 6); //寄存器/內存movcrGeneralPurposeRegister = ((ExitQualification & 0x00000F00) >> 8); //寄存器下標if (movcrControlRegister != 3) { // not for cr3__asm int 3}if (movcrAccessType == 0) { // CR3 <-- reg32Vmx_VmWrite(GUEST_CR3, *(PULONG)((ULONG)&g_GuestRegs + 4 * movcrGeneralPurposeRegister));}else { // reg32 <-- CR3*(PULONG)((ULONG)&g_GuestRegs + 4 * movcrGeneralPurposeRegister) = Vmx_VmRead(GUEST_CR3);} }

    執行結果:

    可以看到系統在不斷訪問控制寄存器,讓我們看看是誰干的。

    破案了,原來是線程切換的時候訪問了Cr3。

    由于系統在不斷地切換線程,因此也就在不斷地輸出調試信息,這個時候系統會處于假卡死狀態,無法正常操作。

    把輸出調試信息的代碼注釋掉之后,系統就變得流暢了起來,但是這并不代表已經完全沒問題了。

    當進行特定操作時,仍然會觸發其他原因導致的VM-Exit,例如當打開一個進程時,會觸發退出碼0A(CPUID)。

    CPUID

    描述:匯編指令,用于獲取CPU的相關信息,當Guest調用該指令時,會觸發VM-Exit信號。

    處理方法:在Host中模擬執行,并返回結果。

    void HandleCPUID() {//特殊處理,用于測試VT是否開啟,注意保證參數的獨立性。if (g_GuestRegs.eax == 'Mini'){g_GuestRegs.ebx = 0x88888888;g_GuestRegs.ecx = 0x11111111;g_GuestRegs.edx = 0x12345678;}//正常情況,替Guest模擬執行CPUIDelse Asm_CPUID(g_GuestRegs.eax, &g_GuestRegs.eax, &g_GuestRegs.ebx, &g_GuestRegs.ecx, &g_GuestRegs.edx); }

    執行結果(CPUID的調用頻次不高,開啟調試信息問題不大):

    可以發現已經能夠正常處理CPUID指令,然后將EAX改為「Mini」的ASCII碼,再調用CPUID試試。

    ECX、EDX、EBX返回的結果正是Handle處理的結果,說明現在系統確實是處于VT模式。

    VMCALL

    描述:執行VMCALL指令時,能夠觸發一次VM-Exit。

    使用場景:當需要退出VT模式時,如果直接調用VMXOFF指令,由于Guest將沒有權限執行,因此將會出錯。可行的思路是先使用VMCALL切換到VMX root模式,由Host來執行退出部分的代碼。

    代碼實現

    ULONG g_vmcall_arg; ULONG g_stop_esp, g_stop_eip;void HandleVmCall() {if (g_vmcall_arg == 'SVT'){Vmx_VmClear(g_VMXCPU.pVMCSRegion_PA.LowPart, g_VMXCPU.pVMCSRegion_PA.HighPart);Vmx_VmxOff();__asm {mov esp, g_stop_espjmp g_stop_eip}}else {__asm int 3} }

    處理完這幾個退出碼之后,基本就初步實現了一個最小VT框架。如果后續遇到其它退出碼,可再通過查手冊解決。

    完整代碼

    //vtasm.h #ifndef VTASM_H #define VTASM_Htypedef union {struct{unsigned SSE3 : 1;unsigned PCLMULQDQ : 1;unsigned DTES64 : 1;unsigned MONITOR : 1;unsigned DS_CPL : 1;unsigned VMX : 1;unsigned SMX : 1;unsigned EIST : 1;unsigned TM2 : 1;unsigned SSSE3 : 1;unsigned Reserved : 22;};}_CPUID_ECX;typedef struct _IA32_FEATURE_CONTROL_MSR {unsigned Lock : 1; // Bit 0 is the lock bit - cannot be modified once lock is setunsigned Reserved1 : 1; // Undefinedunsigned EnableVmxon : 1; // Bit 2. If this bit is clear, VMXON causes a general protection exceptionunsigned Reserved2 : 29; // Undefinedunsigned Reserved3 : 32; // Undefined} IA32_FEATURE_CONTROL_MSR;typedef struct _VMX_BASIC_MSR {unsigned RevId : 32;unsigned szVmxOnRegion : 12;unsigned ClearBit : 1;unsigned Reserved : 3;unsigned PhysicalWidth : 1;unsigned DualMonitor : 1;unsigned MemoryType : 4;unsigned VmExitInformation : 1;unsigned Reserved2 : 9; } VMX_BASIC_MSR, * PVMX_BASIC_MSR;typedef union {struct{unsigned PE : 1;unsigned MP : 1;unsigned EM : 1;unsigned TS : 1;unsigned ET : 1;unsigned NE : 1;unsigned Reserved_1 : 10;unsigned WP : 1;unsigned Reserved_2 : 1;unsigned AM : 1;unsigned Reserved_3 : 10;unsigned NW : 1;unsigned CD : 1;unsigned PG : 1;//unsigned Reserved_64:32;};}_CR0;typedef union {struct {unsigned VME : 1;unsigned PVI : 1;unsigned TSD : 1;unsigned DE : 1;unsigned PSE : 1;unsigned PAE : 1;unsigned MCE : 1;unsigned PGE : 1;unsigned PCE : 1;unsigned OSFXSR : 1;unsigned PSXMMEXCPT : 1;unsigned UNKONOWN_1 : 1; //These are zerounsigned UNKONOWN_2 : 1; //These are zerounsigned VMXE : 1; //It's zero in normalunsigned Reserved : 18; //These are zero//unsigned Reserved_64:32;}; }_CR4;typedef union {struct{unsigned CF : 1;unsigned Unknown_1 : 1; //Always 1unsigned PF : 1;unsigned Unknown_2 : 1; //Always 0unsigned AF : 1;unsigned Unknown_3 : 1; //Always 0unsigned ZF : 1;unsigned SF : 1;unsigned TF : 1;unsigned IF : 1;unsigned DF : 1;unsigned OF : 1;unsigned TOPL : 2;unsigned NT : 1;unsigned Unknown_4 : 1;unsigned RF : 1;unsigned VM : 1;unsigned AC : 1;unsigned VIF : 1;unsigned VIP : 1;unsigned ID : 1;unsigned Reserved : 10; //Always 0//unsigned Reserved_64:32; //Always 0}; }_EFLAGS;void Asm_CPUID(ULONG uFn, PULONG uRet_EAX, PULONG uRet_EBX, PULONG uRet_ECX, PULONG uRet_EDX);void Asm_IN(ULONG uRet_EAX, ULONG uPort);ULONG64 Asm_ReadMsr(ULONG uIndex);ULONG Asm_GetEflags(); ULONG Asm_GetCs(); ULONG Asm_GetDs(); ULONG Asm_GetEs(); ULONG Asm_GetFs(); ULONG Asm_GetGs(); ULONG Asm_GetSs(); ULONG Asm_GetTr();ULONG Asm_GetGdtBase(); ULONG Asm_GetIdtBase(); ULONG Asm_GetGdtLimit(); ULONG Asm_GetIdtLimit();ULONG Asm_GetCr0(); ULONG Asm_GetCr3(); ULONG Asm_GetCr4();void Asm_SetCr4(ULONG uNewCr4);void Vmx_VmxOn(ULONG LowPart, ULONG HighPart); void Vmx_VmxOff();void Vmx_VmClear(ULONG LowPart, ULONG HighPart); void Vmx_VmPtrld(ULONG LowPart, ULONG HighPart); ULONG Vmx_VmRead(ULONG uField); void Vmx_VmWrite(ULONG uField, ULONG uValue); void Vmx_VmLaunch(); void Vmx_VmCall();#endif //vtasm.asm .686p .model flat, stdcall option casemap:none.data.codeAsm_CPUID Proc uses ebx esi edi fn:dword, ret_eax:dword, ret_ebx:dword, ret_ecx:dword, ret_edx:dwordmov eax, fncpuidmov esi, ret_eaxmov dword ptr [esi], eaxmov esi, ret_ebxmov dword ptr [esi], ebxmov esi, ret_ecxmov dword ptr [esi], ecxmov esi, ret_edxmov dword ptr [esi], edxret Asm_CPUID EndpAsm_IN Proc uRet_EAX:dword, uPort:dwordmov eax, uRet_EAXmov edx, uPortin eax, dx Asm_IN EndpAsm_ReadMsr Proc Index:dwordmov ecx,Indexrdmsrret Asm_ReadMsr EndpAsm_GetCr0 Procmov eax, cr0ret Asm_GetCr0 EndpAsm_GetCr3 Procmov eax, cr3ret Asm_GetCr3 EndpAsm_GetCr4 Procmov eax, cr4ret Asm_GetCr4 EndpAsm_SetCr4 Proc NewCr4:dwordmov eax,NewCr4mov cr4, eaxret Asm_SetCr4 EndpVmx_VmxOn Proc LowPart:dword,HighPart:dwordpush HighPartpush LowPartVmxon qword ptr [esp]add esp,8ret Vmx_VmxOn EndpVmx_VmxOff ProcVmxoffret Vmx_VmxOff EndpAsm_GetEflags PROCpushfdpop eaxret Asm_GetEflags ENDPVmx_VmClear Proc LowPart:dword,HighPart:dwordpush HighPartpush LowPartvmclear qword ptr [esp]add esp,8ret Vmx_VmClear endpVmx_VmPtrld Proc LowPart:dword,HighPart:dwordpush HighPartpush LowPartvmptrld qword ptr [esp]add esp,8ret Vmx_VmPtrld endpVmx_VmRead Proc uses ecx Field:dwordmov eax,Fieldvmread ecx,eaxmov eax,ecxret Vmx_VmRead endpVmx_VmWrite Proc uses ecx Field:dword,Value:dwordmov eax,Fieldmov ecx,Valuevmwrite eax,ecxret Vmx_VmWrite endpAsm_GetCs PROCmov eax, csret Asm_GetCs ENDPAsm_GetDs PROCmov eax, dsret Asm_GetDs ENDPAsm_GetEs PROCmov eax, esret Asm_GetEs ENDPAsm_GetSs PROCmov eax, ssret Asm_GetSs ENDPAsm_GetFs PROCmov eax, fsret Asm_GetFs ENDPAsm_GetGs PROCmov eax, gsret Asm_GetGs ENDPAsm_GetTr PROCstr eaxret Asm_GetTr ENDPAsm_GetGdtBase PROCLOCAL gdtr[10]:BYTEsgdt gdtrmov eax, dword PTR gdtr[2]ret Asm_GetGdtBase ENDPAsm_GetGdtLimit PROCLOCAL gdtr[10]:BYTEsgdt gdtrmov ax, WORD PTR gdtr[0]ret Asm_GetGdtLimit ENDPAsm_GetIdtBase PROCLOCAL idtr[10]:BYTEsidt idtrmov eax, dword PTR idtr[2]ret Asm_GetIdtBase ENDPAsm_GetIdtLimit PROCLOCAL idtr[10]:BYTEsidt idtrmov ax, WORD PTR idtr[0]ret Asm_GetIdtLimit ENDPVmx_VmLaunch Procvmlaunchret Vmx_VmLaunch endpVmx_VmCall Procvmcallret Vmx_VmCall endpEND //vtsystem.h #ifndef VTSYSTEM_H #define VTSYSTEM_H #include <ntddk.h>/*MSR definition*/ #define MSR_IA32_FEATURE_CONTROL 0x03a #define MSR_IA32_VMX_BASIC 0x480 #define MSR_IA32_VMX_PINBASED_CTLS 0x481 #define MSR_IA32_VMX_PROCBASED_CTLS 0x482 #define MSR_IA32_VMX_EXIT_CTLS 0x483 #define MSR_IA32_VMX_ENTRY_CTLS 0x484#define MSR_IA32_SYSENTER_CS 0x174 #define MSR_IA32_SYSENTER_ESP 0x175 #define MSR_IA32_SYSENTER_EIP 0x176 #define MSR_IA32_DEBUGCTL 0x1d9//VMX Exit Reasons #define EXIT_REASON_CPUID 10 #define EXIT_REASON_VMCALL 18 #define EXIT_REASON_CR_ACCESS 28typedef struct _VMX_CPU {PVOID pVMXONRegion;PHYSICAL_ADDRESS pVMXONRegion_PA;PVOID pVMCSRegion;PHYSICAL_ADDRESS pVMCSRegion_PA;PVOID pStack;BOOLEAN bVTStartSuccess; }VMX_CPU, * PVMX_CPU;/* VMCS Encordings */ enum {VIRTUAL_PROCESSOR_ID = 0x00000000,POSTED_INTR_NV = 0x00000002,GUEST_ES_SELECTOR = 0x00000800,GUEST_CS_SELECTOR = 0x00000802,GUEST_SS_SELECTOR = 0x00000804,GUEST_DS_SELECTOR = 0x00000806,GUEST_FS_SELECTOR = 0x00000808,GUEST_GS_SELECTOR = 0x0000080a,GUEST_LDTR_SELECTOR = 0x0000080c,GUEST_TR_SELECTOR = 0x0000080e,GUEST_INTR_STATUS = 0x00000810,HOST_ES_SELECTOR = 0x00000c00,HOST_CS_SELECTOR = 0x00000c02,HOST_SS_SELECTOR = 0x00000c04,HOST_DS_SELECTOR = 0x00000c06,HOST_FS_SELECTOR = 0x00000c08,HOST_GS_SELECTOR = 0x00000c0a,HOST_TR_SELECTOR = 0x00000c0c,IO_BITMAP_A = 0x00002000,IO_BITMAP_A_HIGH = 0x00002001,IO_BITMAP_B = 0x00002002,IO_BITMAP_B_HIGH = 0x00002003,MSR_BITMAP = 0x00002004,MSR_BITMAP_HIGH = 0x00002005,VM_EXIT_MSR_STORE_ADDR = 0x00002006,VM_EXIT_MSR_STORE_ADDR_HIGH = 0x00002007,VM_EXIT_MSR_LOAD_ADDR = 0x00002008,VM_EXIT_MSR_LOAD_ADDR_HIGH = 0x00002009,VM_ENTRY_MSR_LOAD_ADDR = 0x0000200a,VM_ENTRY_MSR_LOAD_ADDR_HIGH = 0x0000200b,TSC_OFFSET = 0x00002010,TSC_OFFSET_HIGH = 0x00002011,VIRTUAL_APIC_PAGE_ADDR = 0x00002012,VIRTUAL_APIC_PAGE_ADDR_HIGH = 0x00002013,APIC_ACCESS_ADDR = 0x00002014,APIC_ACCESS_ADDR_HIGH = 0x00002015,POSTED_INTR_DESC_ADDR = 0x00002016,POSTED_INTR_DESC_ADDR_HIGH = 0x00002017,EPT_POINTER = 0x0000201a,EPT_POINTER_HIGH = 0x0000201b,EOI_EXIT_BITMAP0 = 0x0000201c,EOI_EXIT_BITMAP0_HIGH = 0x0000201d,EOI_EXIT_BITMAP1 = 0x0000201e,EOI_EXIT_BITMAP1_HIGH = 0x0000201f,EOI_EXIT_BITMAP2 = 0x00002020,EOI_EXIT_BITMAP2_HIGH = 0x00002021,EOI_EXIT_BITMAP3 = 0x00002022,EOI_EXIT_BITMAP3_HIGH = 0x00002023,VMREAD_BITMAP = 0x00002026,VMWRITE_BITMAP = 0x00002028,XSS_EXIT_BITMAP = 0x0000202C,XSS_EXIT_BITMAP_HIGH = 0x0000202D,GUEST_PHYSICAL_ADDRESS = 0x00002400,GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401,VMCS_LINK_POINTER = 0x00002800,VMCS_LINK_POINTER_HIGH = 0x00002801,GUEST_IA32_DEBUGCTL = 0x00002802,GUEST_IA32_DEBUGCTL_HIGH = 0x00002803,GUEST_IA32_PAT = 0x00002804,GUEST_IA32_PAT_HIGH = 0x00002805,GUEST_IA32_EFER = 0x00002806,GUEST_IA32_EFER_HIGH = 0x00002807,GUEST_IA32_PERF_GLOBAL_CTRL = 0x00002808,GUEST_IA32_PERF_GLOBAL_CTRL_HIGH = 0x00002809,GUEST_PDPTR0 = 0x0000280a,GUEST_PDPTR0_HIGH = 0x0000280b,GUEST_PDPTR1 = 0x0000280c,GUEST_PDPTR1_HIGH = 0x0000280d,GUEST_PDPTR2 = 0x0000280e,GUEST_PDPTR2_HIGH = 0x0000280f,GUEST_PDPTR3 = 0x00002810,GUEST_PDPTR3_HIGH = 0x00002811,GUEST_BNDCFGS = 0x00002812,GUEST_BNDCFGS_HIGH = 0x00002813,HOST_IA32_PAT = 0x00002c00,HOST_IA32_PAT_HIGH = 0x00002c01,HOST_IA32_EFER = 0x00002c02,HOST_IA32_EFER_HIGH = 0x00002c03,HOST_IA32_PERF_GLOBAL_CTRL = 0x00002c04,HOST_IA32_PERF_GLOBAL_CTRL_HIGH = 0x00002c05,PIN_BASED_VM_EXEC_CONTROL = 0x00004000,CPU_BASED_VM_EXEC_CONTROL = 0x00004002,EXCEPTION_BITMAP = 0x00004004,PAGE_FAULT_ERROR_CODE_MASK = 0x00004006,PAGE_FAULT_ERROR_CODE_MATCH = 0x00004008,CR3_TARGET_COUNT = 0x0000400a,VM_EXIT_CONTROLS = 0x0000400c,VM_EXIT_MSR_STORE_COUNT = 0x0000400e,VM_EXIT_MSR_LOAD_COUNT = 0x00004010,VM_ENTRY_CONTROLS = 0x00004012,VM_ENTRY_MSR_LOAD_COUNT = 0x00004014,VM_ENTRY_INTR_INFO_FIELD = 0x00004016,VM_ENTRY_EXCEPTION_ERROR_CODE = 0x00004018,VM_ENTRY_INSTRUCTION_LEN = 0x0000401a,TPR_THRESHOLD = 0x0000401c,SECONDARY_VM_EXEC_CONTROL = 0x0000401e,PLE_GAP = 0x00004020,PLE_WINDOW = 0x00004022,VM_INSTRUCTION_ERROR = 0x00004400,VM_EXIT_REASON = 0x00004402,VM_EXIT_INTR_INFO = 0x00004404,VM_EXIT_INTR_ERROR_CODE = 0x00004406,IDT_VECTORING_INFO_FIELD = 0x00004408,IDT_VECTORING_ERROR_CODE = 0x0000440a,VM_EXIT_INSTRUCTION_LEN = 0x0000440c,VMX_INSTRUCTION_INFO = 0x0000440e,GUEST_ES_LIMIT = 0x00004800,GUEST_CS_LIMIT = 0x00004802,GUEST_SS_LIMIT = 0x00004804,GUEST_DS_LIMIT = 0x00004806,GUEST_FS_LIMIT = 0x00004808,GUEST_GS_LIMIT = 0x0000480a,GUEST_LDTR_LIMIT = 0x0000480c,GUEST_TR_LIMIT = 0x0000480e,GUEST_GDTR_LIMIT = 0x00004810,GUEST_IDTR_LIMIT = 0x00004812,GUEST_ES_AR_BYTES = 0x00004814,GUEST_CS_AR_BYTES = 0x00004816,GUEST_SS_AR_BYTES = 0x00004818,GUEST_DS_AR_BYTES = 0x0000481a,GUEST_FS_AR_BYTES = 0x0000481c,GUEST_GS_AR_BYTES = 0x0000481e,GUEST_LDTR_AR_BYTES = 0x00004820,GUEST_TR_AR_BYTES = 0x00004822,GUEST_INTERRUPTIBILITY_INFO = 0x00004824,GUEST_ACTIVITY_STATE = 0X00004826,GUEST_SYSENTER_CS = 0x0000482A,VMX_PREEMPTION_TIMER_VALUE = 0x0000482E,HOST_IA32_SYSENTER_CS = 0x00004c00,CR0_GUEST_HOST_MASK = 0x00006000,CR4_GUEST_HOST_MASK = 0x00006002,CR0_READ_SHADOW = 0x00006004,CR4_READ_SHADOW = 0x00006006,CR3_TARGET_VALUE0 = 0x00006008,CR3_TARGET_VALUE1 = 0x0000600a,CR3_TARGET_VALUE2 = 0x0000600c,CR3_TARGET_VALUE3 = 0x0000600e,EXIT_QUALIFICATION = 0x00006400,GUEST_LINEAR_ADDRESS = 0x0000640a,GUEST_CR0 = 0x00006800,GUEST_CR3 = 0x00006802,GUEST_CR4 = 0x00006804,GUEST_ES_BASE = 0x00006806,GUEST_CS_BASE = 0x00006808,GUEST_SS_BASE = 0x0000680a,GUEST_DS_BASE = 0x0000680c,GUEST_FS_BASE = 0x0000680e,GUEST_GS_BASE = 0x00006810,GUEST_LDTR_BASE = 0x00006812,GUEST_TR_BASE = 0x00006814,GUEST_GDTR_BASE = 0x00006816,GUEST_IDTR_BASE = 0x00006818,GUEST_DR7 = 0x0000681a,GUEST_RSP = 0x0000681c,GUEST_RIP = 0x0000681e,GUEST_RFLAGS = 0x00006820,GUEST_PENDING_DBG_EXCEPTIONS = 0x00006822,GUEST_SYSENTER_ESP = 0x00006824,GUEST_SYSENTER_EIP = 0x00006826,HOST_CR0 = 0x00006c00,HOST_CR3 = 0x00006c02,HOST_CR4 = 0x00006c04,HOST_FS_BASE = 0x00006c06,HOST_GS_BASE = 0x00006c08,HOST_TR_BASE = 0x00006c0a,HOST_GDTR_BASE = 0x00006c0c,HOST_IDTR_BASE = 0x00006c0e,HOST_IA32_SYSENTER_ESP = 0x00006c10,HOST_IA32_SYSENTER_EIP = 0x00006c12,HOST_RSP = 0x00006c14,HOST_RIP = 0x00006c16, };typedef struct _GUEST_REGS {ULONG eax;ULONG ecx;ULONG edx;ULONG ebx;ULONG esp;ULONG ebp;ULONG esi;ULONG edi;ULONG eip;ULONG eflags; }GUEST_REGS, * PGUEST_REGS;extern VMX_CPU g_VMXCPU;//檢查當前處理器是否支持VT BOOLEAN IsVTEnabled(); //開啟VT NTSTATUS StartVirtualTechnology(); //關閉VT NTSTATUS StopVirtualTechnology();#define Log(message,value) {{KdPrint(("[MinVT] %-40s [%p]\n",message,value));}}#endif //vtsystem.c #include "vtsystem.h" #include "vtasm.h" #include "exithandler.h"extern ULONG g_back_esp; extern ULONG g_back_eip;VMX_CPU g_VMXCPU;BOOLEAN IsVTEnabled() {ULONG uRet_EAX, uRet_ECX, uRet_EDX, uRet_EBX;_CPUID_ECX uCPUID;_CR0 uCr0;_CR4 uCr4;IA32_FEATURE_CONTROL_MSR msr;//1. CPUIDAsm_CPUID(1, &uRet_EAX, &uRet_EBX, &uRet_ECX, &uRet_EDX);*((PULONG)&uCPUID) = uRet_ECX;if (uCPUID.VMX != 1){Log("ERROR: 這個CPU不支持VT!", 0);return FALSE;}// 2. MSR*((PULONG)&msr) = (ULONG)Asm_ReadMsr(MSR_IA32_FEATURE_CONTROL);if (msr.Lock != 1){Log("ERROR:VT指令未被鎖定!", 0);return FALSE;}// 3. CR0 CR4*((PULONG)&uCr0) = Asm_GetCr0();*((PULONG)&uCr4) = Asm_GetCr4();if (uCr0.PE != 1 || uCr0.PG != 1 || uCr0.NE != 1){Log("ERROR:這個CPU沒有開啟VT!", 0);return FALSE;}if (uCr4.VMXE == 1){Log("ERROR:這個CPU已經開啟了VT!", 0);Log("可能是別的驅動已經占用了VT,你必須關閉它后才能開啟。", 0);return FALSE;}Log("SUCCESS:這個CPU支持VT!", 0);return TRUE; }static ULONG VmxAdjustControls(ULONG Ctl, ULONG Msr) {LARGE_INTEGER MsrValue;MsrValue.QuadPart = Asm_ReadMsr(Msr);Ctl &= MsrValue.HighPart; /* bit == 0 in high word ==> must be zero */Ctl |= MsrValue.LowPart; /* bit == 1 in low word ==> must be one */if (MSR_IA32_VMX_PINBASED_CTLS == Msr) //關閉外部中斷信號{Ctl &= ~1;}if (MSR_IA32_VMX_PROCBASED_CTLS == Msr) //關閉I/O訪問信號{Ctl &= ~0x03000000;}return Ctl; }static ULONG GetSegBase(ULONG Select) {ULONG GdtBase = Asm_GetGdtBase();ULONGLONG Descriptor = *(PULONGLONG)(GdtBase + Select);ULONG Base = 0;Base |= (Descriptor & 0xff00000000000000) >> 32;Base |= (Descriptor & 0x000000ff00000000) >> 16;Base |= (Descriptor & 0x00000000ffff0000) >> 16;return Base; }static ULONG GetSegLimit(ULONG Select) {ULONG GdtBase = Asm_GetGdtBase();ULONGLONG Descriptor = *(PULONGLONG)(GdtBase + Select);ULONG Limit = 0;Limit |= (Descriptor & 0x000f000000000000) >> 32;Limit |= Descriptor & 0x000000000000ffff;//if Desc.G == 1 ? 4kb : byteif (Descriptor & 0x0080000000000000){Limit <<= 12;Limit |= 0xfff;}return Limit; }static ULONG GetSegAR(ULONG Select) {ULONG GdtBase = Asm_GetGdtBase();ULONGLONG Descriptor = *(PULONGLONG)(GdtBase + Select);ULONG AR = 0;AR |= (Descriptor & 0x00f0ff0000000000) >> 40;return AR; }void __declspec(naked) GuestEntry() {__asm {mov ax, esmov es, axmov ax, dsmov ds, axmov ax, fsmov fs, axmov ax, gsmov gs, axmov ax, ssmov ss, axmov esp, g_back_espjmp g_back_eip} }void SetupVMCS() {ULONG GdtBase, IdtBase;GdtBase = Asm_GetGdtBase();IdtBase = Asm_GetIdtBase();//// 1.Guest State Area//Vmx_VmWrite(GUEST_CR0, Asm_GetCr0());Vmx_VmWrite(GUEST_CR3, Asm_GetCr3());Vmx_VmWrite(GUEST_CR4, Asm_GetCr4());Vmx_VmWrite(GUEST_DR7, 0x400);Vmx_VmWrite(GUEST_RFLAGS, Asm_GetEflags() & ~0x200); //cliVmx_VmWrite(GUEST_ES_SELECTOR, Asm_GetEs() & 0xFFF8);Vmx_VmWrite(GUEST_CS_SELECTOR, Asm_GetCs() & 0xFFF8);Vmx_VmWrite(GUEST_DS_SELECTOR, Asm_GetDs() & 0xFFF8);Vmx_VmWrite(GUEST_FS_SELECTOR, Asm_GetFs() & 0xFFF8);Vmx_VmWrite(GUEST_GS_SELECTOR, Asm_GetGs() & 0xFFF8);Vmx_VmWrite(GUEST_SS_SELECTOR, Asm_GetSs() & 0xFFF8);Vmx_VmWrite(GUEST_TR_SELECTOR, Asm_GetTr() & 0xFFF8);// 重要的段寄存器信息需要在進入Guest前加載Vmx_VmWrite(GUEST_CS_AR_BYTES, GetSegAR(Asm_GetCs() & 0xFFF8));Vmx_VmWrite(GUEST_CS_BASE, GetSegBase(Asm_GetCs() & 0xFFF8));Vmx_VmWrite(GUEST_CS_LIMIT, GetSegLimit(Asm_GetCs() & 0xFFF8));Vmx_VmWrite(GUEST_TR_AR_BYTES, GetSegAR(Asm_GetTr() & 0xFFF8));Vmx_VmWrite(GUEST_TR_BASE, GetSegBase(Asm_GetTr() & 0xFFF8));Vmx_VmWrite(GUEST_TR_LIMIT, GetSegLimit(Asm_GetTr() & 0xFFF8));// 其他寄存器可在進入Guest后加載,先將屬性的第16位置1,即不可用狀態Vmx_VmWrite(GUEST_ES_AR_BYTES, 0x10000);Vmx_VmWrite(GUEST_FS_AR_BYTES, 0x10000);Vmx_VmWrite(GUEST_DS_AR_BYTES, 0x10000);Vmx_VmWrite(GUEST_SS_AR_BYTES, 0x10000);Vmx_VmWrite(GUEST_GS_AR_BYTES, 0x10000);Vmx_VmWrite(GUEST_LDTR_AR_BYTES, 0x10000);// CS、ESP、EIPVmx_VmWrite(GUEST_SYSENTER_CS, Asm_ReadMsr(MSR_IA32_SYSENTER_CS) & 0xFFFFFFFF);Vmx_VmWrite(GUEST_SYSENTER_ESP, Asm_ReadMsr(MSR_IA32_SYSENTER_ESP) & 0xFFFFFFFF);Vmx_VmWrite(GUEST_SYSENTER_EIP, Asm_ReadMsr(MSR_IA32_SYSENTER_EIP) & 0xFFFFFFFF); // KiFastCallEntry// GDTRVmx_VmWrite(GUEST_GDTR_BASE, GdtBase);Vmx_VmWrite(GUEST_GDTR_LIMIT, Asm_GetGdtLimit());// LDTRVmx_VmWrite(GUEST_IDTR_BASE, IdtBase);Vmx_VmWrite(GUEST_IDTR_LIMIT, Asm_GetIdtLimit());Vmx_VmWrite(GUEST_RSP, ((ULONG)g_VMXCPU.pStack) + 0x1000); // Guest 臨時棧Vmx_VmWrite(GUEST_RIP, (ULONG)GuestEntry); // 客戶機的入口點// Link Shadow VMCSVmx_VmWrite(VMCS_LINK_POINTER, 0xffffffff);Vmx_VmWrite(VMCS_LINK_POINTER_HIGH, 0xffffffff);//// 2.Host State Area//Vmx_VmWrite(HOST_CR0, Asm_GetCr0());Vmx_VmWrite(HOST_CR3, Asm_GetCr3());Vmx_VmWrite(HOST_CR4, Asm_GetCr4());Vmx_VmWrite(HOST_ES_SELECTOR, Asm_GetEs() & 0xFFF8);Vmx_VmWrite(HOST_CS_SELECTOR, Asm_GetCs() & 0xFFF8);Vmx_VmWrite(HOST_DS_SELECTOR, Asm_GetDs() & 0xFFF8);Vmx_VmWrite(HOST_FS_SELECTOR, Asm_GetFs() & 0xFFF8);Vmx_VmWrite(HOST_GS_SELECTOR, Asm_GetGs() & 0xFFF8);Vmx_VmWrite(HOST_SS_SELECTOR, Asm_GetSs() & 0xFFF8);Vmx_VmWrite(HOST_TR_SELECTOR, Asm_GetTr() & 0xFFF8);Vmx_VmWrite(HOST_TR_BASE, GetSegBase(Asm_GetTr() & 0xFFF8));Vmx_VmWrite(HOST_GDTR_BASE, GdtBase);Vmx_VmWrite(HOST_IDTR_BASE, IdtBase);Vmx_VmWrite(HOST_IA32_SYSENTER_CS, Asm_ReadMsr(MSR_IA32_SYSENTER_CS) & 0xFFFFFFFF);Vmx_VmWrite(HOST_IA32_SYSENTER_ESP, Asm_ReadMsr(MSR_IA32_SYSENTER_ESP) & 0xFFFFFFFF);Vmx_VmWrite(HOST_IA32_SYSENTER_EIP, Asm_ReadMsr(MSR_IA32_SYSENTER_EIP) & 0xFFFFFFFF); // KiFastCallEntryVmx_VmWrite(HOST_RSP, ((ULONG)g_VMXCPU.pStack) + 0x2000); //Host 臨時棧Vmx_VmWrite(HOST_RIP, (ULONG)VMMEntryPoint); //這里定義我們的VMM處理程序入口//// 3.虛擬機運行控制域//Vmx_VmWrite(PIN_BASED_VM_EXEC_CONTROL, VmxAdjustControls(0, MSR_IA32_VMX_PINBASED_CTLS));Vmx_VmWrite(CPU_BASED_VM_EXEC_CONTROL, VmxAdjustControls(0, MSR_IA32_VMX_PROCBASED_CTLS));//// 4.VMEntry運行控制域//Vmx_VmWrite(VM_ENTRY_CONTROLS, VmxAdjustControls(0, MSR_IA32_VMX_ENTRY_CTLS));//// 5.VMExit運行控制域//Vmx_VmWrite(VM_EXIT_CONTROLS, VmxAdjustControls(0, MSR_IA32_VMX_EXIT_CTLS)); }NTSTATUS StartVirtualTechnology() {PVOID pVMXONRegion;PVOID pVMCSRegion;PVOID pStack;VMX_BASIC_MSR Msr;ULONG uRevId;_CR4 uCr4;_EFLAGS uEflags;if (!IsVTEnabled())return STATUS_NOT_SUPPORTED;//VMXE*((PULONG)&uCr4) = Asm_GetCr4();uCr4.VMXE = 1;Asm_SetCr4(*((PULONG)&uCr4));//VMX version*((PULONG)&Msr) = (ULONG)Asm_ReadMsr(MSR_IA32_VMX_BASIC);uRevId = Msr.RevId;//VMXON regionpVMXONRegion = ExAllocatePoolWithTag(NonPagedPool, 0x1000, 'vmon'); //4KBif (!pVMXONRegion){Log("ERROR:申請VMXON內存區域失敗!", 0);return STATUS_MEMORY_NOT_ALLOCATED;}RtlZeroMemory(pVMXONRegion, 0x1000);g_VMXCPU.pVMXONRegion = pVMXONRegion;g_VMXCPU.pVMXONRegion_PA = MmGetPhysicalAddress(pVMXONRegion);*((PULONG)g_VMXCPU.pVMXONRegion) = uRevId;//VMXONVmx_VmxOn(g_VMXCPU.pVMXONRegion_PA.LowPart, g_VMXCPU.pVMXONRegion_PA.HighPart);// if CF = 0*((PULONG)&uEflags) = Asm_GetEflags();if (uEflags.CF != 0){Log("ERROR:開啟VT失敗!", 0);return STATUS_UNSUCCESSFUL;}Log("SUCCESS:開啟VT成功!", 0);//VMCSpVMCSRegion = ExAllocatePoolWithTag(NonPagedPool, 0x1000, 'vmon'); //4KBif (!pVMCSRegion){Log("ERROR:申請VMCS內存區域失敗!", 0);return STATUS_MEMORY_NOT_ALLOCATED;}RtlZeroMemory(pVMCSRegion, 0x1000);*((PULONG)pVMCSRegion) = uRevId;g_VMXCPU.pVMCSRegion = pVMCSRegion;g_VMXCPU.pVMCSRegion_PA = MmGetPhysicalAddress(pVMCSRegion);Vmx_VmClear(g_VMXCPU.pVMCSRegion_PA.LowPart, g_VMXCPU.pVMCSRegion_PA.HighPart);Vmx_VmPtrld(g_VMXCPU.pVMCSRegion_PA.LowPart, g_VMXCPU.pVMCSRegion_PA.HighPart);//Stack,一半給Guest用,一半給Host用pStack = ExAllocatePoolWithTag(NonPagedPool, 0x2000, 'stck');if (!pStack){Log("ERROR:申請Stack內存區域失敗!", 0);return STATUS_MEMORY_NOT_ALLOCATED;}RtlZeroMemory(pStack, 0x2000);g_VMXCPU.pStack = pStack;//SetupSetupVMCS(); //設置VMCS字段//LaunchVmx_VmLaunch();//===================================================//正常情況下,VMLAUNCH執行后,CPU會進入虛擬機中//如果走到這里,說明執行失敗//===================================================Log("ERROR:VmLaunch指令調用失敗!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", Vmx_VmRead(VM_INSTRUCTION_ERROR))return STATUS_SUCCESS; }extern ULONG g_vmcall_arg; extern ULONG g_stop_esp; extern ULONG g_stop_eip;NTSTATUS StopVirtualTechnology() {_CR4 uCr4;g_vmcall_arg = 'STOP';__asm {pushadpushfdmov g_stop_esp, espmov g_stop_eip, offset STOP}Vmx_VmCall();STOP:__asm {popfdpopad}*((PULONG)&uCr4) = Asm_GetCr4();uCr4.VMXE = 0;Asm_SetCr4(*((PULONG)&uCr4));ExFreePool(g_VMXCPU.pVMXONRegion);ExFreePool(g_VMXCPU.pVMCSRegion);ExFreePool(g_VMXCPU.pStack);Log("SUCCESS:關閉VT成功!", 0);return STATUS_SUCCESS; } //exithandler.h #ifndef EXITHANDLER_H #define EXITHANDLER_Hvoid VMMEntryPoint(void);#endif //exithandler.c #include "exithandler.h" #include "vtsystem.h" #include "vtasm.h"GUEST_REGS g_GuestRegs;void HandleCPUID() {//特殊處理,用于測試VT是否開啟,注意保證參數的獨立性。if (g_GuestRegs.eax == 'Mini'){g_GuestRegs.ebx = 0x88888888;g_GuestRegs.ecx = 0x11111111;g_GuestRegs.edx = 0x12345678;}//正常情況,替Guest模擬執行CPUIDelse Asm_CPUID(g_GuestRegs.eax, &g_GuestRegs.eax, &g_GuestRegs.ebx, &g_GuestRegs.ecx, &g_GuestRegs.edx); }ULONG g_vmcall_arg; ULONG g_stop_esp, g_stop_eip;void HandleVmCall() {if (g_vmcall_arg == 'STOP'){Vmx_VmClear(g_VMXCPU.pVMCSRegion_PA.LowPart, g_VMXCPU.pVMCSRegion_PA.HighPart);Vmx_VmxOff();__asm {mov esp, g_stop_espjmp g_stop_eip}}else {__asm int 3} }void HandleCrAccess() {ULONG movcrControlRegister;ULONG movcrAccessType;ULONG movcrOperandType; //只是讀了,沒有使用,通常都是寄存器ULONG movcrGeneralPurposeRegister;ULONG movcrLMSWSourceData;ULONG ExitQualification;ExitQualification = Vmx_VmRead(EXIT_QUALIFICATION); //獲取具體信息movcrControlRegister = (ExitQualification & 0x0000000F); //控制寄存器下標movcrAccessType = ((ExitQualification & 0x00000030) >> 4); //讀/寫movcrOperandType = ((ExitQualification & 0x00000040) >> 6); //寄存器/內存movcrGeneralPurposeRegister = ((ExitQualification & 0x00000F00) >> 8); //寄存器下標if (movcrControlRegister != 3) { // not for cr3__asm int 3}if (movcrAccessType == 0) { // CR3 <-- reg32Vmx_VmWrite(GUEST_CR3, *(PULONG)((ULONG)&g_GuestRegs + 4 * movcrGeneralPurposeRegister));}else { // reg32 <-- CR3*(PULONG)((ULONG)&g_GuestRegs + 4 * movcrGeneralPurposeRegister) = Vmx_VmRead(GUEST_CR3);} }static void VMMEntryPointEbd(void) {ULONG ExitReason;ULONG ExitInstructionLength;ULONG GuestResumeEIP;ExitReason = Vmx_VmRead(VM_EXIT_REASON);ExitInstructionLength = Vmx_VmRead(VM_EXIT_INSTRUCTION_LEN);g_GuestRegs.eflags = Vmx_VmRead(GUEST_RFLAGS);g_GuestRegs.esp = Vmx_VmRead(GUEST_RSP);g_GuestRegs.eip = Vmx_VmRead(GUEST_RIP);//Log("ExitReason", ExitReason);//Log("g_GuestRegs.eip", g_GuestRegs.eip);switch (ExitReason){case EXIT_REASON_CPUID:HandleCPUID();Log("EXIT_REASON_CPUID", 0);break;case EXIT_REASON_VMCALL:HandleVmCall();Log("EXIT_REASON_VMCALL", 0);break;case EXIT_REASON_CR_ACCESS:HandleCrAccess();//Log("EXIT_REASON_CR_ACCESS", 0);break;default:Log("not handled reason: %p", ExitReason);__asm int 3;break;}//Resume:GuestResumeEIP = g_GuestRegs.eip + ExitInstructionLength;Vmx_VmWrite(GUEST_RIP, GuestResumeEIP);Vmx_VmWrite(GUEST_RSP, g_GuestRegs.esp);Vmx_VmWrite(GUEST_RFLAGS, g_GuestRegs.eflags); }void __declspec(naked) VMMEntryPoint(void) {__asm{mov g_GuestRegs.eax, eaxmov g_GuestRegs.ecx, ecxmov g_GuestRegs.edx, edxmov g_GuestRegs.ebx, ebxmov g_GuestRegs.esp, espmov g_GuestRegs.ebp, ebpmov g_GuestRegs.esi, esimov g_GuestRegs.edi, edipushfdpop eaxmov g_GuestRegs.eflags, eax//需要設置fs和gs,否則無法正常運行mov ax, fsmov fs, axmov ax, gsmov gs, ax}//盡量不要在裸函數中定義局部變量,或實現太多功能,最好封裝成函數VMMEntryPointEbd();__asm {mov eax, g_GuestRegs.eaxmov ecx, g_GuestRegs.ecxmov edx, g_GuestRegs.edxmov ebx, g_GuestRegs.ebxmov esp, g_GuestRegs.espmov ebp, g_GuestRegs.ebpmov esi, g_GuestRegs.esimov edi, g_GuestRegs.edi//vmresume__emit 0x0f__emit 0x01__emit 0xc3} } //driver.c #include <ntddk.h> #include "vtasm.h" #include "vtsystem.h"VOID DriverUnload(PDRIVER_OBJECT pDriver) {StopVirtualTechnology();DbgPrint("Driver unload. \r\n"); }ULONG g_back_esp; ULONG g_back_eip;NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path) {DbgPrint("Driver load. \r\n");pDriver->DriverUnload = DriverUnload;__asm{pushadpushfdmov g_back_esp, espmov g_back_eip, offset BACK}StartVirtualTechnology(); //開啟VTBACK:__asm{popfdpopad}//Log("Return To DriverEntry", 0);return STATUS_SUCCESS; }

    執行結果

    參考資料

    • VT虛擬化架構編寫視頻教程①~⑥課
    • 周鶴《VT技術入門》系列視頻教程
    • github項目:VT_Learn
    • github項目: HyperPlatform
    • Intel開發手冊 卷3:Chapter 23 ~ Chapter 33
    • x86內部函數列表

    總結

    以上是生活随笔為你收集整理的Intel VT学习笔记(六)—— VM-Exit Handler的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    亚洲永久精品在线 | 亚洲国产wwwccc36天堂 | 狠狠色伊人亚洲综合网站色 | 日韩欧美视频一区 | 亚洲在线精品 | 91自拍91| 成人看片| 国产日产精品一区二区三区四区 | 色婷婷在线播放 | 婷婷 综合 色| 亚洲精品国产精品乱码不99热 | 国产精品私拍 | 亚洲国产大片 | 久九视频| 最新国产精品拍自在线播放 | 人人草在线观看 | 天天插伊人 | 中文字幕色网站 | 麻豆传媒电影在线观看 | 亚洲国产影院 | 久久国内免费视频 | 亚洲精品视频二区 | 精品国产一区二区在线 | 久久五月天色综合 | 九九久久久久久久久激情 | 香蕉视频网站在线观看 | 在线国产视频 | 99草视频 | 一区二区三区日韩在线观看 | 久久久久综合视频 | 国产xxxx性hd极品 | 国产成人三级三级三级97 | 久99久精品视频免费观看 | 色综合天天狠狠 | 精品福利国产 | 国产精品高清在线观看 | 操操操日日日干干干 | 欧美大码xxxx | 麻豆成人网 | 色香蕉视频 | 免费的黄色av | 国产高清av在线播放 | 一区二区久久久久 | 久久国产女人 | 天天色棕合合合合合合 | 免费精品视频在线观看 | 久久8 | 亚洲国产精品成人av | 丁香电影小说免费视频观看 | 午夜影视av | 人成免费网站 | 久久精品国产一区二区三区 | 免费看一级片 | 99精品国产99久久久久久97 | 99产精品成人啪免费网站 | 精品在线观看视频 | 在线看成人 | 亚洲三级国产 | 国产精品99在线播放 | 国产黄色在线观看 | 中日韩免费视频 | 亚洲国产高清在线观看视频 | 日韩电影中文,亚洲精品乱码 | 国产视频一区二区三区在线 | 久久夜色精品国产欧美一区麻豆 | 久久极品| 99精品国产在热久久下载 | 深夜免费福利网站 | 天天色天天干天天色 | 一区二区三区免费 | 蜜臀av性久久久久蜜臀av | 日韩av在线高清 | 欧美一区二区三区在线视频观看 | 亚洲欧美视频一区二区三区 | 五月天综合色激情 | 丁香花在线观看视频在线 | 欧美 日韩 视频 | 欧美性一级观看 | 久久免费99精品久久久久久 | 色婷婷啪啪免费在线电影观看 | 在线免费观看黄色 | 四月婷婷在线观看 | 国产成人久久av免费高清密臂 | 免费成人在线观看 | 久久精品日产第一区二区三区乱码 | 日韩精品免费一区二区在线观看 | 中文字幕免费中文 | 在线观看视频三级 | 亚洲精品一区二区三区新线路 | 瑞典xxxx性hd极品 | 人人超在线公开视频 | 天天操狠狠操网站 | 成人va天堂 | 91最新地址永久入口 | 久久噜噜少妇网站 | 天天综合天天做天天综合 | 免费在线观看黄 | 久久精品一区 | 日韩区视频 | 欧美日韩精品国产 | 国产黄网站在线观看 | 中文伊人| 日本一区二区高清不卡 | 91看国产 | 极品国产91在线网站 | 少妇精品久久久一区二区免费 | 成年人免费观看国产 | 亚洲日本欧美在线 | 超碰97成人| 手机在线黄色网址 | 亚洲激情精品 | 国产精品久久久久久久妇 | 国产无区一区二区三麻豆 | 久久婷婷丁香 | 中文字幕乱偷在线 | 久久精品免费播放 | 狠狠色丁香 | 国产一区二区三区四区在线 | 国产又粗又猛又黄视频 | japanesexxxhd奶水 91在线精品一区二区 | 婷婷色在线 | 在线观看免费视频你懂的 | 日韩欧美在线一区 | aaa日本高清在线播放免费观看 | 福利区在线观看 | 日韩视频中文字幕在线观看 | 超碰在线人人草 | 国产伦理一区二区三区 | 亚洲精品在线看 | 美女网站色 | 亚洲日本韩国一区二区 | 在线看黄色的网站 | 久久精品美女视频网站 | 香蕉视频在线免费看 | 91在线免费播放视频 | 成人免费视频在线观看 | 亚洲资源网 | 久久不卡免费视频 | 五月婷婷黄色 | 就要干b | 日日草av | 欧美一区二区三区在线观看 | 久久天天躁狠狠躁夜夜不卡公司 | 97av.com| 欧美日韩一区三区 | 国产精品视屏 | 久草视频在 | 少妇视频一区 | 天天操天天操天天操天天操天天操 | 婷婷色站| 成人性生交大片免费观看网站 | 国产亚洲午夜高清国产拍精品 | 青青河边草免费直播 | 国内丰满少妇猛烈精品播放 | 西西大胆免费视频 | 国产精品久久久久久久久费观看 | 日韩色中色 | 中文字幕刺激在线 | 成人黄色一级视频 | 天堂激情网 | 碰超在线观看 | 婷婷伊人综合 | 91成人在线观看喷潮 | 天天操天操 | 亚洲第一中文字幕 | www久久99| av一区二区三区在线观看 | 国产免费观看视频 | 国产精品一区二区av日韩在线 | 最近最新最好看中文视频 | 国产精品久久久久久久久久不蜜月 | 日韩一区二区三区高清在线观看 | 欧美性粗大hdvideo | 日韩一级片大全 | 亚洲一区二区三区在线看 | 成人h视频在线播放 | 日韩久久片 | 69av免费视频 | 五月婷婷网站 | 天天插综合网 | 免费亚洲精品视频 | 91毛片在线 | 国产精品久久久久久久久久99 | 久久久久国产精品一区 | 麻豆视频在线播放 | 久草在线视频资源 | 日韩精品久久久久久久电影竹菊 | 国产一级二级三级视频 | 国产成人精品久久久久蜜臀 | 西西4444www大胆艺术 | 久久天堂网站 | 国产日韩欧美在线影视 | 久久免费毛片视频 | 五月婷婷一区二区三区 | 91精品国产一区二区在线观看 | 天天弄天天干 | 精品一区电影 | av噜噜噜在线播放 | 久久精品站 | 四虎www com | 综合激情| 丁香综合网 | 国产精品久久久久久久久久白浆 | 女人18片毛片90分钟 | 久视频在线播放 | 欧美精品午夜 | 九九九电影免费看 | 亚洲免费不卡 | 日本久久久久久久久久 | 久久成人国产精品免费软件 | 一区二区在线不卡 | 99精品成人 | 亚洲va欧洲va国产va不卡 | 日韩中文字幕视频在线观看 | 91麻豆.com| 999精品网| 天天插狠狠插 | 日本三级不卡视频 | 九色视频网址 | 在线精品视频在线观看高清 | 国产拍揄自揄精品视频麻豆 | av国产在线观看 | 国产99在线| 九九热免费在线视频 | 欧美一级黄色视屏 | 国产精品一区二区 91 | 精品国产伦一区二区三区观看体验 | 九九久久久久久久久激情 | 中文字幕中文字幕在线中文字幕三区 | 草久久久久久久 | 狂野欧美激情性xxxx | 51久久夜色精品国产麻豆 | www.久久婷婷 | 在线免费av网 | 日韩最新av在线 | 国产小视频在线免费观看 | av福利超碰网站 | 美女在线免费视频 | 成人禁用看黄a在线 | 在线观看网站黄 | 综合婷婷丁香 | 色老板在线视频 | 中文字幕亚洲精品在线观看 | 国产精品美女久久久网av | 欧美日韩免费在线视频 | 久草精品免费 | 黄色大全在线观看 | 五月天六月丁香 | 国产传媒中文字幕 | 五月天丁香 | 国产精品免费大片视频 | 最新av免费在线观看 | 欧美成人tv | 亚洲国产成人在线播放 | 黄色精品免费 | 黄色aa久久 | 99视频偷窥在线精品国自产拍 | 久亚洲| 中文国产成人精品久久一 | 欧美国产日韩一区二区三区 | 97伊人网| 久久综合五月天婷婷伊人 | 国产美女精品视频免费观看 | 欧美精品xx | 久久久久久久久久久电影 | 国产男女无遮挡猛进猛出在线观看 | 一区二区三区免费网站 | 婷婷久月| 免费av试看 | 国产精品精 | 久久超碰免费 | 成人福利在线观看 | 99视频这里只有 | 国产精品18videosex性欧美 | 欧美日韩高清一区二区三区 | 日韩专区在线播放 | 久精品一区 | 蜜臀av性久久久久蜜臀aⅴ四虎 | 欧美在线free| 免费99视频 | 欧美三级免费 | 一区二区在线不卡 | 国产精品成人久久久久久久 | 99久久精品午夜一区二区小说 | 婷婷久久综合九色综合 | 亚洲精品小视频 | 成人午夜久久 | 亚洲美女免费精品视频在线观看 | 射射色| 久久论理| 日韩精品观看 | 国产精品一区二区久久国产 | 久久久99久久 | 精品产品国产在线不卡 | 中文字幕有码在线 | 婷婷av网 | 久久久久麻豆v国产 | www免费| 夜夜躁日日躁狠狠久久av | 99re中文字幕| 毛片网站在线观看 | 久久精品国产精品 | 国产精品久久久久久久妇 | 97在线观看视频免费 | 国产成人亚洲在线观看 | 国产在线观看网站 | 激情五月婷婷激情 | 九九九视频在线 | 国产精品久久久久久av | 日韩精品中文字幕在线播放 | 免费观看视频的网站 | 国产在线免费av | 成人久久久精品国产乱码一区二区 | 99热在线看 | 2018好看的中文在线观看 | 91少妇精拍在线播放 | 欧美一级爽 | 日韩欧美高清在线 | 久久免费精品视频 | www.五月婷婷.com | 亚洲成a人片77777kkkk1在线观看 | 久久综合九色综合网站 | 国产精品国产亚洲精品看不卡15 | 国产精品日韩久久久久 | 蜜臀av性久久久久蜜臀aⅴ四虎 | 国产一级精品绿帽视频 | 国内精品视频在线 | 国产精品av免费 | 成人在线观看av | 色.www | 日韩在线观看中文字幕 | 午夜婷婷综合 | 狠狠操天天干 | 色婷五月天| 国产一区高清在线观看 | 中文一区二区三区在线观看 | 中文字幕亚洲综合久久五月天色无吗'' | 丝袜制服天堂 | 色资源中文字幕 | 国产99视频在线观看 | 色婷婷播放 | 久久99久久99精品免费看小说 | 国产成人免费网站 | 国产亚洲成av人片在线观看桃 | 国产高清久久久久 | 最近能播放的中文字幕 | 射射射av | 久久99久国产精品黄毛片入口 | 色综合色综合久久综合频道88 | 91天堂在线观看 | 久久黄色小说 | 97免费视频在线播放 | 日韩理论在线观看 | 五月天高清欧美mv | 久久久久久久久久久免费 | 国产福利91精品张津瑜 | 国产福利一区二区三区在线观看 | 99久久夜色精品国产亚洲96 | 午夜a区 | 一级黄色大片 | 久草网首页 | 国产91精品一区二区绿帽 | 久草在线手机视频 | 久久久久久久综合色一本 | 亚洲国产欧美在线人成大黄瓜 | 伊人夜夜 | 999在线视频 | 国产在线精品国自产拍影院 | 色视频在线观看 | 成年人在线看片 | 欧美一区二区在线免费看 | 日韩黄色在线观看 | 在线视频日韩欧美 | 欧美精品中文字幕亚洲专区 | 久久久久久片 | 亚洲免费在线观看视频 | 国产视频一区在线播放 | 伊人影院99 | 天天干天天操天天搞 | 色婷婷 亚洲 | 18国产精品白浆在线观看免费 | 91人人人 | a爱爱视频 | 在线观看免费版高清版 | www操操 | 1000部18岁以下禁看视频 | 国产在线观看国语版免费 | 久久超碰97 | 色婷婷www| 欧洲亚洲精品 | 国产精品免费久久久久 | 国产精品久久久久四虎 | 99久久精品国产一区二区三区 | 国模一区二区三区四区 | 亚洲欧美在线观看视频 | 黄色亚洲| 欧洲亚洲国产视频 | 久久优| 欧美日韩免费看 | 久久国产精品99国产精 | 男女男视频 | 美女久久久久久久久久 | 久久视频国产精品免费视频在线 | 一区二区三区福利 | 色永久免费视频 | 日韩视频一区二区 | 色橹橹欧美在线观看视频高清 | 国产最新精品视频 | 国产成年免费视频 | 婷婷天天色 | 中文字幕丝袜美腿 | 最近最新中文字幕 | 色在线中文字幕 | av黄网站 | 国产精品久久久精品 | 在线视频久 | 欧美男男激情videos | 欧洲激情综合 | 国产亚洲久久 | 国产精品毛片一区二区 | 天天看天天操 | 久久久久激情 | 国内亚洲精品 | 精品一区二区三区四区在线 | 免费观看的av网站 | 免费久久视频 | 人人爽人人 | 日韩欧美专区 | 99精品久久99久久久久 | 色的网站在线观看 | 亚洲永久国产精品 | 日韩av免费大片 | 国产韩国日本高清视频 | 日本精品在线 | www.com操| 伊人五月天 | 色哟哟国产精品 | 久久久网址 | 国产午夜精品一区二区三区 | 五月天堂网 | 天天综合狠狠精品 | 成人免费观看视频网站 | 国产日韩精品一区二区在线观看播放 | 欧美日韩免费观看一区二区三区 | 国产色爽 | 国产精品久久久久久麻豆一区 | 国产精品自产拍在线观看蜜 | 国产精品永久久久久久久www | 免费麻豆视频 | 麻豆视频网址 | 日本激情中文字幕 | 99久久99久久精品国产片 | 国产精品视频地址 | 久久成人18免费网站 | 激情网站免费观看 | 九九爱免费视频在线观看 | 久久成人视屏 | 亚洲精品99久久久久中文字幕 | 美女视频黄,久久 | 激情婷婷综合网 | 欧美精品被 | 日韩在线观看三区 | 国产1区2| 娇妻呻吟一区二区三区 | 在线欧美中文字幕 | 国产精品免费久久久久久久久久中文 | 亚洲综合小说电影qvod | 色婷婷综合成人av | 999在线视频 | 久久视精品 | 国产情侣一区 | 五月综合激情婷婷 | 97av精品 | 91在线超碰 | 一区二区三区四区久久 | www黄在线 | av高清不卡 | 国产精品白虎 | 91色蜜桃 | 国产视频每日更新 | 在线精品观看国产 | 日韩高清激情 | 99在线观看精品 | 在线观看av大片 | 啪啪激情网 | 在线播放一区二区三区 | 91精品国自产在线观看 | 国产麻豆精品久久一二三 | 久久精品日韩 | 日韩电影在线观看一区二区三区 | 9999激情| 香蕉视频18 | 五月花丁香婷婷 | 日韩草比| 精品高清美女精品国产区 | 天天操天 | 91中文字幕视频 | 香蕉久草在线 | 久久久男人的天堂 | 99在线观看 | 久久婷婷色综合 | 黄色影院在线播放 | 成人黄色小说在线观看 | 亚洲va综合va国产va中文 | 中文字幕黄色av | 超碰成人网| 欧洲精品在线视频 | 免费看黄的视频 | 久久久久亚洲精品中文字幕 | 国产v欧美| 一区二区三区免费在线播放 | 99国产精品久久久久久久久久 | 天天爱天天色 | 国产九色91 | 国内视频在线观看 | 高清av影院 | 在线观看韩日电影免费 | 18女毛片 | 国产乱码精品一区二区三区介绍 | 久久精品视频播放 | 国产一区在线视频播放 | 国产精品久久影院 | 亚洲精品一区二区三区新线路 | 精品国产中文字幕 | 国产永久免费高清在线观看视频 | 日韩精品中文字幕在线 | 国产精品99久久久久久人免费 | 天天干天天插 | 欧美一级片 | www.狠狠色 | 91人人揉日日捏人人看 | 91 在线视频 | 在线日韩精品视频 | 少妇bbbb | 伊人干综合 | 久久综合久色欧美综合狠狠 | 一区二区男女 | 国产中出在线观看 | 又黄又爽又无遮挡的视频 | 免费瑟瑟网站 | 麻豆影视在线观看 | 狠狠操狠狠操 | 粉嫩av一区二区三区入口 | 91黄色小视频 | 成人小视频在线 | 久久视频精品在线观看 | 成人av观看 | 女人18片毛片90分钟 | 午夜视频免费播放 | 精品高清美女精品国产区 | av在线播放快速免费阴 | 久久免费黄色大片 | 97色在线视频 | 久久综合影视 | av在线电影播放 | 久久99视频 | 狠狠干电影| 久久精品国产成人 | 天天色综合久久 | 在线视频区| 国产亚洲精品久久久久秋 | 国产精品成人在线 | 亚洲人视频在线 | 色视频在线免费 | 黄色成人影院 | 精品国产99国产精品 | 天天色天天干天天色 | 波多野结衣小视频 | 久久草草影视免费网 | 一区二区精品视频 | 国产福利a| 日韩理论影院 | 蜜桃视频精品 | 外国av网 | 免费观看一区二区三区视频 | 国产专区视频在线 | 亚洲精品美女久久久 | 一本一本久久a久久精品牛牛影视 | 国产精品xxxx18a99 | 久久av在线播放 | 国产精品亚洲片夜色在线 | 亚洲最新在线视频 | 高清精品在线 | 亚洲另类人人澡 | 色综合久久久久久中文网 | 欧美三人交 | 免费在线观看av网址 | 中文字幕91 | 日韩av不卡在线播放 | 岛国av在线免费 | 久久国产区 | 日韩电影在线观看一区二区三区 | 免费在线观看成人小视频 | 91香蕉国产在线观看软件 | 日日夜夜天天 | 亚洲黄色免费电影 | 久久国内视频 | 黄色在线免费观看网站 | 日韩黄色中文字幕 | 人人要人人澡人人爽人人dvd | 色综合久久88色综合天天免费 | 欧美a级一区二区 | 欧美日韩国产一区二区在线观看 | 国产成人精品综合久久久久99 | 操操碰| 中文字幕在线观看视频一区二区三区 | 久久福利电影 | 亚洲美女视频在线观看 | 天天做天天射 | 精品国产免费久久 | 日韩精品一区二 | 日韩欧美xxxx | 中文字幕视频在线播放 | 亚洲专区路线二 | 色香天天| 成人动漫一区二区三区 | 欧美日韩裸体免费视频 | 亚洲人av免费网站 | 麻豆久久久 | 91精品区 | 欧美 国产 视频 | 日韩av一区二区三区在线观看 | а天堂中文最新一区二区三区 | 久久精品首页 | 中文字幕精品www乱入免费视频 | 日日躁你夜夜躁你av蜜 | 日本大片免费观看在线 | 午夜精品福利一区二区三区蜜桃 | 久久久99精品免费观看app | 99re久久资源最新地址 | 最近中文字幕国语免费av | 免费观看性生交 | 免费在线观看成人小视频 | 天天夜夜狠狠操 | 丁香婷婷综合网 | 日韩免费中文 | 最近免费中文字幕 | 欧美一级在线观看视频 | 天天爱天天操天天干 | 又大又硬又黄又爽视频在线观看 | 日韩欧美在线观看一区二区 | 成人久久18免费网站图片 | 在线之家免费在线观看电影 | 深夜免费福利 | 婷婷五月色综合 | 国产99久久精品一区二区永久免费 | 成人午夜在线电影 | 午夜美女av| 日日干天天爽 | 中文不卡视频 | 亚洲精品福利在线观看 | 狠狠狠狠狠狠狠狠干 | 天天综合亚洲 | 91亚洲精品久久久蜜桃 | 999视频在线播放 | 精品久久久网 | 蜜桃av人人夜夜澡人人爽 | 欧美一级专区免费大片 | 成人精品999 | 午夜久久福利影院 | 欧美日韩高清在线 | 97人人艹| 亚洲国产精品电影在线观看 | 9999毛片 | 亚洲黄色在线免费观看 | 成人va视频| 狠狠久久综合 | 日韩欧美一区二区在线 | 国产色在线观看 | 国产亚洲精品成人 | 国产在线欧美 | 91大神精品视频在线观看 | 草在线 | 在线观看成年人 | 日本精品视频在线观看 | 欧美性色19p | 精品国产综合区久久久久久 | 精品久久久久国产免费第一页 | 玖玖在线播放 | 中文av在线播放 | 亚洲精品国产第一综合99久久 | 国产在线播放不卡 | 成人黄在线观看 | 婷婷日| 亚洲精品国偷拍自产在线观看 | 免费视频在线观看网站 | 精品 一区 在线 | 亚洲手机av | 日韩在线视频一区 | 深爱激情五月综合 | 国产精品理论视频 | 欧美一区二区三区在线播放 | 日韩欧美国产精品 | 成人免费一级 | 国产亚洲精品电影 | av日韩国产| 成人一级在线 | 国产亚洲人 | 特级西西444www高清大视频 | 一区二区精品国产 | 欧美一区二视频在线免费观看 | 日韩免费中文 | 欧美人交a欧美精品 | 99精品一级欧美片免费播放 | 久久调教视频 | 国产成人精品女人久久久 | 日本精品视频在线播放 | 午夜成人免费影院 | 免费视频一区二区 | 在线观看视频国产一区 | 天天夜夜狠狠操 | 国产99在线 | 亚洲精品自拍视频在线观看 | 天天操天天操一操 | 六月激情婷婷 | 日韩精品在线视频免费观看 | 欧美日韩视频精品 | 国产经典 欧美精品 | 精品一二三四五区 | 久草在线观 | 国产色视频网站2 | 国产97在线看 | 国产精品综合av一区二区国产馆 | 韩国av一区二区三区在线观看 | 国产五码一区 | 国产免费视频在线 | 成人永久免费 | 国产一线天在线观看 | 国产婷婷精品av在线 | 亚洲精品国产品国语在线 | av电影一区二区三区 | 色老板在线视频 | 色综合久久中文综合久久牛 | 天天做天天看 | 在线精品观看 | 亚在线播放中文视频 | 叶爱av在线 | 久久久久女人精品毛片 | 亚洲三级性片 | 国产免费久久 | 国产中文字幕视频在线观看 | 天天搞天天干 | 在线免费观看欧美日韩 | 久久精品爱爱视频 | 中文成人字幕 | 久久视频免费在线观看 | 九九免费在线观看 | 国产在线久草 | 一级片在线| 亚洲三级黄 | 伊人首页 | 国产不卡片 | 国产另类av| 亚洲蜜桃在线 | 久草在线综合网 | 美女在线观看av | 黄色片毛片| 色橹橹欧美在线观看视频高清 | 一区二区三区不卡在线 | 探花系列在线 | 在线 视频 一区二区 | 超碰人人干人人 | 久久99这里只有精品 | 中文字幕 国产精品 | 亚洲精品久久激情国产片 | 国产最顶级的黄色片在线免费观看 | 国产一级高清 | 最近最新mv字幕免费观看 | 99亚洲精品在线 | 国产精品成人一区二区三区 | 日韩久久精品一区 | 久久精品视频中文字幕 | 国产精品一区二区在线 | 中文一区在线观看 | 日韩在线观看中文字幕 | 国产最新在线 | 免费国产一区二区 | 免费视频久久久久 | 又黄又刺激的视频 | 国产视频在线播放 | 免费观看一级成人毛片 | 日韩电影中文字幕 | 久操操| 深夜免费福利视频 | 精品成人久久 | 久黄色| 久久首页| 色网站在线免费观看 | 国产一二三区在线观看 | 国产99re | 久久国产香蕉视频 | 亚洲精品456在线播放乱码 | 婷婷色视频 | 最近日韩免费视频 | 亚洲蜜桃av | 国产理论影院 | 精品亚洲视频在线观看 | 久久久污 | 91精品欧美一区二区三区 | 中午字幕在线 | 91在线播 | 国产又粗又猛又黄又爽 | 国产精品九九九九九九 | 国产精品扒开做爽爽的视频 | 亚洲国产激情 | 国产成人在线一区 | 天天干,天天射,天天操,天天摸 | 亚州精品国产 | 国产精品日韩 | 91精品国产高清自在线观看 | 色婷婷97 | 国产精品久久久久久吹潮天美传媒 | 91高清完整版在线观看 | 国产黄色视 | a级片在线播放 | 亚洲第一成网站 | 亚洲国产欧美在线看片xxoo | 亚洲精品国产精品99久久 | 999国内精品永久免费视频 | 亚洲国产视频网站 | 69国产在线观看 | 精品久久久国产 | 黄色网址国产 | 国产一区免费观看 | 毛片网在线观看 | 97在线资源 | 日韩av偷拍 | 亚洲伊人婷婷 | 色黄www小说 | 美女视频黄免费网站 | 天天操天天操天天爽 | 欧美性超爽 | 久久精品视频免费观看 | 中文字幕第一页在线视频 | 欧美午夜精品久久久久 | 国产在线观看中文字幕 | 青青草视频精品 | 国产成人一级电影 | 国产污视频在线观看 | 亚洲视频第一页 | 日韩一三区 | 国产在线观看污片 | 久久亚洲区 | 国产精品一区二区白浆 | 日韩女同一区二区三区在线观看 | av 一区二区三区四区 | 久久精品免费播放 | 久久免费视频这里只有精品 | 精品国产福利在线 | 国产打女人屁股调教97 | 91精品秘密在线观看 | 中文字幕在线看视频国产中文版 | 日韩三级在线 | 中文字幕在线观看91 | 在线中文字幕观看 | 国产xvideos免费视频播放 | 999视频在线播放 | 国产精品不卡一区 | 日韩av免费观看网站 | 日韩三级免费观看 | 国产精品96久久久久久吹潮 | 日韩亚洲国产中文字幕 | 狠狠干我| 99久久久国产精品美女 | 国产成人精品综合久久久久99 | 成人免费xxxxxx视频 | 国产精品二区三区 | 亚洲激情免费 | zzijzzij亚洲成熟少妇 | 九九热视频在线免费观看 | 深夜免费福利 | 96看片 | 91视视频在线直接观看在线看网页在线看 | 玖玖国产精品视频 | 91福利视频免费观看 | 国产精品高潮久久av | 国产精品嫩草影院123 | 欧美人zozo | 99精品视频播放 | 国产精品久久久久久久久久久久午夜 | 一区二区三区免费播放 | 国产.精品.日韩.另类.中文.在线.播放 | 视频在线观看一区 | 久久久人人人 | 日韩精品一区二区三区免费视频观看 | 免费看的黄网站 | 中文字幕在线中文 | 亚洲做受高潮欧美裸体 | 午夜视频免费在线观看 | 97理论电影 | 五月婷婷综合在线 | 亚洲综合五月 | 国产伦理久久精品久久久久_ | 天天狠狠操| 久久久久一区二区三区四区 | 91在线你懂的| 亚洲国产精品电影 | 在线亚洲播放 | 日韩免费在线观看 | 欧美一级片播放 | 久久久香蕉视频 | 五月激情丁香婷婷 | 999久久a精品合区久久久 | 免费a v网站 | 日本护士三级少妇三级999 | 国产免费又粗又猛又爽 | 成人羞羞视频在线观看免费 | 在线观看免费视频 | 丰满少妇对白在线偷拍 | 久久资源在线 | 亚洲开心激情 | 黄色国产高清 | 色婷婷国产精品一区在线观看 | 久久久精品影视 | 91精品国产91p65| 亚洲va天堂va欧美ⅴa在线 | 一级性视频 | 丁香五月缴情综合网 | 日日夜夜添 | 国产成人久 | 99久久久国产免费 | 国产中文字幕一区 | 天天射成人| 一区二区三区免费在线 | 久久久久久久久久影视 | 精品久久网站 | 激情视频免费观看 | 欧美一级性生活片 | 中文字幕视频一区二区 | 一区免费在线 | 粉嫩av一区二区三区四区在线观看 | 欧美a级在线播放 | 中文字幕亚洲欧美 | 91av社区 | 激情欧美一区二区三区 | 黄色免费电影网站 | 国产视频欧美视频 | 久久99国产精品 | 久久免费黄色 | 亚洲一区二区三区四区在线视频 | 9在线观看免费高清完整 | 69精品 | 国产免费黄视频在线观看 | 高清av免费观看 | 日韩在线视频精品 | 中文字幕在线日 | 亚洲在线视频网站 | 夜色资源网 | 久久国产免 | 中文字幕一区二区三区乱码在线 | 国产精品一区二区三区免费看 | 亚洲天天综合 | 中文字幕中文字幕 | 美女黄频免费 | 91精品视频一区 | 国模精品在线 | 久久一区二区三区国产精品 | 欧美 日韩 国产 成人 在线 | 国内精品久久久久影院优 | 日韩精品国产一区 | 亚洲人xxx | 久影院 | 国产日韩在线视频 | 天天天天射 | 2022国产精品视频 | 国产一区久久 | 天堂网一区 | 亚洲人成免费网站 | 欧美一二三区播放 | 四虎在线观看 | 日韩专区 在线 | 91亚·色 | 国产免费久久 | 在线观看理论 | 久久经典国产 | 国产亚州精品视频 | 免费视频网| 欧美日韩国产一区二 | 黄色大片中国 | 波多野结衣理论片 | 在线观看中文字幕dvd播放 | 亚洲精品中文在线观看 | 午夜精品久久久久久久久久久久久久 | 五月婷婷电影网 | 欧美激情精品久久久久久免费印度 | 三级黄免费看 | 97av在线 | 亚洲自拍偷拍色图 | 国产中文字幕国产 | 欧美老女人xx | 国产精品正在播放 | 91最新在线视频 | 国产中文字幕一区二区 | 一个色综合网站 | 日韩视频在线播放 | 日韩一级电影在线观看 | 国产精品高潮久久av | 亚洲激情婷婷 |