确定外部进程的主线程 ID(ReadProcessMemory - 错误 299)

Posted

技术标签:

【中文标题】确定外部进程的主线程 ID(ReadProcessMemory - 错误 299)【英文标题】:Determining main thread id of extern process (ReadProcessMemory - Err 299) 【发布时间】:2014-08-06 11:22:44 【问题描述】:

我试图获取另一个进程的主线程 ID,就像这里建议的那样:

https://***.com/a/8058710/1386873

DWORD GetMainThreadId(DWORD dwPid)

    LPCVOID lpTid;
    _asm
    
        mov eax, fs:[18h]
        add eax, 36
        mov lpTid, eax
    

    HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, dwPid);
    if (hProcess == NULL)
        return NULL;

    int dwTid = 0;
    if (ReadProcessMemory(hProcess, lpTid, (LPVOID)&dwTid, sizeof(int), NULL) == FALSE)
    
        CloseHandle(hProcess);
        return NULL;
    

    CloseHandle(hProcess);

    return (DWORD)dwTid;

但这不起作用:ReadProcessMemory 总是从GetLastError() 返回一个 299 代码,这意味着“ERROR_PARTIAL_COPY - 仅完成了 ReadProcessMemory 或 WriteProcessMemory 请求的一部分。”。好吧,错误消息很清楚,但是为什么会发生这种情况? BytesRead 也始终为 0。 我得到这样的进程ID:

unsigned long GetTargetProcessIdFromWindow(LPCWSTR className, LPCWSTR windowName)

    unsigned long processID = 0;
    HWND targetWnd;

    targetWnd = FindWindow(className, windowName);
    GetWindowThreadProcessId(targetWnd, &processID);

    return processID;

这似乎工作正常。什么可能导致这种情况?我尝试了不同的应用程序(计算器、记事本等)。我的应用程序是为 Win32 构建的,我的操作系统是 Windows 64 位。 这和TIB有关系吗?据我了解,只要我按照我的方式为 Win32 构建它应该没问题,不是吗。

感谢任何提示。

【问题讨论】:

Win32 not 没问题,此代码不适用于 64 位进程。他们的 TEB 位于完全不同的地址,您永远无法通过 32 位进程访问该地址。构建为 x64 也不是解决办法,现在您无法读取 32 位进程的 TEB。 @HansPassant 雅。在我写完这篇文章后,我意识到 Notepad.exe 和 Calculator.exe 可能是 64 位进程。但我也尝试将它与 32 位版本的程序一起使用,但它不起作用。 【参考方案1】:

请考虑使用 Toolhlp 函数 - CreateToolhelp32Snapshot() 和 Thread32First()。

【讨论】:

是的。我现在用这个。但据我了解,除了查看快照时间之外,没有简单的方法可以确定其他进程的主线程。即使那样它也不可靠,因为主线程可能已经关闭。对我来说,在进程中获取一个随机线程的id就足够了,所以这个解决方案很好。

以上是关于确定外部进程的主线程 ID(ReadProcessMemory - 错误 299)的主要内容,如果未能解决你的问题,请参考以下文章

运行外部进程而不冻结 vb6 中的主 UI

确定持有文件锁的线程

调用异步方法后,进程似乎没有回到 WPF 应用程序中的主线程

『叶问』#40,MySQL进程号连接ID查询IDInnoDB线程与系统线程如何对应

如何在Windows下暂停和恢复任何外部进程?

CPU高获取其线程ID然后分析