Okay – next experiment was to try to figure out how to tell the difference between binaries built with and without the /SAFESEH Visual C++ linker option. Here’s a pretty good explanation of what that linker option does – http://msdn2.microsoft.com/en-us/library/9a89h429(VS.80).aspx, but it doesn’t explain why it should be used, or what happens if something goes wrong in a SafeSEH image at runtime.Then I realized that SafeSEH is really just another name for software-enforced data execution prevention, or DEP. See this link – http://technet.microsoft.com/en-us/library/bb457155.aspx.
If software-enforced DEP is enabled, and the image is compiled SafeSEH, a run-time exception will only be dispatched if the exception handler is registered in the image header. It’s not stated explicitly what happens if an otherwise matching but un-registered (and therefore presumably compromised) handler is encountered on the stack. I guess either a handler in the registered chain is used instead, or a STATUS_ACCESS_VIOLATION exception is raised. Either way, the process is most likely toast, which is the desired defensive outcome.
I suppose the registered handler table could be brute-force overriden by locating its virtual address, marking it as writable, and then clobbering the first address in the chain with a new one. Mounting such an attack would seem to require the ability to run arbitrary code, in which case all is lost anyway. However, it’s clear that SafeSEH and hardware-enforced DEP complement each other quite well with respect to reducing the damage that is likely to be done following a stack buffer overflow.
Anyway, returning to the original question, detecting the presence of the safe exception handler table turns out to be pretty easy with dumpbin. The following sections – Load Config and Safe Exception Handler Table – are completely missing from binaries built without SafeSEH.
>link /dump /all On\xxx.dll
Section contains the following load config:
1001405C Security Cookie
10012F40 Safe Exception Handler Table
B Safe Exception Handler Count
Safe Exception Handler Table
Interestingly, even when compiling code that doesn’t explicitly use SEH (http://msdn2.microsoft.com/en-us/library/ms680657.aspx) or C++ exceptions, linking against any of the usual default run time libraries (at least in Visual C++ 2005) seems to result in the presence of the above PE header tables. Indeed, according to the docs, safe SEH info will be present by default unless the image is linked against a library built with an older version of the compiler. Explicit usage of the /SAFESEH option in that situation results in a link-time error, which makes it a good reminder to recompile.