📄 asmmacro.s
字号:
mov edi, [ebp+KTRAP_FRAME_DR1]
mov ebx, [ebp+KTRAP_FRAME_DR7]
/* Load them */
mov dr3, esi
mov dr6, edi
mov dr7, ebx
jmp V86DebugContinue
PendingUserApc:
/* Raise to APC level */
mov ecx, APC_LEVEL
call @KfRaiseIrql@4
/* Save KIRQL and deliver APCs */
push eax
sti
push ebp
push 0
push UserMode
call _KiDeliverApc@12
/* Restore IRQL */
pop ecx
call @KfLowerIrql@4
cli
/* Check if we're not in V86 anymore */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz ExitBegin
.endm
//
// @name TRAP_EPILOG
//
// This macro creates an epilogue for leaving any system trap.
// It is used for exiting system calls, exceptions, interrupts and generic
// traps.
//
// @param SystemCall
// Specifies whether this trap will exit a system call. If so, special
// code will be assembled to potentially use SYSEXIT instead of IRETD.
//
// @param RestorePreviousMode
// Specifies if the previous mode should be restored.
//
// @param RestoreSegments
// Specifies if the segment registers should be restored.
//
// @param RestoreVolatiles
// Specifies if the volatile registers should be restored.
//
// @param RestoreAllRegs
// Specifies if volatiles and segments should both be restored.
//
// @remark
//
.macro TRAP_EPILOG SystemCall, RestorePreviousMode, RestoreSegments, RestoreVolatiles, RestoreAllRegs
#ifdef DBG
/* Assert the flags */
pushfd
pop edx
test edx, EFLAGS_INTERRUPT_MASK
jnz 6f
/* Assert the stack */
cmp esp, ebp
jnz 6f
/* Assert the trap frame */
#endif
5:
#ifdef DBG
sub dword ptr [esp+KTRAP_FRAME_DEBUGARGMARK], 0xBADB0D00
jnz 0f
/* Assert FS */
mov bx, fs
cmp bx, KGDT_R0_PCR
jnz 1f
/* Assert exception list */
cmp dword ptr PCR[KPCR_EXCEPTION_LIST], 0
jnz 2f
1:
push -1
call _KeBugCheck@4
#endif
2:
/* Get exception list */
mov edx, [esp+KTRAP_FRAME_EXCEPTION_LIST]
#ifdef DBG
/* Assert the saved exception list */
or edx, edx
jnz 1f
UNHANDLED_PATH
1:
#endif
/* Restore it */
mov PCR[KPCR_EXCEPTION_LIST], edx
.if \RestorePreviousMode
/* Get previous mode */
mov ecx, [esp+KTRAP_FRAME_PREVIOUS_MODE]
#ifdef DBG
/* Assert the saved previous mode */
cmp ecx, -1
jnz 1f
UNHANDLED_PATH
1:
#endif
/* Restore the previous mode */
mov esi, PCR[KPCR_CURRENT_THREAD]
mov byte ptr [esi+KTHREAD_PREVIOUS_MODE], cl
.else
#ifdef DBG
/* Assert the saved previous mode */
mov ecx, [esp+KTRAP_FRAME_PREVIOUS_MODE]
cmp ecx, -1
jz 1f
UNHANDLED_PATH
1:
#endif
.endif
/* Check for debug registers */
test dword ptr [esp+KTRAP_FRAME_DR7], ~DR7_RESERVED_MASK
jnz 2f
/* Check for V86 */
4:
test dword ptr [esp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz V86_Exit
/* Check if the frame was edited */
test word ptr [esp+KTRAP_FRAME_CS], FRAME_EDITED
jz 7f
.if \RestoreAllRegs
/* Check the old mode */
cmp word ptr [esp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
bt word ptr [esp+KTRAP_FRAME_CS], 0
cmc
ja 8f
.endif
.if \RestoreVolatiles
/* Restore volatiles */
mov edx, [esp+KTRAP_FRAME_EDX]
mov ecx, [esp+KTRAP_FRAME_ECX]
mov eax, [esp+KTRAP_FRAME_EAX]
.endif
/* Check if we were called from kernel mode */
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R0_CODE
jz 9f
.if \RestoreSegments
/* Restore segment registers */
lea esp, [ebp+KTRAP_FRAME_GS]
pop gs
pop es
pop ds
.endif
/* Restore FS */
3:
lea esp, [ebp+KTRAP_FRAME_FS]
pop fs
9:
/* Skip debug information and unsaved registers */
lea esp, [ebp+KTRAP_FRAME_EDI]
pop edi
pop esi
pop ebx
pop ebp
/* Check for ABIOS */
cmp word ptr [esp+8], 0x80
ja AbiosExit
/* Pop error code */
add esp, 4
.if \SystemCall
/* Check if previous CS is from user-mode */
test dword ptr [esp+4], 1
/* It is, so use Fast Exit */
jnz FastExit
/* Jump back to stub */
pop edx
pop ecx
popf
jmp edx
.ret:
.endif
iret
.if \SystemCall
FastExit:
/* Is SYSEXIT Supported/Wanted? */
cmp dword ptr ss:[_KiFastSystemCallDisable], 0
jnz .ret
test dword ptr [esp+8], EFLAGS_TF
jnz .ret
/* Restore FS to TIB */
mov ecx, KGDT_R3_TEB + RPL_MASK
mov fs, ecx
/* We will be cleaning up the stack ourselves */
pop edx /* New Ring 3 EIP */
add esp, 4 /* Skip Ring 3 DS */
and dword ptr [esp], 0xfffffdff /* Remove EFLAGS_INTERRUPT_MASK from EFLAGS */
popf /* Restore old EFLAGS */
pop ecx /* Old Ring 3 SS:ESP */
/*
* At this point:
* ECX points to the old User Stack.
* EDX points to the instruction to execute in usermode after the sysenter
*/
sti
sysexit
.endif
.if \RestoreAllRegs
8:
/* Restore EAX */
mov eax, [esp+KTRAP_FRAME_EAX]
/* Skip registers */
add esp, 0x30
/* Restore segments and volatiles */
pop gs
pop es
pop ds
pop edx
pop ecx
/* Jump back to mainline code */
jmp 3b
.endif
#if DBG
0:
/* Fix up the mask */
add dword ptr [esp+KTRAP_FRAME_DEBUGARGMARK], 0xBADB0D00
6:
UNHANDLED_PATH
jmp 5b
#endif
2:
/* Check if this was V86 mode */
test dword ptr [esp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz 1f
/* Check if it was user mode */
test word ptr [esp+KTRAP_FRAME_CS], MODE_MASK
jz 4b
1:
/* Clear DR7 */
xor ebx, ebx
mov dr7, ebx
/* Get DR0, 1, 2 */
mov esi, [ebp+KTRAP_FRAME_DR0]
mov edi, [ebp+KTRAP_FRAME_DR1]
mov ebx, [ebp+KTRAP_FRAME_DR2]
/* Set them */
mov dr0, esi
mov dr1, edi
mov dr2, ebx
/* Get DR3, 6, 7 */
mov esi, [ebp+KTRAP_FRAME_DR3]
mov edi, [ebp+KTRAP_FRAME_DR6]
mov ebx, [ebp+KTRAP_FRAME_DR7]
/* Set them */
mov dr3, esi
mov dr6, edi
mov dr7, ebx
jmp 4b
7:
/* Restore real CS value */
mov ebx, [esp+KTRAP_FRAME_TEMPCS]
mov [esp+KTRAP_FRAME_CS], ebx
/*
* If ESP was modified, then a special interrupt exit stack
* must be created to "update" ESP's value in a legal manner
*/
mov ebx, [esp+KTRAP_FRAME_TEMPESP]
sub ebx, 0xC
mov [esp+KTRAP_FRAME_ERROR_CODE], ebx
/* Copy Interrupt Stack */
mov esi, [esp+KTRAP_FRAME_EFLAGS]
mov [ebx+8], esi
mov esi, [esp+KTRAP_FRAME_CS]
mov [ebx+4], esi
mov esi, [esp+KTRAP_FRAME_EIP]
mov [ebx], esi
.if \RestoreVolatiles
/* Restore volatiles */
mov eax, [esp+KTRAP_FRAME_EAX]
mov edx, [esp+KTRAP_FRAME_EDX]
mov ecx, [esp+KTRAP_FRAME_ECX]
.endif
/* Return */
add esp, KTRAP_FRAME_EDI
pop edi
pop esi
pop ebx
pop ebp
mov esp, [esp]
iret
.endm
//
// @name INT_EPILOG
//
// This macro creates an epilogue for leaving any system trap.
// It is used for exiting system calls, exceptions, interrupts and generic
// traps.
//
// @param Spurious - TRUE if the interrupt was unexpected and spurious.
//
// @remark None.
//
.macro INT_EPILOG Spurious
.if \Spurious
/* Just exit the trap */
jmp _Kei386EoiHelper@0
.else
/* Disable interrupts */
cli
/* End the interrupt and do EOI */
call _HalEndSystemInterrupt@8
jmp _Kei386EoiHelper@0
.endif
.endm
#ifdef DBG
.macro VERIFY_INT Label
/* Get the current time and mask it to 192 ticks */
mov eax, _KeTickCount
and eax, 0xC0
/* Check if we're in the same tick area */
cmp eax, dword ptr [edi+KINTERRUPT_TICK_COUNT]
jg VfRst_&Label
jl VfWrap_&Label
/* If we got here, then our count is too large */
dec word ptr [edi+KINTERRUPT_DISPATCH_COUNT]
jz VfOvr_&Label
Vf_&Label:
.endm
.macro VERIFY_INT_END Label, Info
VfOvr_&Label:
/* Decrement the dispatch count and check if we should bug check */
dec word ptr [edi+KINTERRUPT_DISPATCH_COUNT+2]
jz 1f
/* Update the tick count */
add eax, 0x40
mov [edi+KINTERRUPT_TICK_COUNT], eax
jmp VfRstDef_&Label
.1:
/* Check if the debugger is enabled */
cmp byte ptr __KdDebuggerEnabled, 0
jnz 1f
/* It isn't, bugcheck */
push Info
push edi
push [edi+KINTERRUPT_SERVICE_CONTEXT]
push [edi+KINTERRUPT_SERVICE_ROUTINE]
push HARDWARE_INTERRUPT_STORM
call _KeBugCheckEx@20
1:
/* Debugger enabled, do a debug print + break instead */
push [edi+KINTERRUPT_SERVICE_ROUTINE]
push offset _IsrOverflowMsg
call _DbgPrint
add esp, 8
int 3
/* Breakpoint handled, get the new tick count */
mov eax, _KeTickCount
and eax, 0xC0
VfRst_&Label:
/* Reset tick count */
mov dword ptr [edi+KINTERRUPT_TICK_COUNT], eax
mov word ptr [edi+KINTERRUPT_DISPATCH_COUNT+2], 64
VfRstDef_&Label:
/* Put default overflow count and continue */
mov ax, _KiISROverflow
mov word ptr [edi+KINTERRUPT_DISPATCH_COUNT], ax
jmp Vf_&Label
VfWrap_&Label:
/* Check if we wrapped */
add eax, 0x40
cmp eax, [edi+KINTERRUPT_TICK_COUNT]
je Vf_&Label
/* We did, start over */
mov eax, _KeTickCount
jmp VfRst_&Label
.endm
#else
/* We don't verify interrupts on retail builds */
.macro VERIFY_INT Label
.endm
.macro VERIFY_INT_END Label, Info
.endm
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -