【问题标题】:CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, PID) returns INVALID_HANDLE_VALUECreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, PID) 返回 INVALID_HANDLE_VALUE
【发布时间】:2021-04-26 07:02:16
【问题描述】:

代码:

#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;
        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);
}

无论 PID 是什么,我总是得到INVALID_HANDLE_VALUEHANDLE ProcessesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL)GetPID 中被调用并且运行良好。但是如果我们设置ProcessID = 0,输出:

Started looking for module Process.exe with PID 0...
Modules snapshot had been took successfully!
Starting modulelist scan...
Found MCBEBot.exe at 1 (PID: 13180)
Found ntdll.dll at 1 (PID: 13180)
Found KERNEL32.DLL at 1 (PID: 13180)
Found KERNELBASE.dll at 1 (PID: 13180)
Found ucrtbase.dll at 1 (PID: 13180)
Found MSVCP140.dll at 1 (PID: 13180)
Found VCRUNTIME140.dll at 1 (PID: 13180)
Found VCRUNTIME140_1.dll at 1 (PID: 13180)
Found sechost.dll at 1 (PID: 13180)
Found RPCRT4.dll at 1 (PID: 13180)

怎么了?如何通过 PID 获取真实的模块快照?为什么我收到INVALID_HANDLE_VALUE?我试图在 x86 和 x64 之间切换 - 没有帮助。

函数GetPID()返回正确的PID。

我将不胜感激!

【问题讨论】:

  • 你有这个条件if (hSnapshot == NULL || hSnapshot == INVALID_HANDLE_VALUE) {并打电话给Module32First(hSnapshot /* Srsly?!? */, &amp;modEntry);
  • @πάνταῥεῖ,这不是问题,那条线是多余的。不过谢谢指点!
  • 你确定这不是问题所在?请在您的问题中详细说明。这是一个重要的事实。更好的是,删除所有不相关的内容,并在此处提供所需的 minimal reproducible example
  • @πάνταῥεῖ,因为如果它到达该代码,则意味着它返回INVALID_HANDLE_VALUE。这是不应该的。我在CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, PID) 中遇到了问题,其他我可以轻松解决。这就是我在这里的原因:)
  • @Genken 最好使用您的调试器,并逐行逐步执行。在每一步检查变量值。

标签: c++ windows process operating-system pid


【解决方案1】:

我已经重建了代码,这有帮助!

MODULEENTRY32 GetModule(const char* ModuleName, unsigned long long ProcessID) {
    HANDLE ModuleSnapshot = INVALID_HANDLE_VALUE;
    MODULEENTRY32 ModuleEntry;

    ModuleSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID);
    if (ModuleSnapshot == INVALID_HANDLE_VALUE) {cout << "Failed while snapshotting modules. 4" << endl; return ModuleEntry; system("pause");}
    ModuleEntry.dwSize = sizeof(MODULEENTRY32);
    cout << "Sanning for modules on PID " << ProcessID << "..." << endl;

    Module32First(ModuleSnapshot, &ModuleEntry);
    while (true) {
        cout << "Found module: \"" << ModuleEntry.szModule << "\" at " << ModuleEntry.th32ModuleID <<" (PID: " << ModuleEntry.th32ProcessID << ")" << endl;
        if (!strcmp(ModuleEntry.szModule, ModuleName) && ModuleEntry.th32ModuleID == 1) {break;}
        Module32Next(ModuleSnapshot, &ModuleEntry);
    }

    CloseHandle(ModuleSnapshot);
    return ModuleEntry;
}

P。 S.while (true) {...} 构造相当危险,不要使用它!

【讨论】:

  • 不要使用它” - 确实。请改用if(Module32First(..)) { do { ... } while(Module32Next(..)); }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-24
  • 2011-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多