createRemoteThread 函数 (processthreadsapi.h)

创建在另一个进程的虚拟地址空间中运行的线程。

使用 CreateRemoteThreadEx 函数创建在另一个进程的虚拟地址空间中运行的线程,并选择性地指定扩展属性。

语法

HANDLE CreateRemoteThread(
  [in]  HANDLE                 hProcess,
  [in]  LPSECURITY_ATTRIBUTES  lpThreadAttributes,
  [in]  SIZE_T                 dwStackSize,
  [in]  LPTHREAD_START_ROUTINE lpStartAddress,
  [in]  LPVOID                 lpParameter,
  [in]  DWORD                  dwCreationFlags,
  [out] LPDWORD                lpThreadId
);

参数

[in] hProcess

要在其中创建线程的进程句柄。 句柄必须具有 PROCESS_CREATE_THREADPROCESS_QUERY_INFORMATIONPROCESS_VM_OPERATIONPROCESS_VM_WRITEPROCESS_VM_READ 访问权限,并且在某些平台上没有这些权限可能会失败。 有关详细信息,请参阅 进程安全和访问权限

[in] lpThreadAttributes

指向 SECURITY_ATTRIBUTES 结构的指针,该结构指定新线程的安全描述符,并确定子进程是否可以继承返回的句柄。 如果 lpThreadAttributes 为 NULL,则线程将获取默认安全描述符,并且无法继承句柄。 访问控制在来自创建者主令牌的线程的默认安全描述符中列出 (ACL) 。

Windowsxp: 线程的默认安全描述符中的 ACL 来自创建者的主令牌或模拟令牌。 此行为随 Windows XP SP2 和 Windows Server 2003 更改。

[in] dwStackSize

堆栈的初始大小(以字节为单位)。 系统将此值舍入到最近的页。 如果此参数为 0 (零) ,则新线程将使用可执行文件的默认大小。 有关详细信息,请参阅 线程堆栈大小

[in] lpStartAddress

指向 LPTHREAD_START_ROUTINE要由 线程执行的应用程序定义函数的指针,表示远程进程中线程的起始地址。 函数必须存在于远程进程中。 有关详细信息,请参阅 ThreadProc

[in] lpParameter

指向要传递给线程函数的变量的指针。

[in] dwCreationFlags

控制线程创建的标志。

含义
0
线程在创建后立即运行。
CREATE_SUSPENDED
0x00000004
线程以挂起状态创建,在调用 ResumeThread 函数之前不会运行。
STACK_SIZE_PARAM_IS_A_RESERVATION
0x00010000
dwStackSize 参数指定堆栈的初始保留大小。 如果未指定此标志, dwStackSize 将指定提交大小。

[out] lpThreadId

指向接收线程标识符的变量的指针。

如果此参数为 NULL,则不返回线程标识符。

返回值

如果函数成功,则返回值是新线程的句柄。

如果函数失败,则返回值为 NULL。 要获得更多的错误信息,请调用 GetLastError。

请注意,即使 lpStartAddress 指向数据、代码或不可访问,CreateRemoteThread 也可能成功。 如果启动地址在线程运行时无效,则会发生异常,并且线程终止。 由于启动地址无效而导致的线程终止作为线程进程的错误退出进行处理。 此行为类似于 CreateProcess 的异步性质,即即使进程引用无效或缺少动态链接库,也会创建 (DLL) 。

注解

CreateRemoteThread 函数会导致新的执行线程在指定进程的地址空间中开始。 线程有权访问进程打开的所有对象。

在Windows 8之前,终端服务根据设计隔离每个终端会话。 因此,如果目标进程与调用进程位于不同的会话中, CreateRemoteThread 将失败。

创建新线程句柄时具有对新线程的完全访问权限。 如果未提供安全描述符,则句柄可用于任何需要线程对象句柄的函数中。 提供安全描述符时,在授予访问权限之前,对句柄的所有后续使用执行访问检查。 如果访问检查拒绝访问,则请求进程无法使用句柄获取对线程的访问权限。

如果线程是在可运行状态下创建的, (也就是说,如果未) 使用 CREATE_SUSPENDED 标志,则线程可以在 CreateThread 返回之前开始运行,尤其是在调用方收到所创建线程的句柄和标识符之前。

创建的线程优先级为 THREAD_PRIORITY_NORMAL。 使用 GetThreadPrioritySetThreadPriority 函数获取和设置线程的优先级值。

当线程终止时,线程对象会获得一个信号状态,该状态满足正在等待该对象的线程。

线程对象将保留在系统中,直到线程终止,并且通过调用 CloseHandle 关闭其所有句柄。

ExitProcessExitThreadCreateThreadCreateRemoteThread 函数以及由于 CreateProcess 调用 () 而启动的进程在进程中相互序列化。 一次只有其中一个事件在地址空间中发生。 这意味着存在以下限制:

  • 在进程启动和 DLL 初始化例程期间,可以创建新线程,但在为进程完成 DLL 初始化之前,这些线程不会开始执行。
  • 一个进程中一个线程一次只能位于 DLL 初始化或分离例程中。
  • ExitProcess 在所有线程完成其 DLL 初始化或分离例程后返回。
此函数的常见用途是将线程注入正在调试以发出中断的进程。 但是,不建议使用此用法,因为额外的线程会让调试应用程序的人员感到困惑,并且使用此技术有几个副作用:
  • 它将单线程应用程序转换为多线程应用程序。
  • 它会更改进程的计时和内存布局。
  • 它会导致调用进程中每个 DLL 的入口点。
此函数的另一个常见用途是将线程注入进程以查询堆或其他进程信息。 这可能会导致上一段落中提到的相同副作用。 此外,如果线程尝试获取另一个线程正在使用的锁的所有权,应用程序可能会死锁。

要求

要求
最低受支持的客户端 Windows XP [仅限桌面应用]
最低受支持的服务器 Windows Server 2003 [仅限桌面应用]
目标平台 Windows
标头 processthreadsapi.h (包括 Windows Server 2003、Windows Vista、Windows 7、Windows Server 2008 Windows Server 2008 R2)
Library Kernel32.lib
DLL Kernel32.dll

另请参阅

CloseHandle

CreateProcess

CreateRemoteThreadEx

CreateThread

ExitProcess

ExitThread

GetThreadPriority

进程和线程函数

ResumeThread

SECURITY_ATTRIBUTES

SetThreadPriority

ThreadProc

线程