在Windows中,没有线程的进程有什么用?

4szc88ey  于 2022-12-14  发布在  Windows
关注(0)|答案(1)|浏览(200)

我正在阅读Windows Internals (7th Edition),他们在第1章:

进程

[...]Windows进程包括以下内容:

  • [...]
    *至少有一个执行线程尽管“空”进程是可能的,但它(大多数情况下)没有用。

在这个上下文中,“大多数”是什么意思?没有线程的进程能做什么?这有什么用?
编辑:还有,在a 2015 talk中,Mark Russinovich说一个进程“至少有一个线程”(19:12)。这是一个概括吗?
Disclaimer: I work for Microsoft.

nlejzf6q

nlejzf6q1#

我想答案已经在评论中出来了。似乎至少有两种场景,无线程进程会很有用。

场景1:捕获进程快照

正如RbMm所评论的,可以使用PSS_CAPTURE_VA_CLONE选项调用PssCaptureSnapshot来创建一个无线程(或“空”)进程(使用ZwCreateProcessEx,大概是duplicate the target process's memory in kernel mode)。
这里的主要用途是调试,如果开发人员希望在某个时间点检查进程的内存。
值得注意的是,Eryk Sun指出,空进程对于检查句柄不是必需的(即使空进程同时拥有自己的内存空间 * 和 * 句柄),因为已经有一种方法可以检查进程的句柄,而无需创建新进程或复制内存。

场景2:安全地派生具有特定继承句柄的进程

Raymond Chen解释了无线程进程的另一个用途:安全地创建具有继承句柄的新的“真实的”进程。
当线程想要创建一个新进程(CreateProcess)时,有几种方法可以将句柄传递给新进程:

  • 使句柄可继承,并将CreateProcess设置为bInheritHandles = true
  • 使句柄可继承,将其添加到PROC_THREAD_ATTRIBUTE_LIST,并将该列表传递给CreateProcess调用。

然而,它们提供了相互冲突的保证,当调用者希望同时创建两个 * 具有不同句柄 * 的线程时,可能会导致问题。
为了继承一个句柄,你不仅要把它放在PROC_THREAD_ATTRIBUTE_LIST中,而且你还必须使这个句柄是可继承的。这意味着如果另一个线程没有使用PROC_THREAD_ATTRIBUTE_LIST技巧,而是直接使用bInheritHandles = true执行Create­Process,它会无意中继承你的句柄。
您可以使用无线程进程来缓解这种情况。
1.创建无线程进程。

  1. DuplicateHandle要捕获到这个新的无线程进程中的所有句柄。
  2. CreateProcess使用PROC_THREAD_ATTRIBUTE_LIST创建新的真实的的分叉进程,但将此进程的名义父进程设置为无线程进程(使用PROC_THREAD_ATTRIBUTE_PARENT_PROCESS)。
    您现在可以并发地执行CreateProcess,而不用担心其他调用方,并且您现在可以关闭重复的句柄和空进程。

相关问题