B таблице 6–4 приведена информация по некоторым Windows-функциям, связанным с процессами. Более подробные сведения см. в документации Windows API в MSDN Library.
ЭКСПЕРИМЕНТ: применение команды !process отладчика ядра
Эта команда выводит подмножество информации из блока EPROCESS. Ee вывод для каждого процесса делится на две части. Сначала вы видите часть, показанную ниже (если вы не указываете адрес или идентификатор процесса, команда !process выводит сведения для активного процесса на текущем процессоре).
Вслед за базовой информацией о процессе появляется список его потоков. Данная часть поясняется в эксперименте «Применение команды !thread отладчика ядра» далее в этой главе. Еще одна команда, позволяющая получить информацию о процессе, — !handle. Она создает дамп таблицы описателей, принадлежащей процессу (см. раздел «Описатели объектов и таблица описателей, принадлежащая процессу» главы 3). Структуры защиты процессов и потоков описываются в главе 8.
Что делает функция CreateProcess
K этому моменту мы уже рассмотрели структуры, которые являются частью процесса, и API-функции, позволяющие вам (и операционной системе) манипулировать процессами. Вы также научились пользоваться различными утилитами для наблюдения за тем, как процессы взаимодействуют с системой. Ho как эти процессы появляются на свет и как они завершаются, выполнив задачи, для которых они предназначались? B следующих разделах вы узнаете, как порождаются Windows-процессы.
Создание Windows-процесса осуществляется вызовом одной из таких функций, как CreateProcess, CreateProcessAsUser, CreateProcessWithTokenW или CreateProcessWitbLogonW, и проходит в несколько этапов с участием трех компонентов операционной системы: Kernel32.dll (библиотеки клиентской части Windows), исполнительной системы и процесса подсистемы окружения Windows (Csrss). Поскольку архитектура Windows поддерживает несколько подсистем окружения, операции, необходимые для создания объекта «процесс» исполнительной системы (которым могут пользоваться и другие подсистемы окружения), отделены от операций, требуемых для создания Windows-процесса. Поэтому часть действий Windows-функции CreateProcess специфична для семантики, привносимой подсистемой Windows.
B приведенном ниже списке перечислены основные этапы создания процесса Windows-функцией CreateProcess. Детальное описание действий на каждом этапе дается в следующих разделах.
ПРИМЕЧАНИЕ Многие этапы работы CreateProcess связаны с подготовкой виртуального адресного пространства процесса и поэтому требуют понимания массы структур и терминов, связанных с управлением памятью и описываемых в главе 7.
1. Открывается файл образа (EXE), который будет выполняться в процессе.
2. Создается объект «процесс» исполнительной системы.
3. Создается первичный поток (стек, контекст и объект «поток» исполнительной системы).
4. Подсистема Windows уведомляется о создании нового процесса и потока.
5. Начинается выполнение первичного потока (если не указан флаг CREATE_SUSPENDED).
6. B контексте нового процесса и потока инициализируется адресное пространство (например, загружаются требуемые DLL) и начинается выполнение программы.
Общая схема создания процесса в Windows показана на рис. 6–5. Прежде чем открыть исполняемый образ для выполнения, CreateProcess делает следующее.
• При вызове CreateProcess класс приоритета указывается в параметре CreationFlags, и, вызывая CreateProcess, вы можете задать сразу несколько классов приоритета. Windows выбирает самый низкий из них.
• Когда для нового процесса не указывается класс приоритета, по умолчанию принимается Normal, если только класс приоритета процесса-создателя не равен IdIe или Below Normal. B последнем случае новый процесс получает тот же класс приоритета, что и у родительского процесса.
• Если для нового процесса указан класс приоритета Real-time, а создатель не имеет привилегии Increase Scheduling Priority, устанавливается класс приоритета High. Иначе говоря, функция CreateProcess завершается успешно, даже если у того, кто ее вызвал, недостаточно привилегий для создания процессов с классом приоритета Real-time, — просто класс приоритета нового процесса будет ниже Real-time.
• Все окна сопоставляются с объектами «рабочий стол», которые являются графическим представлением рабочего пространства. Если при вызове CreateProcess не указан конкретный объект «рабочий стол», новый процесс сопоставляется с текущим объектом «рабочий стол» процесса-создателя.
Этап 1: открытие образа, подлежащего выполнению
Как показано на рис. 6–6 и в таблице 6–5, на первом этапе CreateProcess должна найти нужный Windows-образ, который будет выполнять файл, указанный вызвавшим процессом, и создать объект «раздел» для его последующего проецирования на адресное пространство нового процесса. Если имя образа не указано, используется первая лексема командной строки (первая часть командной строки, которая заканчивается пробелом или знаком табуляции и является допустимой в качестве имени образа).
B Windows XP и Windows Server 2003 CreateProcess проверяет, не запрещает ли политика безопасности на данной машине запуск этого образа (см. главу 8).
Если в качестве исполняемого файла указана Windows-программа, ее имя используется напрямую. A если исполняемый файл является не Windows-приложением, а программой MS-DOS, Winl6 или POSIX, то CreateProcess ищет образ поддержки (support image) для запуска этой программы. Данный процесс необходим потому, что приложения, не являющиеся Windows-программами, нельзя запускать напрямую. Вместо этого Windows использует один из нескольких специальных образов поддержки, которые и отвечают за запуск приложений, отличных от Windows-программ. Так, если вы пытаетесь запустить POSIX-приложение, CreateProcess идентифицирует его как таковое и вызывает исполняемый Windows-файл поддержки POSIX, Posix.exe. A если вы запускаете программу MS-DOS или Winl6, стартует исполняемый Windows-файл поддержки Ntvdm.exe. Короче говоря, вы не можете напрямую создать процесс, не являющийся Windows-процессом. Если Windows не найдет соответствующий файл поддержки, вызов CreateProcess закончится неудачей.
Конкретное решение о запуске того или иного файла поддержки CreateProcess принимает так.
• Если исполняемый файл — программа MS-DOS с расширением EXE, COM или PIF, подсистеме Windows посылается сообщение, чтобы она проверила, не создан ли уже процесс поддержки MS-DOS (Ntvdm.exe, указанный в параметре реестра HKLMSYSTEMCurrentControlSetControlWOWCmdline). Если да, этот процесс используется для запуска программы MS-DOS — подсистема Windows посылает виртуальной DOS-машине (Virtual DOS Machine, VDM) сообщение для запуска новой программы, — после чего управление возвращается к CreateProcess. Если нет, запускается Ntvdm.exe и повторно выполняется первый этап CreateProcess.
• Если исполняемый файл — командный файл с расширением BAT или CMD, запускается Cmd.exe, обрабатывающий командную строку Windows, и повторно выполняется первый этап CreateProcess. (Имя командного файла передается Cmd.exe как первый параметр.)
• Если исполняемый файл — приложение Winl6 (Windows 3.1), CreateProcess решает, надо ли для его запуска создавать новый процесс VDM или оно должно использовать глобальный для всех сеансов процесс VDM (который, возможно, еще не создан). Решение определяется флагами CREATE_SEPARATE_WOW_VDM и CREATE_SHARED_WOW_VDM. Если эти флаги не заданы, то по умолчанию решение принимается, исходя из значения параметра реестра HKLMSYSTEMCurrentControlSetControlWOWDefaultSeparateVDM. Если программа будет работать в отдельной VDM, запускается приложение, указанное в HKLMSYSTEMCurrentControlSetControlWOWWowCmdline, и повторно выполняется первый этап CreateProcess. B ином случае подсистема Windows посылает сообщение для проверки возможности использования общего процесса VDM. (Это исключено, если процесс VDM сопоставлен с другим объектом «рабочий стол» или если его параметры защиты отличны от таковых для вызывающего процесса. Тогда нужно создавать новый процесс VDM.) Если задействовать общий процесс VDM нельзя, подсистема Windows посылает ему сообщение о необходимости запуска нового образа, и управление возвращается к CreateProcess. Если процесс VDM еще не создан (или если он существует, но использовать его нельзя), запускается образ поддержки VDM и повторно выполняется первый этап CreateProcess. K этому моменту CreateProcess успешно открывает допустимый исполняемый файл Windows и создает для него объект «раздел». Этот объект еще не спроецирован на память, но уже открыт. Однако сам факт успешного создания объекта «раздел» не означает того, что запускаемый файл является допустимым Windows-образом, — он может быть DLL или исполняемым файлом POSIX. Если это исполняемый файл POSIX, запускается Posix.exe, и CreateProcess заново выполняет действия первого этапа. A если это DLL, вызов CreateProcess заканчивается неудачей.