📄 exp.c
字号:
/* Check if we were in V86 Mode */
if (TrapFrame->EFlags & EFLAGS_V86_MASK)
{
/* Simply copy the CS value */
TrapFrame->SegCs = Context->SegCs;
}
else
{
/* We weren't in V86, so sanitize the CS */
TrapFrame->SegCs = Ke386SanitizeSeg(Context->SegCs, PreviousMode);
/* Don't let it under 8, that's invalid */
if ((PreviousMode != KernelMode) && (TrapFrame->SegCs < 8))
{
/* Force it to User CS */
TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
}
}
/* Handle SS Specially for validation */
KiSsToTrapFrame(TrapFrame, Context->SegSs);
/* Write ESP back; take into account Edited Trap Frames */
KiEspToTrapFrame(TrapFrame, Context->Esp);
/* Handle our V86 Bias if we went through a switch */
if (V86Switch) Ki386AdjustEsp0(TrapFrame);
}
/* Process the Integer Registers */
if ((ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
{
/* Copy them manually */
TrapFrame->Eax = Context->Eax;
TrapFrame->Ebx = Context->Ebx;
TrapFrame->Ecx = Context->Ecx;
TrapFrame->Edx = Context->Edx;
TrapFrame->Esi = Context->Esi;
TrapFrame->Edi = Context->Edi;
}
/* Process the Context Segments */
if ((ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
{
/* Check if we were in V86 Mode */
if (TrapFrame->EFlags & EFLAGS_V86_MASK)
{
/* Copy the V86 Segments directly */
TrapFrame->V86Ds = Context->SegDs;
TrapFrame->V86Es = Context->SegEs;
TrapFrame->V86Fs = Context->SegFs;
TrapFrame->V86Gs = Context->SegGs;
}
else if (!(TrapFrame->SegCs & MODE_MASK))
{
/* For kernel mode, write the standard values */
TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK;
TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK;
TrapFrame->SegFs = Ke386SanitizeSeg(Context->SegFs, PreviousMode);
TrapFrame->SegGs = 0;
}
else
{
/* For user mode, return the values directly */
TrapFrame->SegDs = Context->SegDs;
TrapFrame->SegEs = Context->SegEs;
TrapFrame->SegFs = Context->SegFs;
/* Handle GS specially */
if (TrapFrame->SegCs == (KGDT_R3_CODE | RPL_MASK))
{
/* Don't use it, if user */
TrapFrame->SegGs = 0;
}
else
{
/* Copy it if kernel */
TrapFrame->SegGs = Context->SegGs;
}
}
}
/* Handle the extended registers */
if (((ContextFlags & CONTEXT_EXTENDED_REGISTERS) ==
CONTEXT_EXTENDED_REGISTERS) && (TrapFrame->SegCs & MODE_MASK))
{
/* Get the FX Area */
FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
/* Check if NPX is present */
if (KeI386NpxPresent)
{
/* Flush the NPX State */
KiFlushNPXState(NULL);
/* Copy the FX State */
RtlCopyMemory(&FxSaveArea->U.FxArea,
&Context->ExtendedRegisters[0],
MAXIMUM_SUPPORTED_EXTENSION);
/* Remove reserved bits from MXCSR */
FxSaveArea->U.FxArea.MXCsr &= ~0xFFBF;
/* Mask out any invalid flags */
FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
/* Check if this is a VDM app */
if (PsGetCurrentProcess()->VdmObjects)
{
/* Allow the EM flag */
FxSaveArea->Cr0NpxState |= Context->FloatSave.Cr0NpxState &
(CR0_EM | CR0_MP);
}
}
}
/* Handle the floating point state */
if (((ContextFlags & CONTEXT_FLOATING_POINT) ==
CONTEXT_FLOATING_POINT) && (TrapFrame->SegCs & MODE_MASK))
{
/* Get the FX Area */
FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
/* Check if NPX is present */
if (KeI386NpxPresent)
{
/* Flush the NPX State */
KiFlushNPXState(NULL);
/* Check if we have Fxsr support */
if (KeI386FxsrPresent)
{
/* Convert the Fn Floating Point state to Fx */
FxSaveArea->U.FxArea.ControlWord =
(USHORT)Context->FloatSave.ControlWord;
FxSaveArea->U.FxArea.StatusWord =
(USHORT)Context->FloatSave.StatusWord;
FxSaveArea->U.FxArea.TagWord =
KiTagWordFnsaveToFxsave((USHORT)Context->FloatSave.TagWord);
FxSaveArea->U.FxArea.ErrorOpcode =
(USHORT)((Context->FloatSave.ErrorSelector >> 16) & 0xFFFF);
FxSaveArea->U.FxArea.ErrorOffset =
Context->FloatSave.ErrorOffset;
FxSaveArea->U.FxArea.ErrorSelector =
Context->FloatSave.ErrorSelector & 0xFFFF;
FxSaveArea->U.FxArea.DataOffset =
Context->FloatSave.DataOffset;
FxSaveArea->U.FxArea.DataSelector =
Context->FloatSave.DataSelector;
/* Clear out the Register Area */
RtlZeroMemory(&FxSaveArea->U.FxArea.RegisterArea[0],
SIZE_OF_FX_REGISTERS);
/* Loop the 8 floating point registers */
for (i = 0; i < 8; i++)
{
/* Copy from Fn to Fx */
RtlCopyMemory(FxSaveArea->U.FxArea.RegisterArea + (i * 16),
Context->FloatSave.RegisterArea + (i * 10),
10);
}
}
else
{
/* Copy the structure */
FxSaveArea->U.FnArea.ControlWord = Context->FloatSave.
ControlWord;
FxSaveArea->U.FnArea.StatusWord = Context->FloatSave.
StatusWord;
FxSaveArea->U.FnArea.TagWord = Context->FloatSave.TagWord;
FxSaveArea->U.FnArea.ErrorOffset = Context->FloatSave.
ErrorOffset;
FxSaveArea->U.FnArea.ErrorSelector = Context->FloatSave.
ErrorSelector;
FxSaveArea->U.FnArea.DataOffset = Context->FloatSave.
DataOffset;
FxSaveArea->U.FnArea.DataSelector = Context->FloatSave.
DataSelector;
/* Loop registers */
for (i = 0; i < SIZE_OF_80387_REGISTERS; i++)
{
/* Copy registers */
FxSaveArea->U.FnArea.RegisterArea[i] =
Context->FloatSave.RegisterArea[i];
}
}
/* Mask out any invalid flags */
FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
/* Check if this is a VDM app */
if (PsGetCurrentProcess()->VdmObjects)
{
/* Allow the EM flag */
FxSaveArea->Cr0NpxState |= Context->FloatSave.Cr0NpxState &
(CR0_EM | CR0_MP);
}
}
else
{
/* FIXME: Handle FPU Emulation */
//ASSERT(FALSE);
}
}
/* Handle the Debug Registers */
if ((ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
{
/* Loop DR registers */
for (i = 0; i < 4; i++)
{
/* Sanitize the context DR Address */
SafeDr = Ke386SanitizeDr(KiDrFromContext(i, Context), PreviousMode);
/* Save it in the trap frame */
*KiDrFromTrapFrame(i, TrapFrame) = SafeDr;
/* Check if this DR address is active and add it in the DR mask */
if (SafeDr) DrMask |= DR_MASK(i);
}
/* Now save and sanitize DR6 */
TrapFrame->Dr6 = Context->Dr6 & DR6_LEGAL;
if (TrapFrame->Dr6) DrMask |= DR_MASK(6);
/* Save and sanitize DR7 */
TrapFrame->Dr7 = Context->Dr7 & DR7_LEGAL;
KiRecordDr7(&TrapFrame->Dr7, &DrMask);
/* If we're in user-mode */
if (PreviousMode != KernelMode)
{
/* FIXME: Save the mask */
//KeGetCurrentThread()->DispatcherHeader.DebugActive = DrMask;
}
}
/* Check if thread has IOPL and force it enabled if so */
if (KeGetCurrentThread()->Iopl) TrapFrame->EFlags |= 0x3000;
/* Restore IRQL */
if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
}
VOID
NTAPI
KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame,
IN OUT PCONTEXT Context)
{
PFX_SAVE_AREA FxSaveArea;
struct _AlignHack
{
UCHAR Hack[15];
FLOATING_SAVE_AREA UnalignedArea;
} FloatSaveBuffer;
FLOATING_SAVE_AREA *FloatSaveArea;
KIRQL OldIrql;
ULONG i;
/* Do this at APC_LEVEL */
OldIrql = KeGetCurrentIrql();
if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
/* Start with the Control flags */
if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
{
/* EBP, EIP and EFLAGS */
Context->Ebp = TrapFrame->Ebp;
Context->Eip = TrapFrame->Eip;
Context->EFlags = TrapFrame->EFlags;
/* Return the correct CS */
if (!(TrapFrame->SegCs & FRAME_EDITED) &&
!(TrapFrame->EFlags & EFLAGS_V86_MASK))
{
/* Get it from the Temp location */
Context->SegCs = TrapFrame->TempSegCs & 0xFFFF;
}
else
{
/* Return it directly */
Context->SegCs = TrapFrame->SegCs & 0xFFFF;
}
/* Get the Ss and ESP */
Context->SegSs = KiSsFromTrapFrame(TrapFrame);
Context->Esp = KiEspFromTrapFrame(TrapFrame);
}
/* Handle the Segments */
if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
{
/* Do V86 Mode first */
if (TrapFrame->EFlags & EFLAGS_V86_MASK)
{
/* Return from the V86 location */
Context->SegGs = TrapFrame->V86Gs & 0xFFFF;
Context->SegFs = TrapFrame->V86Fs & 0xFFFF;
Context->SegEs = TrapFrame->V86Es & 0xFFFF;
Context->SegDs = TrapFrame->V86Ds & 0xFFFF;
}
else
{
/* Check if this was a Kernel Trap */
if (TrapFrame->SegCs == KGDT_R0_CODE)
{
/* Set valid selectors */
TrapFrame->SegGs = 0;
TrapFrame->SegFs = KGDT_R0_PCR;
TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK;
TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK;
}
/* Return the segments */
Context->SegGs = TrapFrame->SegGs & 0xFFFF;
Context->SegFs = TrapFrame->SegFs & 0xFFFF;
Context->SegEs = TrapFrame->SegEs & 0xFFFF;
Context->SegDs = TrapFrame->SegDs & 0xFFFF;
}
}
/* Handle the simple registers */
if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
{
/* Return them directly */
Context->Eax = TrapFrame->Eax;
Context->Ebx = TrapFrame->Ebx;
Context->Ecx = TrapFrame->Ecx;
Context->Edx = TrapFrame->Edx;
Context->Esi = TrapFrame->Esi;
Context->Edi = TrapFrame->Edi;
}
/* Handle extended registers */
if (((Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) ==
CONTEXT_EXTENDED_REGISTERS) && (TrapFrame->SegCs & MODE_MASK))
{
/* Get the FX Save Area */
FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
/* Make sure NPX is present */
if (KeI386NpxPresent)
{
/* Flush the NPX State */
KiFlushNPXState(NULL);
/* Copy the registers */
RtlCopyMemory(&Context->ExtendedRegisters[0],
&FxSaveArea->U.FxArea,
MAXIMUM_SUPPORTED_EXTENSION);
}
}
/* Handle Floating Point */
if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) ==
CONTEXT_FLOATING_POINT) && (TrapFrame->SegCs & MODE_MASK))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -