Conseguir uma identificação no tópico principal do processo
-
21-09-2019 - |
Pergunta
Eu criei um encadeamento adicional em algum pequeno aplicativo de teste e quero suspender o encadeamento principal deste thread adicional. O tópico adicional é criado via CreateRemoteThread
de um processo externo.
Desde SuspendThread
precisa de uma HANDLE
Para o tópico que deve ser suspenso, quero saber como conseguir isso HANDLE
do código em execução no meu thread adicional.
Solução 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;
}
Outras dicas
Eu não acho que há algo que diferencia o tópico principal de outros threads depois que o processo é iniciado. No entanto, você pode Enumere todos os fios no processo, E use GetThreadTimes Para encontrar o tópico com o primeiro tempo de criação. Ligar OPETHEAD para obter um HANDLE
De um ID do thread.
Obtenha o ID do thread com esta função:
/* 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;
}
Simples, abra o tópico para obter a alça:
/*
* 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 que você não apenas cria um global em todo o programa (use extern se você precisar)
HANDLE mainThread ;
DWORD mainThreadId ;
Na primeira linha de principal (antes que qualquer threads seja criado) faça
mainThread = GetCurrentThread() ;
mainThreadId = GetCurrentThreadId() ;
Você pode usar Qualquer forma de IPC Compartilhar o ID ou o identificador com o processo remoto (não verificou o compartilhamento do identificador funcionará, mas deve!)
Várias funções úteis da API deste tipo estão sob o (é claro!) Ajuda da ferramenta suíte. o CreateToolhelp32Snapshot()
A API tirará um instantâneo dos threads em execução para um processo especificado.
// Take a snapshot of all running threads
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
if( hThreadSnap == INVALID_HANDLE_VALUE )
return( FALSE );
Código de exemplo completo aqui.
A estrutura retornada não diferencia o fio primário dos outros. Não conheço um mecanismo para fazê -lo; Enquanto algumas versões do tempo de execução do C e exitprocess () no final do encadeamento primário, em todas as versões recentes, o processo continua a ser executado até o último thread sair.
A recomendação do Interjay de usar o GetThreadTimes pode ser a melhor aposta. Se você puder CreateProcess()
o processo de destino, o membro hthread do PROCESS_INFORMATION
O bloco contém o TID para o encadeamento primário. Bem -vindo a todas as idéias de outras pessoas.