Structured Exception Handling,即SEH,是windows的异常处理机制.官方已不建议使用SEH,而是用ISO标准的c++异常处理.但是因为要向前兼容,所以在windows下SEH还是可以使用的,除了系统的代码大量使用以外,自己在一些特殊情况下,也是非常好用的.
也是一些基础啦.
SEH结构
SEH其实说穿了就是几个结构体,然后window根据结构体的信息来进行相应处理.
即定义SEH的结构体ntdll!_EXCEPTION_REGISTRATION_RECORD,与SEH处理异常接受异常信息的结构体VCRUNTIME140!_EXCEPTION_RECORD
大致既是:
_EXCEPTION_REGISTRATION_RECORD->handle->_except_handler4->_except_handler4_common()->_EXCEPTION_RECORD
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| //winseh.cpp int main() { std::cout << "Hello World!\n" __try { _asm { mov eax, 0 mov [eax], 0 } } __except(EXCEPTION_EXECUTE_HANDLER){ MessageBox(NULL, NULL, NULL, NULL) } } ---------- 0:000> u winseh!main l40 winseh!main [c:\users\root\source\repos\winseh\winseh\winseh.cpp @ 9]: 010f1000 55 push ebp 010f1001 8bec mov ebp,esp 010f1003 6afe push 0FFFFFFFEh 010f1005 6838250f01 push offset winseh!__rtc_tzz+0x4 (010f2538) 010f100a 6885130f01 push offset winseh!_except_handler4 (010f1385)--+//seh->Handler 010f100f 64a100000000 mov eax,dword ptr fs:[00000000h]---------------+//seh->Next 010f1015 50 push eax <--push fs:[0] 010f1016 83ec08 sub esp,8 010f1019 53 push ebx 010f101a 56 push esi 010f101b 57 push edi 010f101c a104300f01 mov eax,dword ptr [winseh!__security_cookie (010f3004)] 010f1021 3145f8 xor dword ptr [ebp-8],eax 010f1024 33c5 xor eax,ebp 010f1026 50 push eax 010f1027 8d45f0 lea eax,[ebp-10h] <--0x010f1015 010f102a 64a300000000 mov dword ptr fs:[00000000h],eax <--SEH链最后的结构地址 010f1030 8965e8 mov dword ptr [ebp-18h],esp 010f1033 8b0d34200f01 mov ecx,dword ptr [winseh!_imp_?coutstd (010f2034)] 010f1039 e852000000 call winseh!std::operator<<<std::char_traits<char> > (010f1090) 010f103e c745fc00000000 mov dword ptr [ebp-4],0 010f1045 b800000000 mov eax,0 <---- 010f104a c60000 mov byte ptr [eax],0 010f104d eb17 jmp winseh!main+0x66 (010f1066) 010f104f b801000000 mov eax,1 0:000> bp 010f1045 0:000> r ---------- //seh链 此处为fs:[0]->0x00b5fba0->0x00b5fc0c->0x00b5fc24->0xffffffff //所对应的处理函数为: 0x010f1385->0x010f1385->0x77a186d0->0x77a25196 0:000> !exchain 00b5fb58: winseh!_except_handler4+0 (010f1385) CRT scope 0, filter: winseh!main+4f (010f104f) func: winseh!main+55 (010f1055) 00b5fba0: winseh!_except_handler4+0 (010f1385) CRT scope 0, filter: winseh!__scrt_common_main_seh+127 (010f15a5) func: winseh!__scrt_common_main_seh+13b (010f15b9) 00b5fc0c: ntdll!_except_handler4+0 (77a186d0) CRT scope 0, filter: ntdll!__RtlUserThreadStart+3c97b (77a42f79) func: ntdll!__RtlUserThreadStart+3ca17 (77a43015) 00b5fc24: ntdll!FinalExceptionHandlerPad22+0 (77a25196) Invalid exception stack at ffffffff ------------ 0:000> dt ntdll!_EXCEPTION_REGISTRATION_RECORD +0x000 Next : Ptr32 _EXCEPTION_REGISTRATION_RECORD //下一个SEH结构地址 +0x004 Handler : Ptr32 _EXCEPTION_DISPOSITION //异常处理函数 ------------ //手动验证一波 0:000> dg fs P Si Gr Pr Lo Sel Base Limit Type l ze an es ng Flags ---- -------- -------- ---------- - -- -- -- -- -------- 0053 00916000 00000fff Data RW Ac 3 Bg By P Nl 000004f3 0:000> dt ntdll!_EXCEPTION_REGISTRATION_RECORD -l next poi(fs:[0]) next at 0x00b5fb58 //fs:[0]指向seh头 --------------------------------------------- +0x000 Next : 0x00b5fba0 _EXCEPTION_REGISTRATION_RECORD +0x004 Handler : 0x010f1385 _EXCEPTION_DISPOSITION winseh!_except_handler4+0
next at 0x00b5fba0 --------------------------------------------- +0x000 Next : 0x00b5fc0c _EXCEPTION_REGISTRATION_RECORD +0x004 Handler : 0x010f1385 _EXCEPTION_DISPOSITION winseh!_except_handler4+0
next at 0x00b5fc0c --------------------------------------------- +0x000 Next : 0x00b5fc24 _EXCEPTION_REGISTRATION_RECORD +0x004 Handler : 0x77a186d0 _EXCEPTION_DISPOSITION ntdll!_except_handler4+0
next at 0x00b5fc24 --------------------------------------------- +0x000 Next : 0xffffffff _EXCEPTION_REGISTRATION_RECORD +0x004 Handler : 0x77a25196 _EXCEPTION_DISPOSITION ntdll!FinalExceptionHandlerPad22+0 ----
|
SEH异常处理函数
相关处理函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| 0:000> u 77a25196 //SEH最终处理 ntdll!FinalExceptionHandlerPad22: 77a25196 90 nop ntdll!FinalExceptionHandlerPad23: 77a25197 90 nop ntdll!FinalExceptionHandlerPad24: 77a25198 90 nop ...more 77a251c0 e9f2b80500 jmp ntdll!_FinalExceptionHandler (77a80ab7)
0:000> u 010f1385 winseh!_except_handler4 [d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\eh\i386\chandler4gs.c @ 84]: 010f1385 55 push ebp 010f1386 8bec mov ebp,esp 010f1388 ff7514 push dword ptr [ebp+14h] 010f138b ff7510 push dword ptr [ebp+10h] 010f138e ff750c push dword ptr [ebp+0Ch] 010f1391 ff7508 push dword ptr [ebp+8] 010f1394 68a8130f01 push offset winseh!__security_check_cookie (010f13a8) 010f1399 6804300f01 push offset winseh!__security_cookie (010f3004) 010f139e e8370b0000 call winseh!except_handler4_common (010f1eda) <---- 010f13a3 83c418 add esp,18h 010f13a6 5d pop ebp 010f13a7 c3 ret
0:000> x vcruntime140!_except_handler4_common 74fe4480 VCRUNTIME140!_except_handler4_common ( unsigned int *, //0x0 __security_cookie <function> *, //0x4 __security_check_cookie struct _EXCEPTION_RECORD *, //0x8 <---- struct _EXCEPTION_REGISTRATION_RECORD *, //0xc struct _CONTEXT *,//0x10 void *//0x14 (DispatcherContent) ) 0:000> dt _EXCEPTION_RECORD winseh!_EXCEPTION_RECORD +0x000 ExceptionCode : Uint4B //Exception Code 错误代码 +0x004 ExceptionFlags : Uint4B //EstablisherFlags +0x008 ExceptionRecord : Ptr32 _EXCEPTION_RECORD //*ExceptionRecord +0x00c ExceptionAddress : Ptr32 Void //ExceptionAddress 出错地址 +0x010 NumberParameters : Uint4B //# os Parameters +0x014 ExceptionInformation : [15] Uint4B
|