Difference between revisions of "Techwiki:SEH64"

From ReactOS Wiki
Jump to: navigation, search
(References)
(References)
Line 194: Line 194:
 
*[http://msdn.microsoft.com/en-us/library/ms794374.aspx MSDN: UNWIND_INFO Structure]
 
*[http://msdn.microsoft.com/en-us/library/ms794374.aspx MSDN: UNWIND_INFO Structure]
 
*[http://msdn.microsoft.com/en-us/library/b6sf5kbd.aspx MSDN: The Language Specific Handler]
 
*[http://msdn.microsoft.com/en-us/library/b6sf5kbd.aspx MSDN: The Language Specific Handler]
 +
*[http://msdn.microsoft.com/en-us/library/ms235241.aspx MSDN: Unwind Helpers for MASM]
 
*[http://www.nynaeve.net/?p=107 Collided Unwinds]
 
*[http://www.nynaeve.net/?p=107 Collided Unwinds]
*[http://msdn.microsoft.com/en-us/library/ms235241.aspx Unwind Helpers for MASM]
 
 
*[http://msdn.microsoft.com/en-us/library/aa363082(VS.85).aspx MSDN: EXCEPTION_RECORD Structure]
 
*[http://msdn.microsoft.com/en-us/library/aa363082(VS.85).aspx MSDN: EXCEPTION_RECORD Structure]
 
*[http://www.smartmobili.com/content/view/44/41/lang,english/ SEH exceptions on Windows CE (ARM)]  *[http://www.smartmobili.com/content/view/40/42/lang,fr/ 2]
 
*[http://www.smartmobili.com/content/view/44/41/lang,english/ SEH exceptions on Windows CE (ARM)]  *[http://www.smartmobili.com/content/view/40/42/lang,fr/ 2]
 
*[http://www.bugbrowser.com/dev/dumpwriter/exception_lifetime.html Lifetime of an exception]
 
*[http://www.bugbrowser.com/dev/dumpwriter/exception_lifetime.html Lifetime of an exception]

Revision as of 17:26, 28 April 2009

Function Table

The function table can be found in the .pdata section of the executable. It's an array of RUNTIME_FUNCTION structures. NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION] is the corresponding data directory entry. It's VirtualAddress member points to the beginning of this section, it's Size member divided by sizeof(RUNTIME_FUNCTION) gives the numer of entries.

typedef struct _RUNTIME_FUNCTION
{
    ULONG BeginAddress;
    ULONG EndAddress;
    ULONG UnwindData;
} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;

BeginAddress is the RVA of the beginning of the corresponding function. EndAddress is the RVA of the end of the corresponding function. UnwindData is the RVA of the UNWIND_INFO structure belonging to this function.

All RUNTIME_FUNCTION entries are sorted, beginning with the smallest address and never overlapping. There may be gaps though. If an address is not found inside the table, it is supposed to be a leaf function and RSP points to the functions return address.

The table that corresponds to a certain address can be found using

PRUNTIME_FUNCTION
NTAPI
RtlLookupFunctionTable(
    IN DWORD64 ControlPc,
    OUT PDWORD64 ImageBase,
    OUT PULONG Length);

The function entry can be found by using

PRUNTIME_FUNCTION
NTAPI
RtlLookupFunctionEntry(
    IN DWORD64 ControlPc,
    OUT PDWORD64 ImageBase,
    OUT PUNWIND_HISTORY_TABLE HistoryTable);

Unwind Data

The UnwindData member of the RUNTIME_FUNCTION entry is the RVA of an UNWIND_INFO structure.

typedef struct _UNWIND_INFO
{
    UBYTE Version:3;
    UBYTE Flags:5;
    UBYTE SizeOfProlog;
    UBYTE CountOfCodes;
    UBYTE FrameRegister:4;
    UBYTE FrameOffset:4;
    UNWIND_CODE UnwindCode[1];
/*  union
    {
        OPTIONAL ULONG ExceptionHandler;
        OPTIONAL ULONG FunctionEntry;
    };
    OPTIONAL ULONG ExceptionData[];
*/
} UNWIND_INFO, *PUNWIND_INFO;

Version

Should be 1

Flags

Can be can be one of the following values
#define UNW_FLAG_NHANDLER 0
#define UNW_FLAG_EHANDLER 1
#define UNW_FLAG_UHANDLER 2
#define UNW_FLAG_???      3
#define UNW_FLAG_CHAININFO 4

SizeOfProlog

Size of the functions prolog in bytes.

CountOfCodes

Number of UNWIND_CODE entries in this structure.

FrameRegister

FrameOffset

ExceptionHandler

RVA of the language specific handler. See below.

ExceptionData

This data is specific to the language specific handler and a pointer to this data is passed to the handler in the DISPATCHER_CONTEXT structure.

The exception handler for RtlpExecuteHandlerForUnwind (RtlpUnwindHandler) has a Flags value of 3. The handler is responsible for collided unwinds, see http://www.nynaeve.net/?p=107

The Language specific handler

This function must correspond to the following prototype:

typedef EXCEPTION_DISPOSITION
(*PEXCEPTION_ROUTINE)(
    IN PEXCEPTION_RECORD ExceptionRecord,
    IN ULONG64 EstablisherFrame,
    IN OUT PCONTEXT ContextRecord,
    IN OUT PDISPATCHER_CONTEXT DispatcherContext);

_C_specific_handler

In this case ExceptionData is a SCOPE_TABLE structure.

typedef struct _SCOPE_TABLE {
    ULONG Count;
    struct
    {
        ULONG BeginAddress;
        ULONG EndAddress;
        ULONG HandlerAddress;
        ULONG JumpTarget;
    } ScopeRecord[1];
} SCOPE_TABLE, *PSCOPE_TABLE;

_CxxFrameHandler3

This function is exported by msvcr90.dll. Used with C++ exceptions (try/catch). In this case the Flags field in the UNWIND_INFO structure is 3. http://multitouchvista.codeplex.com/Thread/View.aspx?ThreadId=51520

int
__CxxFrameHandler3(
    EHExceptionRecord * pExcept,
    EHRegistrationNode * pRN,
    void * pContext,
    void * pDC);

struct EHExceptionRecord
{
    EXCEPTION_RECORD ExceptionRecord;
    ???
};

struct EHRegistrationNode (FIXME: this is x86)
{
  EHRegistrationNode *prev;
  DWORD ehhandler_code;
  DWORD id;
  DWORD saved_ebp;
};

The ExceptionData is an RVA to some data in the rdata segment:

typedef struct
{
    DWORD unknown00; // 0x19930522
    DWORD unknown04; // 0x2
    RVA   Data1;     // points to DATA1 in .rdata
    DWORD unknown0c; // 0x1
    RVA   Data2;     // points to DATA2 in .rdata
    DWORD unknown14; // 8
    RVA   Data3;     // points to DATA3 in .rdata
    DWORD unknown1c; // 0x28
    DWORD unknown20; // 0
    DWORD unknown24; // 0
} DATA0;

typedef struct
{
    DWORD dw0; // 0xffffffff
    DWORD dw1; // 0
    DWORD dw2; // 0xffffffff
    DWORD dw3; // 0
} DATA1;

typedef struct
{
    DWORD dw0;    // 0
    DWORD dw1;    // 0
    DWORD dw2;    // 1
    DWORD dw3;    // Number of catch blocks
    RVA   Data4;  // points to array of DATA4 in .rdata, one for each catch
} DATA2;

typedef struct
{
    RVA ThrowingFunction;
    DWORD dw04; // 0xffffffff
    RVA ScopeBegin;
    DWORD dw0c; // 0x0
    RVA EndScope;
    DWORD dw14; // 0xffffffff
    RVA Sub1;
    DWORD dw1c; // 0
    RVA Sub2;
    DWORD dw1c; // 1
    RVA Sub3;
    DWORD dw1c; // 0
    ... more RVA/DWORD combinations for more catch blocks
} DATA3;

typedef struct
{
    DWORD dw0;          // 0
    RVA   Data5;        // points to .data
    DWORD dw2;          // 0x24
    RVA   HandlerFunc; 
    DWORD dw4;          // 0x38
} DATA4;

References