понедельник, 21 декабря 2009 г.

Но кто такие KnownDLLs?

Это перевод What are KnownDLLs anyway? Автор: Ларри Остерман.

В моём предыдущем посте о DLL и их работе, я упомянул, что winmm.dll была KnownDLL ("Известные DLL") в Longhorn. Кажется, это баг в существующих KnownDLL. Но что, чёрт возьми, такое, эти Known DLLs?

Ну, кажется, у нас есть статья в KB, которую я прорезюмирую.

KnownDLL - это механизм в Windows NT (и Win9x), который позволяет системе “кэшировать” часто используемые системные DLL. Изначально он был добавлен для ускорения времени загрузки приложений, но он также может рассматриваться как механизм безопасности, поскольку он не даёт людям пользоваться слабыми правами на папки приложений и кидать троянские версии системных библиотек в них (поскольку все ключевые системные DLL являются KnownDLLs, то версия библиотеки в папке с приложением будет игнорирована). Как механизм безопасности он не особенно силён (если вам разрешена запись в папку с программой, то вы можете создать и другие формы хаоса), но он всё же может рассматриваться как механизм безопасности.

Если вы помните из моего предыдущего поста, то когда загрузчик находит запись об импорте из DLL в исполняемом файле, он открывает файл и пытается спроецировать его в память. Ну, это не СОВСЕМ так. Фактически, прежде чем это случится, загрузчик ОС ищет существующую секцию (имеется ввиду типа MMF), называемую \KnownDlls\<имя-файла-DLL>. Если эта секция существует, то вместо открытия файла загрузчик просто использует указанную секцию. Затем он следует всем “обычным” правилам для загрузки DLL.

Когда система загружается, она смотрит в реестре на путь HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\KnownDLLs и создаёт секции \KnownDlls\<имя-файла-DLL> для каждой DLL, перечисленной под этим ключом реестра.

Если вы сравните ключ HKLM\System\CCS\Control\Session Manager\KnownDLLs с секциями под \KnownDlls (используя просмотрщик типа WinObj), то вы заметите, что контейнер \KnownDlls всегда содержит больше записей, чем ключ реестра. Это потому что секции в \KnownDlls получаются как транзитивное замыкание DLL, перечисленных в KnownDLLs. Т.е. если DLL указана в KnownDLLs, то все DLL, которые статически связаны с ней, ТАКЖЕ перечисляются в секциях \KnownDlls.

Кроме того, если вы посмотрите на ключ реестра KnownDLLs, то вы увидите, что там не указываются пути поиска. Это потому что все KnownDLLs предполагаются размещёнными в папке, указанной в ключе реестра HKLM\System\CCS\Control\KnownDLLs\DllDirectory. И снова, этот аспект KnownDLLs является механизмом безопасности – требуя, чтобы все KnownDLLs лежали в одной папке, мы делаем сложнее внедрение троянской версии DLL одной из KnownDLLs.

Ах, и если загрузка KnownDLLs вызывает какие-то проблемы, или вы, по какой-то причине, не хотите чтобы система грузила DLL как KnownDll, то вы можете установить исключение в ключе HKLM\System\CCS\Control\Session Manager\ExcludeFromKnownDlls. Так что в моём примере, пока баг в существующих KnownDLLs не исправили, я просто добавил winmm.dll в мой список ExcludeFromKnownDlls.

Читать далее.

Комментариев нет:

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

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.