Часть 2
Сегодня я расскажу о новых свойствах системы реализованных разработчиками Microsoft для того, чтобы средствами восстановления приходилось пользоваться как можно реже. К ним относятся: (1) «подпись» драйверов (Driver Signing), (2) служба защиты системных файлов (System File Protection) и (3) методика верификации драйвера (Driver Verifier), о которой пойдет речь в следующий раз в части 3.
«Подпись» драйвера (Driver Signing)
Марк Русинович доктор философии в области вычислительной техники Университета Карнеги-Меллон и один из соавторов многих популярных утилит для Windows NT, включая NTFSDOS, Filemon, Regmon и Recover. С ним можно связаться по электронной почте по адресу mark@sysinternais.com или через Web-узел http://www.sysinternais.com |
На Экране 1 представлено диалоговое окно Driver Signing Options (Обращение через Control Panel => System => закладка Hardware).
ЭКРАН 1. Установка действий системы при проверке «подписи» драйвера. |
Что скрывается за словосочетанием «Microsoft подписывает драйвер»? Во-первых, для файла драйвера генерируется некоторый цифровой код — хэш-код (hash). Он представляет собой число, поставленное в соответствие содержимому файла. Это число уникально, т. е. нет таких двух файлов, для которых хэш-коды были бы одинаковыми. Затем с помощью технологии шифрования, разработанной фирмой VeriSign (компанией, предоставляющей услуги цифровой аутентикации), Microsoft выполняет шифрование хэш-кода открытым ключом. Зашифрованный хэш-код — это своеобразная «подпись» (сигнатура) драйвера. Впоследствии и драйвер, и его «подпись» поставляются вместе. Если известен открытый ключ, то сигнатуру драйвера в любой момент можно расшифровать. На CD-ROM с Windows 2000 помимо собственно файлов-драйверов содержатся и их сигнатуры. После установки системы обратите внимание на каталог %systemroot%system32catroot: именно здесь хранится информация о сигнатурах установленных драйверов в так называемых catalog-файлах. Драйверы устройств и их сигнатуры, разработанные OEM-партнерами Microsoft, после проведения соответствующих испытаний на совместимость с Windows 2000 (HCL-тестирование) предоставляются поставщикам системы. В каталоге Catroot имеются два файла с одинаковым именем sysmast и подкаталог, имя которого состоит из набора цифр и букв, а длина превышает 8 символов. Sysmast — главный индекс catalog-файлов. В подкаталоге находятся catalog-файлы для различных компонентов Windows 2000. Например, fp.cat — это каталог сигнатур для файлов приложения FrontPage, а nt5.cat и nt5inf.cat хранят сигнатуры для системных файлов.
Драйверы в Windows 2000 устанавливаются по-разному. Наиболее общий подход означает, что, когда подсистема Plug-and-Play (PnP) обнаруживает появление нового устройства, она пытается проинсталлировать соответствующий драйвер автоматически. При этом подсистема ядра PnP извещает пользовательский компонент PnP о появлении нового устройства. Последний (UMPNPMGR) реализован в виде библиотеки %systemroot%system32umpnpmgr.dll. Когда в систему добавляется новое устройство, UMPNPMGR начинает поиск информационного файла инсталляции драйвера (INF-файла). Этот файл может располагаться или в каталоге %systemroot%INF, или на внешнем носителе — дискете, или CD-ROM — в случае использования OEM-драйверов. INF-файлы имеют расширение и представляют собой обычный текстовый файл, содержащий инструкции по установке драйвера, той или иной степени сложности. Это могут быть директивы по копированию файлов — откуда и куда, задания новых значений в реестре, — в общем, все то, что нужно выполнить в системе при инсталляции нового драйвера или приложения. Другой способ установки драйвера состоит в применении мастера установки, Hardware Installation Wizard (HIW), реализованного в виде библиотеки %systemroot%system32 newdev.dll. HIW последовательно, шаг за шагом, проходит тем же путем, что и UMPNPMGR, когда локализует местонахождение INF-файла.
UMPNPMGR и HIW используют вызовы API, предоставляемые библиотекой %systemroot%system32 setupapi.dll (SETUPAPI), для работы с INF-файлом. С помощью вызовов SETUPAPI обрабатываются инструкции по установке драйвера и проверяется параметр реестра HKEY_ LOCAL_MACHINESOFTWARE MicrosoftDriverSigningPolicy. Если он не установлен, то проверяется HKEY_CURRENT_USERSoftwareMicrosoft DriverSigningPolicy. Именно эти параметры реестра устанавливаются в диалоговом окне Driver Signing Options. Когда во время работы в данном диалоге выдается директива Apply setting as system default, то устанавливается параметр реестра HKEY_LOCAL_MACHINE; в противном случае изменение происходит в HKEY_CURRENT_USER. Компонент UMPNPMGR сначала проверяет значение Policy в ветви HKEY_LOCAL_MACHINE и если оно установлено, то система присваивает ему наивысший приоритет, и индивидуальные установки, заданные в политике «подписи» драйверов не принимаются во внимание, кем бы они ни были заданы — администраторами или обычными пользователями. Значение 0 означает, что инсталляция драйверов будет производиться в системе без рассмотрения «подписи». Если значение равно 1, то при попытке установить драйвер без «подписи» будет выполнено обращение к SetupAPI, и пользователю придется дополнительно подтвердить необходимость установки такого драйвера. Значение Policy, равное 2, не позволит установить в системе драйвер без соответствующей «подписи».
В том случае, когда политика «подписей» диктует SetupAPI, в обязательном порядке проверять сигнатуры драйверов, с помощью соответствующего вызова API осуществляется поиск нужного каталожного файла. Затем SetupAPI обращается к CryptoAPI, в котором реализованы криптографические функции, для вычисления хэш-кода файла драйвера и дешифровки сигнатуры каталожного файла на основе открытого ключа от VeriSign. Если полученные значения не совпадают или для драйвера не найден catalog-файл, то SetupAPI либо запросит пользователя, нужно ли продолжать установку драйвера, либо процесс прервется, и будет выдано сообщение об ошибке.
Windows File Protection
В процессе разработки Windows 2000 Microsoft произвела опрос пользователей NT с целью выяснить, что, по их мнению, служит причиной нестабильности NT 4.0. В результатах опроса часто упоминался так называемый «библиотечный кошмар». Суть «кошмара» состоит в том, что в комплект поставки многих приложений разработчики добавляют библиотеки, необходимые для работы и самой системы NT. Резон разработчиков прост: не зависеть от того, какая версия библиотеки присутствует в системе. Например, приложения, написанные с использованием возможностей библиотеки Microsoft Foundation Classes (MFC) C++, часто поставляются с определенной копией библиотеки mfc42.dll. Компания Microsoft выпустила несколько версий этой библиотеки, и возможно, не все они совместимы с той, на которую рассчитано данное приложение. Проблема множества версий DLL распространяется даже на библиотеки, с которыми работает ядро NT.
В Windows 2000 появилась служба защиты от подобных приложений — Windows File Protection (WFP). До третьей бета-версии эта защита носила название System File Protector. WFP выполняет функции обеспечения безопасности системных файлов, в том числе файлов DLL, драйверов, шрифтов, INF-файлов и исполняемых файлов. Когда WFP «замечает» изменение в одном из охраняемых файлов, активизируется механизм защиты и произведенное изменение нейтрализуется оригинальной копией файла.
Во время активизации подсистемы Windows Logon (%systemroot% system32winlogon.exe) подгружается одна из библиотек WFP — %systemroot%system32sfc.dll (System File Checker — SFC). SFC экспортирует несколько функций для процедуры Winlogon, среди них SfcInitProt — функция инициализации. SfcInitProt в первую очередь считывает реестр в части SFC, именно раздел HKEY_LOCAL_MACHINESOFTWAREMicrosoft WindowsNTCurrentVersion Winlogon. Сначала анализируется параметр SFCDisable. Если оно не установлено в 0 и отладчик ядра (WinDbg) активен, то SFC дезактивирует службу WFP.
Вслед за этим SFC проверяет параметр SFCScan. Если его значение равно 1, то после завершения инициализации системы будет выполняться контроль целостности (сканирование) системных файлов. Если же он равен 2, то после завершения контроля целостности SFCScan имеет нулевое значение. Оно же задается по умолчанию. При этом сканирование системных файлов после завершения процедуры Winlogon не производится, но SFC тем не менее активизируется. В состав Windows 2000 входит утилита sfc.exe, с помощью которой можно задавать значение параметра SFCScan.
После завершения обработки параметра SFCScan анализируется параметр реестра SfcDllCacheDir. Последний параметр реестра, который проверяет служба SFC, — SFCQuota (тип данных DWORD). Значение этого параметра устанавливает максимальное количество данных (в мегабайтах), которое SFC должна контролировать. Все упомянутые параметры реестра необязательны; это означает, что, если они не заданы, считается, что им присвоено значение 0. Исключение составляет лишь SFCQuota: если оно явно не задано, то SFC присваивает ему значение -1. Это означает, что размер данных, контролируемых SFC, не ограничен.
После того как считаны все установки реестра, SfcInitProt вызывает функцию SfcInitializeDllLists. Эта функция начинает обработку списка контролируемых службой SFC файлов. Если Windows 2000 установлена в разделе NTFS, то проверяются права доступа к системным каталогам и соответствие этих прав рекомендациям SFC по защите системы. SFC контролирует около 3000 системных файлов. (Список SFC можно просмотреть на http://www.sysinternals.com/misc.htm. Библиотека Sfc.dll обеспечивает защиту указанных в списке файлов.) На Рисунке 1 приведен фрагмент списка системных каталогов, за которыми SFC устанавливает наблюдение. Не все файлы из обширного списка SFC присутствуют в каждой установленной Windows 2000.
РИСУНОК 1. Фрагмент списка каталогов,
за которыми следит SFC.
%systemroot% %systemroot%system %systemroot%system32 %systemroot%system32wbem %systemroot%system32usrri %systemroot%system32spool prtprocs %systemroot%system32spool prtprocsw32x86 %systemroot%system32spool driversw32x863 %systemroot%system32 pcproxy %systemroot%system32 eminst %systemroot%system32os2dll %systemroot%system32 pp %systemroot%system32 etmon %systemroot%system32mui 009 %systemroot%system32mts %systemroot%system32mtsmtxclex %systemroot%system32inetsrv %systemroot%system32export %systemroot%system32drivers %systemroot%system32com %systemroot%system32clients sclient etwin32aСледовательно, реальное число контролируемых файлов может быть меньше 3000. Копии оригинальных файлов из списка SFC хранятся в каталоге %systemroot% system32dllcache, если только в реестре в параметре SfcDllCacheDir не указано иное. Тем самым Microsoft предусмотрела возможность хранения архивной копии контролируемых файлов в некотором общедоступном месте в сети, что особенно целесообразно при административном (корпоративном) развертывании систем. SFC трактует значение SfcDllCacheDir (тип данных String), как путь к копии защищенных файлов. При этом путь может задаваться в формате UNC и содержать описание сетевого диска. При подготовке к проведению автоматической инсталляции можно указать в файле unattended.txt нужный путь. Но надо иметь в виду, что, прежде чем SFC реально обратится в каталог, заданный параметром SfcDllCacheDir, пользователь должен иметь права на чтение в этом каталоге. Когда SFC производит отмену внесенных изменений, то в первую очередь происходит обращение в каталог Dllcache за оригинальной копией измененного или удаленного системного файла.
Вслед за SfcInitializeDllLists процедура SfcInitProt вызывает функцию SfcBuildDirectoryWatchList. Задача этой функции состоит в том, чтобы каждый раз, когда будет происходить обращение к каталогу, содержащему защищенные файлы, служба SFC получала уведомление о модификации (change-notification). SfcBuildDirectoryWatchList открывает каждый такой каталог и оставляет открытым. В Windows 2000 любое приложение может запросить системное подтверждение для проведения изменений внутри данного каталога. Если бы такой возможности не было, то для контроля потенциальных изменений пришлось бы периодически анализировать файл за файлом в контролируемом каталоге. Чтобы оценить преимущество change-notification, нужно открыть один и тот же каталог в Windows Explorer и окне DOS (с командной строки), затем в окне DOS удалить или переименовать произвольный файл. Windows Explorer автоматически начнет выполнять обновление окна, чтобы проведенные в каталоге изменения были отражены и в его окне.
Если из параметра реестра SFCScan следует, что SFC должна выполнить сканирование системных файлов, то следующим шагом в процедуре инициализации службы SFC будет верификация файлов. Эту задачу выполняет функция SfcScanProtectedDlls. На основе списка контролируемых файлов, сформированных с помощью SfcInitializeDllLists, функция SfcValidateDLL выполняет обращение к каждому из них и проводит верификацию содержимого файла. В дальнейшем SFC обращается к функции SfcValidateDLL всякий раз, когда устанавливается факт изменения системных файлов.
Когда начальное сканирование (в общем случае необязательное) завершено, SFC запускает специальный поток защиты (watchdog thread). Этот поток находится в состоянии ожидания события change-notifications, относящегося к каталогам, где хранятся SFC-файлы. Когда система «сообщает» о том, что приложение произвело изменение одного или нескольких контролируемых файлов, данный поток вызывает функцию SfcValidateDLL для каждого такого изменения, и происходит возврат к оригинальным копиям файлов. SfcValidateDLL поочередно вызывает функцию SfcGetValidationData и SfcValidateFileSignature для измененных файлов. С их помощью устанавливается версия файла и проверяется его цифровая «подпись». Дополнительно проверяется факт верификации цифровой подписи для копии файла в каталоге Dllcache. На CD-ROM с Windows 2000 содержатся все SFC-файлы, а также соответствующие «подписи» от Microsoft. SfcValidateFileSignature использует несколько функций из состава CryptoAPI, среди которых есть такая, которая позволяет вычислить хэш-код файла. С помощью другой импортируемой функции SfcValidateFileSignature вычисляет ссылку на файл, содержащий цифровую «подпись» для данного файла.
Итак, SfcValidateFileSignature располагает и хэш-кодом, и ссылкой на catalog-файл. Вслед за этим выполняется вызов функции WinVerifyTrust — функции ядра Windows 2000 для верификации цифровой подписи. WinVerifyTrust на основе открытого ключа от VeriSign расшифровывает цифровую «подпись» и получает хэш-код catalog-файла «подписи». Выполняется сравнение хэш-кодов, и если они совпадают, то WinVerifyTrust регистрирует этот факт. Если файл поврежден, изменен или отсутствует, функция возвращает код ошибки, а SfcValidateFileSignature сообщает системе о сбое при проведении верификации сигнатур.
Проверяя «подписи» обоих файлов, того, который используется системой, и его оригинальной копии, SfcValidateDLL «узнает» произошло ли изменение. Если верификация оригинальной копии завершена с ошибкой, SFC необходимо восстановить архивную копию до того, как потребуется заменить файл, используемый системой в данный момент. Для определения пути к установочным файлам Windows 2000 (пути, откуда производилась инсталляция системы), служба SFC анализирует параметр реестра HKEY_LOCAL_MACHINESOFTWARE MicrosoftWindowsNTCurrentVersionSourcePath. В качестве источника архивных копий системных файлов может служить и установочный носитель, но, если он отсутствует (например, CD-ROM Windows 2000 не вставлен в устройство для чтения компакт-дисков), SFC предлагает предоставить этот носитель. Если же SFC не может установить местонахождение архивных файлов или если пользователь в ответ на запрос вставить носитель нажимает Cancel, то служба SFC не обновляет файл, и на экран выводится соответствующее сообщение (см. Экран 2). SFC использует функции SetupAPI (%systemroot%system32setupapi.dll), чтобы обнаружить и скопировать необходимые файлы с инсталляционного носителя.
ЭКРАН 2. Сообщение службы SFC. |
После того как функция SfcValidateDLL установила, что архивная копия в каталоге Dllcache отвечает всем предъявляемым требованиям или выполнено копирование архивного файла с установочного носителя, служба SFC выполняет восстановление измененного системного файла, используя архивную версию. При этом в системный журнал (System Event Log) производится запись о системном файле, который был модифицирован.
Иногда необходимо установить новые версии файлов, которые контролируются WFP, и Windows 2000 должна предоставить механизм для выполнения такой операции. Например, установка программных «заплаток» (hotfixes), пакетов обновлений, установка Windows 2000 в режиме Upgrade предполагает штатное обновление системных файлов. Поскольку эти программы изменяют системные файлы, т. е. файлы, «подписанные» Microsoft, следовательно, изменяются или добавляются соответствующие catalog-файлы и их сигнатуры. Изменения копируются поверх существующих версий. WFP обнаруживает эти изменения, но считает их правомочными, так как хэш-коды системных и catalog-файлов совпадают. В то же время WFP распознает, что хэш-коды обновленных файлов отличаются от хэш-кодов одноименных файлов во время самого последнего проведенного сканирования, и поэтому переписывает каталог Dllcache, заполняя его новыми файлами. После штатного обновления системных файлов необходима перезагрузка для того, чтобы внесенные изменения вступили в силу, и каждый компонент системы стал использовать новые версии файлов. Не существует никакого иного способа сообщить приложениям, что нужно работать с обновленными версиями системных файлов, кроме как перезагрузка системы в целом.
Специалисты Microsoft надеются, что благодаря WFP, который обеспечивает защиту системных файлов, пользователи не будут сталкиваться с неустойчивостью Windows 2000 по причине «библиотечного кошмара». Тем не менее не надо думать, что WFP — это своего рода «бронежилет» для системных файлов. Поскольку SFC имеет буфер ограниченного размера для фиксации изменений в контролируемом множестве файлов, существует опасность, что буфер может переполниться. Если это произойдет, SFC просто сбросит его содержимое. Или, например, если в каталоге %systemroot%system32 вдруг удаляются все системные файлы, то WFP будет не в состоянии произвести возврат к исходному состоянию, так как заранее неизвестно, что эти файлы удалены. В таком случае необходимо сканировать системные файлы с помощью утилиты sfc.exe с ключом /scannow или же воспользоваться опцией Repair, запустив программу установки Windows 2000 с CD-ROM для проведения перезаписи системных файлов.
Три угла атаки
Для решения проблем, связанных с обеспечением должной надежности новой системы, специалисты компании Microsoft сконцентрировала свои усилия в трех направлениях. Во-первых, как было рассказано в первой части настоящей статьи, в Windows 2000 реализованы новые механизмы для выявления и устранения возникающих проблем. Во-вторых, предприняты усилия по предотвращению несанкционированного «расползания» OC через системные файлы и драйверы. В заключительной части будет рассмотрен последний «угол атаки» на проблему надежности Windows 2000. Речь пойдет об инструментальных средствах разработчика, которые должны помочь программисту создавать более надежные драйверы устройств, а администратору системы — с высокой точностью локализовать проблемный драйвер.