Among other improvements in Windows XP SP2 and Windows Server 2003 Microsoft
introduced the concept of "safe structured exception handling." The general idea is to
collect handlers' entry points in a designated read-only table and have each entry point
verified against this table for exceptions prior to control being passed to the handler.
In order for an executable to be created with a safe exception handler table, each object
file on the linker command line must contain a special symbol named @feat.00
. If any object file passed to the linker does not have this
symbol, then the exception handler table is omitted from the executable and thus the
run-time checks will not be performed for the application. By default, the table is
omitted from the executable silently if this happens and therefore can be easily
overlooked. A user can instruct the linker to refuse to produce an executable without
this table by passing the /safeseh
command line option.
As of version 1.1.0, Yasm adds this special symbol to win32
object files so its output does not fail to link with /safeseh
.
Yasm also has directives to support registering custom exception handlers. The
safeseh
directive instructs the assembler to produce
appropriately formatted input data for the safe exception handler table. A typical use
case is given in Example 15.1.
Example 15.1. Win32 safeseh
Example
section .text extern _MessageBoxA@16 safeseh handler ; register handler as "safe handler" handler: push DWORD 1 ; MB_OKCANCEL push DWORD caption push DWORD text push DWORD 0 call _MessageBoxA@16 sub eax,1 ; incidentally suits as return value ; for exception handler ret global _main _main: push DWORD handler push DWORD [fs:0] mov DWORD [fs:0],esp ; engage exception handler xor eax,eax mov eax,DWORD[eax] ; cause exception pop DWORD [fs:0] ; disengage exception handler add esp,4 ret text: db 'OK to rethrow, CANCEL to generate core dump',0 caption:db 'SEGV',0 section .drectve info db '/defaultlib:user32.lib /defaultlib:msvcrt.lib '
If an application has a safe exception handler table, attempting to execute any
unregistered exception handler will result in immediate program termination. Thus it is
important to register each exception handler’s entry point with the safeseh
directive.
All mentions of linker in this section refer to the Microsoft linker version 7.x and
later. The presence of the @feat.00
symbol and the data for
the safe exception handler table cause no backward incompatibilities and thus "safeseh"
object files generated can still be linked by earlier linker versions or by non-Microsoft
linkers.