Невозможно загрузить некоторые функции из DLL с помощью GetProcAddress () - PullRequest
3 голосов
/ 14 августа 2011

Я пытаюсь создать DLL, которую позже хотел бы внедрить в некоторые процессы, используя функцию SetWindowsHookEx (). Странно то, что когда я пытаюсь загрузить DLL и использовать GetProcAddress, чтобы получить адрес содержащейся в ней процедуры, она возвращает NULL, если я пытаюсь получить адрес процедуры обработки сообщений CBT, но она отлично работает для другие функции.

Это код.

ЗАГОЛОВОК DLL (.h)

#include <windows.h>

extern "C" {
    __declspec(dllexport) LRESULT CALLBACK hookProc(int code, WPARAM wParam, LPARAM lParam);
    __declspec(dllexport) int add(int a, int b);
}

ФАЙЛ DLL (.cpp)

#include "SimpleHook.h"

extern "C" {
    __declspec(dllexport) LRESULT CALLBACK hookProc(int code, WPARAM wParam, LPARAM lParam) {
        return CallNextHookEx(0, code, wParam, lParam);
    }

    __declspec(dllexport) int add(int a, int b) {
        return a + b;
    }
}

ГЛАВНЫЙ ФАЙЛ

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

int main(int argc, char* argv[]) {
    HINSTANCE dllHandle = LoadLibrary(_T("SimpleHook.dll"));

    if (dllHandle) {
        // returns the correct address
        cout << "add address: " << GetProcAddress(dllHandle, "add") << endl;

        // returns NULL
        cout << "hookProc address: " << GetProcAddress(dllHandle, "hookProc") << endl;
    }
}

Если я использую GetLastError (), я получаю код ошибки 127 со значением:

ERROR_PROC_NOT_FOUND: указанная процедура не найдена.

Странно то, что другие функции из того же файла загружаются правильно. Любая помощь с благодарностью!

Ответы [ 3 ]

5 голосов
/ 14 августа 2011

Соглашение о вызовах изменяет название искажения.* * * * * Функции __stdcall всегда имеют свои имена с добавлением _ и искажены и другими способами, так что ссылка завершается ошибкой, но функция __cdecl не искажается, и поэтому она найдена.

Чтобы импортировать из библиотеки DLL, созданной с помощью __declspec(dllexport), необходимо всегда включать заголовок со __declspec(dllimport) для всего, что вы хотите импортировать, и связывать библиотеку, полученную при сборкеDLL.Это гарантирует, что все ваши функции связываются правильно, и вам не нужно переходить к C-совместимым ссылкам.

Не следует использовать GetProcAddress и extern "C" в сочетании с __declspec(dllexport).

Заголовок:

#include <windows.h>

#ifndef MAIN
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif

DLL_API LRESULT CALLBACK hookProc(int code, WPARAM wParam, LPARAM lParam);
DLL_API int add(int a, int b);

DLL .cpp файл:

#include "SimpleHook.h"

DLL_API LRESULT CALLBACK hookProc(int code, WPARAM wParam, LPARAM lParam) {
    return CallNextHookEx(0, code, wParam, lParam);
}

DLL_API int add(int a, int b) {
    return a + b;
}

Основной файл .cpp:

#define MAIN
#include "SimpleHook.h"

int main(int argc, char* argv[]) {

    if (dllHandle) {
        // returns the correct address
        cout << "add address: " << add << endl;

        // returns NULL
        cout << "hookProc address: " << hookProc << endl;
    }
}

Не забудьте добавить библиотеку в компоновщик.

3 голосов
/ 14 августа 2011

Макрос CALLBACK преобразуется в __stdcall .Поэтому вам необходимо добавить символ подчеркивания и добавить размер аргументов к имени функции:

cout << "hookProc address: " << GetProcAddress(dllHandle, "_hookProc@12")
     << endl;
1 голос
/ 14 августа 2011

Вы должны использовать инструмент, такой как dumpbin или Dependency Walker, чтобы узнать искаженное имя.

Или вы можете использовать DEF-файл при связывании, чтобы поместить выбранное вами имя в таблицу экспорта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...