获取进程主线程的句柄

Eta*_*tan 14 c++ windows multithreading dll-injection

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

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

int*_*jay 16

我不认为在进程启动后,主线程与其他线程有区别.但是,您可以枚举进程中的所有线程,并使用GetThreadTimes查找具有最早创建时间的线程.打电话的OpenThread获得HANDLE从一个线程ID.


Eta*_*tan 7

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 甚至没有保证进程的"主"线程仍然存在!进程的主线程可能已经完成了一个`ExitThread`. (6认同)

mtx*_*mtx 6

使用此函数获取线程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;
}
Run Code Online (Sandbox Code Playgroud)

简单地打开线程来获取句柄:

/*
 * 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);
}
Run Code Online (Sandbox Code Playgroud)

  • 我不相信这会在各种环境下完美运行.具体来说,假设所有机器上的每个进程中的Tib地址都相等,甚至GetMainThreadId()的调用者都是主线程,对吧?你应该解释它是如何工作的,因为它有太多可疑的东西要问. (3认同)