Какая польза от процесса без потоков в Windows? - PullRequest
0 голосов
/ 04 мая 2020

Я читаю Windows Internals (7-е издание) , и они пишут о процессах в главе 1:

Processes

[.. .] процесс Windows включает в себя следующее:

  • [...]
  • По крайней мере, один поток выполнения Хотя «пустой» процесс возможно, это (в основном) бесполезно.

Что в данном контексте означает «в основном»? Что может делать процесс без потоков и как это может быть полезно?

РЕДАКТИРОВАТЬ: Кроме того, в докладе 2015 года Марк Руссинович говорит, что процесс имеет «по крайней мере один поток» (19:12). Это было обобщением?

1 Ответ

0 голосов
/ 07 мая 2020

Думаю, что ответ вышел в комментариях. Кажется, есть как минимум два сценария ios, в которых может быть полезен беспоточный процесс.

Сценарий 1: создание моментальных снимков процесса

Это, вероятно, самый простой. Как прокомментировал RbMm, PssCaptureSnapshot можно вызвать с параметром PSS_CAPTURE_VA_CLONE для создания беспоточного (или «пустого») процесса (используя ZwCreateProcessEx, предположительно для дублирования памяти целевого процесса в режиме ядра ) .

Основное использование здесь будет для отладки, если разработчик захочет проверить память процесса в определенный момент времени.

Примечательно, что Эрик Сан указывает, что пустой процесс не необходимо для проверки дескрипторов (даже если пустой процесс содержит как свое собственное пространство памяти , так и дескрипторы), поскольку уже существует способ проверить дескрипторы процесса без создания нового процесса или дублирования памяти.

Сценарий 2: разветвление процессов с определенными c унаследованными дескрипторами --- безопасно

Раймонд Чен объясняет другое использование беспоточного процесса: безопасное создание новых «реальных» процессов с унаследованными дескрипторами.

Когда поток хочет создать новый процесс (CreateProcess), есть несколько способов передать дескрипторы новому процессу: * 10 23 *

  • Сделайте дескриптор наследуемым и CreateProcess с помощью bInheritHandles = true.
  • Сделайте дескриптор наследуемым, добавьте его в PROC_THREAD_ATTRIBUTE_LIST и передайте этот список вызову CreateProcess .

Однако они предлагают противоречивые гарантии, которые могут вызвать проблемы, когда вызывающие стороны хотят создать два потока с разными дескрипторами одновременно. Как говорит Раймонд в Почему люди блокируют вызовы CreateProcess? :

Для того, чтобы дескриптор был унаследован, вам нужно не только поместить его в PROC_THREAD_ATTRIBUTE_LIST, но вы также должны сделать дескриптор наследуемым. Это означает, что если другой поток не на борту с трюком PROC_THREAD_ATTRIBUTE_LIST и выполняет прямую Create­Process с bInheritHandles = true, он непреднамеренно унаследует ваши дескрипторы.

Вы можете использовать процесс без потоков чтобы смягчить это. В общем:

  1. Создайте процесс без потоков.
  2. DuplicateHandle все дескрипторы, которые вы хотите захватить в этот новый процесс без потоков.
  3. CreateProcess ваш новый, реальный разветвленный процесс, использующий PROC_THREAD_ATTRIBUTE_LIST, но установив номинальный родительский процесс этого процесса как беспоточный (с PROC_THREAD_ATTRIBUTE_PARENT_PROCESS).

Теперь вы можете CreateProcess одновременно без беспокоиться о других вызывающих, и теперь вы можете закрыть повторяющиеся дескрипторы и пустой процесс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...