After some research:
The helper, which saves the situation from failure, is another register - EBP, a base pointer that points to the beginning of the stack frame. All access to local variables of the function is carried out using this pointer (with the exception of optimized code, see below). Before the function returns, the stack pointer reset to the value of the base pointer.
Before a function (such as PInvoke) calls another function (an imported DLL function), the stack pointer points to the end of the local variables of the function of the calling function. The caller then pushes the parameters onto the stack and calls this other function.
In the described situation, when a function calls another function like __stdcall, although it is actually __cdecl, no one clears the stack from these parameters. Thus, after returning from the called subscriber, the stack pointer points to the end of the block of specified parameters. This is similar to the caller function (PInvoke), which has just received a few local variables.
Since access to the local variables of the caller is through the base pointer, it will not break anything. The only thing that can happen is that the call function will be called many times in a row. In this case, the stack will grow and may overflow. But since PInvoke calls the DLL function only once and then returns, the stack pointer is simply reset to the base pointer, and all is well. Edit: As indicated here , the code can also be optimized to store local variables only in CPU registers. In this case, EBP is not used and thus an invalid ESP may result in an invalid address being returned.
source share