How to call MessageBox with GetProcAddress function?
Asked Answered
I

1

4

I want to call MessageBox() function in such way:

1). load needed library
2). get the function address
3). call it

So, for such aim as I understand, I should define new type with all types of arguments in MessageBox function.

It returnes INT and accepts: HWND, LPCSTR, LPCSTR, UNIT.

So I registred new type:

typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);

I have problems with calling such function. Does such way work for all functions or only for exported?
How can I call MessageBox exactly in such way?

Full code:

#include <iostream>
#include <windows.h>

using namespace std;

typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);

int main(void)
{
    HINSTANCE__ *hModule = LoadLibrary(L"\\Windows\\System32\\User32.dll");
    msgbox *me = 0;

    if(hModule != 0)
    {
        me = (msgbox*)GetProcAddress(hModule, "MessageBox");
    }

    return 0;
}
Intermix answered 12/4, 2012 at 16:53 Comment(0)
B
5

Why are you declaring everything as a pointer?

LoadLibrary returns an HMODULE, not an HINSTANCE__ * (it will work with the latter but it's always better to adhere to the documentation).

Similarly, msgbox is typedef'd to a function pointer type, so me is a msgbox, not a msgbox *.

The reason why GetProcAddress fails is because user32.dll exports 2 functions, MessageBoxA and MessageBoxW. When you simply call MessageBox in your code, macros defined in Windows.h replace it with one of the 2 actual function names depending on whether you're compiling for UNICODE or not. But when you're trying to directly access the exported function as you are doing, you need to explicitly specify which one you're trying to get a pointer to.

#include <iostream>
#include <windows.h>

typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);

int main(void)
{
  HMODULE hModule = ::LoadLibrary(L"User32.dll");
  msgbox me = NULL;

  if( hModule != NULL ) {
    me = reinterpret_cast<msgbox>( ::GetProcAddress(hModule, "MessageBoxA") );
  }

  if( me != NULL ) {
    (*me)( NULL, "I'm a MessageBox", "Hello", MB_OK );
  }

  if( hModule != NULL ) {
    ::FreeLibrary( hModule );
  }
}
Boneblack answered 12/4, 2012 at 17:31 Comment(9)
don't you know how to call NON-exported functions in DLL? Thank you!Intermix
@Intermix I don't think there's any way to do thatBoneblack
what do you think about this topic? #2265199Intermix
@Intermix I think there's a reason it's not been answered, there's no way to do it :-)Boneblack
there were comments above question. Wait! Let's think! What's non-exported function in dll? do they have entry point in address region? maybe it's possible with offsets do smth with them, what do you think?Intermix
about " HMODULE, not an HINSTANCE__ * ", doesn't HMODULE be an HINSTANCE__ ? #define preprocessor is just hint for compiler how to comiple, if you go F12 to look, what is "HMODULE", it will HININSTANCE__ in header, won't it?Intermix
@user1131997: Always go with the official documentation. What if the next version of visual studio makes HMODULE not a HINSTANCE__* anymore?Correlation
@MooingDuck I have not think about such stuff! Thank you very much! Now , I undersstood!Intermix
Can you explain why the need for resolution operator before API calls?Bolter

© 2022 - 2024 — McMap. All rights reserved.