When SEH is used there is a registration process where an exception structure is
created for every function as a local variable. The last field of the structure overlaps the
location where frame pointer EBP points. Function's prologue creates this structure on
its stack frame and registers it with the operating system at runtime. The significance of
this is that the pointer to the exception handler and the pointer to the Next exception
handler are both stored on the stack in the program function’s local variables section of
its stack frame.
参考:http://rogunix.com/docs/Reversing&Exploiting/Understanding%20SEH%20Exploitation.pdf
SEH Record会作为局部变量存放在栈中,或者说它与局部变量在栈中相邻存放,先存放SEH Record,再存放局部变量。
When an exception occurs in a program function, the system exception dispatcher
routine runs and sets up its own stack frame.While doing so, it will push elements of
this Exception Handler structure onto the stack since this is part of a function prologue to
execute the exception code. Keep in mind that this is a separate stack used for the
exception dispatcher and not directly related to the program stack that we overwrote with
the buffer.
当异常发生时,SEH的Handler并不会在当前程序的栈环境中执行,而是会使用独立的栈,在这个栈中,esp+8的位置上保存着指向SEH Record的指针,所以这就是为什么需要
PPR(pop;pop;ret)的原因了。