Esempio n. 1
0
BOOLEAN
FASTCALL
KiVdmOpcodePOPF(IN PKTRAP_FRAME TrapFrame,
                IN ULONG Flags)
{
    ULONG Esp, V86EFlags, EFlags, TrapEFlags;

    /* Build flat ESP */
    Esp = (TrapFrame->HardwareSegSs << 4) + (USHORT)TrapFrame->HardwareEsp;

    /* Check for OPER32 */
    if (KiVdmGetPrefixFlags(Flags) & PFX_FLAG_OPER32)
    {
        /* Read EFlags */
        EFlags = *(PULONG)Esp;
        Esp += 4;
    }
    else
    {
        /* Read EFlags */
        EFlags = *(PUSHORT)Esp;
        Esp += 2;
    }

    /* Set new ESP */
    TrapFrame->HardwareEsp = Esp - (TrapFrame->HardwareSegSs << 4);

    /* Mask out IOPL from the flags */
    EFlags &= ~EFLAGS_IOPL;

    /* Save the V86 flags, but mask out the nested task flag */
    V86EFlags = EFlags & ~EFLAGS_NESTED_TASK;

    /* Now leave only alignment, nested task and interrupt flag */
    EFlags &= (EFLAGS_ALIGN_CHECK | EFLAGS_NESTED_TASK | EFLAGS_INTERRUPT_MASK);

    /* Get trap EFlags */
    TrapEFlags = TrapFrame->EFlags;

    /* Check for VME support */
    if(KeI386VirtualIntExtensions)
    {
        /* Copy the IF flag into the VIF one */
        V86EFlags &= ~EFLAGS_VIF;
        if(V86EFlags & EFLAGS_INTERRUPT_MASK)
        {
            V86EFlags |= EFLAGS_VIF;
            /* Don't set the interrupt flag */
            V86EFlags &= ~EFLAGS_INTERRUPT_MASK;
        }
    }

    /* Add V86 flag */
    V86EFlags |= EFLAGS_V86_MASK;

    /* Update EFlags in trap frame */
    TrapFrame->EFlags |= V86EFlags;

    /* Check if ESP0 needs to be fixed up */
    if (TrapEFlags & EFLAGS_V86_MASK) Ki386AdjustEsp0(TrapFrame);

    /* Update the V8086 EFlags state */
    KiVdmClearVdmEFlags(EFLAGS_ALIGN_CHECK | EFLAGS_NESTED_TASK | EFLAGS_INTERRUPT_MASK);
    KiVdmSetVdmEFlags(EFlags);

    /* FIXME: Check for VDM interrupts */

    /* Update EIP */
    TrapFrame->Eip += KiVdmGetInstructionSize(Flags);

    /* We're done */
    return TRUE;
}
Esempio n. 2
0
BOOLEAN
FASTCALL
KiVdmOpcodeIRET(IN PKTRAP_FRAME TrapFrame,
                IN ULONG Flags)
{
    ULONG Esp, V86EFlags, EFlags, TrapEFlags, Eip;

    /* Build flat ESP */
    Esp = (TrapFrame->HardwareSegSs << 4) + TrapFrame->HardwareEsp;

    /* Check for OPER32 */
    if (KiVdmGetPrefixFlags(Flags) & PFX_FLAG_OPER32)
    {
        /* Build segmented EIP */
        TrapFrame->Eip = *(PULONG)Esp;
        TrapFrame->SegCs = *(PUSHORT)(Esp + 4);

        /* Set new ESP */
        TrapFrame->HardwareEsp += 12;

        /* Get EFLAGS */
        EFlags = *(PULONG)(Esp + 8);
    }
    else
    {
        /* Build segmented EIP */
        TrapFrame->Eip = *(PUSHORT)Esp;
        TrapFrame->SegCs = *(PUSHORT)(Esp + 2);

        /* Set new ESP */
        TrapFrame->HardwareEsp += 6;

        /* Get EFLAGS */
        EFlags = *(PUSHORT)(Esp + 4);
    }

    /* Mask out EFlags */
    EFlags &= ~(EFLAGS_IOPL + EFLAGS_VIF + EFLAGS_NESTED_TASK + EFLAGS_VIP);
    V86EFlags = EFlags;

    /* Check for VME support */
    ASSERT(KeI386VirtualIntExtensions == FALSE);

    /* Add V86 and Interrupt flag */
    EFlags |= EFLAGS_V86_MASK | EFLAGS_INTERRUPT_MASK;

    /* Update EFlags in trap frame */
    TrapEFlags = TrapFrame->EFlags;
    TrapFrame->EFlags = (TrapFrame->EFlags & EFLAGS_VIP) | EFlags;

    /* Check if ESP0 needs to be fixed up */
    if (!(TrapEFlags & EFLAGS_V86_MASK)) Ki386AdjustEsp0(TrapFrame);

    /* Update the V8086 EFlags state */
    KiVdmClearVdmEFlags(EFLAGS_INTERRUPT_MASK);
    KiVdmSetVdmEFlags(V86EFlags);

    /* Build flat EIP and check if this is the BOP instruction */
    Eip = (TrapFrame->SegCs << 4) + TrapFrame->Eip;
    if (*(PUSHORT)Eip == 0xC4C4)
    {
        /* Dispatch the BOP */
        VdmDispatchBop(TrapFrame);
    }
    else
    {
        /* FIXME: Check for VDM interrupts */
       DPRINT("FIXME: Check for VDM interrupts\n");
    }

    /* We're done */
    return TRUE;
}
Esempio n. 3
0
VOID
NTAPI
VdmSwapContext(IN PKTRAP_FRAME TrapFrame,
               IN PCONTEXT OutContext,
               IN PCONTEXT InContext)
{
    ULONG EFlags, OldEFlags;

    /* Make sure that we're at APC_LEVEL and that this is a valid frame */
    ASSERT(KeGetCurrentIrql() == APC_LEVEL);
    //ASSERT(TrapFrame->DbgArgMark == 0xBADB0D00);

    /* Check if this is a V86 frame */
    if (TrapFrame->EFlags & EFLAGS_V86_MASK)
    {
        /* Copy segment registers */
        OutContext->SegGs = TrapFrame->V86Gs;
        OutContext->SegFs = TrapFrame->V86Fs;
        OutContext->SegEs = TrapFrame->V86Es;
        OutContext->SegDs = TrapFrame->V86Ds;
    }
    else if (TrapFrame->SegCs != (KGDT_R3_CODE | RPL_MASK))
    {
        /* This was kernel mode, copy segment registers */
        OutContext->SegGs = TrapFrame->SegGs;
        OutContext->SegFs = TrapFrame->SegFs;
        OutContext->SegEs = TrapFrame->SegEs;
        OutContext->SegDs = TrapFrame->SegDs;
    }

    /* Copy CS and SS */
    OutContext->SegCs = TrapFrame->SegCs;
    OutContext->SegSs = TrapFrame->HardwareSegSs;

    /* Copy general purpose registers */
    OutContext->Eax = TrapFrame->Eax;
    OutContext->Ebx = TrapFrame->Ebx;
    OutContext->Ecx = TrapFrame->Ecx;
    OutContext->Edx = TrapFrame->Edx;
    OutContext->Esi = TrapFrame->Esi;
    OutContext->Edi = TrapFrame->Edi;

    /* Copy stack and counter */
    OutContext->Ebp = TrapFrame->Ebp;
    OutContext->Esp = TrapFrame->HardwareEsp;
    OutContext->Eip = TrapFrame->Eip;

    /* Finally the flags */
    OutContext->EFlags = TrapFrame->EFlags;

    /* Now copy from the in frame to the trap frame */
    TrapFrame->SegCs = InContext->SegCs;
    TrapFrame->HardwareSegSs = InContext->SegSs;

    /* Copy the general purpose registers */
    TrapFrame->Eax = InContext->Eax;
    TrapFrame->Ebx = InContext->Ebx;
    TrapFrame->Ecx = InContext->Ecx;
    TrapFrame->Edx = InContext->Edx;
    TrapFrame->Esi = InContext->Esi;
    TrapFrame->Edi = InContext->Edi;

    /* Copy the stack and counter */
    TrapFrame->Ebp = InContext->Ebp;
    TrapFrame->HardwareEsp = InContext->Esp;
    TrapFrame->Eip = InContext->Eip;

    /* Check if the context is from V86 */
    EFlags = InContext->EFlags;
    if (EFlags & EFLAGS_V86_MASK)
    {
        /* Sanitize the flags for V86 */
        EFlags &= KeI386EFlagsAndMaskV86;
        EFlags |= KeI386EFlagsOrMaskV86;
    }
    else
    {
        /* Add RPL_MASK to segments */
        TrapFrame->SegCs |= RPL_MASK;
        TrapFrame->HardwareSegSs |= RPL_MASK;

        /* Check for bogus CS */
        if (TrapFrame->SegCs < KGDT_R0_CODE)
        {
            /* Set user-mode */
            TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
        }

        /* Sanitize flags and add interrupt mask */
        EFlags &= EFLAGS_USER_SANITIZE;
        EFlags |=EFLAGS_INTERRUPT_MASK;
    }

    /* Save the new eflags */
    OldEFlags = TrapFrame->EFlags;
    TrapFrame->EFlags = EFlags;

    /* Check if we need to fixup ESP0 */
    if ((OldEFlags ^ EFlags) & EFLAGS_V86_MASK)
    {
        /* Fix it up */
        Ki386AdjustEsp0(TrapFrame);
    }

    /* Check if this is a V86 context */
    if (InContext->EFlags & EFLAGS_V86_MASK)
    {
        /* Copy VDM segments */
        TrapFrame->V86Gs = InContext->SegGs;
        TrapFrame->V86Fs = InContext->SegFs;
        TrapFrame->V86Es = InContext->SegEs;
        TrapFrame->V86Ds = InContext->SegDs;
    }
    else
    {
        /* Copy monitor segments */
        TrapFrame->SegGs = InContext->SegGs;
        TrapFrame->SegFs = InContext->SegFs;
        TrapFrame->SegEs = InContext->SegEs;
        TrapFrame->SegDs = InContext->SegDs;
    }

    /* Clear the exception list and return */
    TrapFrame->ExceptionList = EXCEPTION_CHAIN_END;
}