I have looked into this again in a little more detail.
What I think is happening is the following:
in delphi an exception is raised.
Delphi.Sytstem._RaiseExcept
RaiseException
RtlRaiseException
RtlDispatchException
RtlpExecuteHandlerForExecption
Delphi.System._ExceptionHandler
UnhandledExceptionFilter
EXCEPTION_DISPOSITION
__cdecl Delphi.System.ExceptionHandler(
struct _EXCEPTION_RECORD *ExceptionRecord,
void * EstablisherFrame,
struct _CONTEXT *ContextRecord,
void * DispatcherContext
);
Source code can be found here (search for _RaiseExcept, _ExceptionHandler):
http://www.getunderstand.com/documents/sample_reports/udelphi_example_repor…
what you can see in the code for _ExceptionHandler is
10680 LEA EAX,[ESP+4]
10681 PUSH EAX
10682 CALL UnhandledExceptionFilter
This is an unmodified esp, so esp points to the return address and esp+4
points to the function parameters
so it's effectively doing something like
|EXCEPTION_POINTER ExceptionPointers;
||||ExceptionPointers||||.||ExceptionRecord| = ExceptionRecord;|
ExceptionPointers||||.||||ContextRecord| = EstablisherFrame;
UnhandledExceptionFilter(&|ExceptionPointers|);
It is done that way in multiple locations (line 9641, 9666 (push / esp+8), 10028, 10064,
...)
so It's obviously done intentionally.