CreateRemoteThreadEx 函数 (processthreadsapi.h)
创建一个线程,该线程在另一个进程的虚拟地址空间中运行,并选择性地指定扩展属性,例如处理器组相关性。
语法
HANDLE CreateRemoteThreadEx(
[in] HANDLE hProcess,
[in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] SIZE_T dwStackSize,
[in] LPTHREAD_START_ROUTINE lpStartAddress,
[in, optional] LPVOID lpParameter,
[in] DWORD dwCreationFlags,
[in, optional] LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList,
[out, optional] LPDWORD lpThreadId
);
参数
[in] hProcess
要在其中创建线程的进程句柄。 句柄必须具有PROCESS_CREATE_THREAD、PROCESS_QUERY_INFORMATION、PROCESS_VM_OPERATION、PROCESS_VM_WRITE和PROCESS_VM_READ访问权限。 在 Windows 10版本 1607 中,代码必须获取新句柄的这些访问权限。 但是,从 Windows 10 版本 1703 开始,如果新句柄有权获得这些访问权限,系统会为你获取这些访问权限。 有关详细信息,请参阅 进程安全和访问权限。
[in, optional] lpThreadAttributes
指向 SECURITY_ATTRIBUTES 结构的指针,该结构指定新线程的安全描述符,并确定子进程是否可以继承返回的句柄。 如果 lpThreadAttributes 为 NULL,则线程将获取默认安全描述符,并且无法继承句柄。 访问控制在来自创建者主令牌的线程的默认安全描述符中列出 (ACL) 。
[in] dwStackSize
堆栈的初始大小(以字节为单位)。 系统将此值舍入到最近的页。 如果此参数为 0 (零) ,则新线程将使用可执行文件的默认大小。 有关详细信息,请参阅 线程堆栈大小。
[in] lpStartAddress
指向 LPTHREAD_START_ROUTINE要由 线程执行的应用程序定义函数的指针,表示远程进程中线程的起始地址。 函数必须存在于远程进程中。 有关详细信息,请参阅 ThreadProc。
[in, optional] lpParameter
指向要传递给 lpStartAddress 指向的线程函数的变量的指针。 此参数可以为 NULL。
[in] dwCreationFlags
控制线程创建的标志。
值 | 含义 |
---|---|
|
线程在创建后立即运行。 |
|
线程以挂起状态创建,在调用 ResumeThread 函数之前不会运行。 |
|
dwStackSize 参数指定堆栈的初始保留大小。 如果未指定此标志, dwStackSize 将指定提交大小。 |
[in, optional] lpAttributeList
包含新线程的其他参数的属性列表。 此列表由 InitializeProcThreadAttributeList 函数创建。
[out, optional] lpThreadId
指向接收线程标识符的变量的指针。
如果此参数为 NULL,则不返回线程标识符。
返回值
如果函数成功,则返回值是新线程的句柄。
如果函数失败,则返回值为 NULL。 要获得更多的错误信息,请调用 GetLastError。
注解
CreateRemoteThreadEx 函数会导致新的执行线程在指定进程的地址空间中开始。 线程有权访问进程打开的所有对象。 lpAttribute 参数可用于指定扩展属性,例如新线程的处理器组相关性。 如果 lpAttribute 为 NULL,则函数的行为与 CreateRemoteThread 相同。
在Windows 8之前,终端服务根据设计隔离每个终端会话。 因此,如果目标进程与调用进程位于不同的会话中, CreateRemoteThread 将失败。
创建新线程句柄时具有对新线程的完全访问权限。 如果未提供安全描述符,则句柄可用于任何需要线程对象句柄的函数中。 提供安全描述符时,在授予访问权限之前,对句柄的所有后续使用执行访问检查。 如果访问检查拒绝访问,则请求进程无法使用句柄获取对线程的访问权限。
如果线程是在可运行状态下创建的, (也就是说,如果未) 使用CREATE_SUSPENDED标志,则线程可以在 CreateThread 返回之前开始运行,尤其是在调用方收到所创建线程的句柄和标识符之前。
线程的创建优先级为 THREAD_PRIORITY_NORMAL。 若要获取和设置线程的优先级值,请使用 GetThreadPriority 和 SetThreadPriority 函数。
当线程终止时,线程对象会获得一个信号状态,该状态满足正在等待该对象的线程。
线程对象将保留在系统中,直到线程终止,并且通过调用 CloseHandle 关闭其所有句柄。
ExitProcess、ExitThread、CreateThread、CreateRemoteThread 函数以及由于 CreateProcess 调用 () 而启动的进程在进程中相互序列化。 一次只有其中一个事件在地址空间中发生。 这意味着存在以下限制:
- 在进程启动和 DLL 初始化例程期间,可以创建新线程,但在为进程完成 DLL 初始化之前,这些线程不会开始执行。
- 一个进程中一个线程一次只能位于 DLL 初始化或分离例程中。
- ExitProcess 在所有线程完成其 DLL 初始化或分离例程后返回。
- 它将单线程应用程序转换为多线程应用程序。
- 它会更改进程的计时和内存布局。
- 它会导致调用进程中每个 DLL 的入口点。
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows 7 [仅限桌面应用] |
最低受支持的服务器 | Windows Server 2008 R2 [仅限桌面应用] |
目标平台 | Windows |
标头 | processthreadsapi.h (包括 Windows Server 2008 Windows Server 2008 R2 上的 Windows.h) |
Library | Kernel32.lib |
DLL | Kernel32.dll |