首页
社区
课程
招聘
[求助]vmm捕获缺页异常的问题
2014-4-21 13:55 9547

[求助]vmm捕获缺页异常的问题

2014-4-21 13:55
9547
求大牛指导VMM如何捕获缺页异常~~

有没有看过bluepill源码的,指导一下如何在bluepill里添加对page fault的捕获。或者帮忙讲解一下其他VMM如何捕获和处理缺页异常的~~

急求!!请各位大牛帮忙!!

阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

收藏
免费 0
打赏
分享
最新回复 (21)
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
exediy 1 2014-4-22 04:19
2
0
把异常注入回去。
雪    币: 75
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xiaogangha 2014-4-22 09:56
3
0
能不能麻烦把注入的过程说的具体一点?还有,究竟是哪种缺页异常,比如是改写只读页面,还是执行不可执行页面等,应该如何判断呢?谢谢啦~
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
exediy 1 2014-4-22 15:25
4
0
缺页异常无法判断是读还是写造成的,只能判断是不是执行错误或者是读写错误。

VMX_VMCS_RO_EXIT_QUALIFICATION 是不是 VMX_VMCS64_GUEST_RIP
雪    币: 75
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xiaogangha 2014-4-22 20:09
5
0
“VMX_VMCS_RO_EXIT_QUALIFICATION”和“ VMX_VMCS64_GUEST_RIP”我都没有在intel手册和vmm源码中找到,请问如果想判断是执行错误还是读写错误应该通过哪个域来判断?
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
exediy 1 2014-4-22 21:35
6
0
#define         VMX_VMCS_RO_EXIT_QUALIFICATION   0x6400
#define         VMX_VMCS_RO_IO_RIP   0x6408
雪    币: 75
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xiaogangha 2014-4-22 22:05
7
0
找到这两个域了,非常感谢~~

我看到intel手册里关于异常回注部分,说要将vm-exit interruption information写入vm-entry interruption information,将vm-exit interruption error-code 写入vm-entry exception error-code,然后执行vmresume。   我按照这个意思在异常处理函数中相应的写了三条语句,不过系统崩溃了。    还请指导一下,回注的具体处理过程~~
雪    币: 257
活跃值: (67)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
AioliaSky 1 2014-4-22 22:41
8
0
VMM也落后了,会被猥琐的方式检测到,SMM才厉害
雪    币: 75
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xiaogangha 2014-4-22 22:51
9
0
smm是什么?
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
exediy 1 2014-4-23 17:22
10
0
请贴代码
雪    币: 75
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xiaogangha 2014-4-23 21:33
11
0
static BOOLEAN NTAPI VmxDispatchException (
  PCPU Cpu,
  PGUEST_REGS GuestRegs,
  PNBP_TRAP Trap,
  BOOLEAN WillBeAlsoHandledByGuestHv
)
{
    ULONG64 uIntrInfo, vector;
	
    if (!Cpu || !GuestRegs)
        return TRUE;

    uIntrInfo = VmxRead (VM_EXIT_INTR_INFO); 
    if((uIntrInfo & INTR_INFO_VALID_MASK)==0)
    {
        _KdPrint (("VmxDispatchException(): invalid\n"));
        return TRUE;
    }
	
    vector = uIntrInfo & INTR_INFO_VECTOR_MASK;
    if ((uIntrInfo & INTR_INFO_NMI_UNBLOCKED_BY_IRET) &&
        !(VmxRead(IDT_VECTORING_INFO_FIELD) & INTR_INFO_VALID_MASK) &&
        (vector != TRAP_double_fault) )
    {
        VmxWrite(GUEST_INTERRUPTIBILITY_INFO,
            VmxRead(GUEST_INTERRUPTIBILITY_INFO)|VMX_INTR_SHADOW_NMI);
    }
	
    if (vector == TRAP_page_fault)
    {
        VmxWrite(VM_ENTRY_EXCEPTION_ERROR_CODE, 
            VmxRead(VM_EXIT_INTR_ERROR_CODE));
        VmxWrite(VM_ENTRY_INTR_INFO_FIELD, VmxRead (VM_EXIT_INTR_INFO));
        VmxResume();
    }
    return TRUE;
}


是在bluepill的源码里改的,bluepill公开源码里注册了异常处理函数,但是没有针对page fault的处理,参考了一下xen的vmx_vmexit_handler()函数,不过挺多没看明白的。
最后编译生成的是Windows驱动程序,目前仅能运行在64位Windows Server 2003上,我的处理器是Intel Core2 Quad Q6600 2.4GHz。上面的代码运行后会蓝屏。
异常回注的具体实现还请帮忙指导~~非常感谢!!
雪    币: 281
活跃值: (28)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
aiwuxian 1 2014-4-23 22:41
12
0
mark
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
exediy 1 2014-4-24 16:00
13
0
把CR2写回去.还有RIP  重新填充VM_ENTRY_INTR_INFO_FIELD 结构.直接使用好像会有问题
雪    币: 75
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xiaogangha 2014-4-25 09:35
14
0
VMCS结构里既没有GUEST_CR2这个域,又没有HOST_CR2这个域,请问,把CR2写回去是指把什么值写到CR2寄存器中?
雪    币: 8865
活跃值: (2379)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
cvcvxk 10 2014-4-25 14:04
15
0
贴个代码
其实很简单
ErrorCode = _ReadVMCS(VM_EXIT_INTR_ERROR_CODE);
			ExitQualification = _ReadVMCS(EXIT_QUALIFICATION);
			_SetCr2(ExitQualification);
			_WriteVMCS(VM_ENTRY_EXCEPTION_ERROR_CODE, ErrorCode);
			InjectEvent = 0;
			pInjectEvent->Vector = PAGE_FAULT_EXCEPTION;
			pInjectEvent->InterruptionType = HARDWARE_EXCEPTION;
			pInjectEvent->DeliverErrorCode = 1;
			pInjectEvent->Valid = 1;
			_WriteVMCS(VM_ENTRY_INTR_INFO_FIELD, InjectEvent);
			_WriteVMCS(GUEST_RIP, _ReadVMCS(GUEST_RIP));
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
exediy 1 2014-4-25 15:29
16
0
你贴我的代码!    要引导嘛  直接贴代码 人家也看不懂什么个意思!
雪    币: 8865
活跃值: (2379)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
cvcvxk 10 2014-4-25 15:54
17
0
引导半天没见效果啊,所以还是贴一下的好。
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
房有亮 3 2014-4-25 16:00
18
0
diy老板 好有耐心啊。
雪    币: 75
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xiaogangha 2014-4-25 16:39
19
0
非常感谢!
还有三个问题不明白:
1、_SetCr2()函数的功能是否为将ExitQualification的值写入CR2寄存器?
2、pInjectEvent结构体定义是什么样的?在将异常注入回Guest OS的过程中何时用到了pInjectEvent?
3、为什么向VM_ENTRY_INTR_INFO_FIELD域写入0?
雪    币: 75
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xiaogangha 2014-4-25 16:41
20
0
哈哈~感谢引导,都怪我太笨了,一直有问题不明白~~
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
exediy 1 2014-4-25 19:06
21
0
前两个问题涉及太多 可以自己百度下CR寄存器的用途 跟VM_ENTRY_INTR_INFO_FIELD结构.
第三个问题答案是,清空结构
雪    币: 75
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xiaogangha 2014-4-26 10:32
22
0
关于_SetCr2()我的理解是:
在发生缺页异常时,exit_qualification域包含引起该异常的线性地址,而CR2寄存器是用来保存引起异常的线性地址的,所以,在将异常回注的时候,要将exit_qualification域的值写入CR2寄存器。
不知道我理解的是否正确?
游客
登录 | 注册 方可回帖
返回