中断拦截
在VMCS域内设置 Exception Bitmap
可接管guest系统中断。
事件注入
vmm可以设置事件注入(event injection
)IDT,以便在进入guest之后执行中断例程,详见Intel白皮书 24.8.3。其事件注入的时机为guest环境刚刚恢复resume后,模拟CPU中断调用IDT表中的中断例程,实现host接管中断的透明化。
在vmm接管到系统中断时,可通过读 VM-Exit Interruption-Information Field
获取中断类型type以及中断号vector。
通过设置 VM-Entry Interruption-Information Field
以及 VM-entry exception error code
、VM-entry instruction length
实现事件注入。
code
VT框架中关于中段拦截与事件注入的相关代码如下:
void HandleOfInterruption()
{
ExitInterruptInformation ExitInterruptInfo = { 0 };
asm_vmread(&ExitInterruptInfo, VM_EXIT_INTR_INFO);
if (ExitInterruptInfo.Bits.valid)
{
/*
中断类型: 0.外部中断, 2.nmi, 3.硬件中断, 6.软中断
*/
if (ExitInterruptInfo.Bits.vector == 3) // int3 软中断
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] int3 ==> GuestRIP: 0x%p, GuestRSP: 0x%p\n", g_pGuestRegs->rip, g_pGuestRegs->rsp);
}
/*
else if (ExitInterruptInfo.Bits.vector == 1) // debug 硬件中断
{
//DbgBreakPoint();
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] debug ==> GuestRIP: 0x%p, GuestRSP: 0x%p\n", g_pGuestRegs->rip, g_pGuestRegs->rsp);
g_pGuestRegs->rflags &= 0xfffffffffffffeff;
}
*/
else
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[+] 未处理中断 ==> type: %d, index: %d\n", ExitInterruptInfo.Bits.type, ExitInterruptInfo.Bits.vector);
/*
事件注入
*/
VmEntryInterruptionInformationField InterruptionInformationField = { 0 };
InterruptionInformationField.Bits.valid = TRUE;
InterruptionInformationField.Bits.type = ExitInterruptInfo.Bits.type;
InterruptionInformationField.Bits.vector = ExitInterruptInfo.Bits.vector;
if (ExitInterruptInfo.Bits.errorCodeValid)
{
UINT64 ExitInterruptErrorCode = 0;
InterruptionInformationField.Bits.deliver_error_code = TRUE;
asm_vmread(&ExitInterruptErrorCode, VM_EXIT_INTR_ERROR_CODE);
asm_vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, ExitInterruptErrorCode);
}
__int64 ExitInstructionLength = 0;
asm_vmread(&ExitInstructionLength, VM_EXIT_INSTRUCTION_LEN);
asm_vmwrite(VM_ENTRY_INSTRUCTION_LEN, ExitInstructionLength);
asm_vmwrite(VM_ENTRY_INTR_INFO_FIELD, InterruptionInformationField.all);
}
else
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[!] 无效ExitInterruptInfo.\n");
}