ГЛABA 4  Механизмы управления

ГЛABA 4  Механизмы управления

B этой главе описываются три фундаментальных механизма Microsoft Windows, критически важных для управления системой и ее конфигурирования:

реестр;

сервисы;

Windows Management Instrumentation (Инструментарий управления Windows).

Реестр

Реестр играет ключевую роль в конфигурировании и управлении Windows. Это хранилище общесистемных и пользовательских параметров. Реестр не является статичной совокупностью хранящихся на жестком диске данных, как думают многие. Прочитав этот раздел, вы увидите, что он представляет собой окно в мир различных структур, которые хранятся в памяти компьютера и поддерживаются ядром и исполнительной системой. Данный раздел не претендует на роль полного справочника по реестру Windows. Исчерпывающая информация такого рода для Windows 2000 находится в справочном файле «Technical Reference to the Windows 2000 Registry» (Regentry.chm), который поставляется с ресурсами Windows 2000, а для Windows XP и Windows Server 2003 эта информация доступна через Интернет по ссылке http:// www.microsoft.com/windowssewer2003/tecbinfo/reskit/deploykitmsp

Мы начнем с обзора структуры реестра, рассмотрим поддерживаемые им типы данных и ключевую информацию, хранящуюся в реестре Windows. Потом заглянем поглубже внутрь и обсудим механизмы, используемые диспетчером конфигурации — компонентом исполнительной системы, который отвечает за реализацию базы данных реестра. Среди прочего мы коснемся внутренней структуры реестра на диске, способов выборки конфигурационной информации по запросу приложений и мер защиты этой важнейшей системной базы данных.

Просмотр и изменение реестра

Как правило, следует избегать прямого редактирования реестра — приложения и система, хранящие в реестре параметры, которые могут потребовать настройки вручную, должны предоставлять соответствующий пользовательский интерфейс (UI) для их модификации. Однако, как вы уже неоднократно видели в этой книге, для изменения некоторых дополнительных и отладочных параметров никакого UI не предусмотрено. Поэтому в Windows включен ряд утилит, позволяющих просматривать и модифицировать реестр.

Windows 2000 поставляется с двумя утилитами для редактирования реестра — Regedit.exe и Regedt32.exe, — тогда как в Windows XP и Windows Server 2003 имеется лишь Regedit.exe. Причина в том, что версия Regedit в Windows 2000 была перенесена из Windows 98 и поэтому не поддерживала редактирование или просмотр параметров защиты и типов данных, не определенных в Windows 98. Поэтому в Windows 2000 была добавлена Regedt32, которая не обладала развитыми средствами поиска и поддержки импорта/экс-порта, но поддерживала параметры защиты и специфичные для Windows 2000 типы данных. Regedit, поставляемая с Windows XP и Windows Server 2003, распознает все типы данных в реестре и позволяет редактировать параметры защиты, ввиду чего необходимость в Regedt32 отпала.

Существует также целый ряд утилит для работы с реестром из командной строки. Например, Reg.exe, включенная в Windows XP и Windows Server 2003 и доступная в Windows 2000 Support Tools, дает возможность импортировать, экспортировать, создавать резервные копии и восстанавливать разделы реестра, а также сравнивать, модифицировать и удалять разделы и параметры.

Использование реестра

Конфигурационные данные всегда считываются в следующих случаях.

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

При входе Explorer и другие Windows-компоненты считывают из реестра предпочтения данного пользователя, в том числе буквы подключенных сетевых дисков, размещение ярлыков, а также настройки рабочего стола, меню и др.

При запуске приложения считывают общесистемные параметры, например список дополнительных установленных компонентов, информацию о лицензировании, настройки для данного пользователя (меню, размещение панелей инструментов, список недавно открывавшихся документов и т. д.). Однако чтение реестра возможно и в другие моменты, скажем, в ответ на модификацию его параметра или раздела. Некоторые приложения ведут мониторинг своих конфигурационных параметров в реестре и считывают обновленные значения, как только обнаруживают изменения. Ho в целом, если система простаивает, работы с реестром не должно быть. Реестр обычно модифицируется в следующих ситуациях.

Исходная структура реестра и многие настройки по умолчанию определяются его прототипной версией, поставляемой на дистрибутиве Windows и копируемой при установке новой системы.

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

При установке драйвера устройства подсистема Plug and Play создает разделы и параметры в реестре, которые сообщают диспетчеру ввода-вывода, как запускать драйвер, а также создает другие параметры, определяющие работу этого драйвера. (Подробнее об установке драйверов устройств см. главу 9.)

Когда вы изменяете параметры приложения или системы через UI, эти изменения часто сохраняются в реестре.

ПРИМЕЧАНИЕ Как ни печально, но некоторые приложения периодически опрашивают реестр на предмет изменений, тогда как делать это следует через функцию RegNotifyCbangeKey, которая отправляет поток в сон до тех пор, пока в интересующей его части реестра не произойдет какое-нибудь изменение.

Типы данных в реестре

Реестр — это база данных, структура которой аналогична структуре логического тома. Он содержит разделы (keys), напоминающие дисковые каталоги, и параметры (values), которые можно сравнить с файлами на диске. Раздел представляет собой контейнер, содержащий другие разделы, называемые подразделами (subkeys), и/или параметры. Параметры хранят собственно данные. Разделы верхнего уровня называются корневыми. Здесь мы будем использовать термины «подраздел» и «раздел» как синонимы (лишь корневые разделы не могут быть подразделами).

Соглашение об именовании разделов и параметров заимствовано из файловой системы. Таким образом, параметру можно присвоить имя, которое сохраняется в каком-либо разделе. Исключением из этой схемы является безымянный параметр, присутствующий в каждом разделе. Утилиты реестра, Regedit и Regedt32, по-разному показывают этот параметр: Regedit обозначает его как (Default) [(По умолчанию)], a Regedt32 — как ‹No Name› (‹БЕЗ ИМЕНИ›).

B параметрах хранятся данные 15 типов, перечисленных в таблице 4–1. Большинство параметров реестра имеет тип REG_DWORD, REGBINARY или REG_SZ. Параметры типа REG_DWORD содержат числовые или булевы значения, параметры типа REGBINARY — данные, требующие более 32 битов, или произвольные двоичные данные (например зашифрованные пароли), а параметры типа REGSZ — строки (естественно, в Unicode-формате), которые могут представлять такие элементы, как имена, пути, типы и имена файлов.

Особенно интересен тип REG_LINK, поскольку он позволяет разделу ссылаться на другой раздел или параметр. Например, если параметр RootlLink содержит значение Root2RegKey типа REG_LINK, а параметр RegKey — RegValue, то значение RegValue можно идентифицировать двумя путями: RootlLinkRegValue и Root2RegKeyRegValue. Как поясняется в следующем разделе, Windows интенсивно использует ссылки в реестре: три из шести корневых разделов реестра представляют собой ссылки на подразделы трех корневых разделов, которые ссылками не являются. Ссылки не записываются на диск, а создаются динамически при каждой загрузке системы.

Логическая структура реестра

Вы можете проследить схему организации реестра через данные, которые в нем хранятся. Существует шесть корневых разделов (добавлять или удалять корневые разделы нельзя), описанных в таблице 4–2.

Почему имена корневых разделов начинаются с буквы «H»? Дело в том, что имена корневых разделов представляют Windows-описатели (Handles) разделов (KEY). Как говорилось в главе 1, HKLM является аббревиатурой HKEY_LOCAL_MACHINE. B таблице 4–3 приводится список всех корневых разделов и их аббревиатур. Содержимое и предназначение каждого из них подробно обсуждаются в следующих разделах главы.

HKEY_CURRENT_USER

Корневой раздел HKCU содержит данные о предпочтениях и конфигурации программного обеспечения для локально зарегистрированного пользователя. Этот раздел ссылается на профиль текущего пользователя, находящийся на жестком диске в файле Documents and Settings‹имя_полъзователя› Ntuser.dat (описание файлов реестра см. в разделе «Внутренние механизмы реестра» далее в этой главе). При каждой загрузке профиля пользователя (например, при регистрации в системе или при выполнении сервисного процесса в увязке с именем какого-либо пользователя) HKCU создается как ссылка на подраздел соответствующего пользователя в HKEY_USERS. Некоторые подразделы HKCU перечислены в таблице 4–4.

HKEY_USERS

HKU содержит подраздел для каждого загруженного профиля пользователя, регистрационную базу данных классов и подраздел HKU.DEFAULT, связанный с профилем для системы (этот профиль предназначен для процессов, выполняемых под локальной системной учетной записью; см. раздел «Сервисы» далее в этой главе). Данный профиль используется Winlogon, например, чтобы изменения в параметрах фона рабочего стола были реализованы на экране входа. Если пользователь входит в систему в первый раз и если его учетная запись не зависит от доменного профиля роуминга (т. е. профиль пользователя извлекается из централизованного хранилища в сети по указанию контроллера домена), система создает профиль для его учетной записи на основе профиля, хранящегося в каталоге C: Documents and Set-tingsDefault User.

Каталог, где система хранит профили, определяется параметром реестра HKLMSoftwareMicrosoftWindows NTCurrentVersionProfileListProfilesDi-rectory, который по умолчанию устанавливается в %SystemDrive%Documents and Settings. Раздел ProfileList также хранит список профилей, имеющихся в системе. Информация по каждому профилю помещается в подраздел, имя которого отражает SID учетной записи, соответствующей данному профилю (сведения о SID см. в главе 8). Информация в разделе профиля включает время последней загрузки этого профиля (параметры ProfileLoadTimeLow и ProfileLoadTimeHigh), двоичное представление SID учетной записи (параметр Sid) и путь к кусту профиля на диске в каталоге ProfileImagePath (о кустах см. раздел «Кусты» далее в этой главе). Windows XP и Windows Server 2003 показывают список профилей в диалоговом окне управления профилями пользователей, которое представлено на рис. 4–1. Чтобы открыть это окно, запустите апплет System (Система) из Control Panel (Панель управления), перейдите на вкладку Advanced (Дополнительно) и в разделе User Profiles (Профили пользователей) щелкните кнопку Settings (Параметры).

Рис. 4–1. Диалоговое окно User Profiles (Профили пользователей)

ЭКСПЕРИМЕНТ: наблюдение за загрузкой и выгрузкой профилей

Чтобы увидеть, как профиль загружается в реестр, а потом выгружается, запустите командой runas какой-нибудь процесс под учетной записью пользователя, не вошедшего на данный момент в систему. Пока новый процесс выполняется, запустите Regedit и обратите внимание на загруженный раздел профиля в HKEY_USERS. После завершения процесса нажмите в Regedit клавишу F5 для обновления, и этого профиля в реестре больше не будет.

HKEY_CLASSES_ROOT

HKCR включает информацию двух типов: сопоставления расширений файлов и регистрационные данные СОМ-классов. Для каждого зарегистрированного типа файлов существует свой раздел. Большинство разделов содержит параметры типа REG_S2, ссылающиеся на другие разделы HKCR, где находится информация о сопоставлениях классов файлов. Например, HKCR.xls ссылается на сведения о файлах Microsoft Excel в разделе HKCUExcel.Sheet.8 (последняя цифра указывает на версию Microsoft Excel). Другие разделы содержат детальную информацию о конфигурации СОМ-объектов, зарегистрированных в системе.

Раздел HKEYCLASSESROOT формируется на основе:

специфичных для конкретного пользователя регистрационных данных классов в HKCUSOFTWAREClasses (хранятся в Documents and Settings ‹имя_полъзователя›1.оса SettingsApplication DataMicrosoftWindows Usrclass.dat);

общесистемных регистрационных данных классов в HKLMSOFTWARE Classes.

Причина, по которой регистрационные данные, специфичные для каждого пользователя, были отделены от общесистемных, заключается в том, что это дает возможность включать соответствующие настройки и в профили «блуждающих» пользователей (профили роуминга). Это же устранило дыру в защите: непривилегированный пользователь не может изменить или удалить разделы в HKEYCLASSESROOT и тем самым повлиять на функционирование приложений в системе. Непривилегированные пользователи и приложения могут считывать общесистемные данные и добавлять новые разделы и параметры в общесистемные данные (которые отражаются на данные, специфичные для этих пользователей), но изменять существующие разделы и параметры им разрешается лишь в собственных данных.

HKEY_LOCAL_MACHINE

HKLM — корневой раздел, содержащий подразделы с общесистемной конфигурационной информацией: HARDWARE, SAM, SECURITY, SOFTWARE и SYSTEM.

Подраздел HKLMHARDWARE содержит описание аппаратного обеспечения системы и все сопоставления драйверов с устройствами. Диспетчер устройств, который запускается с вкладки Hardware (Оборудование) окна свойств системы, позволяет просматривать информацию об устройствах, получаемую простым считыванием значений параметров из раздела HARDWARE.

ЭКСПЕРИМЕНТ: забавы с разделом Hardware

Вы можете обмануть своих коллег или друзей, заставив их поверить в то, что у вас самый последний процессор, модифицировав параметр ProcessorNameString в разделе HKLMHARDWAREDESCRIPTIONSystemCentralProcessor. Апплет System (Система) отображает значение параметра ProcessorNameString на вкладке General (Общие). Ho изменение остальных параметров никак не влияет на информацию, выводимую апплетом System, так как система кэширует многие параметры для использования функциями, через которые приложения запрашивают у системы возможности установленного на данном компьютере процессора.

B HKLMSAM находится информация о локальных учетных записях и группах, например пароли, определения групп и сопоставления с доменами. Система Windows Server, работающая как контроллер домена, хранит доменные и групповые учетные записи в Active Directory — базе данных, которая содержит общедоменные параметры и сведения. (Active Directory в этой книге не рассматривается.) По умолчанию дескриптор защиты раздела SAM сконфигурирован так, что к нему не имеет доступа даже администратор.

B HKLMSECURITY хранятся данные, которые относятся к общесистемным политикам безопасности, а также сведения о правах, назначенных пользователям. HKLMSAM связан с подразделом SECURITY в разделе HKLMSE-CURITYSAM. По умолчанию содержимое HKLMSECURITY недоступно для просмотра, поскольку параметры защиты разрешают доступ только по учетной записи System. Вы можете сменить дескриптор защиты, чтобы администраторы получили доступ к этому разделу для чтения, или, если вам любопытно, что там находится, запустить Regedit под локальной системной учетной записью с помощью PsExec (как это сделать, будет показано в соответствующем эксперименте). Ho это почти ничего не даст, так как данные в нем не документированы, а пароли зашифрованы (по алгоритму необратимого шифрования).

HKLMSOFTWARE — то место, где Windows хранит общесистемную конфигурационную информацию, не требуемую при загрузке системы. Кроме того, здесь сохраняют свои общесистемные настройки приложения сторонних разработчиков (пути к файлам, каталоги приложений, даты лицензий и сроки их окончания).

HKLMSYSTEM содержит общесистемную конфигурационную информацию, необходимую для загрузки системы, например списки загружаемых драйверов и запускаемых сервисов. Поскольку эта информация критична для запуска системы, Windows делает ее копию, называемую последней удачной конфигурацией (last known good control set). Она позволяет вернуться к последней работоспособной конфигурации, если после изменений, внесенных в текущую конфигурацию, система перестала загружаться. Подробнее об этом — ближе к концу главы.

HKEY_CURRENT_CONFIG

HKEY_CURRENT_CONFIG — просто ссылка на текущий профиль оборудования, хранящийся в HKLMSYSTEMCurrentControlSetHardware ProfilesCur-rent. Профили оборудования позволяют администратору изменять базовые настройки системных драйверов. Хотя реальный профиль может меняться от загрузки к загрузке, благодаря разделу HKCC приложения всегда имеют дело с текущим активным профилем. Управление профилями оборудования осуществляется через диалоговое окно Hardware Profiles (Профили оборудование), которое открывается кнопкой Settings (Профили оборудования) в одноименном разделе на вкладке Hardware (Оборудование) в апплете System. При загрузке Ntldr предложит указать, какой профиль вам нужен, если он не один.

HKEY_PERFORMANCE_DATA

Реестр также является механизмом, который в Windows обеспечивает доступ к значениям счетчиков производительности. При этом не важно, предоставлены счетчики компонентами операционной системы или серверными приложениями. Одна из дополнительных выгод обращения к счетчикам производительности через реестр — возможность удаленного мониторинга рабочих характеристик без лишних издержек, поскольку удаленный доступ к реестру легко получить через обычные API-функции реестра.

Обратиться напрямую к этим данным можно только программным путем через Windows-функции реестра типа RegQueryValueEx, открыв специальный раздел с именем HKEY_PERFORMANCE_DATA. Доступ к разделу HKPD из редактора реестра невозможен — здесь хранится не сама информация о производительности, а ссылки на соответствующие источники этих данных.

Информация, относящаяся к счетчикам производительности, доступна и через функции Performance Data Helper (PDH), предоставляемые Performance Data Helper API (Pdh.dll). Компоненты, используемые для получения значений счетчиков производительности, показаны на рис. 4–2.

Анализ и устранение проблем с реестром

Поскольку система и приложения сильно зависят от конфигурационных параметров, изменение данных в реестре может вызвать их сбои. Когда системе или приложению не удается считать параметры, которые, как предполагается, всегда доступны, это программное обеспечение может рухнуть и при этом выводить сообщения об ошибках, скрывающие корень проблемы. He понимая, как сбоящая система или программа обращается к реестру, практически невозможно выяснить, какие разделы или параметры реестра сконфигурированы неправильно. B такой ситуации ответ может дать утилита Regmon.

Regmon позволяет наблюдать за обращениями к реестру. При этом Regmon выводит информацию о процессе, обращающемся к реестру, а также сообщает время, тип и результат доступа. Эти сведения полезны для того, чтобы увидеть, как приложения и система взаимодействуют с реестром, найти места хранения конфигурационных параметров, записываемых приложениями и системой, и устранить неполадки, связанные с отсутствием каких-либо разделов или параметров реестра. Regmon включает расширенные средства фильтрации и выделения информации, чтобы вы могли сосредоточиться на операциях над выбранными разделами или параметрами, либо операциях, выполняемых конкретными процессами.

Как работает Regmon

Утилита Regmon полагается на драйвер устройства, который она извлекает из своего исполняемого образа и запускает в период своего выполнения. При первом запуске она требует, чтобы в учетной записи, под которой она выполняется, были привилегии Load Driver и Debug; при последующих запусках в том же сеансе загрузки системы достаточно одной привилегии Debug, так как драйвер является резидентным.

Ha самом деле внутри исполняемого файла Regmon хранится три драйвера: один — для Windows 95, Windows 98 и Windows Millennium, другой — для Windows NT, Windows 2000 и Windows XP, a третий — для Windows Server 2003. Почему драйвер для Windows Server 2003 отделен от драйвера для аналогичных систем? A потому, что в Windows NT, Windows 2000 и Windows XP единственный способ, которым драйвер может вести мониторинг всех операций с реестром — перехват системных вызовов (system-call hooking), и потому, что в Windows Server 2003 драйвер может использовать с той же целью механизм обратного вызова реестра (registry callback mechanism). (Windows 95, Windows 98 и Windows Millennium поддерживают другой механизм мониторинга реестра.)

Вспомните раздел «Диспетчеризация системных сервисов» главы 3 — там говорилось, что адреса функций системных сервисов хранятся в диспетчерской таблице системных сервисов в ядре. Драйвер может обнаруживать вызов системного сервиса, сохранив адрес соответствующей функции из массива и заменив этот элемент массива адресом своей функции-ловушки (hook function). После этого любые вызовы данного сервиса поступают в функцию-ловушку, установленную драйвером, и эта функция может проверять или модифицировать параметры вызова, а при необходимости и выполнять исходную функцию системного сервиса. Если функция-ловушка вызывает исходную функцию, драйвер также получает возможность изучить результат операции и возвращаемые ею данные, например значения параметров реестра. Ha рис. 4–3 показано, как Regmon перехватывает вызовы функций реестра в режиме ядра.

Механизм обратного вызова реестра впервые появился в Windows XP; однако Regmon по-прежнему использует перехват системных вызовов (system-call hooking), работая в Windows XP, потому что в ней этот механизм сообщает не обо всех операциях с реестром. Используя механизм обратного вызова, драйвер регистрирует в диспетчере конфигурации функцию обратного вызова. Диспетчер конфигурации запускает функции обратного вызова, установленные драйвером, в определенные моменты выполнения системных сервисов реестра, чтобы драйвер видел все обращения к реестру и мог их контролировать. Этот механизм используют антивирусные программы, которые сканируют данные реестра или блокируют неавторизованным процессам доступ к реестру для записи.

ЭКСПЕРИМЕНТ: анализ операций с реестром в простаивающей системе

Поскольку реестр реализует функцию RegNotiJyChangeKey, с помощью которой приложения могут запрашивать уведомление об изменениях в реестре, не опрашивая его постоянно, в простаивающей системе Regmon не должен обнаруживать повторяющиеся обращения к одним и тем же разделам или параметрам реестра. Любая такая активность указывает на плохо написанное приложение, которое отрицательно влияет на общую производительность системы.

Запустите Regmon и через несколько секунд изучите журнал вывода, чтобы выяснить, не пытается ли какая-то программа постоянно опрашивать реестр. Найдя в выводе строку, связанную с опросом, щелкните ее правой кнопкой мыши и выберите из контекстного меню команду Process Properties, чтобы узнать, какой процесс занимается такой деятельностью.

ЭКСПЕРИМЕНТ: поиск параметров приложения в реестре с помощью Regmon

Иногда при анализе проблем нужно определить, где в реестре хранятся те или иные параметры системы или приложения. B этом эксперименте вы используете Regmon для поиска параметров Notepad (Блокнот). Notepad, как и большинство Windows-приложений, сохраняет пользовательские предпочтения (например, включение режима переноса строк, выбранный шрифт и его размер, позиция окна) между запусками. Наблюдая с помощью Regmon, когда Notepad считывает или записывает свои параметры, вы сможете выявить раздел реестра, в котором хранятся эти параметры. Вот как это делается.

1. Пусть Notepad сохранит какой-нибудь параметр, который вы легко найдете в трассировочном выводе Regmon. Для этого запустите Notepad, выберите шрифт Times New Roman и закройте Notepad.

2. Запустите Regmon. Откройте диалоговое окно фильтра выделения информации и введите notepad.exe в фильтре Include. Тогда Regmon будет протоколировать только активность notepad.exe в столбце Process или Path.

3. Снова запустите Notepad и остановите в Regmon перехват событий, просто выбрав команду-переключатель Capture Events в меню FiIe утилиты Regmon.

4. Прокрутите полученный журнал к верхней строке и выберите ее.

5. Нажмите Ctrl+F, чтобы открыть диалоговое окно Find, и введите строку поиска times new. Regmon должен выделить строку вроде показанной на следующей иллюстрации. Остальные операции в непосредственной близости должны относиться к другим параметрам Notepad.

Наконец, дважды щелкните выделенную строку. Regmon запустит Regedit (если он еще не выполняется) и заставит его перейти к соответствующему параметру реестра.

Методики анализа проблем с применением Regmon

Выявить причины сбоев приложения или системы, связанные с реестром, позволяют две базовые методики анализа с использованием Regmon.

Найдите в трассировке Regmon последнее, что делало приложение перед сбоем. Это может указать на источник проблемы.

Сравните трассировку Regmon для сбойного приложения с аналогичной трассировкой в работающей системе.

При первом подходе запустите сначала Regmon, затем приложение. B момент сбоя вернитесь в Regmon и остановите протоколирование (нажав Ctrl+E). Прокрутите журнал до конца и найдите последние операции, выполнявшиеся приложением перед сбоем (крахом, зависанием или чем-то еще). Начните с последней строки и изучайте, на какие файлы и/или разделы реестра были ссылки, — это часто помогает локализовать источник проблемы.

Второй подход полезен, когда приложение сбоит в одной системе, но работает в другой. Создайте в Regmon журналы трассировки приложения в сбойной и работающей системе, потом откройте их в Microsoft Excel (согласитесь с параметрами по умолчанию, предлагаемыми мастером импорта) и удалите первые три столбца. (Если вы их не удалите, сравнение покажет, что все строки различаются, так как в первых трех столбцах содержится информация, которая меняется между запусками.) Наконец, сравните полученные файлы журналов. (Для этого можно использовать и утилиту WinDiff, которая в Windows XP включена в дистрибутив как один из бесплатных инструментов, а для Windows 2000 предлагается в составе ресурсов.)

Вы должны обратить особое внимание на записи в трассировке Regmon со значениями «NOTFOUND» или «ACCESS DENIED» в столбце Result. NOTFOUND сообщается, когда приложение пыталось обратиться к несуществующему разделу или параметру реестра. Bo многих случаях отсутствующий раздел или параметр — вещь безобидная, так как процесс, не сумевший обнаружить искомое в реестре, просто использует значения по умолчанию. Ho для некоторых параметров нет значений по умолчанию, и поэтому приложения сбоят, не найдя их в реестре.

Ошибки, связанные с отказом в доступе, — частая причина сбоев приложений; такие ошибки возникают, когда у приложения нет разрешения на доступ к нужному разделу реестра. Это касается приложений, в которых не проверяются результаты операций с реестром или не предусматривается восстановление после соответствующих ошибок.

Также подозрительна строка со значением «BUFROVERFLOW». Она не указывает на наличие в приложении эксплойта (exploit), использующего переполнение буфера. Такое значение посылается диспетчером конфигурации программе, которая выделила под буфер для хранения параметра реестра слишком мало места. Разработчики приложений часто пользуются этим, чтобы определить, какой буфер надо выделить для хранения того или иного значения. Сначала выполняется запрос к реестру с буфером нулевой длины и в ответ поступает сообщение с ошибкой переполнения буфера и истинным размером данных. Тогда программа создает буфер указанного размера и повторно считывает данные. Поэтому вы должны обнаружить операции, которые возвращают BUFROVERFLOW и при повторной попытке дают успешный результат.

Вот один из примеров использования Regmon для анализа реальной проблемы. Эта утилита избавила пользователя от полной переустановки Windows XP Симптом был таким: Internet Explorer зависал при запуске, если пользователь предварительно не устанавливал вручную соединение с Интернетом. Оно было задано как соединение по умолчанию, поэтому запуск Internet Explorer должен бы вызывать автоматическое подключение к Интернету (Internet Explorer был настроен на отображение начальной страницы по умолчанию при запуске).

Изучение журнала Regmon для операций Internet Explorer при запуске, начиная с того места, где Internet Explorer зависал, позволило обнаружить запрос, адресованный разделу в HKCUSoftwareMicrosoftRAS Phonebook. Пользователь сообщил, что ранее он удалил средство набора телефонных номеров, сопоставленное с этим разделом, и вручную создал соединение по коммутируемой линии. Поскольку имя такого соединения не совпадало с именем удаленной программы, получалось, что соответствующий раздел не был удален программой удаления средства набора телефонных номеров и что именно это было причиной зависания Internet Explorer. После удаления этого раздела Internet Explorer стал работать нормально.

Протоколирование операций под непривилегированными учетными записями или во время входа/выхода

Нередко наблюдается следующая ситуация. Приложение работает при выполнении под учетной записью, входящей в группу Administrators (Администраторы), и сбоит при запуске под учетной записью непривилегированного пользователя. Как уже говорилось, Regmon требует привилегий, которые обычно не выдаются стандартным учетным записям пользователей, но вести трассировку приложений, выполняемых в сеансе входа непривилегированного пользователя, все же можно. Для этого запустите Regmon под административной учетной записью командой runas.

Если проблема с реестром относится ко входу или выходу по учетной записи, вы также должны предпринять особые меры, чтобы использовать Regmon для трассировки этих этапов сеанса входа. Приложения, выполняемые под системной учетной записью, не завершаются при выходе пользователя, и благодаря этому вы можете работать с Regmon, несмотря на выход текущего пользователя и последующий вход того же или другого пользователя. Чтобы запустить Regmon под системной учетной записью, введите команду at, встроенную в Windows, и укажите флаг /interactive или запустите утилиту PsExec, например так:

psexec — i — s — d c: egmon.exe

Ключ — i сообщает PsExec, что окно Regmon должно появиться в интерактивной консоли, ключ — d заставляет PsExec запустить Regmon под системной учетной записью, а ключ — d указывает PsExec запустить Regmon и завершиться, не дожидаясь закрытия Regmon. После этой команды данный экземпляр Regmon переживет выход пользователя, и его окно вновь появится на рабочем столе, когда кто-то войдет в систему; при этом он будет протоколировать активность в реестре в обоих случаях.

Еще один способ мониторинга активности в реестре во время входа, выхода, загрузки системы или ее выключения — использовать функцию Regmon для протоколирования с момента загрузки системы. Для этого вы должны выбрать Log Boot в меню Options. При следующем запуске системы драйвер устройства Regmon будет протоколировать активность в реестре с самых ранних этапов загрузки, записывая информацию в журнал Windows Regmon.log. Протоколирование будет продолжаться до тех пор, пока не закончится свободное место на диске, пока система не будет выключена или пока вы не запустите Regmon. Файл журнала, хранящий трассировку операций над реестром при загрузке, входе, выходе и выключении системы Windows XP, обычно занимает 50-150 Мб.

Внутренние механизмы реестра

Из этого раздела вы узнаете, как диспетчер конфигурации (компонент исполнительной системы, реализующий реестр) организует файлы реестра на диске. Мы исследуем, как диспетчер конфигурации управляет реестром по мере его чтения и изменения приложениями и другими компонентами системы. Мы также обсудим механизмы, с помощью которых диспетчер конфигурации позволяет восстанавливать реестр, даже если система рухнула непосредственно в ходе внесения в него изменений.

Кусты

Реестр представлен на диске не просто одним большим файлом, а набором отдельных файлов, называемых кустами (hives). B каждом кусте содержится дерево реестра, у которого есть раздел, служащий корнем, или начальной точкой, дерева. Подразделы с их параметрами находятся под корнем. Возможно, вы подумали, что корневые разделы, показываемые редактором реестра, соответствуют корневым разделам кустов, но это не так. B таблице 4–5 перечислены кусты реестра и имена их файлов на диске. Полные имена всех файлов кустов (вместе с путями), кроме относящихся к профилям пользователей, жестко определяются самим диспетчером конфигурации. При загрузке кустов диспетчер конфигурации отмечает путь к каждому кусту в подразделе HKLMSYSTEMCurrentControlSetControlHivelist и удаляет пути к выгруженным из памяти кустам. (Профили пользователей выгружаются в отсутствие ссылок на них.) Для формирования привычной структуры реестра, отображаемой редактором реестра, диспетчер конфигурации создает корневые разделы и связывает кусты друг с другом.

Заметьте, что некоторые кусты, перечисленные в таблице 4–5, являются изменяемыми и не имеют сопоставленных файлов. Система создает и манипулирует такими кустами только в памяти, поэтому они существуют лишь временно. Изменяемые кусты создаются при каждой загрузке системы. Пример подобного куста — HKLMHARDWARE, в котором хранятся сведения о физических устройствах и назначенных им ресурсах. Распознавание оборудования и распределение ресурсов происходят при каждой загрузке системы, поэтому было бы нелогично хранить данные этого куста на диске.

ЭКСПЕРИМЕНТ: загрузка и выгрузка кустов вручную

Regedt32 в Windows 2000 и Regedit в Windows XP или Windows Server 2003 позволяют загружать кусты, к которым можно обращаться через меню FiIe этих редакторов реестра. Такая возможность полезна при анализе проблем, когда нужно просмотреть или отредактировать куст, полученный с незагружаемой системы или из резервной копии. B этом эксперименте вы используете Regedt32 (при наличии Windows 2000) или Regedit (при наличии Windows XP или Windows Server 2003) для загрузки версии куста HKLMSYSTEM, создаваемой программой Windows Setup и сохраняемый в каталоге WindowsRepair в ходе установки.

1. Кусты можно загружать только в HKLM или HKU, поэтому откройте Regedit или Regedt32, укажите HKLM, а затем выберите Load Hive (Загрузить куст) из меню FiIe (Файл) в Regedit или из меню Registry (Реестр) в Regedt32.

2. Перейдите в каталог WindowsRepair в диалоговом окне Load Hive (Загрузить куст), выберите System.bak и откройте его. При запросе введите Test в качестве имени раздела, в который будет загружаться этот куст.

3. Откройте только что созданный раздел HKLMTest и изучите содержимое куста.

4. Откройте HKLMSysternCurrentControlSetControlHivelist и найдите элемент RegistryMachineTest, который продемонстрирует, как диспетчер конфигурации перечисляет загруженные кусты в разделе HiveList.

5. Укажите HKLMTest и выберите Unload Hive (Выгрузить куст) из меню FiIe в Regedit или из меню Registry в Regedt32 для выгрузки этого куста.

Лимиты на размеры кустов

B некоторых случаях размеры кустов ограничиваются. Например, Windows ограничивает размер куста HKLMSYSTEM. Это делается из-за того, что Ntldr считывает весь куст HKLMSYSTEM в физическую память почти в самом начале процесса загрузки, когда поддержки виртуальной памяти еще нет. Кроме того, Ntldr загружает в физическую память Ntoskrnl и драйверы устройств периода загрузки. (Подробнее о роли Ntldr в процессе загрузки см. главу 6.) B Windows 2000 Ntldr устанавливает фиксированный верхний предел на размер этого куста в 12 Мб, но в Windows XP и Windows Server 2003 тот же куст может быть размером до 200 Мб или до четверти объема физической памяти, установленной в системе (в зависимости от того, какой предел будет достигнут раньше).

B Windows 2000 также существует лимит на общий размер всех загруженных кустов. Она использует для хранения кустов реестра пул подкачиваемой памяти, и поэтому общий объем загруженных данных реестра ограничен доступным размером этого пула. При инициализации диспетчер памяти определяет его размер на основе целого ряда факторов, в том числе объема физической памяти в системе. B системе, где диспетчер памяти создает самый большой из возможных пул подкачиваемой памяти, размер реестра ограничен 376 Мб. Поскольку система не сможет эффективно работать, если пула подкачиваемой памяти будет недостаточно для других целей, Windows 2000 не позволит данным реестра занять более 80 % этого пула. Для просмотра или модификации ограничения на размер реестра, как показано на рис. 4–4, щелкните кнопку Change (Изменить) в разделе Virtual Memory (Виртуальная память) диалогового окна Performance Options (Параметры быстродействия), доступного с вкладки Advanced (Дополнительно) окна свойств системы.

Лимит на общий размер загруженных кустов реестра может привести к ограничению числа пользователей, одновременно входящих в систему Windows 2000 с Terminal Services, поскольку каждый профиль пользователя увеличивает размер загруженных кустов. B Windows XP и Windows Server 2003 диспетчер конфигурации использует не пул подкачиваемой памяти, а функции проецирования в системную память, предоставляемые диспетчером памяти. При этом проецируются лишь те части кустов реестра, к которым происходят обращения в данный момент времени. Ограничений на размер реестра в Windows XP или Windows Server 2003 нет, и общий размер загруженных кустов не сказывается на масштабируемости Terminal Services.

ЭКСПЕРИМЕНТ: просмотр описателей кустов

Диспетчер конфигурации открывает кусты, используя таблицу описателей режима ядра (см. главу 3), поэтому он может обращаться к ним из контекста любого процесса. Применение такой таблицы — эффективная альтернатива подходу, основанному на использовании драйверов или компонентов исполнительной системы для простого обращения из системных процессов к одним лишь описателям (которые должны быть защищены от пользовательских процессов). Просмотреть описатели кустов можно с помощью утилиты Process Explorer. B Windows 2000 диспетчер объектов сообщает об описателях из таблицы как об открытых в системном процессе System Idle, а в Windows XP и Windows Server 2003 он показывает описатели как открытые в процессе System. Укажите нужный процесс и выберите Handles из подменю Lower Pane View в меню View. Задайте сортировку по типу описателя и прокручивайте список, пока не увидите файлы кустов, как на следующей иллюстрации.

Особый тип разделов, символьная ссътка (symbolic link), позволяет диспетчеру конфигурации связывать кусты для организации реестра. Символьная ссылка — это раздел, который переадресует диспетчер конфигурации к другому разделу. Так, раздел HKLMSAM представляет собой символьную ссылку на раздел в корне куста SAM.

Структура куста

Диспетчер конфигурации делит куст на логические единицы, называемые блоками (blocks), по аналогии с тем, как файловая система делит диск на кластеры. По определению размер блока реестра составляет 4096 байтов (4 Кб). Размер куста увеличивается кратно размеру блоков. Первый блок куста называется базовым (base block); он включает глобальную информацию о кусте, в том числе сигнатуру regf, идентифицирующую файл как куст, порядковые номера, метку времени последней записи в куст, номер версии формата, контрольную сумму и внутреннее имя файла куста (например, УстройствоРаздел_жесткого_диска1WINDOWSSYSTEM32ConfigSAM). Мы поясним смысл порядковых номеров и метки времени, когда будем рассматривать механизм записи данных в файл куста. Номер версии формата указывает формат данных куста. B Windows 2000 диспетчер конфигурации использует формат данных куста версии 1.3. B Windows XP и Windows Server 2003 применяется тот же формат данных для совместимости с профилями роуминга Windows 2000, но для кустов System и Software используется формат версии 1.5, обеспечивающий более эффективный поиск, а также хранение больших значений.

Windows упорядочивает хранимые в кусте данные с помощью контейнеров, которые называются ячейками (cells). Ячейка может содержать раздел, параметр, дескриптор защиты, список подразделов или параметров раздела. Поле в начале ячейки описывает тип ее данных. Все типы данных поясняются в таблице 4–6. Размер ячейки указывается в ее заголовке. Когда ячейка присоединяется к кусту, последний должен быть соответственно увеличен. Для этого система создает блок, называемый приемником (bin). Размер приемника равен размеру ячейки, округленному до ближайшего большего значения, кратного размеру блока. Пространство между концом ячейки и концом приемника считается свободным, и система может помещать в него другие ячейки. Приемники тоже имеют заголовки, но с сигнатурой bbin, и поле, в которое записывается размер приемника и его смещение в файле куста.

Используя для отслеживания активных частей реестра приемники вместо ячеек, Windows упрощает себе управление реестром. Так, система обычно создает и удаляет приемники реже, чем ячейки, а это позволяет диспетчеру конфигурации эффективнее управлять памятью. Считывая куст в память, диспетчер конфигурации может выбирать только приемники, содержащие ячейки (т. е. активные приемники), и игнорировать пустые (удаленные). B результате добавления или удаления ячеек куст может содержать пустые приемники вперемешку с активными. Такая ситуация напоминает фрагментацию диска, возникающую при создании и удалении файлов. Когда приемник становится пустым, диспетчер конфигурации объединяет его со смежными пустыми приемниками, формируя непрерывный пустой приемник как можно большего размера. Диспетчер конфигурации также объединяет смежные пустые ячейки для формирования свободных ячеек большего размера. (Диспетчер конфигурации уплотняет куст, только когда приемники в конце куста освобождаются. Вы можете уплотнить реестр за счет его резервного копирования и последующего восстановления с помощью Windows-функций RegSaveKey и Reg-ReplaceKey, используемых утилитой Windows Backup.)

Ссылки, образующие структуру куста, называются индексами ячеек (cell indexes). Индекс ячейки представляет собой ее смещение в файле куста. Таким образом, он похож на указатель из одной ячейки на другую и интерпретируется диспетчером конфигурации относительно начала куста. Например, как видно из таблицы 4–6, ячейка раздела содержит поле с индексом ячейки родительского раздела; индекс ячейки подраздела указывает на ячейку со списком подчиненных ему подразделов. Ячейка списка подразделов содержит список индексов, ссылающихся на ячейки подчиненных подразделов. Поэтому если вам нужно найти, скажем, ячейку раздела для подраздела А, родительским разделом которого является раздел В, вы должны сначала найти ячейку со списком подразделов раздела B по ее индексу в ячейке раздела В. После этого с помощью списка индексов из ячейки списка подразделов раздела B можно отыскать ячейки любых подразделов раздела В. При этом для каждой ячейки подраздела вы проверяете, не совпадает ли хранящееся там имя раздела с именем искомого (в данном случае — А).

Ячейки, приемники и блоки можно легко перепутать, поэтому для прояснения различий между ними обратимся к структуре простого куста реестра. Образец файла куста реестра, схема которого показана на рис. 4–5, включает в себя базовый блок и два приемника. Первый приемник пуст, а во втором есть несколько ячеек. Логично, что в таком кусте может быть всего два раздела: корневой Root и его подраздел, Sub Key. B Root находятся два параметра: VaI 1 и VaI 2. Ячейка списка подразделов определяет местонахождение подразделов корневого раздела, а ячейка списка параметров — адрес параметров корневого раздела. Свободные промежутки во втором приемнике являются пустыми ячейками. Учтите, что на схеме не показаны ячейки дескрипторов защиты для двух разделов, которые должны присутствовать в составе куста.

Рис. 4–5. Внутренняя структура куста реестра

Ha рис. 4–6 показано окно утилиты Disk Probe (Dskprobe.exe) с образцом содержимого первого приемника куста SYSTEM. Обратите внимание на сигнатуру приемника, bbin. Под ней можно увидеть сигнатуру nk. Это сигнатура ячейки раздела (kn). Обратный порядок отображения сигнатуры определяется порядком хранения данных в системах типа x86. Ячейка, которой диспетчер конфигурации присвоил внутреннее имя $$$PROTO.HIV, является корневой ячейкой куста SYSTEM, как указывает следующее за сигнатурой nk имя.

Для оптимизации поиска подразделов и параметров диспетчер конфигурации сортирует ячейки списков подразделов в алфавитном порядке. Если нужно найти подраздел в списке, диспетчер использует двоичный поиск. При этом он сразу обращается в середину списка. Если искомое имя в соответствии с алфавитным порядком находится перед разделами из середины списка, диспетчер узнает, что оно хранится в первой половине списка. B ином случае оно должно быть во второй половине списка подразделов. И так до тех пор, пока диспетчер не найдет искомый подраздел или не обнаружит его отсутствие. Ячейки списков параметров не сортируются, так что новые параметры всегда добавляются в конец списка.

Карты ячеек

Данный текст является ознакомительным фрагментом.