0

I wanted to call an exported function (MessageBoxW from User32.dll) by its ordinal number. I have written the following code but it doesn't show a message box to me. I used dependecy walker to find out ordinal number of MessageBoxW in User32.dll. Ordinal number of the exported function is 2157.

#include <Windows.h>
#include <iostream>
#include <functional>

typedef int(WINAPI *MsgBOX)
(
    _In_opt_ HWND hWnd,
    _In_opt_ LPCWSTR lpText,
    _In_opt_ LPCWSTR lpCaption,
    _In_ UINT uType
);

int main(int argc, char* argv[])
{
    HINSTANCE handle_user32_dll = LoadLibrary(TEXT("User32.dll"));
    std::function<int(HWND, LPCWSTR, LPCWSTR, UINT)> MsgBoxInstance;
    int ordinal_number = 2157;

    if(!handle_user32_dll)
    {
        std::cout << "Dll isn't loaded successfuly." << std::endl;
    }
    else
    {
        MsgBoxInstance = reinterpret_cast<MsgBOX>(GetProcAddress(handle_user32_dll, (LPCSTR)ordinal_number));

        if (!MsgBoxInstance)
        {
            std::cout << "Function didn't resolved.";
        }
        else
        {
            MsgBoxInstance(NULL, TEXT("Resource not available\nDo you want to try again?"), TEXT("Account Details"), MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);
        }
    }

    FreeLibrary(handle_user32_dll);

    return 0;
}

When I run the above program, it doesn't show MessageBoxW result to me, also it shows me the following error:

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

Although, I specified WINAPI in typedef signature but it gives me the above error again. However, when I used the name of the MessageBoxW rather than its ordinal number, programs work fine.

Timberwolf
  • 81
  • 7
  • "*I wanted to call an exported function (MessageBoxW from User32.dll) by its ordinal number*" - why? If a function is exported by name, use it. It is much safer. Don't call functions by ordinal unless you absolutely need to. Calling functions by ordinal is risky as ordinal values can change between DLL versions. – Remy Lebeau Dec 28 '20 at 10:38
  • I need to use ordinal number for research purpose. – Timberwolf Dec 28 '20 at 10:43
  • 2
    It sounds like the function you got wasn't MessageBoxW – user253751 Dec 28 '20 at 10:58
  • All the more reason not to call functions by ordinal. You just don't know what you will get, especially for DLLs you don't control – Remy Lebeau Dec 28 '20 at 18:01

0 Answers0