14

いくつかの小さなテストアプリで追加のスレッドを作成しましたが、この追加のスレッドからメインスレッドを一時停止したいと思います。追加のスレッドはCreateRemoteThread、外部プロセスから作成されます。

SuspendThread一時停止するスレッドが必要なので、追加のスレッドで実行されているコードからHANDLEこれを取得する方法を知りたいです。HANDLE

4

5 に答える 5

17

プロセスが開始されると、メインスレッドを他のスレッドと区別するものはないと思います。ただし、プロセス内のすべてのスレッドを列挙し、GetThreadTimesを使用して、作成時間が最も早いスレッドを見つけることができます。OpenThreadを呼び出しHANDLEて、スレッドIDからを取得します。

于 2009-12-28T14:17:35.400 に答える
8
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;
}
于 2009-12-30T20:10:16.163 に答える
8

この関数でスレッドIDを取得します。

/* 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);
}
于 2011-11-08T23:55:42.103 に答える
4

プログラム全体のグローバルを作成してみませんか(必要に応じてexternを使用してください)

HANDLE mainThread ;
DWORD mainThreadId ;

mainの最初の行で、(スレッドが作成される前に)

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

任意の形式のIPCを使用して、IDまたはHANDLEをリモートプロセスと共有できます(HANDLEの共有が機能することは確認されていませんが、機能するはずです!)

于 2011-06-05T17:25:30.173 に答える
2

このタイプの便利なAPI関数の多くは、(もちろん!)ツールヘルプスイートの下にあります。CreateToolhelp32Snapshot()APIは、指定されたプロセスの実行中のスレッドのスナップショットを取得します。

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

完全なサンプルコードはこちら。

返される構造体は、プライマリスレッドを他のスレッドと区別しません。私はそうするためのメカニズムを知りません。一部のバージョンのCランタイムは、プライマリスレッドの最後ですべてExitProcess()を実行しますが、最近のすべてのバージョンでは、最後のスレッドが終了するまでプロセスが実行され続けます。

GetThreadTimesを使用するというInterjayの推奨は、最善の策かもしれません。ターゲットプロセスが可能な場合CreateProcess()、ブロックのhThreadメンバーにはPROCESS_INFORMATION、プライマリスレッドのtidが含まれます。他の人からのアイデアを歓迎します。

于 2009-12-28T14:20:40.840 に答える