Думаю, что ответ вышел в комментариях. Кажется, есть как минимум два сценария 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
и выполняет прямую CreateProcess
с bInheritHandles = true
, он непреднамеренно унаследует ваши дескрипторы.
Вы можете использовать процесс без потоков чтобы смягчить это. В общем:
- Создайте процесс без потоков.
DuplicateHandle
все дескрипторы, которые вы хотите захватить в этот новый процесс без потоков. CreateProcess
ваш новый, реальный разветвленный процесс, использующий PROC_THREAD_ATTRIBUTE_LIST
, но установив номинальный родительский процесс этого процесса как беспоточный (с PROC_THREAD_ATTRIBUTE_PARENT_PROCESS
).
Теперь вы можете CreateProcess
одновременно без беспокоиться о других вызывающих, и теперь вы можете закрыть повторяющиеся дескрипторы и пустой процесс.