Получение дескриптора основного потока процесса
-
21-09-2019 - |
Вопрос
Я создал дополнительный поток в каком-то небольшом тестовом приложении и хочу приостановить основной поток из этого дополнительного потока.Дополнительный поток создается с помощью CreateRemoteThread
из внешнего процесса.
С тех пор как SuspendThread
нуждается в HANDLE
что касается потока, который должен быть приостановлен, я хочу знать, как получить это HANDLE
из кода, запущенного в моем дополнительном потоке.
Решение 2
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;
}
Другие советы
Я не думаю, что есть что-то, что отличало бы основной поток от других потоков после запуска процесса.Однако вы можете перечислить все потоки в процессе, и использовать GetThreadTimes чтобы найти поток с самым ранним временем создания.Вызов OpenThread чтобы получить HANDLE
из идентификатора потока.
Получите идентификатор потока с помощью этой функции:
/* 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);
}
Почему бы вам просто не создать глобальный файл для всей программы (используйте внешний если надо)
HANDLE mainThread ;
DWORD mainThreadId ;
В первой строке main (до создания потоков) выполните
mainThread = GetCurrentThread() ;
mainThreadId = GetCurrentThreadId() ;
Вы можете использовать любая форма ИПЦ чтобы поделиться идентификатором или 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 завершают выполнение функции ExitProcess() в конце основного потока, во всех последних версиях процесс продолжает выполняться до завершения последнего потока.
Рекомендация Interjay использовать GetThreadTimes может быть лучшим выбором.Если ты сможешь CreateProcess()
целевой процесс, член hThread системы PROCESS_INFORMATION
блок содержит tid для основного потока.Приветствую любые идеи от других.