Марк Руссинович - 1.Внутреннее устройство Windows (гл. 1-4)
Утилита 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 стал работать нормально.