Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetProcAddress returns 0 For All Functions [duplicate]

First of all yes I have searched this for a while now and can't find any answers relevant to my case. Basically I am trying to get the address of a function in a windows DLL (dnsapi.dll) and GetProcAddress is returning 0. After a while of scratching my head I even went on to create a program which simply uses GetProcAddress of MessageBox in user32.dll. Same result. Here is the code of the second program I made which still doesn't work:

#include <stdio.h>
#include <Windows.h>

int main() {
    HINSTANCE hLib = LoadLibrary(TEXT("user32.dll"));
    DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBox");

    printf("%ld", MsgBoxAddr);
    getchar();

    return 0;
}

BTW GetLastError returns 127 which seems to be the most common error returned when GetProcAddress doesn't work but I can't figure out what is wrong, I have tried with many functions and DLL's, not just these couple.

Thanks. :)

EDIT: The linked article solved my problem, the functions I tried all had unicode and anis versions (w and a). Using the full API names solved the problems. Thanks for linking that question.

Thank you.

like image 549
Rob Lennon Avatar asked Nov 23 '13 04:11

Rob Lennon


2 Answers

Some common APIs are not the real names of the functions, including LoadLibrary and MessageBox. All those functions don't exist!

Thats because most Windows APIs that take text as parameter will have two versions of each, one that accepts ANSI text and other that accept UNICODE text. Those "functions" you know are actually preprocessor macros that will route you to the right function automatically depending on your Visual Studio project's default charset.

MessageBox for instance, don't exist. What exist are the functions MessageBoxA and MessageBoxW, one for ANSI other for UNICODE. So this is how you will get their address:

ANSI:

HINSTANCE hLib = LoadLibraryA("user32.dll");
DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBoxA");

UNICODE:

HINSTANCE hLib = LoadLibraryW(L"user32.dll");
DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBoxW");

Automatic:

HINSTANCE hLib = LoadLibrary(TEXT("user32.dll"));
#ifdef UNICODE
DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBoxW");
#else
DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBoxA");
#endif
like image 147
Havenard Avatar answered Oct 22 '22 20:10

Havenard


Havenard already gave the answer, so don't accept mine (but do read it).

A better way to solve it is to define:

#ifndef _CRT_STRINGIZE  // Might be already defined in crtdefs.h, but if not...
#define __CRT_STRINGIZE(Value) #Value
#define _CRT_STRINGIZE(Value) __CRT_STRINGIZE(Value)
#endif

and then use

GetProcAddress(hLib, TEXT(_CRT_STRINGIZE(MessageBox)));
like image 32
user541686 Avatar answered Oct 22 '22 20:10

user541686