I have a lot questions after reading the post about decoding structural exception 0xE06D7363 from "The Old New Thing". I like computer magic like that: take address from here add the constant two and half time and you get it. However, this magic don't help to understand how it really works and what happened if I do that. So, following code from CRT kill all magic.
Welcome - ehdata.h. This header appears only in VS2012 and VS2013 (see "%Program Files (x86)%\Microsoft Visual Studio 12.0\VC\crt\src\ehdata.h"):
typedef struct EHExceptionRecord {
DWORD ExceptionCode; // The code of this exception. (= EH_EXCEPTION_NUMBER)
DWORD ExceptionFlags; // Flags determined by NT
struct _EXCEPTION_RECORD *ExceptionRecord; // An extra exception record (not used)
void * ExceptionAddress; // Address at which exception occurred
DWORD NumberParameters; // Number of extended parameters. (= EH_EXCEPTION_PARAMETERS)
struct EHParameters {
DWORD magicNumber; // = EH_MAGIC_NUMBER1
void * pExceptionObject; // Pointer to the actual object thrown
ThrowInfo *pThrowInfo; // Description of thrown object
#if _EH_RELATIVE_OFFSETS
void *pThrowImageBase; // Image base of thrown object
#endif
} params;
} EHExceptionRecord;
////////////////////////////////////////////////
typedef const struct _s_ThrowInfo {
unsigned int attributes; // Throw Info attributes (Bit field)
PMFN pmfnUnwind; // Destructor to call when exception
// has been handled or aborted.
#if _EH_RELATIVE_OFFSETS && !defined(VERSP_IA64) && !defined(_M_CEE_PURE) /*IFSTRIP=IGN*/
__int32 pForwardCompat; // Image relative offset of Forward compatibility frame handler
__int32 pCatchableTypeArray;// Image relative offset of CatchableTypeArray
#else
#if defined(__cplusplus)
int (__cdecl* _EH_PTR64 pForwardCompat)(...); // Forward compatibility frame handler
#else
int (__cdecl* _EH_PTR64 pForwardCompat)(); // Forward compatibility frame handler
#endif
CatchableTypeArray * _EH_PTR64 pCatchableTypeArray; // Pointer to list of pointers to types.
#endif
} ThrowInfo;
////////////////////////////////////////////////
typedef const struct _s_CatchableTypeArray {
int nCatchableTypes;
#if _EH_RELATIVE_OFFSETS && !defined(VERSP_IA64) && !defined(_M_CEE_PURE) /*IFSTRIP=IGN*/
__int32 arrayOfCatchableTypes[]; // Image relative offset of Catchable Types
#else
CatchableType * _EH_PTR64 arrayOfCatchableTypes[];
#endif
} CatchableTypeArray;
////////////////////////////////////////////////
typedef const struct _s_CatchableType {
unsigned int properties; // Catchable Type properties (Bit field)
#if _EH_RELATIVE_OFFSETS && !defined(VERSP_IA64) && !defined(_M_CEE_PURE) /*IFSTRIP=IGN*/
__int32 pType; // Image relative offset of TypeDescriptor
#else
TypeDescriptor * _EH_PTR64 pType; // Pointer to the type descriptor for this type
#endif
PMD thisDisplacement; // Pointer to instance of catch type within
// thrown object.
int sizeOrOffset; // Size of simple-type object or offset into
// buffer of 'this' pointer for catch object
PMFN copyFunction; // Copy constructor or CC-closure
} CatchableType;
////////////////////////////////////////////////
typedef struct TypeDescriptor
{
#if defined(_WIN64) || defined(_RTTI) /*IFSTRIP=IGN*/
const void * _EH_PTR64 pVFTable; // Field overloaded by RTTI
#else
DWORD hash; // Hash value computed from type's decorated name
#endif
void * _EH_PTR64 spare; // reserved, possible for RTTI
char name[]; // The decorated name of the type; 0 terminated.
} TypeDescriptor;
P.S. _EH_RELATIVE_OFFSETS is defined as 1 only in 64-bit mode
No comments:
Post a Comment