[ros-kernel] got kmode SEH to work

Skywing skywing at valhallalegends.com
Sun Jun 27 04:05:35 CEST 2004


At first glance it seems that you can't directly call NtContinue in kernel
mode on real NT because it depends on the stack layout of the caller (!),
assuming the caller is always KiSystemService.

The NT version of NtContinue certainly doesn't bugcheck.  What it seems to
do (given valid parameters) is set the current thread's trap frame to the
trap frame built by KiSystemService, twiddles that trap frame, and returns
through the system service exit mechanism KiServiceExit/KiServiceExit2
directly (it does NOT return to KiSystemService on success, most notably).

This guarantees that the volatile registers eax/ecx/edx aren't corrupted by
KiSystemService.

If given invalid parameters, NtContinue returns an NTSTATUS value to
KiSystemService.

While the NT solution can probably be classified as a hack, it does make
sure that those nonvolatile registers stay correct - something ours still
doesn't do for ecx/edx (even with Royce's hotfix)!

-----Original Message-----
From: ros-kernel-bounces at reactos.com [mailto:ros-kernel-bounces at reactos.com]
On Behalf Of Royce Mitchell III
Sent: Sunday, June 27, 2004 2:35 AM
To: ReactOS Kernel List
Subject: [ros-kernel] got kmode SEH to work

however.... Skywing is pretty sure my fix isn't "correct".

By changing the return value in NtContinue() from STATUS_SUCCESS to 
(NTSTATUS)TrapFrame->Eax, I was able to get SEH to work correctly with 
the following code in drivers/dd/null/null.c. (It turns out EAX gets 
clobbered somewhere between NtContinue() returning and landing back at 
our excepted address - perhaps NtContinue should do it's own special 
dethunking since we *do* want to restore EAX also?)

static DWORD scratch=0;

EXCEPTION_DISPOSITION
__cdecl
_except_handler(
    struct _EXCEPTION_RECORD *ExceptionRecord,
    void * EstablisherFrame,
    PCONTEXT ContextRecord,
    void * DispatcherContext )
{
    // Indicate that we made it to our exception handler
    DbgPrint ( "null.sys:_except_handler() EAX=0x%x, EIP=0x%x, ESP=0x%x, 
EBP=0x%x\n",
        ContextRecord->Eax, ContextRecord->Eip, ContextRecord->Esp, 
ContextRecord->Ebp );

    // Change EAX in the context record so that it points to someplace
    // where we can successfully write
    ContextRecord->Eax = (DWORD)&scratch;

    DbgPrint ( "null.sys:_except_handler() changed EAX to 0x%x", 
ContextRecord->Eax );

    // Tell the OS to restart the faulting instruction
    return ExceptionContinueExecution;
}

[snip]

    case IRP_MJ_CREATE:
    case IRP_MJ_CLOSE:
        {
            DWORD handler = (DWORD)_except_handler;
            DbgPrint ( "null.sys.NullDispatch(): setting up SEH 'frame', 
_except_handler=0x%x\n", handler );
            __asm__ ("\tpushl %0\n" : "=m" (handler) );
            __asm__ ("\tpushl %fs:(0)\n" );
            __asm__ ("\tmovl %esp,%fs:(0)\n" );
            DbgPrint ( "null.sys.NullDispatch(): inside SEH 'frame' - 
about to cause exception\n" );
           
            __asm__ ("\tmovl $0, %eax\n"
                "\tmovl $1, (%eax)\n");

            DbgPrint ( "null.sys.NullDispatch(): after exception, 
closing SEH 'frame'\n" );

            __asm__ ("\tmovl (%esp),%eax\n"
                "\tmovl %eax, %fs:(0)\n"
                "\taddl $8, %esp\n");


Skywing said he'll respond - or whatever - with anything else he finds, 
but I'm going to bed... way too late...


_______________________________________________
Ros-kernel mailing list
Ros-kernel at reactos.com
http://reactos.com/mailman/listinfo/ros-kernel




More information about the Ros-kernel mailing list