08_基本框架_ExitHandler
》 根据 进入VM_EXIT 的原因处理异常
1 // 获取 进入 VMExit 的 原因 3 ExitReason = Vmx_VmRead(VM_EXIT_REASON); 4 // 获取导致 VMExit 的 Opcode 的长度 5 ExitInstructionLength = Vmx_VmRead(VM_EXIT_INSTRUCTION_LEN); 6 // 获取关键 现场环境 7 g_GuestRegs.eflags = Vmx_VmRead(GUEST_EFLAGS); 8 g_GuestRegs.esp = Vmx_VmRead(GUEST_RSP); 9 g_GuestRegs.eip = Vmx_VmRead(GUEST_EIP); 10 11 // 根据 Exit 原因类型,进行处理: 12 switch(ExitReason) 13 { 14 case EXIT_REASON_CPUID:// Handle CPUID 15 HandleCPUID(); 16 Log("EXIT_REASON_CPUID",0); 17 break; 18 case EXIT_REASON_VMCALL:// Handle VMCALL 19 HandleVmCall(); 20 Log("EXIT_REASON_VMCALL",0); 21 break; 22 case EXIT_REASON_CR_ACCESS: 23 HandleCrAccess(); 24 Log("EXIT_REASON_CR_ACCESS!",0); 25 break; 26 default:// As so far, the Exit_Reasons not gonna deal! 27 Log("No setted Handler of Reason:%p",ExitReason); 28 __asm int 3; 29 } 30 //Resume: 设置Guest 继续执行的位置环境 31 // prepare for VM Resuming 32 GuestResumeEIP = g_GuestRegs.eip + ExitInstructionLength; 33 Vmx_VmWrite(GUEST_RIP, GuestResumeEIP); 34 Vmx_VmWrite(GUEST_RSP, g_GuestRegs.esp); 35 36 Vmx_VmWrite(GUEST_RFLAGS, g_GuestRegs.eflags);
2 VM_EXIT Resume. (settled the exit quest and Resume VM)
save the context to resume the VM
1 __asm{ 2 3 // 保存来时的环境 4 mov g_GuestRegs.eax, eax 5 mov g_GuestRegs.ecx, ecx 6 mov g_GuestRegs.edx, edx 7 mov g_GuestRegs.ebx, ebx 8 mov g_GuestRegs.esp, esp 9 mov g_GuestRegs.ebp, ebp 10 mov g_GuestRegs.esi, esi 11 mov g_GuestRegs.edi, edi 12 13 pushfd 14 pop eax 15 mov g_GuestRegs.eflags, eax 16 17 mov ax, fs// 通过切换段选择子,刷新段选择子对应的隐藏部分 18 mov fs, ax 19 mov ax, gs 20 mov gs, ax 21 } 22 // ************************************************** 23 24 // between save and restore! 25 // we can run the handler!!!******************* 26 VMMEntryPointEbd();// In this function , it concluds the main operations. 27 28 // ************************************************** 29 // Resume 30 __asm{ 31 // 恢复来时的环境 32 mov eax, g_GuestRegs.eax 33 mov ecx, g_GuestRegs.ecx 34 mov edx, g_GuestRegs.edx 35 mov ebx, g_GuestRegs.ebx 36 mov esp, g_GuestRegs.esp 37 mov ebp, g_GuestRegs.ebp 38 mov esi, g_GuestRegs.esi 39 mov edi, g_GuestRegs.edi 40 41 // vmresume -- Guest 继续执行 , 这里硬编码而不是call vmx_vmresume()的好处是可以避免栈的变化 42 __emit 0x0f 43 __emit 0x01 44 __emit 0xc3 45 46 }
3 Stop VT ( In Driver Unload..)
When Calls StopVt Func, set the VtEnd FlagVar
1 NTSTATUS StopVirtualTechnology() 2 3 { 4 _CR4 uCr4; 5 if(g_VMXCPU.bVTStartSuccess) 6 { 7 g_vmcall_arg = 'SVT'; 8 __asm{ 9 pushad 10 pushfd 11 mov g_stop_esp, esp 12 mov g_stop_eip, offset LLL 13 } 14 Vmx_VmCall();// to query VmOff() from Handler System 15 // when it handled ,it ret to LLL. 16 LLL: 17 __asm{ 18 popfd 19 popad 20 } 21 g_VMXCPU.bVTStartSuccess = FALSE; 22 *((PULONG)&uCr4) = Asm_GetCr4(); 23 uCr4.VMXE = 0; 24 Asm_SetCr4(*((PULONG)&uCr4)); 25 26 ExFreePool(g_VMXCPU.pVMXONRegion); 27 ExFreePool(g_VMXCPU.pVMCSRegion); 28 ExFreePool(g_VMXCPU.pStack); 29 30 Log("SUCCESS:关闭VT成功!",0); 31 Log("SUCCESS:现在这个CPU退出了VMX模式.",0); 32 } 33 34 return STATUS_SUCCESS; 35 36 }
In handler frame(see 1), the handle func:
1 void HandleVmCall() 2 3 { 4 // A global FlagVar to Verify End or not 5 if (g_vmcall_arg == 'SVT') 6 {// Done the End Flag, Then End VM 7 Vmx_VmClear(g_VMXCPU.pVMCSRegion_PA.LowPart,g_VMXCPU.pVMCSRegion_PA.HighPart); 8 Vmx_VmxOff();// Turn off the VM 9 __asm{ 10 mov esp, g_stop_esp 11 jmp g_stop_eip// return to the StopVT func()/* 12 //inside the func,after VmCall 13 } 14 } else { 15 __asm int 3 16 } 17 18 }
测试效果~!
到当前进度我github上项目源码


浙公网安备 33010602011771号