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.

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top