Uninformed: Informative Information for the Uninformed

Vol 4» 2006.Jun


Exception Handlers

The unwind information structure for a non-leaf function also contains useful information about the way in which exceptions within that function should be dispatched. If the unwind information associated with a function has the UNW_FLAG_EHANDLER or UNW_FLAG_UHANDLER flag set, then the function has an exception handler associated with it. The exception handler is conveyed through the ExceptionHandler attribute which comes immediately after the array of unwind codes. This handler is defined as being a language-specific handler for processing the exception. More specifically, the exception handler is specific to the semantics associated with a given programming language, such as C or C++[3]. For C, the language-specific exception handler is named __C_specific_handler.

Given that all C functions that handle exceptions will have the same exception handler, how does the function-specific code for handling an exception actually get called? For the case of C functions, the function-specific exception handler is stored in a scope table in the ExceptionData portion of the UNWIND_INFO structure4.1. This C scope table is defined by the structures shown below:

typedef struct _C_SCOPE_TABLE_ENTRY {
    ULONG Begin;
    ULONG End;
    ULONG Handler;
    ULONG Target;
} C_SCOPE_TABLE_ENTRY, *PC_SCOPE_TABLE_ENTRY;

typedef struct _C_SCOPE_TABLE {
    ULONG NumEntries;
    C_SCOPE_TABLE_ENTRY Table[1];
} C_SCOPE_TABLE, *PC_SCOPE_TABLE;

The scope table entries describe the function-specific exception handlers in relation to the specific areas of the function that they apply to. Each of the attributes of the C_SCOPE_TABLE_ENTRY is expressed as an RVA. The Target attribute defines the location to transfer control to after the exception is handled.

The reason why all of the exception handler information is useful is because it makes it possible to annotate a function in terms of what exception handlers may be called during its execution. It also makes it possible to identify the exception handler functions that may otherwise not be found due to the fact that they are executed indirectly. For example, the function CcAcquireByteRangeForWrite in ntoskrnl.exe can be annotated in the following fashion:

.text:0000000000434520 ; Exception handler: __C_specific_handler
.text:0000000000434520 ; Language specific handler: sub_4C7F30
.text:0000000000434520
.text:0000000000434520 CcAcquireByteRangeForWrite proc near