GetModuleFileNameExA не будет работать должным образом, когда я попытаюсь связать функцию во время выполнения с psapi.dll (Windows)

Я экспериментирую с загрузкой функций из DLL во время выполнения в Windows. Я попытался сделать программу, которая будет печатать свои собственные модули, на основе этого: https://learn.microsoft.com/en-us/windows/win32/psapi/enumerating-all-modules-for-a-process.

Мне нужны две функции, чтобы делать то, что я хочу: EnumProcessModules и GetModuleFileNameExA. Мне удалось получить их оба из psapi.dll во время выполнения, однако GetModuleFileNameExA просто не работает должным образом, и я не могу сказать, почему

это функциональный скрипт, который я написал:

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <psapi.h>

typedef DWORD (__cdecl *EnumModules)(HANDLE hprocess, HMODULE *moduleHandles, DWORD cb, LPDWORD lpcNeeded);
typedef DWORD (__cdecl *GetModuleName)(HANDLE hprocess, HMODULE hmodule, LPSTR name, DWORD size);

void ErrorMessage(const char *message){
    fprintf(stderr, message);
    exit(EXIT_FAILURE);
}

int PrintModules( HANDLE pHandle )
{
    HMODULE hMods[1024];
    DWORD cbNeeded;
    unsigned int i;

    if (NULL == pHandle)
        return EXIT_FAILURE;

    // Loads the lib
    HMODULE psapiLib = LoadLibrary("C:\\Windows\\SysWOW64\\psapi.dll");
    if (! psapiLib) ErrorMessage("Error loading psapi.dll\n");

    // Get the functions we need from the lib
    EnumModules getModules = (EnumModules)GetProcAddress(psapiLib, "EnumProcessModules");
    GetModuleName getModuleName = (GetModuleName)GetProcAddress(psapiLib, "GetModuleFileNameExA");
    if (!getModules) ErrorMessage("Error finding EnumProcessModules from psapi.dll\n");
    if (!getModuleName) ErrorMessage("Error finding GetModuleFileNameExA from psapi.dll\n");


   // Get a list of all the modules in this process.

    if ( getModules(pHandle, hMods, sizeof(hMods), &cbNeeded))
    {
        for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
        {
            LPSTR szModName;
            szModName = malloc(1024 * sizeof(LPSTR));

            // Get the full path to the module's file.

            // change GetModuleFileNameExA with getModuleName to see the error
            if ( GetModuleFileNameExA( pHandle, hMods[i], szModName, 1024 * sizeof(char))){
                // Print the module name and handle value.
                printf(("\t%s (0x%08X)\n"), szModName, hMods[i] );
                
            }

            free(szModName);
        }
    }

    return 0;
}

int main( void )
{
    HANDLE myHandle = GetCurrentProcess();
    PrintModules(myHandle);
    CloseHandle(myHandle);

    return 0;
}

Если я изменю эту часть

if ( GetModuleFileNameExA( pHandle, hMods[i], szModName, 1024 * sizeof(char))){
                // Print the module name and handle value.
                printf(("\t%s (0x%08X)\n"), szModName, hMods[i] );
                
            }

к этому

if ( getModuleName( pHandle, hMods[i], szModName, 1024 * sizeof(char))){
                // Print the module name and handle value.
                printf(("\t%s (0x%08X)\n"), szModName, hMods[i] );
                
            }

поэтому вместо этого он будет использовать мою функцию, избавляя от необходимости связывать psapi.dll во время загрузки, это просто не работает. Это либо segfault, либо ничего не напечатает. Я пытался модифицировать то, как я представляю буфер, пытался использовать widechar или Tchar, но, похоже, ничего не работает.

Это вывод, который у меня есть с функциональным скриптом: вывод рабочего скрипта

и это вывод, который у меня есть с моей функцией: вывод нефункционального скрипта

Самое смешное, что одна из функций, getModules (указывающая на EnumProcessModules), работала отлично! Я просто не могу понять, что происходит.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
415
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны изменить эту строку кода

typedef DWORD (__cdecl *EnumModules)(HANDLE hprocess, HMODULE *moduleHandles, DWORD cb, LPDWORD lpcNeeded);

к этому.

typedef DWORD(__stdcall* EnumModules)(HANDLE hprocess, HMODULE* moduleHandles, DWORD cb, LPDWORD lpcNeeded);

для получения дополнительной информации вы можете ссылаться на это

То же самое и с GetModuleName typedef. Почти все функции Win32 API используют __stdcall, за исключением таких функций, как wsprintf, которые требуют __cdecl

Remy Lebeau 26.12.2020 23:04

Другие вопросы по теме