From a3a344d380f564c731336325ffd0a6207a0e5ea0 Mon Sep 17 00:00:00 2001 From: short <> Date: Tue, 8 Apr 2003 17:42:51 +0000 Subject: [PATCH] Implemented stripped down SEH functionality --- ntoskrnl/ke/catch.c | 40 +++++++++++++++++++++++++++ ntoskrnl/rtl/i386/exception.c | 57 ++++++++++++++++++++++++++++++++++++++- ntoskrnl/rtl/i386/seh.s | 63 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 149 insertions(+), 11 deletions(-) diff --git a/ntoskrnl/ke/catch.c b/ntoskrnl/ke/catch.c index 6bdda14..2e151de 100644 --- a/ntoskrnl/ke/catch.c +++ b/ntoskrnl/ke/catch.c @@ -28,7 +28,9 @@ /* INCLUDES *****************************************************************/ #include +#ifndef LIBCAPTIVE #include +#endif /* LIBCAPTIVE */ #include #include #include @@ -52,12 +54,15 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, BOOLEAN SearchFrames) { EXCEPTION_DISPOSITION Value; +#ifndef LIBCAPTIVE CONTEXT TContext; +#endif /* LIBCAPTIVE */ DPRINT("KiDispatchException() called\n"); /* PCR->KeExceptionDispatchCount++; */ +#ifndef LIBCAPTIVE if (Context == NULL) { TContext.ContextFlags = CONTEXT_FULL; @@ -70,6 +75,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, Context = &TContext; } +#endif /* LIBCAPTIVE */ #if 0 if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) @@ -79,6 +85,9 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, #endif if (PreviousMode == UserMode) { +#ifdef LIBCAPTIVE + KeBugCheck(0); +#else /* !LIBCAPTIVE */ if (SearchFrames) { PULONG Stack; @@ -121,6 +130,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, /* If that fails then bugcheck */ DbgPrint("Could not terminate thread\n"); KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED); +#endif /* LIBCAPTIVE */ } else { @@ -128,6 +138,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, /* PreviousMode == KernelMode */ +#ifndef LIBCAPTIVE if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB) { Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf); @@ -138,6 +149,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, Action = KdbEnterDebuggerException (ExceptionRecord, Context, Tf); } #endif /* KDBG */ +#endif /* LIBCAPTIVE */ if (Action != kdHandleException) { Value = RtlpDispatchException (ExceptionRecord, Context); @@ -149,16 +161,26 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, */ if (Value != ExceptionContinueExecution) { +#ifndef LIBCAPTIVE KeBugCheck (KMODE_EXCEPTION_NOT_HANDLED); +#else /* !LIBCAPTIVE */ + KeBugCheck (0); +#endif /* LIBCAPTIVE */ } } else { +#ifndef LIBCAPTIVE KeContextToTrapFrame (Context, KeGetCurrentThread()->TrapFrame); +#else /* !LIBCAPTIVE */ + KeBugCheck(0); +#endif /* LIBCAPTIVE */ } } } +#ifndef LIBCAPTIVE + VOID STDCALL ExRaiseAccessViolation (VOID) { @@ -171,6 +193,8 @@ ExRaiseDatatypeMisalignment (VOID) ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT); } +#endif /* LIBCAPTIVE */ + VOID STDCALL ExRaiseStatus (IN NTSTATUS Status) { @@ -195,7 +219,11 @@ NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord, KiDispatchException(ExceptionRecord, Context, PsGetCurrentThread()->Tcb.TrapFrame, +#ifndef LIBCAPTIVE ExGetPreviousMode(), +#else /* !LIBCAPTIVE */ + KernelMode, +#endif /* LIBCAPTIVE */ SearchFrames); return(STATUS_SUCCESS); } @@ -204,7 +232,19 @@ NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord, VOID STDCALL RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord) { +#ifndef LIBCAPTIVE ZwRaiseException(ExceptionRecord, NULL, TRUE); +#else /* !LIBCAPTIVE */ +CONTEXT *LocalContext; + + /* Do not use local variable to benefit from ElectricFence boundary checks */ + LocalContext=ExAllocatePool(PagedPool,sizeof(LocalContext->ContextFlags)); + LocalContext->ContextFlags=0; + + NtRaiseException(ExceptionRecord, LocalContext, TRUE); + + ExFreePool(LocalContext); +#endif /* LIBCAPTIVE */ } /* EOF */ diff --git a/ntoskrnl/rtl/i386/exception.c b/ntoskrnl/rtl/i386/exception.c index 6cec442..a36deb0 100755 --- a/ntoskrnl/rtl/i386/exception.c +++ b/ntoskrnl/rtl/i386/exception.c @@ -18,6 +18,8 @@ /* FUNCTIONS ***************************************************************/ +#ifndef LIBCAPTIVE + #if 1 VOID STDCALL MsvcrtDebug(ULONG Value) @@ -46,7 +48,12 @@ _except_handler2( return (EXCEPTION_DISPOSITION)0; } -void __cdecl +#endif /* LIBCAPTIVE */ + +void +#ifndef LIBCAPTIVE +__cdecl +#endif /* LIBCAPTIVE */ _global_unwind2(PEXCEPTION_REGISTRATION RegistrationFrame) { RtlUnwind(RegistrationFrame, &&__ret_label, NULL, 0); @@ -55,6 +62,7 @@ __ret_label: return; } +#ifndef LIBCAPTIVE /* Implemented in except.s */ @@ -70,12 +78,30 @@ RtlpCaptureContext(PCONTEXT pContext); (*(StackLimit)) = KeGetCurrentKPCR()->StackLimit; \ } +#endif /* LIBCAPTIVE */ + +#ifndef LIBCAPTIVE + #define SehpGetExceptionList() \ (PEXCEPTION_REGISTRATION)(KeGetCurrentThread()->TrapFrame ->ExceptionList) #define SehpSetExceptionList(NewExceptionList) \ KeGetCurrentThread()->TrapFrame->ExceptionList = (PVOID)(NewExceptionList) +#else /* !LIBCAPTIVE */ + +extern guint32 fs_KPCR_ExceptionList; + +#define SehpGetExceptionList() \ + (PEXCEPTION_REGISTRATION)(fs_KPCR_ExceptionList) + +#define SehpSetExceptionList(NewExceptionList) \ + fs_KPCR_ExceptionList = (guint32)(PVOID)(NewExceptionList) + +#endif /* LIBCAPTIVE */ + +#ifndef LIBCAPTIVE + #define SehpCaptureContext(Context) \ { \ KeTrapFrameToContext(KeGetCurrentThread()->TrapFrame, (Context)); \ @@ -92,6 +118,8 @@ AsmDebug(ULONG Value) /* Declare a few prototypes for the functions in except.s */ +#endif /* LIBCAPTIVE */ + EXCEPTION_DISPOSITION RtlpExecuteHandlerForException( PEXCEPTION_RECORD ExceptionRecord, @@ -108,6 +136,7 @@ RtlpExecuteHandlerForUnwind( PVOID DispatcherContext, PEXCEPTION_HANDLER ExceptionHandler); +#ifndef LIBCAPTIVE #ifndef NDEBUG @@ -134,6 +163,8 @@ VOID RtlpDumpExceptionRegistrations(VOID) #endif /* NDEBUG */ +#endif /* LIBCAPTIVE */ + ULONG RtlpDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context) @@ -245,7 +276,11 @@ RtlpDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, else { /* Copy the (possibly changed) context back to the trap frame and return */ +#ifndef LIBCAPTIVE NtContinue(Context, FALSE); +#else /* !LIBCAPTIVE */ + KeBugCheck(0); +#endif /* LIBCAPTIVE */ return ExceptionContinueExecution; } } @@ -286,6 +321,8 @@ RtlpDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, return ExceptionContinueExecution; } +#ifndef LIBCAPTIVE + VOID STDCALL RtlRaiseStatus(NTSTATUS Status) { @@ -300,6 +337,8 @@ RtlRaiseStatus(NTSTATUS Status) RtlRaiseException (& ExceptionRecord); } +#endif /* LIBCAPTIVE */ + VOID STDCALL RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame, PVOID ReturnAddress, @@ -309,7 +348,9 @@ RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame, PEXCEPTION_REGISTRATION ERHead; PEXCEPTION_RECORD pExceptRec; EXCEPTION_RECORD TempER; +#ifndef LIBCAPTIVE CONTEXT Context; +#endif /* LIBCAPTIVE */ DPRINT("RtlUnwind(). RegistrationFrame 0x%X\n", RegistrationFrame); @@ -350,6 +391,7 @@ RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame, } #endif /* NDEBUG */ +#ifndef LIBCAPTIVE Context.ContextFlags = (CONTEXT_i386 | CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS); @@ -361,6 +403,7 @@ RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame, Context.Esp += 0x10; Context.Eax = EaxValue; +#endif /* LIBCAPTIVE */ // Begin traversing the list of EXCEPTION_REGISTRATION while ((ULONG_PTR)ERHead != (ULONG_PTR)-1) @@ -372,7 +415,11 @@ RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame, if (ERHead == RegistrationFrame) { DPRINT("Continueing execution\n"); +#ifndef LIBCAPTIVE NtContinue(&Context, FALSE); +#else /* !LIBCAPTIVE */ + /* FIXME: What to do there? */ +#endif /* LIBCAPTIVE */ return; } else @@ -411,7 +458,11 @@ RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame, ReturnValue = RtlpExecuteHandlerForUnwind( pExceptRec, ERHead, +#ifndef LIBCAPTIVE &Context, +#else /* !LIBCAPTIVE */ + NULL, +#endif /* LIBCAPTIVE */ &NewERHead, ERHead->handler); @@ -466,10 +517,14 @@ RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame, DPRINT("Ran out of exception registrations. RegistrationFrame is (0x%X)\n", RegistrationFrame); +#ifndef LIBCAPTIVE if ((ULONG_PTR)RegistrationFrame == (ULONG_PTR)-1) NtContinue(&Context, FALSE); else NtRaiseException(pExceptRec, &Context, 0); +#else /* !LIBCAPTIVE */ + KeBugCheck(0); +#endif /* LIBCAPTIVE */ } /* EOF */ diff --git a/ntoskrnl/rtl/i386/seh.s b/ntoskrnl/rtl/i386/seh.s index 03ccd6b..72ea62d 100755 --- a/ntoskrnl/rtl/i386/seh.s +++ b/ntoskrnl/rtl/i386/seh.s @@ -54,9 +54,17 @@ #define CONTEXT_EBX 0xA4 #define CONTEXT_EIP 0xB8 +#define __local_unwind2 _local_unwind2 /* LIBCAPTIVE */ +#define __except_handler3 _except_handler3 /* LIBCAPTIVE */ +#define __global_unwind2 _global_unwind2 /* LIBCAPTIVE */ + +#if 0 /* LIBCAPTIVE */ .globl __local_unwind2 +#endif /* LIBCAPTIVE */ .globl __except_handler3 +#if 0 /* LIBCAPTIVE */ + // EAX = value to print _do_debug: pushal @@ -65,17 +73,18 @@ _do_debug: popal ret +#endif /* LIBCAPTIVE */ + #define LU2_TRYLEVEL 0x08 #define LU2_REGFRAME 0x04 // // void -// _local_unwind2(PEXCEPTION_REGISTRATION RegistrationFrame, -// LONG TryLevel) +// _local_unwind2(PEXCEPTION_REGISTRATION RegistrationFrame,LONG TryLevel) // // Parameters: -// [EDX+08h] - PEXCEPTION_REGISTRATION RegistrationFrame -// [EDX+04h] - LONG TryLevel +// [EDX+08h] - LONG TryLevel +// [EDX+04h] - PEXCEPTION_REGISTRATION RegistrationFrame // Registers: // EBP - EBP of call frame we are unwinding // Returns: @@ -83,6 +92,7 @@ _do_debug: // Notes: // Run all termination handlers for a call frame from the current // try-level up to (but not including) the given stop try-level. +#if 0 __local_unwind2: // Setup our call frame so we can access parameters using EDX //pushl %ebp @@ -145,6 +155,7 @@ __local_unwind2: //movl %esi, %esp //popl %ebp ret +#endif #define EH3_DISPCONTEXT 0x14 #define EH3_CONTEXT 0x10 @@ -170,21 +181,24 @@ __except_handler3: // Setup our call frame so we can access parameters using EBP pushl %ebp // Standard ESP in frame (considered part of EXCEPTION_REGISTRATION) movl %esp, %ebp + pushl %ebx /* LIBCAPTIVE */ + pushl %esi /* LIBCAPTIVE */ + pushl %edi /* LIBCAPTIVE */ // Don't trust the direction flag to be cleared cld + // Keep a pointer to the exception registration in EBX + movl EH3_REGFRAME(%ebp), %ebx + // Either we're called to handle an exception or we're called to unwind movl EH3_ERECORD(%ebp), %eax testl $EXCEPTION_UNWIND_MODE, EREC_FLAGS(%eax) jnz .eh3_unwind - // Keep a pointer to the exception registration in EBX - movl EH3_REGFRAME(%ebp), %ebx - // Build an EXCEPTION_POINTERS structure on the stack and store it's // address in the EXCEPTION_REGISTRATION structure - movl EH3_CONTEXT(%esp), %eax + movl EH3_CONTEXT(%ebp), %eax pushl %ebx // Registration frame pushl %eax // Context movl %esp, ER_EPOINTERS(%ebx) // Pointer to EXCEPTION_REGISTRATION on the stack @@ -249,6 +263,7 @@ __except_handler3: // Change the context structure so _except_finish is called in the // correct context since we return ExceptionContinueExecution. +#if 0 /* LIBCAPTIVE */ movl EH3_CONTEXT(%ebp), %eax movl %edi, CONTEXT_EDI(%eax) // Stop try-level @@ -257,6 +272,11 @@ __except_handler3: movl $ExceptionContinueExecution, %eax jmp .eh3_return +#else /* !LIBCAPTIVE */ + // pass %edi + // pass %ebx + jmp _except_finish +#endif /* LIBCAPTIVE */ // Filter returned: EXCEPTION_CONTINUE_SEARCH .eh3_continue: @@ -287,8 +307,8 @@ __except_handler3: // Perform local unwinding .eh3_unwind: - movl $ExceptionContinueSearch, %eax testl $EXCEPTION_TARGET_UNWIND, EREC_FLAGS(%eax) + movl $ExceptionContinueSearch, %eax jnz .eh3_return // Save some important registers @@ -297,7 +317,15 @@ __except_handler3: lea ER_EBP(%ebx), %ebp pushl $-1 pushl %ebx + +#if 0 /* LIBCAPTIVE */ call __local_unwind2 +#else /* !LIBCAPTIVE */ + .extern _local_unwind2_addr + movl _local_unwind2_addr,%eax + call *%eax +#endif /* LIBCAPTIVE */ + addl $8, %esp // Restore some important registers @@ -308,7 +336,13 @@ __except_handler3: // Get me out of here .eh3_return: - movl %ebp, %esp + lea -3*4(%ebp),%esp /* LIBCAPTIVE */ + popl %edi /* LIBCAPTIVE */ + popl %esi /* LIBCAPTIVE */ + popl %ebx /* LIBCAPTIVE */ +#if 0 /* LIBCAPTIVE */ + movl %ebp, %esp +#endif /* LIBCAPTIVE */ popl %ebp ret @@ -337,7 +371,15 @@ _except_finish: // Pointer to exception registration structure pushl %ebx + +#if 0 /* LIBCAPTIVE */ call __local_unwind2 +#else /* !LIBCAPTIVE */ + .extern _local_unwind2_addr + movl _local_unwind2_addr,%eax + call *%eax +#endif /* LIBCAPTIVE */ + addl $8, %esp // Restore some important registers @@ -363,4 +405,5 @@ _except_finish: call *%eax // We should never get here + hlt ret -- 1.8.3.1