stringtranslate.com

DLL Ад

В вычислительной технике DLL Hell — это термин, обозначающий сложности, возникающие при работе с динамически подключаемыми библиотеками (DLL), используемыми в операционных системах Microsoft Windows , [1] особенно в устаревших 16-разрядных версиях , которые все работают в одном пространстве памяти.

DLL Hell может проявляться по-разному, при этом приложения не запускаются и не работают корректно.

DLL Hell — это специфичная для экосистемы Windows форма общей концепции ада зависимостей .

Проблемы

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

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

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

С DLL обычно возникает несколько проблем, особенно после того, как в системе было установлено и удалено множество приложений. К трудностям относятся конфликты между версиями DLL, трудности с получением необходимых DLL и наличие большого количества ненужных копий DLL.

Решения этих проблем были известны еще в то время, когда Microsoft писала систему DLL . Они были включены в замену .NET «Сборки».

Несовместимые версии

Определенная версия библиотеки может быть совместима с некоторыми программами, использующими ее, и несовместима с другими. Windows особенно уязвима к этому из-за акцента на динамическом связывании библиотек C++ и объектов связывания и внедрения объектов (OLE). Классы C++ экспортируют множество методов, и одно изменение в классе, например новый виртуальный метод, может сделать его несовместимым с программами, созданными на основе более ранней версии. У связывания и внедрения объектов есть очень строгие правила, предотвращающие это: интерфейсы должны быть стабильными, а менеджеры памяти не являются общими. Однако этого недостаточно, поскольку семантика класса может измениться. Исправление ошибки в одном приложении может привести к удалению функции из другого. До Windows 2000 Windows была уязвима для этого, поскольку таблица классов COM была общей для всех пользователей и процессов. Только один COM-объект в одной DLL/EXE может быть объявлен как имеющий определенный глобальный идентификатор COM-класса в системе. Если какой-либо программе требовалось создать экземпляр этого класса, она получала текущую централизованно зарегистрированную реализацию. В результате установка программы, устанавливающей новую версию общего объекта, может непреднамеренно привести к поломке других программ, которые были установлены ранее.

топчание DLL

Распространенная и неприятная проблема возникает, когда недавно установленная программа перезаписывает рабочую системную DLL более ранней несовместимой версией. Ранними примерами этого были библиотеки ctl3d.dllи ctl3dv2.dllдля Windows 3.1 : библиотеки, созданные Microsoft, которые сторонние издатели распространяли вместе со своим программным обеспечением, но каждая из них распространяла версию, которую они разработали, а не самую последнюю версию. [2] Удаление DLL происходит по следующим причинам:

Неправильная регистрация COM

В COM и других частях Windows, до появления параллельных сборок без реестра, [ 5] реестр использовался для определения того, какую базовую DLL использовать. Если была зарегистрирована другая версия модуля, то эта DLL будет загружена вместо ожидаемой. Этот сценарий может быть вызван конфликтом установок, в которых регистрируются разные версии одних и тех же библиотек, и в этом случае преимущественную силу будет иметь последняя установка.

Общие модули в памяти

16-разрядные версии Windows (и Windows в Windows ) загружают только один экземпляр любой библиотеки DLL; все приложения ссылаются на одну и ту же копию в памяти до тех пор, пока ни одно приложение не будет использовать ее и она не будет выгружена из памяти. (Для 32-битных и 64-битных версий Windows совместное использование процессов происходит только тогда, когда разные исполняемые файлы загружают модуль из одного и того же каталога; код, но не стек, совместно используется между процессами посредством процесса, называемого «отображение памяти». ) Таким образом, даже если желаемая DLL находится в каталоге, где ее можно ожидать, например, в системном каталоге или каталоге приложения, ни один из этих экземпляров не будет использоваться, если другое приложение запустилось с несовместимой версией из третий каталог. Эта проблема может проявляться в виде 16-битной ошибки приложения, которая возникает только тогда, когда приложения запускаются в определенном порядке.

Отсутствие работоспособности

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

Причины

Несовместимость DLL была вызвана:

DLL Hell был очень распространенным явлением в версиях операционных систем Microsoft до Windows NT. Основная причина заключалась в том, что 16-битные операционные системы не ограничивали процессы своим собственным пространством памяти, тем самым не позволяя им загружать свою собственную версию общий модуль, с которым они были совместимы. Ожидалось, что установщики приложений будут добросовестными гражданами и проверят информацию о версии DLL, прежде чем перезаписывать существующие системные DLL. Стандартные инструменты для упрощения развертывания приложений (которое всегда включает доставку зависимых библиотек DLL операционной системы) были предоставлены Microsoft и другими сторонними поставщиками инструментов. Microsoft даже требовала от поставщиков приложений использовать стандартный установщик и проверять правильность работы своих программ установки, прежде чем им будет разрешено использование логотипа Microsoft. Подход добросовестного установщика не решил проблему, поскольку рост популярности Интернета предоставил больше возможностей для получения несоответствующих приложений.

Использование вредоносным ПО

Неопределенность, с которой неполные библиотеки DLL могут загружаться в операционную систему Windows, в последние годы использовалась вредоносными программами [ когда? ] , открывая новый класс уязвимостей, которые затрагивают приложения многих поставщиков программного обеспечения, а также саму Windows. [6]

Решения

За прошедшие годы были решены или смягчены различные формы ада DLL.

Статическая связь

Простое решение DLL-ада в приложении — статически слинковать все библиотеки, т.е. включить в программу нужную версию библиотеки, а не подхватывать системную библиотеку с заданным именем. [7] Это часто встречается в приложениях C/C++, где вместо того, чтобы беспокоиться о том, какая версия MFC42.DLLустановлена, приложение компилируется для статической компоновки с теми же библиотеками. Это полностью исключает использование DLL и возможно в автономных приложениях с использованием только библиотек, которые предлагают статическую опцию, как это делает библиотека классов Microsoft Foundation . Однако основная цель DLL – совместное использование библиотек времени выполнения между программами для уменьшения накладных расходов на память – приносится в жертву; дублирование библиотечного кода в нескольких программах приводит к раздуванию программного обеспечения и усложняет развертывание исправлений безопасности или новых версий зависимого программного обеспечения.

Защита файлов Windows

Проблема перезаписи DLL (называемая Microsoft «Stomping DLL» ) была несколько уменьшена с помощью Windows File Protection (WFP), [8] , которая была представлена ​​в Windows 2000 . [9] Это предотвращает перезапись системных DLL неавторизованными приложениями, если только они не используют специальные API-интерфейсы Windows , которые разрешают это. По-прежнему может существовать риск того, что обновления от Microsoft будут несовместимы с существующими приложениями, но в текущих версиях Windows этот риск обычно снижается за счет использования параллельных сборок .

Сторонние приложения не могут вмешиваться в файлы ОС, если они не включают законные обновления Windows в свой установщик или если они не отключают службу защиты файлов Windows во время установки, а в Windows Vista или более поздней версии также не берут на себя ответственность за системные файлы и не предоставляют себе доступ. Утилита SFC может отменить эти изменения в любое время.

Одновременный запуск конфликтующих DLL

Решения здесь состоят в том, чтобы иметь разные копии одних и тех же DLL для каждого приложения как на диске, так и в памяти.

Простое ручное решение конфликтов заключалось в размещении разных версий проблемной DLL в папках приложений, а не в общей общесистемной папке. Обычно это работает, если приложение является 32-битным или 64-битным и DLL не использует общую память. В случае 16-битных приложений два приложения не могут выполняться одновременно на 16-битной платформе или на одной и той же 16-битной виртуальной машине в 32-битной операционной системе. OLE препятствовал этому до Windows 98 SE/2000, поскольку более ранние версии Windows имели единый реестр COM-объектов для всех приложений.

В Windows 98 SE/2000 появилось решение, называемое параллельной сборкой [10] , которое загружает отдельные копии DLL для каждого приложения, которому они требуются (и, таким образом, позволяет приложениям, которым требуются конфликтующие DLL, запускаться одновременно). Этот подход устраняет конфликты, позволяя приложениям загружать уникальные версии модуля в свое адресное пространство, сохраняя при этом основное преимущество совместного использования DLL между приложениями (т. е. сокращение использования памяти) за счет использования методов сопоставления памяти для совместного использования общего кода между различными процессами, которые все еще выполняют операции. используйте тот же модуль. Однако библиотеки DLL, использующие общие данные между несколькими процессами, не могут использовать этот подход. [11] Одним из негативных побочных эффектов является то, что потерянные экземпляры DLL не могут обновляться во время автоматизированных процессов.

Портативные приложения

В зависимости от архитектуры приложения и среды выполнения переносимые приложения могут быть эффективным способом решения некоторых проблем с DLL, поскольку каждая программа объединяет свои собственные частные копии любых необходимых ей DLL. [9] Этот механизм основан на том, что приложения не полностью определяют пути к зависимым DLL при их загрузке, а операционная система ищет каталог исполняемого файла перед любым общим местоположением. [12] Однако этот метод также может быть использован вредоносным ПО, [13] и повышенная гибкость может также достигаться за счет безопасности, если частные библиотеки DLL не обновляются с помощью исправлений безопасности так же, как и общие библиотеки. .

Виртуализация приложений также может позволить приложениям запускаться в «пузыре», что позволяет избежать установки файлов DLL непосредственно в операционную систему.

Другие контрмеры

Существуют и другие меры противодействия DLL-аду, некоторые из которых, возможно, придется использовать одновременно; некоторые другие функции, которые помогают смягчить проблему:

Смотрите также

Рекомендации

  1. ^ «Как избежать ада DLL: введение метаданных приложения в Microsoft .NET Framework» . Майкрософт. Октябрь 2000 года.
  2. ^ «Краткий обзор статей CTL3D.DLL в базе знаний службы поддержки Microsoft» . Майкрософт.
  3. ^ Распространение общего компонента среды выполнения C в Visual C++ 2005 и Visual C++ .NET.
  4. ^ KB 830490: Принтер HP Color LaserJet печатает только в оттенках серого или в черно-белом режиме на компьютере под управлением Windows 2000 SP4.
  5. ^ Лесли Мюллер; Стив Уайт (июль 2005 г.). «Активация COM-компонентов без регистрации: пошаговое руководство». Майкрософт .
  6. ^ «Безопасная загрузка библиотек для предотвращения атак с предварительной загрузкой DLL» . Майкрософт. 11 июня 2011 г. Проверено 19 июля 2011 г.
  7. ^ Пфайффер, Тим (1 июня 1998 г.). «Библиотеки DLL Windows: угроза или угроза?». Журнал доктора Добба. Архивировано из оригинала 7 августа 2010 г. Проверено 7 июля 2010 г.
  8. ^ Защита файлов Windows и Windows.
  9. ^ Аб Андерсон, Рик (11 января 2000 г.). «Конец ада DLL». microsoft.com. Архивировано из оригинала 5 июня 2001 г. Проверено 7 июля 2010 г.
  10. ^ «Реализация параллельного совместного использования компонентов в приложениях (расширенная)» . Майкрософт. Архивировано из оригинала 10 декабря 2006 года . Проверено 3 января 2013 г.
  11. ^ «Как мне поделиться данными в моей DLL с приложением или с другими DLL?». Майкрософт . Проверено 11 ноября 2008 г.
  12. ^ Деситтер, Арно (15 июня 2007 г.). «Использование статических и общих библиотек на разных платформах; строка 9: путь к библиотеке». АрноРецепты. Архивировано из оригинала 1 июня 2008 г. Проверено 7 июля 2010 г.
  13. ^ «Безопасная загрузка библиотек для предотвращения атак с предварительной загрузкой DLL» . Майкрософт . Проверено 16 февраля 2013 г.
  14. ^ Параллельные сборки (Windows)

Внешние ссылки