00520CB0 . 6A FF PUSH -1
00520CB2 . 68 E9D85F00 PUSH 005FD8E9 ; SE 处理程序装置
00520CB7 . 64:A1 0000000>MOV EAX, FS:[0]
00520CBD . 50 PUSH EAX
00520CBE . 64:8925 00000>MOV FS:[0], ESP
00520CC5 . 83EC 0C SUB ESP, 0C
00520CC8 . 56 PUSH ESI
00520CC9 . 8D4424 04 LEA EAX, [ESP+4]
00520CCD . 8BF1 MOV ESI, ECX
00520CCF . 50 PUSH EAX
00520CD0 . 8D4C24 0C LEA ECX, [ESP+C]
00520CD4 . 51 PUSH ECX
00520CD5 . C74424 10 000>MOV DWORD PTR [ESP+10], 0
00520CDD . C74424 0C 000>MOV DWORD PTR [ESP+C], 0
其中:PUSH 005FD8E9 为什么称为 ”SE 处理程序装置 ”
MOV FS:[0], ESP 中 FS:[0]示意哪个地址
\\\\\\\\\\\\\\\\\\\\\\\\\\\
00520CB2 . 68 E9D85F00 PUSH 005FD8E9 ;
00520CB7 . 64:A1 0000000>MOV EAX, FS:[0]
00520CBD . 50 PUSH EAX
到此,堆栈中造成了
|Fs[0]|
|5fD8e9|
|-1 |
的构造,其中 Fs:[0]指向原来的 Exception Registration 构造,Exception Registration 的定义如下
struct EXCEPTION_REGISTRATION
{
EXCEPTION_REGISTRATION *prev;
DWORD handler;
};
所以 FS:[0]就是 prev, 5fd8e9 就是 handler 的地址,而此时 Esp 就指向这个新的 EXCEPTION_REGISTRATION 构造
00520CBE . 64:8925 00000>MOV FS:[0], ESP
这一句就是用新的构造的指针放在 FS:[0]外面,从此自定义的 Exception Handler 就取代了原来的,除非自定义的 handler 不违心解决某个 exception,此时旧的才会贝调用
至于为什么把新的 Exception Registration 构造放在栈外面,这个没有无效的解释,不过大多数 Compiler 都是这么作的。
SE=Structured Exception
FS:[0]指向 Exception Registration 的数据结构,外面含有 Exception Handler 的地址