Obtenir une poignée de fil conducteur du processus
-
21-09-2019 - |
Question
J'ai créé un fil supplémentaire dans une application petit test et que vous voulez suspendre le thread principal de ce fil supplémentaire. Le fil supplémentaire est créé via CreateRemoteThread
d'un processus externe.
Depuis SuspendThread
a besoin d'un HANDLE
au fil devrait être suspendu, je veux savoir comment obtenir ce HANDLE
à partir du code en cours d'exécution dans mon fil supplémentaire.
La solution 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;
}
Autres conseils
Je ne pense pas qu'il y ait quelque chose qui différencie le fil conducteur d'autres threads une fois que le processus a commencé. Cependant, vous pouvez énumèrent toutes les discussions dans le processus , et utiliser GetThreadTimes pour trouver le fil avec le plus tôt de création. OpenThread pour obtenir un HANDLE
d'un fil ID.
Obtenez l'ID du sujet avec cette fonction:
/* 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 ouvrir le fil pour obtenir la poignée:
/*
* 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);
}
Pourquoi ne créez-vous pas seulement un programme à l'échelle mondiale (utilisation extern si vous devez)
HANDLE mainThread ;
DWORD mainThreadId ;
Sur la première ligne du principal, (avant que les fils sont créés) faire
mainThread = GetCurrentThread() ;
mainThreadId = GetCurrentThreadId() ;
Vous pouvez utiliser toute forme de IPC de partager l'ID ou la poignée avec le processus distant (ont pas vérifié le partage de la MANCHE fonctionne, mais il se doit!)
Un certain nombre de fonctions API utiles de ce type sont sous le (bien sûr!) Outil d'aide suite . L'API CreateToolhelp32Snapshot()
prendra un instantané de les fils en cours d'exécution pour un processus spécifié.
// Take a snapshot of all running threads
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
if( hThreadSnap == INVALID_HANDLE_VALUE )
return( FALSE );
Code Exemple complet ici.
Le retour struct ne différencie pas le thread principal des autres. Je ne sais pas un mécanisme pour le faire; tandis que certaines versions du runtime C seront tous ExitProcess () à la fin du fil primaire, dans toutes les versions récentes du processus continue de fonctionner jusqu'à ce que le dernier des sorties de fil.
la recommandation Interjay à utiliser GetThreadTimes peuvent être le meilleur pari. Si vous pouvez CreateProcess()
le processus cible, l'élément hThread du bloc PROCESS_INFORMATION
contient la TID pour le fil primaire. Bienvenue toutes les idées des autres.