Вопрос

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

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

Это было полезно?

Решение 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;
}

Другие советы

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

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

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

Почему бы вам просто не создать глобальный файл для всей программы (используйте внешний если надо)

HANDLE mainThread ;
DWORD mainThreadId ;

В первой строке main (до создания потоков) выполните

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

Вы можете использовать любая форма ИПЦ чтобы поделиться идентификатором или HANDLE с удаленным процессом (не проверял, будет ли совместное использование HANDLE работать, но так и должно быть!)

Ряд полезных функций API такого типа находятся в разделе (конечно же!) Помощь с инструментами люкс.Тот Самый 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 может быть лучшим выбором.Если ты сможешь CreateProcess() целевой процесс, член hThread системы PROCESS_INFORMATION блок содержит tid для основного потока.Приветствую любые идеи от других.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top