Domanda

Ho creato un thread aggiuntivo in alcuni piccoli test di app e desidera sospendere il thread principale da questo thread aggiuntivo.Il filo viene creato tramite CreateRemoteThread da un processo esterno.

Dal SuspendThread ha bisogno di un HANDLE per il thread che dovrebbe essere sospeso, voglio sapere come ottenere questo HANDLE dal codice in esecuzione nel mio thread aggiuntivo.

È stato utile?

Soluzione 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;
}

Altri suggerimenti

Non credo che ci sia qualcosa che differenzia il thread principale da altri thread una volta che il processo è iniziato. Tuttavia, puoi enumerare tutte le discussioni nel processo , e utilizzare GetThreadTimes per trovare il filo con il prima ora di creazione. Chiama OpenThread per ottenere un HANDLE da un filo ID.

Ottenere l'ID con questa funzione:

/* 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;
}

Semplice aprire la discussione per ottenere la maniglia:

/*
 * 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);
}

Perché non basta creare un ampio programma globale (uso extern se si deve)

HANDLE mainThread ;
DWORD mainThreadId ;

Nella prima riga del principale (prima di creare qualsiasi thread) fare

mainThread = GetCurrentThread() ;
mainThreadId = GetCurrentThreadId() ;

È possibile utilizzare qualsiasi forma di IPC per condividere l'ID o la maniglia con il processo a distanza (non hanno verificato condividere la maniglia funzionerà, ma dovrebbe!)

Una serie di utili funzioni API di questo tipo sono sotto (ovviamente!) Strumento Di Aiuto suite.Il CreateToolhelp32Snapshot() L'API di scattare un'istantanea del thread in esecuzione di un determinato processo.

// Take a snapshot of all running threads  
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); 
if( hThreadSnap == INVALID_HANDLE_VALUE ) 
  return( FALSE );

Completo di codice di esempio qui.

La struttura restituito non differenziare il thread primario da altri.Non so un meccanismo per farlo;mentre alcune versioni di runtime C saranno tutti ExitProcess() alla fine del thread principale, in tutte le versioni recenti il processo continua a funzionare fino a quando l'ultimo thread viene chiuso.

Interjay raccomandazione di utilizzare GetThreadTimes potrebbe essere la migliore scommessa.Se è possibile CreateProcess() il processo di destinazione, il hThread membro del PROCESS_INFORMATION blocco contiene il tid per il thread primario.Benvenuto idee dagli altri.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top