@Genken
Начинающий администратор

Почему CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, PID) возвращает INVALID_HANDLE_VALUE при обращении не к своему процессу?

Вот код:
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
using namespace std;

DWORD GetPID(const char* ProcessName) {...}

MODULEENTRY32 GetModule(const char* moduleName, unsigned long long ProcessID) {
    MODULEENTRY32 modEntry = { 0 };
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, ProcessID);

    cout << "Started looking for module " << moduleName << " with PID " << ProcessID << "..." << endl;

    if (hSnapshot == NULL || hSnapshot == INVALID_HANDLE_VALUE) {
        cout << GetLastError() << endl;
        Module32First(hSnapshot, &modEntry);
        cout << "Taking snapshot failed. 4" << endl << "Last error:" << GetLastError() << endl; ;
    }
    else {
        cout << "Modules snapshot had been took successfully!" << endl;
        cout << "Starting modulelist scan..." << endl;

        MODULEENTRY32 curr = { 0 };

        curr.dwSize = sizeof(MODULEENTRY32);
        if (Module32First(hSnapshot, &curr)) {
            do {
                if (!strcmp(curr.szModule, moduleName)) {
                    cout << "Found " << curr.szModule << " at " << curr.th32ModuleID << " (PID: " << curr.th32ProcessID << ")" << endl;
                    modEntry = curr;
                    break;
                }
                cout << "Found " << curr.szModule << " at " << curr.th32ModuleID << " (PID: " << curr.th32ProcessID << ")" << endl;
            } while (Module32Next(hSnapshot, &curr));
        }
        CloseHandle(hSnapshot);
    }
    return modEntry;
}
int main() {
     unsigned long long pid = GetPID("Process.exe");
     MODULEENTRY32 module = GetModule("process.exe", pid);
}

Функция GetPID работает нормально, проверил через диспетчер задач; moduleName также присвоен правильно. Так почему же я получаю INVALID_HANDLE_VALUE?

Я добавил вывод в консоль тех модулей, по которым проходится алгоритм, если он всё-таки запускается. И если вызвать GetModule с аргументом ProcessID=0, то вывод будет следующим:
Started looking for module Minecraft.Windows.exe with PID 0...
Modules snapshot had been took successfully!
Starting modulelist scan...
Found MCBEBot.exe at 1 (PID: 20732)
Found ntdll.dll at 1 (PID: 20732)
Found KERNEL32.DLL at 1 (PID: 20732)
Found KERNELBASE.dll at 1 (PID: 20732)
Found ucrtbase.dll at 1 (PID: 20732)
Found MSVCP140.dll at 1 (PID: 20732)
Found VCRUNTIME140.dll at 1 (PID: 20732)
Found sechost.dll at 1 (PID: 20732)
Found RPCRT4.dll at 1 (PID: 20732)

Т. е. вместо 0 в PID функция CreateToolhelp32Snapshot() подставляет PID того процесса, в котором она запущена. В случае если подставить в PID любое значение (как реальный PID процесса, так и рандомное число). Таким образом, эта функция почему-то может обратиться только к своим модулям. Что делать в таком случае? И почему доступ к процессам (в GetPID() вызывается
HANDLE ProcessesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL)
без всяких проблем) происходит нормально, а к модулям - нет?

Заранее спасибо за любую помощь!
  • Вопрос задан
  • 320 просмотров
Пригласить эксперта
Ответы на вопрос 1
Точно не помню, но вроде у каждого процесса своя таблица дескрипторов, и для нее выделяется память в куче для данного процесса. Поэтому нужен доступ к таблице дескрипторов и памяти из другого процесса.
Возможно DuplicateHandle?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы