Получение дескриптора основного потока процесса
Я создал дополнительный поток в небольшом приложении для тестирования и хочу приостановить основной поток из этого дополнительного потока. Дополнительный поток создается через CreateRemoteThread
из внешнего процесса.
С SuspendThread
нужен HANDLE
к потоку, который должен быть приостановлен, я хочу знать, как получить это HANDLE
из кода, выполняемого в моем дополнительном потоке.
5 ответов
Я не думаю, что есть что-то, что отличает основной поток от других потоков после начала процесса. Тем не менее, вы можете перечислить все потоки в процессе, и использовать GetThreadTimes чтобы найти поток с самым ранним временем создания. Звоните OpenThread и 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;
}
получить идентификатор потока, с помощью этой функции:
/* 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 или дескриптора с удаленным процессом (не проверено совместное использование дескриптора будет работать, но он должен!)
ряд полезных функций API этого типа находятся под (конечно!) Помогите люкс. The 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 может быть лучшим выбором. Если сможешь!--17-->CreateProcess()
целевой процесс, член hThread PROCESS_INFORMATION
блок содержит tid для основного потока. Приветствуйте любые идеи от других.