当我尝试从 psapi.dll (windows) 运行时 link 函数时,GetModuleFileNameExA 将无法正常工作

GetModuleFileNameExA won't work like it should when I try to link the function on runtime from psapi.dll (windows)

我正在 windows 的 运行 时间内尝试从 dll 加载函数。我试着做一个程序来打印它自己的模块,基于这个:https://docs.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] );
                
            }

所以它会使用我的函数,而不是在加载时需要 link psapi.dll,它就是行不通。它将出现段错误或不打印任何内容。我已经尝试修改我如何呈现缓冲区,尝试使用 widechar 或 Tchar 但似乎没有任何效果。

这是功能脚本的输出: working script ouput

这是我的函数的输出: non functional script output

有趣的是其中一个函数 getModules(指向 EnumProcessModules)运行得非常好!我就是不明白这是怎么回事。

你应该更改这行代码

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

到此。

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

更多信息可以参考this