获取进程主线程的句柄

发布于 2024-08-16 08:41:33 字数 200 浏览 3 评论 0原文

我在一些小型测试应用程序中创建了一个附加线程,并希望从该附加线程中挂起主线程。附加线程是通过外部进程的 CreateRemoteThread 创建的。

由于 SuspendThread 需要一个指向应挂起的线程的 HANDLE,我想知道如何从在我的附加线程中运行的代码获取此 HANDLE

I have created an additional thread in some small testing app and want to suspend the main thread from this additional thread. The additional thread is created via CreateRemoteThread from an external process.

Since SuspendThread needs a HANDLE to the thread which should be suspended, I want to know how to get this HANDLE from code running in my additional thread.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

清欢 2024-08-23 08:41:33

我认为一旦进程启动,主线程与其他线程就没有任何区别。但是,您可以枚举进程中的所有线程,并使用GetThreadTimes 查找最早的线程创建时间。调用 OpenThread 获取 来自线程 ID 的 HANDLE

I don't think there is anything that differentiates the main thread from other threads once the process has started. However, you can enumerate all threads in the process, and use GetThreadTimes to find the thread with the earliest creation time. Call OpenThread to get a HANDLE from a thread ID.

青丝拂面 2024-08-23 08:41:33

使用此函数获取线程 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);
}

Get the thread id with this function:

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

Simple open the thread to get the handle:

/*
 * 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);
}
计㈡愣 2024-08-23 08:41:33
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;
}
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;
}
素罗衫 2024-08-23 08:41:33

为什么不创建一个程序范围的全局变量(使用 extern 如果必须的话)

HANDLE mainThread ;
DWORD mainThreadId ;

在 main 的第一行,(在创建任何线程之前)

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

您可以使用 任何形式的 IPC 与远程进程共享 id 或 HANDLE(尚未验证共享 HANDLE 是否有效,但应该可以! )

Why don't you just create a program-wide global (use extern if you have to)

HANDLE mainThread ;
DWORD mainThreadId ;

On the first line of main, (before any threads are created) do

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

You can use any form of IPC to share either the id or the HANDLE with the remote process (haven't verified sharing the HANDLE will work but it should!)

输什么也不输骨气 2024-08-23 08:41:33

许多此类有用的 API 函数位于(当然!)工具帮助套件。 CreateToolhelp32Snapshot()< /a> 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() 目标进程,PROCESS_INFORMATION 块包含主线程的 tid。欢迎其他人提出任何想法。

A number of useful API functions of this type are under the (of course!) Tool Help suite. The CreateToolhelp32Snapshot() API will take a snapshot of the running threads for a specified process.

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

Full example code here.

The struct returned does not differentiate the primary thread from the others. I do not know a mechanism to do so; while some versions of the C runtime will all ExitProcess() at the end of the primary thread, in all recent versions the process continues to run until the last thread exits.

Interjay's recommendation to use GetThreadTimes may be the best bet. If you can CreateProcess() the target process, the hThread member of the PROCESS_INFORMATION block contains the tid for the primary thread. Welcome any ideas from others.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文