Log in

View Full Version : GetProcAddress for win32api func


Silver
April 22nd, 2007, 12:50
Hi all,

Quick favour please. Could somebody compile the following code then run it on a Vista machine under debug and tell me if they get a "value of esp was not saved" type error:

Code:
#define MSGFLT_ADD 1
typedef BOOL (*CHANGEWINDOWMESSAGEFILTER)(UINT message, DWORD dwFlag);
HINSTANCE hUser32 = (HINSTANCE)::LoadLibrary(_T("user32.dll");
CHANGEWINDOWMESSAGEFILTER pfnFilter = (CHANGEWINDOWMESSAGEFILTER)::GetProcAddress(hUser32, _T("ChangeWindowMessageFilter");
pfnFilter(WM_USER + 1, MSGFLT_ADD);


ChangeWindowMessageFilter is a Vista-only function that MSDN defines as returning a BOOL and taking an int, dword as params (see:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowfunctions/changewindowmessagefilter.asp
)

Yet for the life of me I can't get this silly piece of code to work - it's like I've misdecl'd it when according to the docs, I haven't.

Much appreciated.

Maximus
April 22nd, 2007, 16:16
whatever language you use, you missed WINAPI declaration, or the __declspec() for the winapi. I believe it won't ever work calling it as a C function unless Vista has changed API rules...

Silver
April 23rd, 2007, 03:56
Maximus, this type of code definitely works - I've used it for accessing exports on machines without the latest SDK installed. The pfnFilter points at the right address (base + export as checked by depends.exe) - it's just the call that fails.

Besides the func takes two 32bit vars as params, so it won't make any difference if I did decl it as stdcall, fastcall or whatever. The params might be pushed in the wrong order but that would cause the function to fail internally with bad params, not return an esp stack balancing error.

I just can't quite understand what's not right here. I'm hoping it's not something Vista specific as this function is Vista only.

Maximus
April 23rd, 2007, 06:27
I am saying this because Winapis clean the stack for you with a ret x. If you call them with cdecl, your compiler will add an add esp,xx ruining your stack. Disassemble it and check. If you see an add esp or such after your call, it is a wrong declaration.
so it makes huge difference the way you declare them.
----
edit: nice, MSDN reports this without the winapi spec. mmh.
are you using it in a 64 bit context or 32-bit compatibility one?

Silver
April 23rd, 2007, 07:04
Quote:
edit: nice, MSDN reports this without the winapi spec. mmh.
are you using it in a 64 bit context or 32-bit compatibility one?


Yep, nice huh. I'm assuming stdcall as standard. I'm using it in 32bit.

I'll explicitly add stdcall tonight and try again, although I've never needed to with other win32 funcs...

blabberer
April 24th, 2007, 00:31
well it never hurts to declare things upfront as far as i know

ive used the kind of code you post but i always do it like this

typedef BOOL (crapapi *PCrapFoo) (dword yadda_yadda, P_CRAP_INSTANCE someshit);

PCrapFoo pcrf;

pcrf = (PCrapFoo) GetProcAddress(handle to dll,"CrapFoo";

pcrf(1234,5678);

where crapapi can be __STDCALL, __CDECL, or whatever

i mean i code all the time without sdks and other gigabyte of accoutrements
from commandline loading libs dynamically

so i am forced to typedef declare everything if i want the code to look like code and not some damn unreadable hack

btw have you turned on optimisation while compiling ?

if yes then when the compiler emits leave retn
the stack will be whitewashed and the retn will return to some known ebp
which might actually be wrong

if such is the case compile in debug mode with optimisation turned off

i can bet that this problem will go away mysteriously returning to haunt you only in release build

LLXX
April 24th, 2007, 02:25
I wouldn't be surprised if this was a bug in Vista.

Silver
April 24th, 2007, 04:28
Quote:
btw have you turned on optimisation while compiling ? .... if such is the case compile in debug mode with optimisation turned off


That was one of my thoughts, but the same thing happens under debug and release I didn't have time to test with the explicit stdcall last night, I'll do it today and post back later.


Quote:
I wouldn't be surprised if this was a bug in Vista.


Hope not, otherwise I'm screwed. I'm amazed how little testing seems to have been done to get VS2005 working on Vista. I'm stuck using VC6 to debug a problem, without the latest SDK that includes the Vista-specific exports because it's incompatible

blabberer
April 24th, 2007, 05:56
well why not check if vista itself is using this api and if it uses trace the code that uses this and find out how it calls or force the application that uses this api to run and log ? shouldnt be a tough task

possibly if it is 32bit code then ollydbgs ctrl+k on this api should yield you a calltree (from where it is called as well what it calls) if you can latch on to atleast one where this is called from then its easy to verify

disavowed
April 24th, 2007, 11:38
Quote:
[Originally Posted by Silver;65150]I'm amazed how little testing seems to have been done to get VS2005 working on Vista. I'm stuck using VC6 to debug a problem, without the latest SDK that includes the Vista-specific exports because it's incompatible

I'm using VS2005 on Vista without any problems. What are you encountering?

Silver
April 25th, 2007, 04:05
Ok, I've now got it working by specifying _stdcall in the typdef. I have absolutely no idea why I need to do this, because in the same source file I GetProcAddress on another win32api function without _stdcall and it works fine. Never mind, thanks all.


Quote:
I'm using VS2005 on Vista without any problems. What are you encountering?


I see the following symptoms with UAC turned on or off, running as a normal user or as administrator, and any permutation thereof. The symptoms get worse if UAC is enabled:

- Random crash of the entire IDE (it just bombs out and I get the Vista "Your program is buggered, do you want to end, debug..." etc)

- White screen of death. At random times when using the IDE it pauses for a second, the screen looks like it's overlayed with a translucent white panel, and that's it. Killing it with Task Manager is the only way out.

- Debugging doesn't work reliably. I can step through the same code 5 times no problem, then the 6th will kill VS completely. Restart VS and the code will work for N times and then die again...

- Constantly forced to recompile everything. I build my code, hit the ! button and I'm told that some of my code needs to be rebuilt again.

- Creating a new MFC project doesn't always work (this one is wierd beyond belief). If I create a new dialog based MFC app, sometimes it works, sometimes when I compile it (with zero code changes from the wizard-generated code) I get a "ThisClass is not a namespace name" error. I never get this problem if I import a VC6 MFC .dsw.

Basically VS2005 is not reliable for me at all, and I'm not the only one with these problems. Google finds many people complaining of the same issue. Some Microsoft responses I've seen suggest that VS should be run with UAC turned off - which is all well and good unless you're trying to fix a UAC related problem.

For reference I have a legal, licensed VS2005 standard with SP1 + Update for Vista. I've gone back to using VC6 until these problems are fixed.