C++ 获取进程主线程的句柄
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1969579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting a handle to the process's main thread
提问by Etan
I have created an additional thread in some small testing app and want to suspend the main thread from this additional thread. The additional thread is created via CreateRemoteThread
from an external process.
我在一些小型测试应用程序中创建了一个附加线程,并希望从这个附加线程挂起主线程。附加线程是通过CreateRemoteThread
外部进程创建的。
Since SuspendThread
needs a HANDLE
to the thread which should be suspended, I want to know how to get this HANDLE
from code running in my additional thread.
由于SuspendThread
需要一个HANDLE
应该挂起的线程,我想知道如何HANDLE
从我的附加线程中运行的代码中获取它。
采纳答案by Etan
DWORD GetMainThreadId () {
const std::tr1::shared_ptr<void> hThreadSnapshot(
CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0), CloseHandle);
if (hThreadSnapshot.get() == INVALID_HANDLE_VALUE) {
throw std::runtime_error("GetMainThreadId failed");
}
THREADENTRY32 tEntry;
tEntry.dwSize = sizeof(THREADENTRY32);
DWORD result = 0;
DWORD currentPID = GetCurrentProcessId();
for (BOOL success = Thread32First(hThreadSnapshot.get(), &tEntry);
!result && success && GetLastError() != ERROR_NO_MORE_FILES;
success = Thread32Next(hThreadSnapshot.get(), &tEntry))
{
if (tEntry.th32OwnerProcessID == currentPID) {
result = tEntry.th32ThreadID;
}
}
return result;
}
回答by interjay
I don't think there is anything that differentiates the main thread from other threads once the process has started. However, you can enumerate all threads in the process, and use GetThreadTimesto find the thread with the earliest creation time. Call OpenThreadto get a HANDLE
from a thread ID.
一旦进程开始,我认为没有任何东西可以将主线程与其他线程区分开来。但是,您可以枚举进程中的所有线程,并使用GetThreadTimes查找创建时间最早的线程。调用OpenThreadHANDLE
从线程 ID 中获取 a 。
回答by mtx
Get the thread id with this function:
使用此函数获取线程 ID:
/* CAUTION: ONLY x86 TESTED
* get the thread id of the main thread of a target process
*
* params:
* DWORD dwPid process id of the target process
*
* return:
* Success thread id
* Error NULL
*/
DWORD GetMainThreadId(DWORD dwPid)
{
LPVOID 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;
DWORD dwTid;
if(ReadProcessMemory(hProcess, lpTid, &dwTid, sizeof(dwTid), NULL) == FALSE)
{
CloseHandle(hProcess);
return NULL;
}
CloseHandle(hProcess);
return dwTid;
}
Simple open the thread to get the handle:
简单打开线程获取句柄:
/*
* get a handle to the main thread of a target process
* if successfull, the returned handle must be closed with CloseHandle()
*
* params:
* DWORD dwPid process id of the target process
* DWORD dwDesiredAccess desired access rights to the thread
*
* return:
* Success thread handle with desired access rights
* Error NULL
*/
HANDLE GetMainThreadHandle(DWORD dwPid, DWORD dwDesiredAccess)
{
DWORD dwTid = GetMainThreadId(dwPid);
if(dwTid == FALSE)
return NULL;
return OpenThread(dwDesiredAccess, FALSE, dwTid);
}
回答by bobobobo
Why don't you just create a program-wide global (use externif you have to)
为什么不创建一个程序范围的全局变量(如果必须,请使用extern)
HANDLE mainThread ;
DWORD mainThreadId ;
On the first line of main, (before any threads are created) do
在 main 的第一行,(在创建任何线程之前)做
mainThread = GetCurrentThread() ;
mainThreadId = GetCurrentThreadId() ;
You can use any form of IPCto share either the id or the HANDLE with the remote process (haven't verified sharing the HANDLE will work but it should!)
您可以使用任何形式的 IPC与远程进程共享 id 或 HANDLE(尚未验证共享 HANDLE 是否有效,但应该可以!)
回答by J.J.
A number of useful API functions of this type are under the (of course!) Tool Helpsuite. The CreateToolhelp32Snapshot()
API will take a snapshot of the running threads for a specified process.
许多此类有用的 API 函数都在(当然!)工具帮助套件下。该CreateToolhelp32Snapshot()
API将正在运行的线程的快照指定进程的。
// Take a snapshot of all running threads
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
if( hThreadSnap == INVALID_HANDLE_VALUE )
return( FALSE );
Full example code here.
完整的示例代码在这里。
The struct returned does not differentiate the primary thread from the others. I do not know a mechanism to do so; while some versions of the C runtime will all ExitProcess() at the end of the primary thread, in all recent versions the process continues to run until the last thread exits.
返回的结构不会将主线程与其他线程区分开来。我不知道这样做的机制;虽然某些版本的 C 运行时将所有 ExitProcess() 都放在主线程的末尾,但在所有最新版本中,进程会继续运行,直到最后一个线程退出。
Interjay's recommendation to use GetThreadTimes may be the best bet. If you can CreateProcess()
the target process, the hThread member of the PROCESS_INFORMATION
block contains the tid for the primary thread. Welcome any ideas from others.
Interjay 建议使用 GetThreadTimes 可能是最好的选择。如果可以CreateProcess()
访问目标进程,则PROCESS_INFORMATION
块的 hThread 成员包含主线程的 tid。欢迎其他人的任何想法。