Yesterday I took a bit of time and updated the Explorer Suite. One important new feauture is the addition of the Exception Directory. I’m no longer working on the old CFF Explorer. However, I thought this feature was too important for people to wait for the new CFF Explorer. Here’s a screenshot of the Exception Directory UI:
If you have no idea how the x64 Structured Exception Handling works, you can briefly read this article on osronline or my article about Vista x64. There’s also a pretty in depth quantity of information in a series of posts on Ken Johnson’s blog. However, don’t hope to find too much information on the web about the real physical layout of the Exception Directory. The MSDN information is incomplete if not wrong and even the SDK doesn’t help. This post isn’t a complete guide to x64 exceptions, I just want to explain how to analyze them inside the CFF Explorer.
In the screenshot above you can see two arrays of tables. The first one is an array of RUNTIME_FUNCTION structures. The last column isn’t part of this structure though: it shows the five high bits of the first byte of the UNWIND_INFO structure refrenced by the UnwindData member of RUNTIME_FUNCTION. This is the declaration of UNWIND_INFO:
[cc lang=”cpp”]typedef struct _UNWIND_INFO {
UBYTE Version : 3;
UBYTE Flags : 5;
UBYTE SizeOfProlog;
UBYTE CountOfCodes;
UBYTE FrameRegister : 4;
UBYTE FrameOffset : 4;
UNWIND_CODE UnwindCode[1];
/* UNWIND_CODE MoreUnwindCode[((CountOfCodes + 1) & ~1) – 1];
* union {
* OPTIONAL ULONG ExceptionHandler;
* OPTIONAL ULONG FunctionEntry;
* };
* OPTIONAL ULONG ExceptionData[]; */
} UNWIND_INFO, *PUNWIND_INFO;[/cc]
The flags represent the type of handlers. An exception flag represents __try/__except blocks, while the termination flag represents __try/__finally blocks.
The second is an array of scope records. An UNWIND_INFO can contain more than one scope records. Let’s consider this little code sample:
[cc lang=”cpp”]__try
{
__try
{
// code
}
__finally
{
// code
}
__try
{
// code
}
__finally
{
// code
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
// code
}[/cc]
As you can see from the screenshot, it results in 3 scope records. The HandlerAddress in a scope record structure can be an RVA to a C_exception_handler function. Or it can be a simple value like EXCEPTION_EXECUTE_HANDLER (which is 1). The last scope record represents the __except statement. Don’t confuse the exception handler (or filter) with its code.
The JumpTarget member, if not 0, is an RVA to the exception code. It’s possible to see if a particular address has an entry inside the Exception Directory by right clicking on the first table and then clicking ‘Is Address Handled’ in the pop-up menu. Nevertheless, remember that exception handlers can be added at runtime with APIs like RtlAddFunctionTable and RtlInstallFunctionTableCallback.
I fixed some minor bugs in the CFF Explorer and one major bug in the Task Explorer. I noticed this bug years ago but never took time to fix it. It showed only when trying to dump the region of an x86 process using the 64 bit version of the Task Explorer. However, x64 is becoming very used and so the bug is now fixed. Also, I thought it would be a good idea on 64-bit platforms to install a 32-bit version of the Task Explorer and a 64-bit one. Thus, the installer now behaves accordingly.