A function call, which can be either cdecl or stdcall

I need to write code that calls an external function, which can be either a call to stdcall or cdecl in a 32-bit Windows application.
My calling code cannot know in advance which one will be. Right now, if I try to call the cdecl function from the call site that was defined as stdcall, I get a checkEsp check dialog, and I assume that there is a good reason.
Is there any way to do this?

+4
source share
3 answers

This can be done as follows:

mov esi, esp push arg3 push arg2 push arg1 call [SomeExternalProc] mov esp, esi ; now the stack is always properly cleaned 

An external procedure must save esi. Or you can use any other register stored by an external procedure, or even a memory variable - local or global.

Well, the order of the arguments is the same for CDECL and STDCALL - in reverse order.

+3
source

You can also use alloca (), which has the side effect of saving and restoring the stack pointer:

 { alloca( (uintptr_t)callback & 2 ); callback(); } 
+1
source

cdecl and stdcall are by definition incompatible. In cdecl, the caller clears the stack, in stdcall, the caller clears the stack. If you accept stdcall, but it is actually cdecl, nobody clears the stack. This means that your ESP (stack pointer) will be confused after the call. Maybe if you give more detailed information, it may work there, but there is no way to call a function without knowing that it calls the convention without starting your stack.

See: http://en.wikipedia.org/wiki/X86_calling_conventions for a difference.

0
source

Source: https://habr.com/ru/post/1491227/


All Articles