Получение дескриптора основного потока процесса

Я создал дополнительный поток в небольшом приложении для тестирования и хочу приостановить основной поток из этого дополнительного потока. Дополнительный поток создается через CreateRemoteThread из внешнего процесса.

С SuspendThread нужен HANDLE к потоку, который должен быть приостановлен, я хочу знать, как получить это HANDLE из кода, выполняемого в моем дополнительном потоке.

5 ответов


Я не думаю, что есть что-то, что отличает основной поток от других потоков после начала процесса. Тем не менее, вы можете перечислить все потоки в процессе, и использовать GetThreadTimes чтобы найти поток с самым ранним временем создания. Звоните OpenThread и HANDLE из идентификатора потока.


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

получить идентификатор потока, с помощью этой функции:

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

просто откройте поток, чтобы получить ручку:

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

почему бы вам просто не создать глобальную программу (используйте extern если нужно)

HANDLE mainThread ;
DWORD mainThreadId ;

в первой строке main (до создания каких-либо потоков) сделайте

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

можно использовать любая форма IPC для совместного использования id или дескриптора с удаленным процессом (не проверено совместное использование дескриптора будет работать, но он должен!)


ряд полезных функций API этого типа находятся под (конечно!) Помогите люкс. The CreateToolhelp32Snapshot() API сделает снимок запущенных потоков для указанного процесса.

// Take a snapshot of all running threads  
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); 
if( hThreadSnap == INVALID_HANDLE_VALUE ) 
  return( FALSE );
код здесь.

возвращаемая структура не отличает основной поток от других. Я не знаю механизма для этого; в то время как некоторые версии среды выполнения C будут все ExitProcess() в конце первичный поток, во всех последних версиях процесс продолжается до выхода последнего потока.

рекомендация Interjay использовать GetThreadTimes может быть лучшим выбором. Если сможешь!--17-->CreateProcess() целевой процесс, член hThread PROCESS_INFORMATION блок содержит tid для основного потока. Приветствуйте любые идеи от других.