我在一些小的testing应用程序中创build了一个额外的线程,并希望从这个额外的线程挂起主线程。 额外的线程是通过CreateRemoteThread
从外部进程创build的。
由于SuspendThread
需要一个HANDLE
来挂起线程,我想知道如何从我的附加线程中运行的代码中获得这个HANDLE
。
一旦进程开始,我不认为有任何区别主线程和其他线程的东西。 但是,您可以枚举进程中的所有线程 ,并使用GetThreadTimes来查找具有最早创建时间的线程。 调用OpenThread从线程ID获取HANDLE
。
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; }
用这个函数获取线程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; }
简单的打开线程来获取句柄:
/* * 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); }
你为什么不创建一个程序范围的全局(如果你必须使用extern )
HANDLE mainThread ; DWORD mainThreadId ;
在main的第一行,(在任何线程被创建之前)做
mainThread = GetCurrentThread() ; mainThreadId = GetCurrentThreadId() ;
您可以使用任何形式的IPC与远程进程共享id或HANDLE(未验证共享HANDLE将工作,但应该!)
这个类型的许多有用的API函数都在(当然是!) 工具帮助套件中。 CreateToolhelp32Snapshot()
API将获取指定进程的正在运行的线程的快照。
// Take a snapshot of all running threads hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); if( hThreadSnap == INVALID_HANDLE_VALUE ) return( FALSE );
完整的示例代码。
返回的结构不区分主线程和其他线程。 我不知道这样做的机制; 而一些版本的C运行时将在主线程结束时全部退出进程(),在所有最新版本中,进程继续运行,直到最后一个线程退出。
Interjay建议使用GetThreadTimes可能是最好的选择。 如果可以CreateProcess()
目标进程, PROCESS_INFORMATION
块的hThread成员包含主线程的tid。 欢迎来自他人的任何想法。