fs:[0] points to ETHREAD
whose first is member NtTib which again is a structure
whose first member is _EXCEPTION_REGISTRATION_RECORD
0:000> dt ntdll!_TEB NtTib.* @$thread
+0x000 NtTib :
+0x000 ExceptionList : 0x0010f76c _EXCEPTION_REGISTRATION_RECORD
+0x004 StackBase : 0x00110000 Void
+0x008 StackLimit : 0x0010d000 Void
+0x00c SubSystemTib : (null)
+0x010 FiberData : 0x00001e00 Void
+0x010 Version : 0x1e00
+0x014 ArbitraryUserPointer : (null)
+0x018 Self : 0x7ffde000 _NT_TIB
0:000> ? @$thread
Evaluate expression: 2147344384 = 7ffde000
the exception registration record contains the chain of exception handlers
0:000> dx -r2 ((ntdll!_EXCEPTION_REGISTRATION_RECORD *)0x10f76c)
((ntdll!_EXCEPTION_REGISTRATION_RECORD *)0x10f76c) : 0x10f76c [Type: _EXCEPTION_REGISTRATION_RECORD *]
[+0x000] Next : 0x10f91c [Type: _EXCEPTION_REGISTRATION_RECORD *]
[+0x000] Next : 0xffffffff [Type: _EXCEPTION_REGISTRATION_RECORD *]
[+0x004] Handler : 0x77ade115 [Type: _EXCEPTION_DISPOSITION (*)(_EXCEPTION_RECORD *,void *,_CONTEXT *,void *)]
[+0x004] Handler : 0x77ade115 [Type: _EXCEPTION_DISPOSITION (*)(_EXCEPTION_RECORD *,void *,_CONTEXT *,void *)]
[Type: _EXCEPTION_DISPOSITION (_EXCEPTION_RECORD *,void *,_CONTEXT *,void *)]
like this
0:000> !exchain
0010f76c: ntdll!_except_handler4+0 (77ade115)
CRT scope 0, filter: ntdll!LdrpDoDebuggerBreak+32 (77b605ac)
func: ntdll!LdrpDoDebuggerBreak+36 (77b605b0)
0010f91c: ntdll!_except_handler4+0 (77ade115)
CRT scope 0, filter: ntdll!_LdrpInitialize+db (77b40ee4)
func: ntdll!_LdrpInitialize+f0 (77b40ef9)
Invalid exception stack at ffffffff
when you push handler
esp will hold the handler
esp 0x12345678 _SEH_HANDLER
when you push fs:[0] you push a pointer to
dx -r2 ((ntdll!_EXCEPTION_REGISTRATION_RECORD *)0x10f76c)
0:000> dd esp
0010f750 779f8159 00000000 00000000 7ffdf000
0:000> a
77b605a6 push fs:[0]
push fs:[0]
77b605ad
0:000> p
0:000> dd esp
0010f74c **0010f76c** 779f8159 00000000 00000000
0010f75c 7ffdf000 00000000 0010f750 77ade115
mov fs:[0] esp
with this you swap out the old EXCEPTION_REGISTRATION_RECORD WITH NEW ONE