Log in

View Full Version : x64 SEH & Explorer Suite Update


Daniel Pistelli
January 18th, 2009, 19:18
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:

http://rcecafe.net/wp-content/uploads/09/cffexcept.jpg

If you have no idea how the x64 Structured Exception Handling works, you can briefly read this article on osronline ("http://www.osronline.com/article.cfm?id=469") 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 ("http://www.nynaeve.net/?p=99"). 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:

Code:
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;

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:

Code:
__try
{
__try
{
// code
}
__finally
{
// code
}

__try
{
// code
}
__finally
{
// code
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
// code
}

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 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.

Kayaker
January 19th, 2009, 00:01
Thank you Daniel. This is one sweet suite of tools. And freeware no less!

Um, did you say new CFF Explorer? What can we look forward to?

Regards,
Kayaker

Daniel Pistelli
January 19th, 2009, 19:43
Hello Kayaker. Well, I don't wanna bore anyone with my stuff, but since you're asking... (so you can't complain)

It may seem quite strange that it took me so much time to design the kernel of the CFF Explorer, a tool for file analysis, but it's true. I haven't finished writing the kernel yet and have just started with the GUI (although that work is much more relaxing). It's difficult to explain why the design was so difficult. First off, i made it absolutely simple to add new formats like say file system formats ecc. The kernel now is "stream" based, so it could even open a process or a disk. And that was easy. Now the more difficult part. The whole project is now cross platform, not only the kernel but also the GUI, it could even be compiled on big endian platforms. Endianess is handled completely, I can even load a file specifying a different endianess from the default one. I can, for instance, load a PE file with big endian values. The kernel is multi-threading in a very complicate way. CFF Objects can be shared among more threads and streams can be shared among more CFF Objects. Every kind of string encoding is handled. I'm currently writing a Big Integer class to implement in the kernel in order to support values of infinite size. The GUI will be very nice and much more advanced. One big feature will also be the complete python integration.

In theory, the CFF Explorer will be available for at least Windows and MacOSX. Maybe even Linux. It will support PE, Elf32 and Mach-O. And that's just the start.

This isn't all, just a taste. And the fact that it took me many months only to design the kernel should tell you that it's really a complex kernel this time. The kernel of the old CFF was a "nice" start point but that took me only a week to create, the first CFF was only a small utility to me and I was much younger at that time. This time I took things very seriously. It will be long before I finish it, but it will surely be a very advanced software product.

Shub-nigurrath
January 20th, 2009, 03:31
compliments Daniel, you are doing a really advanced work. The shopping list is really intriguing.

Daniel Pistelli
January 20th, 2009, 13:39
Thanks Shub.

It occurred to me that I wrote Elf32. I meant Elf. Don't know how that came out.

Shub-nigurrath
January 20th, 2009, 13:50
I see that you are also implementing support for macho format, this would really help the mac and also the OSX scene in general (I mean also iphone for example). Because windows based macho format modifier are not so common indeed.