15

I'm trying to use boost::asio::spawn function like in the example, but it gives me the following error in Release:

libboost_context-vc120-mt-s-1_55.lib(jump_i386_ms_pe_masm.obj) : error LNK2026: module unsafe for SAFESEH image

It is clear that I should set /SAFESEH:NO option in the project's settings but I can't understand what this will actually do. How this affect the behavior of exception handling in the program (both C++ exceptions and SEH)?

btw I'm using MSVC-12.0.

FrozenHeart
  • 19,844
  • 33
  • 126
  • 242

2 Answers2

21

Short answer: disabling SafeSEH will reduce your program security.


Details: SafeSEH is a compiler protection.

On a Windows environment SEH (Structured Exception Handler) records are laid out as follows

Stack data (pointed by TEB - thread environment block)
|
|  I) Pointer to next SEH record II
|  EH pointer
|
|  II) Pointer to next SEH record III
|  EH pointer
|
|  0xFFFFFF
|  default EH (MSVCRT)

Usually SEH-based attacks rely on overwriting one of the above records and having the application throw an exception: this will detour the control flow to your code (I'm not taking into account DEP/ASLR protection systems here so I'm assuming a known +X location). More precisely they often "simulate a EH return" and they fetch the next "evil-crafted" pointer to jump to the shellcode.

SafeSEH works by instructing the operating system to first check the handler pointers for validity (against a table of known valid EHs) before jumping to them. There are a few restrictions to this process and under special circumstances an application might still be vulnerable but a SEH-based attack is less likely to take place (or significantly harder to craft).

When linking against a non-safeSEH compiled module the linker won't be able to generate a "trusted table" of EH locations (it simply cannot tell where and if those are valid EHs) thus the error you're getting.

Some logistic restrictions on the Windows OS engineering, compatibility reasons and the problems bound to controlling addresses falling out of the range of loaded modules (and executable image) led to the choice of disabling this option by default and leaving the user the choice whether to enable it or not.

If your application desperately needs security and you repute the above scenario a potential threat, you should enable it and recompile your modules in order to use it.

Marco A.
  • 43,032
  • 26
  • 132
  • 246
  • 1
    Somewhat off-topic, but the way SEH works internally has become [much more complicated](http://uninformed.org/index.cgi?v=8&a=2&p=20) _(and also much more performant)_ since Vista. – BlueRaja - Danny Pflughoeft Jun 24 '16 at 15:55
  • @Marco If it secures exe, then why by default it's not enabled? – sonu gupta May 04 '17 at 06:36
  • @sonugupta I guess that might have something to do with [compatibility reasons](http://stackoverflow.com/q/14710577/1938163) – Marco A. May 04 '17 at 08:06
  • You say that SafeSEH works Windows checks exception handlers against the table to make sure they haven't been overwritten. But you allude to cases in which an app might still be vulnerable. Can you say something more about those? A quick google search seem to suggest that when the table is missing (how?) the only thing malware has to worry about is that when the code is built with SAFE, handlers can't point into non code segments. So malware looks for pop,pop,ret sequences – Motorhead Jul 07 '22 at 20:32
3

/SAFESEH produces a "Safe Exception Handler Table":

>dumpbin safeseh_yes.dll /loadconfig | find "xcept"
            3001F4D0 Safe Exception Handler Table
                   1 Safe Exception Handler Count
    Safe Exception Handler Table
          30018FE0  __except_handler4

/SAFESEH:NO produces no table:

>dumpbin safeseh_no.dll /loadconfig | find "xcept"
            00000000 Safe Exception Handler Table
                   0 Safe Exception Handler Count

If the table is present the OS uses it to verify that a SEH handler is valid before calling it.

tms
  • 31
  • 2