__stdcall
-
I don't understand why compiler(Microsoft Visual C++ 7.1) always makes code that cleans stack from parameters after execution function that declared as __stdcall: void corrupt { typedef HANDLE (__stdcall *FOO)(...); // function must be called via std convention FOO foo = (FOO)GetProcAddress(LoadLibrary("kernel32.dll"), "GetModuleHandleA"); (*foo)(NULL); } Disassembly: push offset foo.??_C@_0BB@HNEJOH> ; /ProcNameOrdinal = "GetModuleHandleA" push offset foo.??_C@_0N@MDJJJHM> ; |/FileName = "kernel32.dll" call near dword ptr ds:[<&KERNEL32.LoadLibraryA> ; |\LoadLibraryA push eax ; |hModule = 0012F34C mov edi, dword ptr ds:[<&KERNEL32.GetProcAddress> ; |kernel32.GetProcAddress call near edi ; \GetProcAddress push 0 call near eax ; GetModuleHandleA call add esp, 4 ; An unwanted stack clean After execution this function we'll see an access violation, because the return address will be wrong. How can I fix that problem? PS In project options __stdcall is default calling convention
-
I don't understand why compiler(Microsoft Visual C++ 7.1) always makes code that cleans stack from parameters after execution function that declared as __stdcall: void corrupt { typedef HANDLE (__stdcall *FOO)(...); // function must be called via std convention FOO foo = (FOO)GetProcAddress(LoadLibrary("kernel32.dll"), "GetModuleHandleA"); (*foo)(NULL); } Disassembly: push offset foo.??_C@_0BB@HNEJOH> ; /ProcNameOrdinal = "GetModuleHandleA" push offset foo.??_C@_0N@MDJJJHM> ; |/FileName = "kernel32.dll" call near dword ptr ds:[<&KERNEL32.LoadLibraryA> ; |\LoadLibraryA push eax ; |hModule = 0012F34C mov edi, dword ptr ds:[<&KERNEL32.GetProcAddress> ; |kernel32.GetProcAddress call near edi ; \GetProcAddress push 0 call near eax ; GetModuleHandleA call add esp, 4 ; An unwanted stack clean After execution this function we'll see an access violation, because the return address will be wrong. How can I fix that problem? PS In project options __stdcall is default calling convention
you can mark individual functions as "cdecl". then, the calling code is responsible from cleaning the stack. int __cdecl foo(int a); Cleek | Image Toolkits | Thumbnail maker
-
you can mark individual functions as "cdecl". then, the calling code is responsible from cleaning the stack. int __cdecl foo(int a); Cleek | Image Toolkits | Thumbnail maker
They are always situated in system dll's
-
I don't understand why compiler(Microsoft Visual C++ 7.1) always makes code that cleans stack from parameters after execution function that declared as __stdcall: void corrupt { typedef HANDLE (__stdcall *FOO)(...); // function must be called via std convention FOO foo = (FOO)GetProcAddress(LoadLibrary("kernel32.dll"), "GetModuleHandleA"); (*foo)(NULL); } Disassembly: push offset foo.??_C@_0BB@HNEJOH> ; /ProcNameOrdinal = "GetModuleHandleA" push offset foo.??_C@_0N@MDJJJHM> ; |/FileName = "kernel32.dll" call near dword ptr ds:[<&KERNEL32.LoadLibraryA> ; |\LoadLibraryA push eax ; |hModule = 0012F34C mov edi, dword ptr ds:[<&KERNEL32.GetProcAddress> ; |kernel32.GetProcAddress call near edi ; \GetProcAddress push 0 call near eax ; GetModuleHandleA call add esp, 4 ; An unwanted stack clean After execution this function we'll see an access violation, because the return address will be wrong. How can I fix that problem? PS In project options __stdcall is default calling convention
Hi There is a flaw in your code. Thats why it is crashing. Basically compilier try to do second stack clean up.. :(. typedef HANDLE (__stdcall *FOO)(...); // function must be called via std convention The above declaration is the problem.. As is GetModuleHandleA is a standard function following pascal calling (Standard windows) convention. In Pascal calling convention, the number of paramter we are passing to the function and the number of bytes required for that must be known before calling a function. By that way the called function will do clean up. You have declared a function pointer like this.. typedef HANDLE (__stdcall *FOO)(...); (...) which means the function would accept many number of parameters. C/CPP compiler would consider this this is a "C" calling convention. You are calling function in the dll.. That is following pascal calling convention.. When you call the function, the called function will unwind the stack as of pascal calling convention. And your calling function will also try to empty the non-existing stack(Already cleaned).. Thus a problem.. See my uncorrupt() function against your function. void nocorrupt() { typedef HANDLE (__stdcall *FOO)(LPCTSTR); // function must be called via std convention FOO foo = (FOO)GetProcAddress(LoadLibrary("kernel32.dll"), "GetModuleHandleA"); (*foo)(NULL); } This won't crash.. " Action without vision is only passing time, Vision without action is merely day dreaming, But vision with action can change the world " - Words from Nelson Mandela Thanks & Regards, Gopalakrishnan
-
Hi There is a flaw in your code. Thats why it is crashing. Basically compilier try to do second stack clean up.. :(. typedef HANDLE (__stdcall *FOO)(...); // function must be called via std convention The above declaration is the problem.. As is GetModuleHandleA is a standard function following pascal calling (Standard windows) convention. In Pascal calling convention, the number of paramter we are passing to the function and the number of bytes required for that must be known before calling a function. By that way the called function will do clean up. You have declared a function pointer like this.. typedef HANDLE (__stdcall *FOO)(...); (...) which means the function would accept many number of parameters. C/CPP compiler would consider this this is a "C" calling convention. You are calling function in the dll.. That is following pascal calling convention.. When you call the function, the called function will unwind the stack as of pascal calling convention. And your calling function will also try to empty the non-existing stack(Already cleaned).. Thus a problem.. See my uncorrupt() function against your function. void nocorrupt() { typedef HANDLE (__stdcall *FOO)(LPCTSTR); // function must be called via std convention FOO foo = (FOO)GetProcAddress(LoadLibrary("kernel32.dll"), "GetModuleHandleA"); (*foo)(NULL); } This won't crash.. " Action without vision is only passing time, Vision without action is merely day dreaming, But vision with action can change the world " - Words from Nelson Mandela Thanks & Regards, Gopalakrishnan
>There is a flaw in your code. Thats why it is crashing. Basically compilier try to do second stack clean up.. . I know that compiler do stack cleaning after calling this function and in my disassembly I marked this place with comment. >>typedef HANDLE (__stdcall *FOO)(...); // function must be called via std convention >The above declaration is the problem.. As is GetModuleHandleA is a standard function following pascal calling (Standard windows) convention. This is not true. Pascal convention isn't standart windows dll's convention! Standart Windows convention is exacly STD. If you don't trust me just try this code: #include #include void main() { const char* src = "Let's test"; USHORT srcSz = strlen(src); char *dst = new char[srcSz+1]; memset(dst, 0x00, sizeof(src)+1); void *lpLstrcpy = GetProcAddress(LoadLibrary("kernel32.dll"), "lstrcpy"); printf("Testing STD Calling Convention...\n" "In this convention parameters must be stored in stack in back order\n" "And function must clean all it's parameters from stack by itself\n"); __asm { ; I put in stack all parameters in flip order(STD convention rule) push src ; lstrcpy(DESTINATION, SOURCE); push dst ; ^ | call lpLstrcpy ; ----------+ } printf("In dst variable now : %s\n", dst); memset(dst, 0x00, srcSz+1); // Zero memory at dst printf("\nTesting Pascal Calling Convention...\n" "In this convention parameters must be put in stack in normal order\n" "And function doesn't cleans all it's parameters from stack by itself\n"); __try { __asm { push dst push src call lpLstrcpy ; Clean stack sub esp, 0x08 } } __except (EXCEPTION_EXECUTE_HANDLER) { printf("\nOops!\n\n"); } printf("In dst variable now - %s\nOf course you don't see anything after '-'\n", dst); system("PAUSE"); } >In Pascal calling convention, the number of paramter we are passing to the function and the number of bytes required for that must be known before calling a function. >By that way the called function will do clean up. :) If function want it can clean stack if don't can not. Conventions is a way to describe how compiler must generate it's code to call some function. >You have declared a function pointer like this.. >typedef HANDLE (__stdcall *FOO)(...); >(...) which means the function would accept many number of parameters. C/CPP compiler wou
-
>There is a flaw in your code. Thats why it is crashing. Basically compilier try to do second stack clean up.. . I know that compiler do stack cleaning after calling this function and in my disassembly I marked this place with comment. >>typedef HANDLE (__stdcall *FOO)(...); // function must be called via std convention >The above declaration is the problem.. As is GetModuleHandleA is a standard function following pascal calling (Standard windows) convention. This is not true. Pascal convention isn't standart windows dll's convention! Standart Windows convention is exacly STD. If you don't trust me just try this code: #include #include void main() { const char* src = "Let's test"; USHORT srcSz = strlen(src); char *dst = new char[srcSz+1]; memset(dst, 0x00, sizeof(src)+1); void *lpLstrcpy = GetProcAddress(LoadLibrary("kernel32.dll"), "lstrcpy"); printf("Testing STD Calling Convention...\n" "In this convention parameters must be stored in stack in back order\n" "And function must clean all it's parameters from stack by itself\n"); __asm { ; I put in stack all parameters in flip order(STD convention rule) push src ; lstrcpy(DESTINATION, SOURCE); push dst ; ^ | call lpLstrcpy ; ----------+ } printf("In dst variable now : %s\n", dst); memset(dst, 0x00, srcSz+1); // Zero memory at dst printf("\nTesting Pascal Calling Convention...\n" "In this convention parameters must be put in stack in normal order\n" "And function doesn't cleans all it's parameters from stack by itself\n"); __try { __asm { push dst push src call lpLstrcpy ; Clean stack sub esp, 0x08 } } __except (EXCEPTION_EXECUTE_HANDLER) { printf("\nOops!\n\n"); } printf("In dst variable now - %s\nOf course you don't see anything after '-'\n", dst); system("PAUSE"); } >In Pascal calling convention, the number of paramter we are passing to the function and the number of bytes required for that must be known before calling a function. >By that way the called function will do clean up. :) If function want it can clean stack if don't can not. Conventions is a way to describe how compiler must generate it's code to call some function. >You have declared a function pointer like this.. >typedef HANDLE (__stdcall *FOO)(...); >(...) which means the function would accept many number of parameters. C/CPP compiler wou
Anton Mikhalyov, Your Code is successfully crashing :). Fine. But I couldn't understand what you are trying to convey.. Can you list out the difference between Standard Windows calling convention and PAscal calling convention? When I look into windef.h PASCAL defined as __stdcall.. What I need is 1. How arguments are passed? 2. How they are arranged in stack? 3. Who will do cleanup? " Action without vision is only passing time, Vision without action is merely day dreaming, But vision with action can change the world " - Words from Nelson Mandela Thanks & Regards, Gopalakrishnan