📄 trap.s
字号:
lea ebx, [esp+SIZEOF_EXCEPTION_RECORD]
mov [ebx], edx
mov [ebx+4], esi
mov [ebx+8], edi
NoParams:
/* Set the record in ECX and check if this was V86 */
mov ecx, esp
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jz SetPreviousMode
/* Set V86 mode */
mov eax, 0xFFFF
jmp MaskMode
SetPreviousMode:
/* Get the caller's CS */
mov eax, [ebp+KTRAP_FRAME_CS]
MaskMode:
/* Check if it was user-mode or kernel-mode */
and eax, MODE_MASK
/* Dispatch the exception */
push 1
push eax
push ebp
push 0
push ecx
call _KiDispatchException@20
/* End the trap */
mov esp, ebp
jmp _Kei386EoiHelper@0
.endfunc
.func DispatchNoParam
_DispatchNoParam:
/* Call the common dispatcher */
xor ecx, ecx
call _CommonDispatchException
.endfunc
.func DispatchOneParam
_DispatchOneParam:
/* Call the common dispatcher */
xor edx, edx
mov ecx, 1
call _CommonDispatchException
.endfunc
.func DispatchTwoParam
_DispatchTwoParam:
/* Call the common dispatcher */
xor edx, edx
mov ecx, 2
call _CommonDispatchException
.endfunc
/* HARDWARE TRAP HANDLERS ****************************************************/
.func KiFixupFrame
_KiFixupFrame:
/* TODO: Routine to fixup a KTRAP_FRAME when faulting from a syscall. */
UNHANDLED_PATH
.endfunc
.func KiTrap0
TRAP_FIXUPS kit0_a, kit0_t, DoFixupV86, DoNotFixupAbios
_KiTrap0:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kit0_a, kit0_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz V86Int0
/* Check if the frame was from kernelmode */
test word ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jz SendException
/* Check the old mode */
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
jne VdmCheck
SendException:
/* Re-enable interrupts for user-mode and send the exception */
sti
mov eax, STATUS_INTEGER_DIVIDE_BY_ZERO
mov ebx, [ebp+KTRAP_FRAME_EIP]
jmp _DispatchNoParam
VdmCheck:
/* Check if this is a VDM process */
mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz SendException
/* We don't support this yet! */
V86Int0:
/* FIXME: TODO */
UNHANDLED_PATH
.endfunc
.func KiTrap1
TRAP_FIXUPS kit1_a, kit1_t, DoFixupV86, DoNotFixupAbios
_KiTrap1:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kit1_a, kit1_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz V86Int1
/* Check if the frame was from kernelmode */
test word ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jz PrepInt1
/* Check the old mode */
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
jne V86Int1
EnableInterrupts:
/* Enable interrupts for user-mode */
sti
PrepInt1:
/* Prepare the exception */
and dword ptr [ebp+KTRAP_FRAME_EFLAGS], ~EFLAGS_TF
mov ebx, [ebp+KTRAP_FRAME_EIP]
mov eax, STATUS_SINGLE_STEP
jmp _DispatchNoParam
V86Int1:
/* Check if this is a VDM process */
mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz EnableInterrupts
/* We don't support VDM! */
UNHANDLED_PATH
.endfunc
.globl _KiTrap2
.func KiTrap2
_KiTrap2:
/* FIXME: This is an NMI, nothing like a normal exception */
mov eax, 2
jmp _KiSystemFatalException
.endfunc
.func KiTrap3
TRAP_FIXUPS kit3_a, kit3_t, DoFixupV86, DoNotFixupAbios
_KiTrap3:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kit3_a, kit3_t
/* Set status code */
mov eax, 0 //STATUS_SUCCESS
/* Check for V86 */
PrepareInt3:
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz V86Int3
/* Check if the frame was from kernelmode */
test word ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jz PrepInt3
/* Check the old mode */
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
jne V86Int3
EnableInterrupts3:
/* Enable interrupts for user-mode */
sti
PrepInt3:
/* Prepare the exception */
mov esi, ecx
mov edi, edx
mov edx, eax
/* Setup EIP, NTSTATUS and parameter count, then dispatch */
mov ebx, [ebp+KTRAP_FRAME_EIP]
dec ebx
mov ecx, 3
mov eax, STATUS_BREAKPOINT
call _CommonDispatchException
V86Int3:
/* Check if this is a VDM process */
mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz EnableInterrupts3
/* We don't support VDM! */
UNHANDLED_PATH
.endfunc
.func KiTrap4
TRAP_FIXUPS kit4_a, kit4_t, DoFixupV86, DoNotFixupAbios
_KiTrap4:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kit4_a, kit4_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz V86Int4
/* Check if the frame was from kernelmode */
test word ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jz SendException4
/* Check the old mode */
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
jne VdmCheck4
SendException4:
/* Re-enable interrupts for user-mode and send the exception */
sti
mov eax, STATUS_INTEGER_OVERFLOW
mov ebx, [ebp+KTRAP_FRAME_EIP]
dec ebx
jmp _DispatchNoParam
VdmCheck4:
/* Check if this is a VDM process */
mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz SendException4
/* We don't support this yet! */
V86Int4:
UNHANDLED_PATH
.endfunc
.func KiTrap5
TRAP_FIXUPS kit5_a, kit5_t, DoFixupV86, DoNotFixupAbios
_KiTrap5:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kit5_a, kit5_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz V86Int5
/* Check if the frame was from kernelmode */
test word ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jnz CheckMode
/* It did, and this should never happen */
mov eax, 5
jmp _KiSystemFatalException
/* Check the old mode */
CheckMode:
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
jne VdmCheck5
/* Re-enable interrupts for user-mode and send the exception */
SendException5:
sti
mov eax, STATUS_ARRAY_BOUNDS_EXCEEDED
mov ebx, [ebp+KTRAP_FRAME_EIP]
jmp _DispatchNoParam
VdmCheck5:
/* Check if this is a VDM process */
mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz SendException5
/* We don't support this yet! */
V86Int5:
UNHANDLED_PATH
.endfunc
.func KiTrap6
TRAP_FIXUPS kit6_a, kit6_t, DoFixupV86, DoNotFixupAbios
_KiTrap6:
/* It this a V86 GPF? */
test dword ptr [esp+8], EFLAGS_V86_MASK
jz NotV86UD
/* Enter V86 Trap */
V86_TRAP_PROLOG kit6_a, kit6_v
/* Not yet supported (Invalid OPCODE from V86) */
UNHANDLED_PATH
NotV86UD:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kit6_a, kit6_t
/* Check if this happened in kernel mode */
test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jz KmodeOpcode
/* Check for VDM */
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
jz UmodeOpcode
/* Check if the process is vDM */
mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jnz IsVdmOpcode
UmodeOpcode:
/* Get EIP and enable interrupts at this point */
mov esi, [ebp+KTRAP_FRAME_EIP]
sti
/* Set intruction prefix length */
mov ecx, 4
/* Setup a SEH frame */
push ebp
push OpcodeSEH
push PCR[KPCR_EXCEPTION_LIST]
mov PCR[KPCR_EXCEPTION_LIST], esp
OpcodeLoop:
/* Get the instruction and check if it's LOCK */
mov al, [esi]
cmp al, 0xF0
jz LockCrash
/* Keep moving */
add esi, 1
loop OpcodeLoop
/* Undo SEH frame */
pop PCR[KPCR_EXCEPTION_LIST]
add esp, 8
KmodeOpcode:
/* Re-enable interrupts */
sti
/* Setup illegal instruction exception and dispatch it */
mov ebx, [ebp+KTRAP_FRAME_EIP]
mov eax, STATUS_ILLEGAL_INSTRUCTION
jmp _DispatchNoParam
LockCrash:
/* Undo SEH Frame */
pop PCR[KPCR_EXCEPTION_LIST]
add esp, 8
/* Setup invalid lock exception and dispatch it */
mov ebx, [ebp+KTRAP_FRAME_EIP]
mov eax, STATUS_INVALID_LOCK_SEQUENCE
jmp _DispatchNoParam
IsVdmOpcode:
/* Unhandled yet */
UNHANDLED_PATH
/* Return to caller */
jmp _Kei386EoiHelper@0
OpcodeSEH:
/* Get SEH frame */
mov esp, [esp+8]
pop PCR[KPCR_EXCEPTION_LIST]
add esp, 4
pop ebp
/* Check if this was user mode */
test dword ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jnz KmodeOpcode
/* Do a bugcheck */
push ebp
push 0
push 0
push 0
push 0
push KMODE_EXCEPTION_NOT_HANDLED
call _KeBugCheckWithTf@24
.endfunc
.func KiTrap7
TRAP_FIXUPS kit7_a, kit7_t, DoFixupV86, DoNotFixupAbios
_KiTrap7:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kit7_a, kit7_t
/* Get the current thread and stack */
StartTrapHandle:
mov eax, PCR[KPCR_CURRENT_THREAD]
mov ecx, [eax+KTHREAD_INITIAL_STACK]
sub ecx, NPX_FRAME_LENGTH
/* Check if emulation is enabled */
test dword ptr [ecx+FN_CR0_NPX_STATE], CR0_EM
jnz EmulationEnabled
CheckState:
/* Check if the NPX state is loaded */
cmp byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_LOADED
mov ebx, cr0
jz IsLoaded
/* Remove flags */
and ebx, ~(CR0_MP + CR0_TS + CR0_EM)
mov cr0, ebx
/* Check the NPX thread */
mov edx, PCR[KPCR_NPX_THREAD]
or edx, edx
jz NoNpxThread
/* Get the NPX Stack */
mov esi, [edx+KTHREAD_INITIAL_STACK]
sub esi, NPX_FRAME_LENGTH
/* Check if we have FXSR and check which operand to use */
test byte ptr _KeI386FxsrPresent, 1
jz FnSave
fxsave [esi]
jmp AfterSave
FnSave:
fnsave [esi]
AfterSave:
/* Set the thread's state to dirty */
mov byte ptr [edx+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
NoNpxThread:
/* Check if we have FXSR and choose which operand to use */
test byte ptr _KeI386FxsrPresent, 1
jz FrRestore
fxrstor [ecx]
jmp AfterRestore
FrRestore:
frstor [ecx]
AfterRestore:
/* Set state loaded */
mov byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_LOADED
mov PCR[KPCR_NPX_THREAD], eax
/* Enable interrupts to happen now */
sti
nop
/* Check if CR0 needs to be reloaded due to a context switch */
cmp dword ptr [ecx+FN_CR0_NPX_STATE], 0
jz _Kei386EoiHelper@0
/* We have to reload CR0... disable interrupts */
cli
/* Get CR0 and update it */
mov ebx, cr0
or ebx, [ecx+FN_CR0_NPX_STATE]
mov cr0, ebx
/* Restore interrupts and check if TS is back on */
sti
test bl, CR0_TS
jz _Kei386EoiHelper@0
/* Clear TS, and loop handling again */
clts
cli
jmp StartTrapHandle
KernelNpx:
/* Set delayed error */
or dword ptr [ecx+FN_CR0_NPX_STATE], CR0_TS
/* Check if this happened during restore */
cmp dword ptr [ebp+KTRAP_FRAME_EIP], offset FrRestore
jnz UserNpx
/* Skip instruction and dispatch the exception */
add dword ptr [ebp+KTRAP_FRAME_EIP], 3
jmp _Kei386EoiHelper@0
IsLoaded:
/* Check if TS is set */
test bl, CR0_TS
jnz TsSetOnLoadedState
HandleNpxFault:
/* Check if the trap came from V86 mode */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz V86Npx
/* Check if it came from kernel mode */
test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jz KernelNpx
/* Check if it came from a VDM */
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
jne V86Npx
UserNpx:
/* Get the current thread */
mov eax, PCR[KPCR_CURRENT_THREAD]
/* Check NPX state */
cmp byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
/* Get the NPX save area */
mov ecx, [eax+KTHREAD_INITIAL_STACK]
lea ecx, [ecx-NPX_FRAME_LENGTH]
jz NoSaveRestore
HandleUserNpx:
/* Set new CR0 */
mov ebx, cr0
and ebx, ~(CR0_MP + CR0_EM + CR0_TS)
mov cr0, ebx
/* Check if we have FX support */
test byte ptr _KeI386FxsrPresent, 1
jz FnSave2
/* Save the state */
fxsave [ecx]
jmp MakeCr0Dirty
FnSave2:
fnsave [ecx]
wait
MakeCr0Dirty:
/* Make CR0 state not loaded */
or ebx, NPX_STATE_NOT_LOADED
or ebx, [ecx+FN_CR0_NPX_STATE]
mov cr0, ebx
/* Update NPX state */
mov byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
mov dword ptr PCR[KPCR_NPX_THREAD], 0
NoSaveRestore:
/* Clear the TS bit and re-enable interrupts */
and dword ptr [ecx+FN_CR0_NPX_STATE], ~CR0_TS
sti
/* Check if we have FX support */
test byte ptr _KeI386FxsrPresent, 1
jz FnError
/* Get error offset, control and status words */
mov ebx, [ecx+FX_ERROR_OFFSET]
movzx eax, word ptr [ecx+FX_CONTROL_WORD]
movzx edx, word ptr [ecx+FX_STATUS_WORD]
/* Get the faulting opcode */
mov esi, [ecx+FX_DATA_OFFSET]
jmp CheckError
FnError:
/* Get error offset, control and status words */
mov ebx, [ecx+FP_ERROR_OFFSET]
movzx eax, word ptr [ecx+FP_CONTROL_WORD]
movzx edx, word ptr [ecx+FP_STATUS_WORD]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -