Поделиться через


Перечисление всех модулей для процесса

Чтобы определить, какие процессы загружали определенную библиотеку DLL, необходимо перечислить модули для каждого процесса. В следующем примере кода для перечисления модулей текущих процессов в системе используется функция enumProcessModules.

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

// To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
// and compile with -DPSAPI_VERSION=1

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

    // Print the process identifier.

    printf( "\nProcess ID: %u\n", processID );

    // Get a handle to the process.

    hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                            PROCESS_VM_READ,
                            FALSE, processID );
    if (NULL == hProcess)
        return 1;

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

    if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
    {
        for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
        {
            TCHAR szModName[MAX_PATH];

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

            if ( GetModuleFileNameEx( hProcess, hMods[i], szModName,
                                      sizeof(szModName) / sizeof(TCHAR)))
            {
                // Print the module name and handle value.

                _tprintf( TEXT("\t%s (0x%08X)\n"), szModName, hMods[i] );
            }
        }
    }
    
    // Release the handle to the process.

    CloseHandle( hProcess );

    return 0;
}

int main( void )
{

    DWORD aProcesses[1024]; 
    DWORD cbNeeded; 
    DWORD cProcesses;
    unsigned int i;

    // Get the list of process identifiers.

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return 1;

    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the names of the modules for each process.

    for ( i = 0; i < cProcesses; i++ )
    {
        PrintModules( aProcesses[i] );
    }

    return 0;
}

Основная функция получает список процессов с помощью функции EnumProcesses. Для каждого процесса основная функция вызывает функцию PrintModules, передавая его идентификатор процесса. PrintModules, в свою очередь, вызывает функцию OpenProcess для получения дескриптора процесса. Если OpenProcess завершается ошибкой, выходные данные отображают только идентификатор процесса. Например, OpenProcess не удается для процессов простоя и CSRSS, так как ограничения доступа не позволяют коду уровня пользователя открывать их. Затем PrintModules вызывает функцию EnumProcessModules, чтобы получить функцию дескриптора модуля. Наконец, PrintModules вызывает функцию GetModuleFileNameEx один раз для каждого модуля, чтобы получить имена модулей.