Марк Руссинович - 1.Внутреннее устройство Windows (гл. 1-4)
• B системе должно быть менее 16 динамических рабочих потоков.
Динамические потоки завершаются через 10 минут пребывания в неактивном состоянии. B зависимости от рабочей нагрузки исполнительная система может создавать до 16 таких потоков.
Глобальные флаги WindowsWindows поддерживает набор флагов, который хранится в общесистемной глобальной переменной NtGlobalFlag, предназначенной для отладки, трассировки и контроля операционной системы. При загрузке системы переменная NtGlobalFlag инициализируется значением параметра GlobalFlag из раздела реестра HKLMSYSTEMCurrentControlSetControlSession Manager. По умолчанию его значение равно 0, и в системах с обычной конфигурацией глобальные флаги обычно не используются. Кроме того, каждый образ исполняемого файла имеет набор глобальных флагов, позволяющих включать код внутренней трассировки и контроля (хотя битовая структура этих флагов совершенно не соответствует структуре общесистемных глобальных флагов). Эти флаги не документированы, но могут пригодиться при изучении внутреннего устройства Windows.
K счастью, в Platform SDK и средствах отладки есть утилита Gflags.exe, позволяющая просматривать и изменять системные глобальные флаги (либо в реестре, либо в работающей системе) и глобальные флаги образов исполняемых файлов. Gflags поддерживает как GUI-интерфейс, так и командную строку. Параметры командной строки можно узнать, введя gflags /?. При запуске утилиты без параметров выводится диалоговое окно, показанное на рис. 3-28.
Вы можете переключаться между реестром (System Registry) и текущим значением переменной в системной памяти (Kernel Mode). Для внесения изменений нужно щелкнуть кнопку Аррlу (кнопка OK просто закрывает программу). Хотя вы можете изменять флаги в работающей системе, большинство из них требует перезагрузки для того, чтобы изменения вступили в силу.
Поскольку документации на этот счет нет, лучше перезагрузиться после любых изменений.
Выбрав Image File Options, вы должны ввести имя исполняемого в системе файла. Этот переключатель позволяет изменять набор глобальных флагов отдельного образа (а не всей системы). Заметьте, что флаги на рис. 3-29 отличаются от флагов на рис. 3-28.
Рис. 3-29. Настройка в Gflags глобальных флагов образа исполняемого файла
ЭКСПЕРИМЕНТ: включение трассировки загрузчика образов и просмотр NtGlobalFlag
Чтобы увидеть пример детальной трассировочной информации, которую можно получить при установке глобальных флагов, попробуйте запустить Gflags в системе с загруженным отладчиком ядра, которая подключена к компьютеру с запущенной утилитой Kd или Windbg.
Далее попробуйте установить, например, глобальный флаг Show Loader Snaps. Для этого выберите Kernel Mode, установите флажок Show Loader Snaps и щелкните кнопку Apply. Теперь запустите на этой машине какую-нибудь программу, и отладчик ядра будет выдавать информацию, аналогичную показанной ниже.
Для просмотра состояния переменной NtGlobalFlag можно использовать команды /gflags и /gflag отладчика ядра. Первая выводит список всех флагов, указывая, какие из них установлены, a /gflag показывает только установленные флаги.
LPC
LPC (local procedure call) — это механизм межпроцессной связи для высокоскоростной передачи сообщений. Он недоступен через Windows API напрямую и является внутренним механизмом, которым пользуются только компоненты операционной системы Windows. Вот несколько примеров того, где применяется LPC
• Windows-приложения, использующие RPC (документированный API), неявно используют и LPC, когда указывают локальный RPC — разновидность RPC, применяемую для взаимодействия между процессами в рамках одной системы.
• Некоторые функции Windows API обращаются к LPC, посылая сообщения процессу подсистемы Windows.
• Winlogon взаимодействует с процессом LSASS через LPC
• Монитор состояния защиты (компонент исполнительной системы, рассматриваемый в главе 8) также взаимодействует с процессом LSASS через LPC
ЭКСПЕРИМЕНТ: просмотр объектов «порт LPC»
Вы можете увидеть именованные объекты «порт LPC» (LPC port objects) с помощью утилиты Winobj. Запустите Winobj.exe и выберите корневой каталог. Интересующие нас объекты обозначаются значком в виде разъема, как показано ниже.
Для просмотра объектов «порт LPC», используемых RPC, выберите каталог RPC Control, как на следующей иллюстрации.
Вы также можете наблюдать объекты «порт LPC» с помощью команды !lpc отладчика ядра. Параметры этой команды позволяют перечислять порты LPC, сообщения LPC и потоки, ожидающие или посылающие эти сообщения. Для просмотра порта аутентификации LSASS (в него Winlogon посылает запросы на вход в систему) сначала нужно получить список портов в данной системе.
Как правило, LPC используются для взаимодействия между серверным процессом и одним или несколькими клиентскими процессами. LPC-соеди-нение может быть установлено между двумя процессами пользовательского режима или между компонентом режима ядра и процессом пользовательского режима. Например, как говорилось в главе 2, Windows-процессы иногда посылают сообщения подсистеме Windows через LPC Некоторые системные процессы вроде Winlogon и LSASS тоже используют LPC Примерами компонентов режима ядра, взаимодействующих с пользовательскими процессами через LPC, могут служить монитор состояния защиты и LSASS. LPC предусматривает три способа обмена сообщениями.
• Сообщение длиной менее 256 байтов можно передать вызовом LPC с буфером, содержащим сообщение. Затем это сообщение копируется из адресного пространства процесса-отправителя в системное адресное пространство, а оттуда — в адресное пространство процесса-получателя.
• Если клиент и сервер хотят обменяться данными, размер которых превышает 256 байтов, они могут использовать общий раздел, на который они оба спроецированы. Отправитель помещает данные в общий раздел и посылает получателю уведомление с указателем на область раздела, где находятся данные.
• Если серверу нужно считать или записать данные, объем которых превышает размер общего раздела, то их можно напрямую считать из клиентского адресного пространства или записать туда. Для этого LPC предоставляет серверу две функции. Сообщение, посланное первой функцией, обеспечивает синхронизацию передачи последующих сообщений. LPC экспортирует единственный объект исполнительной системы объект «порт» (port object). Однако порты бывают нескольких видов.
• Порт серверного соединения (server connection port) Именованный порт, служащий точкой запроса связи с сервером. Через него клиенты могут соединяться с сервером.
• Коммуникационный порт сервера (server communication port) Безымянный порт, используемый сервером для связи с конкретным клиентом. У сервера имеется по одному такому порту на каждый активный клиент.
• Коммуникационный порт клиента (client communication port) Безымянный порт, используемый конкретным клиентским потоком для связи с конкретным сервером.
• Безымянный коммуникационный порт (unnamed communication port) Порт, создаваемый для связи между двумя потоками одного процесса.
LPC обычно используется так. Сервер создает именованный порт соединения. Клиент посылает в него запрос на установление связи. Если запрос удовлетворен, создается два безымянных порта — коммуникационный порт клиента и коммуникационный порт сервера. Клиент получает описатель коммуникационного порта клиента, а сервер — описатель коммуникационного порта сервера. После этого клиент и сервер используют новые порты для обмена данными.
Схема соединения между клиентом и сервером показана на рис. 3-30.
Трассировка событий ядраРазличные компоненты ядра Windows и несколько базовых драйверов устройств оснащены средствами мониторинга для записи трассировочных данных об их работе, используемых при анализе проблем в системе. Эти компоненты опираются на общую инфраструктуру в ядре, которая предоставляет трассировочные данные механизму пользовательского режима — Event Tracing for Windows (ETW). Приложение, использующее ETW, попадает в одну или более следующих категорий.
• Контроллер (controller) Начинает и прекращает сеансы протоколирования (logging sessions), а также управляет буферными пулами.
• Провайдер (provider) Определяет GUID (globally unique identifiers) для классов событий, для которых он может создавать трассировочные данные, и регистрирует их в ETW. Провайдер принимает команды от контроллера на запуск и остановку трассировки классов событий, за которые он отвечает.