Conseguir una manija de hilo principal del proceso de
-
21-09-2019 - |
Pregunta
He creado un hilo adicional de alguna pequeña aplicación de prueba y querer suspender el hilo principal de este hilo adicional. El hilo adicional se crea a través de CreateRemoteThread
de un proceso externo.
Desde SuspendThread
necesita un HANDLE
al hilo que debe ser suspendido, me gustaría saber cómo conseguir este HANDLE
de código que se ejecuta en mi hilo adicional.
Solución 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;
}
Otros consejos
No creo que hay algo que diferencia el hilo principal de otros temas una vez que el proceso ha comenzado. Sin embargo, puede enumerar todos los hilos en el proceso , y usar GetThreadTimes para encontrar el hilo con el el tiempo más temprano creación. Llamar OpenThread para obtener una HANDLE
de un hilo ID.
Obtener el ID del tema con esta función:
/* 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 abierto el hilo para obtener el identificador:
/*
* 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);
}
¿Por qué no basta con crear un programa a nivel mundial (uso extern si tiene que)
HANDLE mainThread ;
DWORD mainThreadId ;
En la primera línea de principal, (antes se crean todos los hilos) hacer
mainThread = GetCurrentThread() ;
mainThreadId = GetCurrentThreadId() ;
Se puede usar ningún tipo de IPC a la participación ya sea el ID o el mango con el proceso remoto (no han verificado compartir el MANGO funcionará pero debería!)
Una serie de funciones de API de útiles de este tipo están bajo la (por supuesto!) Herramienta de Ayuda suite. El CreateToolhelp32Snapshot()
API tomará una instantánea de los subprocesos que se ejecutan para un proceso especificado.
// Take a snapshot of all running threads
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
if( hThreadSnap == INVALID_HANDLE_VALUE )
return( FALSE );
La estructura devuelto no diferenciar el hilo principal de las otras. No sé un mecanismo para hacerlo; mientras que algunas versiones del tiempo de ejecución C serán todos ExitProcess () en el extremo de la rosca primaria, en todas las versiones recientes el proceso continúa funcionando hasta que las salidas último hilo.
recomendación de Interjay a GetThreadTimes uso puede ser la mejor apuesta. Si puede CreateProcess()
el proceso de destino, el miembro hThread del bloque PROCESS_INFORMATION
contiene el TID para el hilo primario. Bienvenido todas las ideas de los demás.