woshidc523 发表于 2018-1-22 11:41:03

VmExitEvent为什么会死循环呢...

看了TA大大之前,关于VT的帖子【链接我就不发了,想看的坛友们,还是自己找一找吧,说不定有其他主题你也喜欢呢】

一直都感觉vt很神秘,很想自己尝试一下,于是在github上找到一些vt的源码,包括之前 落笔飞花 在论坛里分享给我们的源码,还找一份比较简单直接的源码。HyperBone~这个大家可以在github上直接搜索找到,我就不再贴链接了。

刚开始接触,连项目属性怎么设置都不知道,编译总是不通过,附件代码是修改过项目属性的,win7debug和win10debug大家可以放心使用,如果想编译其他平台,请仔细修改项目属性BuildEvent中的Post-build Event,应该是代码作者自己修改的。。。

回到问题上,编译没有问题,然后我再win7x64平台,windbg开始调试了。

因为我是这两天才开始看vt的,基础很薄弱,就不和大家瞎扯看懂了什么了,就直接说问题吧。在整个vt建立完成之后,就是VmxpExitHandler作为主要处理函数了,根据中断事件分配给不同的函数处理,像我们正常驱动的DeviceIOControl一样,ring3发消息,ring0接收处理一样。
驱动加载完成,我打开c盘就卡死了,断点下到VmExitEvent之后,一直走INTERRUPT_SOFTWARE_EXCEPTION中的VECTOR_BREAKPOINT_EXCEPTION,虚拟机已经卡死。
VOID VmExitEvent( IN PGUEST_STATE GuestState )
{
    INTERRUPT_INFO_FIELD Event = { 0 };
    ULONG64 ErrorCode = 0;
    ULONG InstructionLength = (ULONG)VmcsRead( VM_EXIT_INSTRUCTION_LEN );

    Event.All = (ULONG32)VmcsRead( VM_EXIT_INTR_INFO );
    ErrorCode = VmcsRead( VM_EXIT_INTR_ERROR_CODE );
    if (Event.Fields.ErrorCodeValid)
      __vmx_vmwrite( VM_ENTRY_EXCEPTION_ERROR_CODE, ErrorCode );

    switch (Event.Fields.Type)
    {
    case INTERRUPT_NMI:
      DPRINT( "HyperBone: CPU %d: %s: HandleNmi()\n", CPU_IDX, __FUNCTION__ );
      VmxInjectEvent( INTERRUPT_NMI, VECTOR_NMI_INTERRUPT, 0 );
      ASSERT( FALSE );
      break;

    case INTERRUPT_HARDWARE_EXCEPTION:
      DPRINT( "HyperBone: CPU %d: %s: Hardware Exception (vector = 0x%x)\n", CPU_IDX, __FUNCTION__, Event.Fields.Vector );
      VmxInjectEvent( Event.Fields.Type, Event.Fields.Vector, InstructionLength );
      break;

    case INTERRUPT_SOFTWARE_EXCEPTION:
      switch (Event.Fields.Vector)
      {
      case VECTOR_BREAKPOINT_EXCEPTION:
            DPRINT( "HyperBone: CPU %d: %s: int3 EIP = 0x%p\n", CPU_IDX, __FUNCTION__, GuestState->GuestRip );
            VmxInjectEvent( INTERRUPT_SOFTWARE_EXCEPTION, VECTOR_BREAKPOINT_EXCEPTION, InstructionLength );
            break;

      default:
            DPRINT( "HyperBone: CPU %d: %s: Software Exception (vector = 0x%X)\n", CPU_IDX, __FUNCTION__, Event.Fields.Vector );
            VmxInjectEvent( Event.Fields.Type, Event.Fields.Vector, InstructionLength );
            break;
      }
      break;

    default:
      DPRINT( "HyperBone: CPU %d: %s: Unhandled event type %d\n", CPU_IDX, __FUNCTION__, Event.Fields.Type );
      VmxInjectEvent( Event.Fields.Type, Event.Fields.Vector, InstructionLength );
      break;
    }
}

我真的是新手,不会找什么资料,希望知道的大神可以指点一下,教育也好侮辱也好,求指条明路,这个问题到底是什么情况,我该怎么才能更好理解vt

Tesla.Angela 发表于 2018-1-22 15:04:07

这不是死循环,而是多次触发VMEXIT。

此外INTEL的VT框架建议参考INTEL官方工程HAXM。

woshidc523 发表于 2018-1-22 16:45:03

Tesla.Angela 发表于 2018-1-22 15:04
这不是死循环,而是多次触发VMEXIT。

此外INTEL的VT框架建议参考INTEL官方工程HAXM。 ...

谢谢TA大大,我会去看看HAXM。

我能知道为什么会多次触发VMEXIT吗,VT加载完成后都没事儿,但是打开vs调试软件就会直接卡死【vs远程调试器只是其中一种情况】

tangptr@126.com 发表于 2018-6-26 16:14:13

本帖最后由 tangptr@126.com 于 2018-10-13 03:54 编辑

详情请看Intel 64与IA-32架构程序员开发手册第三卷第25章第2节与第26章第5节第1.2次节。
你的问题在这手册的这两节里有描述。
HyperBone会直接把拦截到的软件异常直接传回给Guest,而Guest同时也没处理好异常而产生了嵌入异常,这个嵌入异常引发了VM-Exit,由于异常性质和前一次完全一样,被HyperBone再次扔回了Guest,以此类推,就是一个死循环。
HyperBone这货真心不建议用,值得参考甚至拿来抄的VT框架,个人看来大概就ksm(有实验性的VT嵌套功能),haxm(处理行为绝对标准,不过这货是安卓模拟器)啥的了。有的大佬是直接抄xen的引擎;如果要抄xen的引擎那就很考验编译器使用能力了,拿IDE基本上是没法玩的。
上述的VT框架都是可跨平台的,放到其他运行在Intel处理器上的操作系统也是能玩的。HyperBone不仅不能跨平台,连32位Windows都玩不了。

woshidc523 发表于 2018-8-20 10:13:52

tangptr@126.com 发表于 2018-6-26 16:14
详情请看Intel 64与IA-32架构程序员开发手册第三卷第25章第2节与第26章第5节第1.2次节。
你的问题在这手册 ...

谢谢大佬解惑,我好好看看你说的ksm,谢谢谢谢~~~
页: [1]
查看完整版本: VmExitEvent为什么会死循环呢...