Вызов функции с адреса не работает - PullRequest
0 голосов
/ 13 сентября 2018

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

Этот фрагмент должен вызывать CreateFileA, используя его адрес, полученный из вызова GetProcAddress. Конечно, в этом простом примере я мог бы просто вызвать его как обычно, но мне нужно извлечь каждый адрес вручную (даже LoadLibraryA и GetProcAddress, но для краткости я не сделал в этом примере)

Что я делаю не так? Почему, если я использую CreateFileA вместо (*CreateFileAAddr) в последней строке, это работает, даже если они указывают на одно и то же?

#include <windows.h>

typedef HMODULE(*_LoadLibraryA)(LPCSTR);
typedef FARPROC(*_GetProcAddress)(HMODULE, LPCSTR);
typedef HANDLE(*_CreateFileA)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);

int main() {
    _LoadLibraryA LoadLibraryAAddr = (_LoadLibraryA)&LoadLibraryA;
    _GetProcAddress GetProcAddressAddr = (_GetProcAddress)&GetProcAddress;

    HMODULE kernel32Handle = (*LoadLibraryAAddr)("Kernel32.dll");
    if (kernel32Handle == NULL) return -1;
    _CreateFileA CreateFileAAddr = (_CreateFileA)((*GetProcAddressAddr)(kernel32Handle, "CreateFileA"));
    if ((unsigned long)CreateFileAAddr != (unsigned long)&CreateFileA) return -1; //Just to check if the address is correct for Debug
    (*CreateFileAAddr)("123.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, OPEN_ALWAYS, NULL);
    return 0;
}

1 Ответ

0 голосов
/ 16 сентября 2018

Согласно моему комментарию, функции Windows API и типы указателей на указанные функции должны быть помечены __stdcall (или WINAPI), что изменит их соглашение о вызовах на то, которое ожидается API (более подробная информация оСоглашение о вызовах stdcall здесь ).

typedef HMODULE(__stdcall *_LoadLibraryA)(LPCSTR);
typedef FARPROC(__stdcall *_GetProcAddress)(HMODULE, LPCSTR);
typedef HANDLE(__stdcall *_CreateFileA)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);

Также примечание: по какой-то причине * должен быть помещен после __stdcall;в противном случае аннотация ничего не сделает.

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