[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] intercept syscall of VM by setting MSR_SYSENTER_CS as 0x0


  • To: xen-devel@xxxxxxxxxxxxx
  • From: toyandong <toyandong@xxxxxxx>
  • Date: Wed, 9 Jul 2014 20:50:01 +0800 (CST)
  • Delivery-date: Wed, 09 Jul 2014 12:51:43 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xen.org>

hi all,

I want to intercept syscall on Xen, by modifing  SYSENTER_MSR_CS as 0x0 to trap sysenter/sysexit into Xen because of #GP.
But the VM crashed after some syscalls are got. The detail of VM is in this http://pan.baidu.com/s/1o61APOe
 I am going to crazying, anyone can help me?

The following is details:

Step 1) first, I set Xen to trap the #GP.

In  vmx_vmexit_handler()

__vmwrite(EXCEPTION_BITMAP, __vmread(EXCEPTION_BITMAP) | (1U<<TRAP_gp_fault));
current->arch.hvm_vmx.exception_bitmap = current->arch.hvm_vmx.exception_bitmap | (1U<<TRAP_gp_fault);

Step 2) set Xen to handle the GP.

In vmx_vmexit_handler()

switch ( exit_reason )
{
case EXIT_REASON_EXCEPTION_NMI:
{
   ...
    switch ( vector )
    {
        //dprintk(XENLOG_G_ERR, "vmexit hander exit_reason %u, vector %d \n", exit_reason, vector);
    case TRAP_debug:...

    case TRAP_gp_fault:
    {

        unsigned char inst[4] = {0,0,0,0};
        printk("[%d]GET #GP MSR_CS=[%lx %x] %lx [%lx %x] !!!\n",v->domain->domain_id,__vmread(GUEST_SYSENTER_CS), regs->cs,regs->eip, regs->esp, regs->ss);

        hvm_copy_from_guest_virt(inst, regs->eip,sizeof(inst),0);

        switch(inst[0])
        {
            case 0x34: printk("sysenter 1 \n");
            {

                __vmwrite(GUEST_CS_SELECTOR, ether_get_imaginary_sysenter_cs(v->domain));
                __vmwrite(GUEST_CS_BASE, 0U);
                __vmwrite(GUEST_CS_LIMIT, ~0U);
                __vmwrite(GUEST_CS_AR_BYTES, 0xc09b);

                __vmwrite(GUEST_SS_SELECTOR, ether_get_imaginary_sysenter_cs(v->domain)+8U);
                __vmwrite(GUEST_SS_BASE, 0U);
                __vmwrite(GUEST_SS_LIMIT, ~0U);
                __vmwrite(GUEST_SS_AR_BYTES, 0xc093);

                regs->eip = __vmread(GUEST_SYSENTER_EIP);
                regs->esp =  __vmread(GUEST_SYSENTER_ESP);
                regs->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF);
                printk("Handle MSR_CS=[%lx %x] %lx [%lx %x]!!!\n",__vmread(GUEST_SYSENTER_CS), regs->cs,regs->eip, regs->esp, regs->ss);

            }break;
            case 0x35: 
            {   
                printk("sysexit n\n");
                __vmwrite(GUEST_CS_SELECTOR, ether_get_imaginary_sysenter_cs(v->domain)+16U+0x3);
                __vmwrite(GUEST_CS_BASE, 0U);
                __vmwrite(GUEST_CS_LIMIT, ~0U);
                __vmwrite(GUEST_CS_AR_BYTES, 0xc0fb);

                __vmwrite(GUEST_SS_SELECTOR, ether_get_imaginary_sysenter_cs(v->domain)+24U+0x3);
                __vmwrite(GUEST_SS_BASE, 0U);
                __vmwrite(GUEST_SS_LIMIT, ~0U);
                __vmwrite(GUEST_SS_AR_BYTES, 0xc0f3);

                regs->eip=regs->edx;
                regs->esp=regs->ecx;
                break;
            }
            default: 
            {
                break;
            }
        }

        break;
    }

Step 3) set MSR_SYSENTER_CS with Null segment selector(0) to raise a #GP by an hypercall

new_cs=0x0;   
vmx_write_sysenter_msr(GUEST_SYSENTER_CS, new_cs);


--
Best Regards,
yandong
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.