📄 trap.s
字号:
cmp al, 0xF
jne CheckRing3Io
/* FIXME */
UNHANDLED_PATH
CheckRing3Io:
/* Get EFLAGS and IOPL */
mov ebx, [ebp+KTRAP_FRAME_EFLAGS]
and ebx, 0x3000
shr ebx, 12
/* Check the CS's RPL mask */
mov ecx, [ebp+KTRAP_FRAME_CS]
and ecx, RPL_MASK
cmp ebx, ecx
jge NotIoViolation
CheckPrivilegedInstruction2:
/* Check if this is a CLI or STI */
cmp al, 0xFA
je IsPrivInstruction
cmp al, 0xFB
je IsPrivInstruction
/* Setup I/O table lookup */
mov ecx, 13
mov edi, offset _KiTrapIoTable
/* Loopup in the table */
repnz scasb
jnz NotIoViolation
/* FIXME: Check IOPM!!! */
IsPrivInstruction:
/* Cleanup the SEH frame */
pop fs:[KPCR_EXCEPTION_LIST]
add esp, 8
/* Setup the exception */
mov ebx, [ebp+KTRAP_FRAME_EIP]
mov eax, STATUS_PRIVILEGED_INSTRUCTION
jmp _DispatchNoParam
NotIoViolation:
/* Cleanup the SEH frame */
pop fs:[KPCR_EXCEPTION_LIST]
add esp, 8
SetException:
/* Setup the exception */
mov ebx, [ebp+KTRAP_FRAME_EIP]
mov esi, -1
mov eax, STATUS_ACCESS_VIOLATION
jmp _DispatchTwoParam
DispatchV86Gpf:
/* FIXME */
UNHANDLED_PATH
.endfunc
.func KiTrap14
Dr_kit14: DR_TRAP_FIXUP
V86_kit14: V86_TRAP_FIXUP
_KiTrap14:
/* Enter trap */
TRAP_PROLOG kit14
/* Check if we have a VDM alert */
cmp dword ptr fs:[KPCR_VDM_ALERT], 0
jnz VdmAlertGpf
/* Get the current thread */
mov edi, fs:[KPCR_CURRENT_THREAD]
/* Get the stack address of the frame */
lea eax, [esp+KTRAP_FRAME_LENGTH+NPX_FRAME_LENGTH]
sub eax, [edi+KTHREAD_INITIAL_STACK]
jz NoFixUp
/* This isn't the base frame, check if it's the second */
cmp eax, -KTRAP_FRAME_EFLAGS
jb NoFixUp
/* Check if we have a TEB */
mov eax, fs:[KPCR_TEB]
or eax, eax
jle NoFixUp
/* Fixup the frame */
call _KiFixupFrame
/* Save CR2 */
NoFixUp:
mov edi, cr2
/* ROS HACK: Sometimes we get called with INTS DISABLED! WTF? */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
je HandlePf
/* Enable interrupts and check if we got here with interrupts disabled */
sti
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
jz IllegalState
HandlePf:
/* Send trap frame and check if this is kernel-mode or usermode */
push ebp
mov eax, [ebp+KTRAP_FRAME_CS]
and eax, MODE_MASK
push eax
/* Send faulting address and check if this is read or write */
push edi
mov eax, [ebp+KTRAP_FRAME_ERROR_CODE]
and eax, 1
push eax
/* Call the access fault handler */
call _MmAccessFault@16
test eax, eax
jl AccessFail
/* Access fault handled, return to caller */
jmp _Kei386EoiHelper@0
AccessFail:
/* First check if this is a fault in the S-LIST functions */
mov ecx, offset _ExpInterlockedPopEntrySListFault@0
cmp [ebp+KTRAP_FRAME_EIP], ecx
jz SlistFault
/* Check if this is a fault in the syscall handler */
mov ecx, offset CopyParams
cmp [ebp+KTRAP_FRAME_EIP], ecx
jz SysCallCopyFault
mov ecx, offset ReadBatch
cmp [ebp+KTRAP_FRAME_EIP], ecx
jnz CheckVdmPf
/* FIXME: TODO */
UNHANDLED_PATH
jmp _Kei386EoiHelper@0
SysCallCopyFault:
/* FIXME: TODO */
UNHANDLED_PATH
jmp _Kei386EoiHelper@0
/* Check if the fault occured in a V86 mode */
CheckVdmPf:
mov ecx, [ebp+KTRAP_FRAME_ERROR_CODE]
and ecx, 1
shr ecx, 1
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz VdmPF
/* Check if the fault occured in a VDM */
mov esi, fs:[KPCR_CURRENT_THREAD]
mov esi, [esi+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [esi+EPROCESS_VDM_OBJECTS], 0
jz CheckStatus
/* Check if we this was in kernel-mode */
test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jz CheckStatus
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
jz CheckStatus
VdmPF:
/* FIXME: TODO */
UNHANDLED_PATH
/* Save EIP and check what kind of status failure we got */
CheckStatus:
mov esi, [ebp+KTRAP_FRAME_EIP]
cmp eax, STATUS_ACCESS_VIOLATION
je AccessViol
cmp eax, STATUS_GUARD_PAGE_VIOLATION
je SpecialCode
cmp eax, STATUS_STACK_OVERFLOW
je SpecialCode
/* Setup an in-page exception to dispatch */
mov edx, ecx
mov ebx, esi
mov esi, edi
mov ecx, 3
mov edi, eax
mov eax, STATUS_IN_PAGE_ERROR
call _CommonDispatchException
AccessViol:
/* Use more proper status code */
mov eax, KI_EXCEPTION_ACCESS_VIOLATION
SpecialCode:
/* Setup a normal page fault exception */
mov ebx, esi
mov edx, ecx
mov esi, edi
jmp _DispatchTwoParam
SlistFault:
/* FIXME: TODO */
UNHANDLED_PATH
IllegalState:
/* This is completely illegal, bugcheck the system */
push ebp
push esi
push ecx
push eax
push edi
push IRQL_NOT_LESS_OR_EQUAL
call _KeBugCheckWithTf@24
VdmAlertGpf:
/* FIXME: NOT SUPPORTED */
UNHANDLED_PATH
.endfunc
.func KiTrap0F
Dr_kit15: DR_TRAP_FIXUP
V86_kit15: V86_TRAP_FIXUP
_KiTrap0F:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kit15
sti
/* Raise a fatal exception */
mov eax, 15
jmp _KiSystemFatalException
.endfunc
.func KiTrap16
Dr_kit16: DR_TRAP_FIXUP
V86_kit16: V86_TRAP_FIXUP
_KiTrap16:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kit16
/* Check if this is the NPX Thread */
mov eax, fs:[KPCR_CURRENT_THREAD]
cmp eax, fs:[KPCR_NPX_THREAD]
/* Get the initial stack and NPX frame */
mov ecx, [eax+KTHREAD_INITIAL_STACK]
lea ecx, [ecx-NPX_FRAME_LENGTH]
/* If this is a valid fault, handle it */
jz HandleNpxFault
/* Otherwise, re-enable interrupts and set delayed error */
sti
or dword ptr [ecx+FN_CR0_NPX_STATE], CR0_TS
jmp _Kei386EoiHelper@0
.endfunc
.func KiTrap17
Dr_kit17: DR_TRAP_FIXUP
V86_kit17: V86_TRAP_FIXUP
_KiTrap17:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kit17
/* FIXME: ROS Doesn't handle alignment faults yet */
mov eax, 17
jmp _KiSystemFatalException
.endfunc
.func KiSystemFatalException
_KiSystemFatalException:
/* Push the trap frame */
push ebp
/* Push empty parameters */
push 0
push 0
push 0
/* Push trap number and bugcheck code */
push eax
push UNEXPECTED_KERNEL_MODE_TRAP
call _KeBugCheckWithTf@24
ret
.endfunc
.func KiCoprocessorError@0
_KiCoprocessorError@0:
/* Get the NPX Thread's Initial stack */
mov eax, [fs:KPCR_NPX_THREAD]
mov eax, [eax+KTHREAD_INITIAL_STACK]
/* Make space for the FPU Save area */
sub eax, SIZEOF_FX_SAVE_AREA
/* Set the CR0 State */
mov dword ptr [eax+FN_CR0_NPX_STATE], 8
/* Update it */
mov eax, cr0
or eax, 8
mov cr0, eax
/* Return to caller */
ret
.endfunc
.func Ki16BitStackException
_Ki16BitStackException:
/* Save stack */
push ss
push esp
/* Go to kernel mode thread stack */
mov eax, fs:[KPCR_CURRENT_THREAD]
add esp, [eax+KTHREAD_INITIAL_STACK]
/* Switch to good stack segment */
UNHANDLED_PATH
.endfunc
/* UNEXPECTED INTERRUPT HANDLERS **********************************************/
.globl _KiStartUnexpectedRange@0
_KiStartUnexpectedRange@0:
GENERATE_INT_HANDLERS
.globl _KiEndUnexpectedRange@0
_KiEndUnexpectedRange@0:
jmp _KiUnexpectedInterruptTail
.func KiUnexpectedInterruptTail
V86_kui: V86_TRAP_FIXUP
Dr_kui: DR_TRAP_FIXUP
_KiUnexpectedInterruptTail:
/* Enter interrupt trap */
INT_PROLOG kui, DoNotPushFakeErrorCode
/* Increase interrupt count */
inc dword ptr [fs:KPCR_PRCB_INTERRUPT_COUNT]
/* Put vector in EBX and make space for KIRQL */
mov ebx, [esp]
sub esp, 4
/* Begin interrupt */
push esp
push ebx
push HIGH_LEVEL
call _HalBeginSystemInterrupt@12
/* Check if it was spurious or not */
or al, al
jnz Handled
/* Spurious, ignore it */
add esp, 8
jmp _Kei386EoiHelper2ndEntry
Handled:
/* Unexpected interrupt, print a message on debug builds */
#if DBG
push [esp+4]
push offset _UnexpectedMsg
call _DbgPrint
add esp, 8
#endif
/* Exit the interrupt */
mov esi, $
cli
call _HalEndSystemInterrupt@8
jmp _Kei386EoiHelper@0
.endfunc
.globl _KiUnexpectedInterrupt
_KiUnexpectedInterrupt:
/* Bugcheck with invalid interrupt code */
push TRAP_CAUSE_UNKNOWN
call _KeBugCheck@4
/* INTERRUPT HANDLERS ********************************************************/
.func KiDispatchInterrupt@0
_KiDispatchInterrupt@0:
/* Get the PCR and disable interrupts */
mov ebx, [fs:KPCR_SELF]
cli
/* Check if we have to deliver DPCs, timers, or deferred threads */
mov eax, [ebx+KPCR_PRCB_DPC_QUEUE_DEPTH]
or eax, [ebx+KPCR_PRCB_TIMER_REQUEST]
or eax, [ebx+KPCR_PRCB_DEFERRED_READY_LIST_HEAD]
jz CheckQuantum
/* Save stack pointer and exception list, then clear it */
push ebp
push dword ptr [ebx+KPCR_EXCEPTION_LIST]
mov dword ptr [ebx+KPCR_EXCEPTION_LIST], -1
/* Save the stack and switch to the DPC Stack */
mov edx, esp
//mov esp, [ebx+KPCR_PRCB_DPC_STACK]
push edx
/* Deliver DPCs */
mov ecx, [ebx+KPCR_PRCB]
call @KiRetireDpcList@4
/* Restore stack and exception list */
pop esp
pop dword ptr [ebx+KPCR_EXCEPTION_LIST]
pop ebp
CheckQuantum:
/* Re-enable interrupts */
sti
/* Check if we have quantum end */
cmp byte ptr [ebx+KPCR_PRCB_QUANTUM_END], 0
jnz QuantumEnd
/* Check if we have a thread to swap to */
cmp byte ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
jz Return
/* FIXME: Schedule new thread */
UNHANDLED_PATH
Return:
/* All done */
ret
QuantumEnd:
/* Disable quantum end and process it */
mov byte ptr [ebx+KPCR_PRCB_QUANTUM_END], 0
call _KiQuantumEnd@0
ret
.endfunc
.func KiInterruptTemplate
V86_kit: V86_TRAP_FIXUP
Dr_kit: DR_TRAP_FIXUP
_KiInterruptTemplate:
/* Enter interrupt trap */
INT_PROLOG kit, DoPushFakeErrorCode
.endfunc
_KiInterruptTemplate2ndDispatch:
/* Dummy code, will be replaced by the address of the KINTERRUPT */
mov edi, 0
_KiInterruptTemplateObject:
/* Dummy jump, will be replaced by the actual jump */
jmp _KeSynchronizeExecution@12
_KiInterruptTemplateDispatch:
/* Marks the end of the template so that the jump above can be edited */
.func KiChainedDispatch2ndLvl@0
_KiChainedDispatch2ndLvl@0:
/* Not yet supported */
UNHANDLED_PATH
.endfunc
.func KiChainedDispatch@0
_KiChainedDispatch@0:
/* Increase interrupt count */
inc dword ptr [fs:KPCR_PRCB_INTERRUPT_COUNT]
/* Save trap frame */
mov ebp, esp
/* Save vector and IRQL */
mov eax, [edi+KINTERRUPT_VECTOR]
mov ecx, [edi+KINTERRUPT_IRQL]
/* Save old irql */
push eax
sub esp, 4
/* Begin interrupt */
push esp
push eax
push ecx
call _HalBeginSystemInterrupt@12
/* Check if it was handled */
or al, al
jz SpuriousInt
/* Call the 2nd-level handler */
call _KiChainedDispatch2ndLvl@0
/* Exit the interrupt */
mov esi, $
cli
call _HalEndSystemInterrupt@8
jmp _Kei386EoiHelper@0
.endfunc
.func KiInterruptDispatch@0
_KiInterruptDispatch@0:
/* Increase interrupt count */
inc dword ptr [fs:KPCR_PRCB_INTERRUPT_COUNT]
/* Save trap frame */
mov ebp, esp
/* Save vector and IRQL */
mov eax, [edi+KINTERRUPT_VECTOR]
mov ecx, [edi+KINTERRUPT_SYNCHRONIZE_IRQL]
/* Save old irql */
push eax
sub esp, 4
/* Begin interrupt */
push esp
push eax
push ecx
call _HalBeginSystemInterrupt@12
/* Check if it was handled */
or al, al
jz SpuriousInt
/* Acquire the lock */
GetIntLock:
mov esi, [edi+KINTERRUPT_ACTUAL_LOCK]
ACQUIRE_SPINLOCK(esi, IntSpin)
/* Call the ISR */
mov eax, [edi+KINTERRUPT_SERVICE_CONTEXT]
push eax
push edi
call [edi+KINTERRUPT_SERVICE_ROUTINE]
/* Release the lock */
RELEASE_SPINLOCK(esi)
/* Exit the interrupt */
cli
call _HalEndSystemInterrupt@8
jmp _Kei386EoiHelper@0
SpuriousInt:
/* Exit the interrupt */
add esp, 8
jmp _Kei386EoiHelper@0
#ifdef CONFIG_SMP
IntSpin:
SPIN_ON_LOCK esi, GetIntLock
#endif
.endfunc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -