GetProcessImageFileNameA "Access violation writing location" 运行时错误

GetProcessImageFileNameA "Access violation writing location" runtime error

我正在使用 EnumProcesses function to get all process IDs on the system. Then I iterate over each process ID and pass it to OpenProcess to get a process handle, which I then pass to GetProcessImageFileNameA 获取进程名称。

这是一个代码片段:

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

DWORD GetProcessName(DWORD processID, TCHAR lpFileName, DWORD nSize)
{
    HANDLE hProcess;
    DWORD pLength;
    
    // Get process handle
    hProcess = OpenProcess(
        PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
        FALSE,
        processID
    );

    if ( !hProcess )
        return NULL;
    
    // Write process name to buffer
    if ( pLength = GetProcessImageFileNameA(hProcess, lpFileName, nSize) )
    {
        CloseHandle(hProcess);
        return pLength;
    }

    CloseHandle(hProcess);
}

int main(void)
{   
    DWORD processIDs[PROC_ID_SIZE], cbNeeded, cProcess;
    unsigned int i;

    // Get process IDs
    if ( !EnumProcesses(processIDs, sizeof(processIDs), &cbNeeded) )
        return 1;
    
    // Get process ID count
    cProcess = cbNeeded / sizeof(DWORD);
    printf("Number of Processes: %u | Size of Process Array: %d\n", cProcess, (int)sizeof(processIDs));

    // Get the process name of each process
    for (i = 0; i < cProcess; i++)
    {   
        if ( processIDs[i] != 0 )
        {   
            // The access violation is happening here
            TCHAR processName[MAX_PATH];
            GetProcessName(processIDs[i], processName, sizeof(processName));
            printf("Process name: %s\n", (char*)processName);
        }
    }
    return 0;
}

编译正常,但出现运行时错误:

Exception thrown at 0x00007FF985433338 (KernelBase.dll) in QuickSave.exe: 0xC0000005: Access violation writing location 0x000000000000F8D0.

我怀疑这是因为我在函数范围之外声明 processName。当我创建另一个函数并在该函数的范围内声明 processName 时,它起作用了。我不太清楚为什么。

DWORD PrintProcessName(DWORD processID)
{
    HANDLE hProcess;
    TCHAR processName[MAX_PATH];
    DWORD pLength;

    // Get process handle
    hProcess = OpenProcess(
        PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
        FALSE,
        processID
    );

    if (!hProcess)
        return NULL;

    // Write process name to buffer and print it
    if ( pLength = GetProcessImageFileNameA(hProcess, processName, sizeof(processName)) )
    {
        printf("Process name: %s\n", (char*)processName);
        return pLength;
    }

    CloseHandle(hProcess);
}

我还在学习 C,所以我可能犯了一个新手错误,但希望有人能帮助我理解这里发生的事情。

我已经修复了你的代码。主要错误是 GetProcessName 的错误声明、processName 大小传递的错误大小、不正确的 printf 格式规范、函数并不总是 return 值、缺少错误检查。

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

#define PROC_ID_SIZE 1000

DWORD GetProcessName(DWORD processID, TCHAR *lpFileName, DWORD nSize)
{
    HANDLE hProcess;
    DWORD pLength;

    // Get process handle
    hProcess = OpenProcess(
        PROCESS_QUERY_LIMITED_INFORMATION,
        FALSE,
        processID
    );

    if (!hProcess)
        return 0;

    // Write process name to buffer
    pLength = GetProcessImageFileNameW(hProcess, lpFileName, nSize);
    CloseHandle(hProcess);
    return pLength;
}

int main(void)
{
    DWORD processIDs[PROC_ID_SIZE], cbNeeded, cProcess;
    unsigned int i;

    // Get process IDs
    if (!EnumProcesses(processIDs, sizeof(processIDs), &cbNeeded))
        return 1;

    // Get process ID count
    cProcess = cbNeeded / sizeof(DWORD);
    printf("Number of Processes: %u | Size of Process Array: %d\n", cProcess, (int)sizeof(processIDs));

    // Get the process name of each process
    for (i = 0; i < cProcess; i++)
    {
        if (processIDs[i] != 0)
        {
            // The access violation is happening here
            TCHAR processName[MAX_PATH];
            if (GetProcessName(processIDs[i], processName, sizeof(processName)/sizeof(processName[0])))
                printf("Process name: %ls\n", processName);
        }
    }
    return 0;
}