プロセスのメインスレッドへのハンドルを取得する
-
21-09-2019 - |
質問
いくつかの小さなテストアプリで追加のスレッドを作成し、この追加のスレッドからメインスレッドを一時停止したいと考えています。追加のスレッドは次のように作成されます。 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 に使用最古の作成時間。スレッドからHANDLE
を取得するために OpenThread に呼び出しIDます。
この機能でスレッド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);
}
プログラム全体のグローバルを作成してみてはいかがでしょうか (使用 外部 必要な場合)
HANDLE mainThread ;
DWORD mainThreadId ;
main の最初の行で、(スレッドが作成される前に)次のようにします。
mainThread = GetCurrentThread() ;
mainThreadId = GetCurrentThreadId() ;
使用できます あらゆる形式の IPC ID または HANDLE をリモート プロセスと共有します (HANDLE の共有が機能することは確認していませんが、機能するはずです!)
このタイプの便利なAPI関数の数は、下にある(もちろん!)<のhref = "http://msdn.microsoft.com/en-us/library/ms686832%28VS.85%29.aspx "REL =" nofollowをnoreferrer ">ツールのヘルプのスイート。 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()
のターゲット処理できる場合は、 PROCESS_INFORMATION
のブロックが含まれているのhThreadメンバープライマリスレッドのためのTID。他人からの任意のアイデアを歓迎します。