Pages Menu
Categories Menu

Опубликовано | Нет комментариев

Подсистемы среды окружения и DLL — библиотеки подсистем

Роль подсистемы среды окружения заключается в предоставлении прикладным программам того или иного поднабора базовых служб исполняющей системы Windows. Каждая подсистема может предоставить доступ к различным поднаборам служб, присущих Windows. Это означает, что из приложений, построенных на использовании одной подсистемы, могут выполняться некие действия, которые не могут выполняться приложением, построенным на использовании другой подсистемы. Например, приложение Windows не может использовать SUA-функцию fork.

Каждый исполняемый образ (.exe) привязан к одной и только к одной подсистеме. При запуске образа код создания процесса исследует код типа подсистемы в заголовке образа, чтобы уведомить соответствующую подсистему о новом процессе. В Microsoft Visual C++ этот код типа указывается с помощью спецификатора /SUBSYSTEM команды link.

Как уже ранее упоминалось, пользовательские приложения не вызывают напрямую системные службы Windows. Вместо этого ими используется одна или несколько DLL-библиотек подсистемы. Эти библиотеки экспортируют документированный интерфейс, который может быть использован программами, связанными с данной подсистемой. Например, API-функции Windows реализованы в DLL-библиотеках подсистемы Windows, таких, как Kernel32.dll, Advapi32.dll, User32.dll и Gdi32.dll. А API-функции SUA реализованы в DLL-библиотеке подсистемы SUA (Psxdll.dll).

Эксперимент: просмотр типа подсистемы образа.

Тип подсистемы образа можно просмотреть с помощью средства Dependency Walker (Depends.exe) (доступно на сайте www.dependencywalker.com). Например, обратите внимание на типы образа для двух различных Windows-образов, Notepad.exe (простой текстовый редактор) и Cmd.exe (командная строка Windows):

Notepad
Cmd

Здесь показано, что Notepad (Блокнот) является GUI-программой, а Cmd является консольной (console), или текстовой программой. И хотя это означает, что существует две разные подсистемы для GUI-программ и текстовых программ, на самом деле есть только одна подсистема Windows, и GUI-программы могут иметь консоли, а консольные программы могут отображать GUI-элементы.

Когда приложение вызывает функцию, находящуюся в DLL-библиотеке подсистемы, может реализоваться одно из трех обстоятельств:

  • Функция полностью реализована в режиме пользователя в DLL-библиотеке подсистемы. Иными словами, процессу подсистемы среды никакое сообщение не отправляется и никакие службы исполняющей системы Windows не вызываются. Функция выполняется в пользовательском режиме, а результаты возвращаются вызвавшему ее коду. Примерами таких функций могут послужить:
  • GetCurrentProcess (всегда возвращающая –1, значение, определяемое во всех, связанных с процессами функциях для ссылки на текущий процесс);
  • GetCurrentProcessId (ID процесса для запущенного процесса не изменяется, поэтому этот ID извлекается из ячейки кэш-памяти, исключая тем самым необходимость обращения к ядру).
  • Функция требует один или несколько вызовов исполняющей системы Windows. Например, Windows-функции ReadFile и WriteFile включают соответственно вызовы базовых внутренних (и недокументированных) системных служб ввода-вывода Windows NtReadFile и NtWriteFile.
  • Функция требует проведения в процессе подсистемы среды окружения некоторой работы. (Процессы подсистем среды окружения, запущенные в пользовательском режиме, отвечают за обслуживание состояния клиентских приложений, находящихся под их управлением.) В этом случае к подсистеме среды окружения делается клиент-серверный запрос посредством отправки подсистеме сообщения для выполнения той или иной операции. Затем DLL-библиотека подсистемы, прежде чем вернуть управление вызывающему коду, ждет ответа.

Некоторые функции могут представлять собой комбинацию из только что перечисленных второго и третьего вариантов. В качестве примеров можно привести Windows-функции CreateProcessи CreateThread.

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.

↓