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.