DLL Ад
В вычислительной технике DLL Hell — это термин, обозначающий сложности, возникающие при работе с динамически подключаемыми библиотеками (DLL), используемыми в Microsoft Windows операционных системах . [1] особенно устаревшие 16-битные версии , которые работают в одном пространстве памяти.
DLL Hell может проявляться по-разному, при этом приложения не запускаются и не работают корректно.
DLL Hell — это специфичная для экосистемы Windows форма общей концепции ада зависимостей .
Проблемы
[ редактировать ]Microsoft DLL — это реализация общих библиотек . Общие библиотеки позволяют объединять общий код в оболочку, 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 происходит потому, что:
- В прошлом Microsoft распространяла библиотеки DLL среды выполнения как общие системные компоненты. [3] (первоначально C:\WINDOWS и C:\WINDOWS\SYSTEM) как способ эффективного совместного использования кода в ОС с общей памятью с ограниченным объемом оперативной памяти и дискового пространства. Следовательно, сторонние разработчики также распространяли их таким образом.
- Установщики приложений обычно выполняются в привилегированном контексте безопасности, который имеет доступ для установки DLL в системные каталоги и для редактирования системного реестра для регистрации новых DLL в качестве COM- объектов. Таким образом, плохо написанный или неправильно настроенный установщик может понизить системную библиотеку в устаревших версиях Windows, в которых защита файлов Windows или защита ресурсов Windows не откатывают изменения. В Windows Vista и более поздних версиях только учетная запись «доверенного установщика» может вносить изменения в основные библиотеки операционной системы.
- Приложениям Windows было разрешено включать обновления ОС в свои собственные программы установки. То есть многие библиотеки Microsoft DLL являются распространяемыми , а это означает, что приложения могут включать их, если им нужны услуги определенных библиотек.
- До появления Windows Installer установщики Windows исторически были коммерческими продуктами; многие люди пытались написать свои собственные установщики, игнорируя или неправильно решая проблемы с управлением версиями в процессе. [ нужна ссылка ]
- Некоторые среды разработки не добавляли автоматически ресурс версии в свои скомпилированные библиотеки, поэтому многие разработчики упускали из виду этот аспект. Проверка дат файлов, перезапись существующих файлов или пропуск операции копирования, если DLL уже установлена, были единственными доступными вариантами вместо правильного управления версиями. [ нужна ссылка ]
- Иногда сама ОС удаляла или заменяла библиотеки DLL более старыми или устаревшими версиями. Например, Windows 2000 устанавливала библиотеки DLL черно-белого принтера поверх DLL, поддерживающих цвет, если черно-белый принтер был установлен после цветного принтера. [4]
Неправильная регистрация COM
[ редактировать ]В COM и других частях Windows, до появления параллельных сборок без реестра, [5] Реестр . использовался для определения того, какую базовую DLL использовать Если была зарегистрирована другая версия модуля, то эта DLL будет загружена вместо ожидаемой. Этот сценарий может быть вызван конфликтом установок, в которых регистрируются разные версии одних и тех же библиотек, и в этом случае преимущественную силу будет иметь последняя установка.
Общие модули в памяти
[ редактировать ]16-разрядные версии Windows (и Windows в Windows ) загружают только один экземпляр любой библиотеки DLL; все приложения ссылаются на одну и ту же копию в памяти до тех пор, пока ни одно приложение не будет использовать ее и она не будет выгружена из памяти. (Для 32-битных и 64-битных версий Windows совместное использование процессов происходит только в том случае, когда разные исполняемые файлы загружают модуль из одного и того же каталога; код, но не стек, распределяется между процессами посредством процесса, называемого «отображение памяти». ) Таким образом, даже если нужная DLL находится в каталоге, где ее можно найти, например, в системном каталоге или каталоге приложения, ни один из этих экземпляров не будет использоваться, если другое приложение запустилось с несовместимой версией из третий каталог. Эта проблема может проявляться в виде 16-битной ошибки приложения, которая возникает только тогда, когда приложения запускаются в определенном порядке.
Отсутствие работоспособности
[ редактировать ]Прямой конфликт с проблемой топота DLL: если обновления DLL не затрагивают все приложения, которые ее используют, то становится намного сложнее «обслуживать» DLL, то есть устранять проблемы, существующие в текущих версиях DLL. . (Исправления безопасности — это особенно сложный и болезненный случай.) Вместо того, чтобы исправлять только последнюю версию DLL, в идеале разработчик должен внести свои исправления и проверить их на совместимость с каждой выпущенной версией DLL.
Причины
[ редактировать ]Несовместимость DLL была вызвана:
- Ограничения памяти в сочетании с отсутствием разделения пространства памяти процесса в 16-разрядных версиях Windows;
- Отсутствие принудительного стандартного управления версиями, именованиями и схемами расположения файловой системы для DLL;
- Отсутствие принудительного стандартного метода установки и удаления программного обеспечения ( управление пакетами );
- Отсутствие централизованной авторитетной поддержки управления и защиты двоичного интерфейса приложений DLL , что позволяет выпускать несовместимые библиотеки DLL с одинаковым именем файла и внутренними номерами версий;
- Упрощенные инструменты управления, предотвращающие идентификацию измененных или проблемных DLL пользователями и администраторами;
- Разработчики нарушают обратную совместимость функций в общих модулях;
- Microsoft выпускает внеочередные обновления для компонентов среды выполнения операционной системы;
- Неспособность более ранних версий Windows запускать одновременно конфликтующие версии одной и той же библиотеки;
- Опора на текущий каталог или
%PATH%
переменная среды, обе из которых меняются со временем и от системы к системе, для поиска зависимых DLL (вместо загрузки их из явно настроенного каталога); - Разработчики повторно используют ClassID из примеров приложений для COM-интерфейсов своих приложений вместо того, чтобы создавать свои собственные новые GUID .
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 (называемая Stomping DLL Microsoft « ») была несколько уменьшена с помощью 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-аду, некоторые из которых, возможно, придется использовать одновременно;некоторые другие функции, которые помогают смягчить проблему:
- Инструменты установки теперь включены в Microsoft Visual Studio , одну из основных сред разработки под Windows. Эти инструменты выполняют проверку версии перед установкой DLL и могут включать предопределенные установочные пакеты в установку .MSI. Это позволяет сторонним приложениям интегрировать обновления компонентов ОС без необходимости писать для этих компонентов собственные установщики.
- Восстановление системы может восстановить систему после неправильной установки, включая повреждение реестра. Хотя это не предотвращает проблему, но облегчает ее устранение.
- Каталог WinSxS ( Windows Side-by-Side ), который позволяет сосуществовать нескольким версиям одних и тех же библиотек.
- Запускайте 16-разрядные приложения в отдельном пространстве памяти в 32-разрядной версии Windows, чтобы позволить двум приложениям одновременно использовать конфликтующие версии одной и той же DLL.
- Используйте версию Windows, включающую защиту файлов Windows . Windows Me и Windows 2000 , выпущенные в 2000 году, поддерживают эту форму защиты системных файлов, равно как и Windows XP и Windows Server 2003 . Его замена, Windows Resource Protection , была представлена в Windows Vista и Windows Server 2008 и использует другой метод защиты системных файлов от изменения.
- COM без регистрации: в Windows XP появился новый режим регистрации COM-объектов, названный « COM без регистрации ». Эта функция позволяет приложениям, которым необходимо устанавливать объекты COM, хранить всю необходимую информацию реестра COM в собственном каталоге приложения, а не в глобальном системном реестре. Таким образом, он обеспечивает механизм одновременной регистрации нескольких версий одной и той же DLL несколькими приложениями (Microsoft называет это « параллельной сборкой »). [14] ). Ада DLL можно в значительной степени избежать, используя COM без регистрации, единственным ограничением является то, что для него требуется как минимум Windows XP или более поздние версии Windows, и его нельзя использовать для серверов EXE COM или общесистемных компонентов, таких как MDAC , MSXML , DirectX или Интернет Эксплорер .
- Поставка операционной системы с функциональной системой управления пакетами , которая способна отслеживать зависимости DLL, поощряя использование менеджера пакетов и препятствуя установке DLL вручную. Установщик Windows , входящий в состав Windows Me , Windows 2000 и всех более поздних версий, предоставляет эту функцию.
- Наличие центральной базы данных или полномочий для разрешения конфликтов DLL и распространения программного обеспечения. Изменения в библиотеке могут быть отправлены в этот орган; таким образом, он может гарантировать сохранение совместимости в разрабатываемых ветках. Если какое-то старое программное обеспечение несовместимо с текущей библиотекой, орган власти может предоставить для него интерфейс совместимости или объединить старую версию в отдельный пакет.
- Если разработчикам программного обеспечения необходимо настроить библиотеку и если основной выпуск библиотеки вряд ли будет включать необходимые им изменения, они могут отправить настроенную DLL для частного использования программы (обычно путем размещения ее в частном каталоге программы) или статически связать ее с программу против настроенной библиотеки.
- Хотя библиотеки DLL лучше всего подходят для модульной организации приложений и компонентов системы, а также в качестве сторонних библиотек, их использование не является обязательным во всех случаях в современных системах, где память больше не является ограничением. Например, если приложению нужна библиотека, которая больше нигде не будет использоваться, ее можно скомпоновать статически, без потери места и с выигрышем в скорости.
- Windows Vista и более поздние версии используют специальную службу TrustedInstaller для установки файлов операционной системы. Другие учетные записи пользователей, включая СИСТЕМУ, не имеют доступа к перезаписи основных двоичных файлов системы. Windows 7 расширяет эту функциональность на некоторые важные части реестра.
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ «Как избежать ада DLL: введение метаданных приложения в Microsoft .NET Framework» . Майкрософт. Октябрь 2000 года.
- ^ «Сводка статей о CTL3D.DLL в базе знаний службы поддержки Microsoft» . Майкрософт.
- ^ Распространение общего компонента среды выполнения C в Visual C++ 2005 и Visual C++ .NET .
- ^ KB 830490: Принтер HP Color LaserJet печатает только в оттенках серого или в черно-белом режиме на компьютере под управлением Windows 2000 SP4 .
- ^ Лесли Мюллер; Стив Уайт (июль 2005 г.). «Активация COM-компонентов без регистрации: пошаговое руководство» . Майкрософт .
- ^ «Безопасная загрузка библиотек для предотвращения атак с предварительной загрузкой DLL» . Майкрософт. 11 июня 2011 г. Проверено 19 июля 2011 г.
- ^ Пфайффер, Тим (1 июня 1998 г.). «Библиотеки DLL Windows: угроза или угроза?» . Журнал доктора Добба. Архивировано из оригинала 7 августа 2010 г. Проверено 7 июля 2010 г.
- ^ Защита файлов Windows и Windows .
- ^ Jump up to: а б Андерсон, Рик (11 января 2000 г.). «Конец ада DLL» . microsoft.com. Архивировано из оригинала 5 июня 2001 г. Проверено 7 июля 2010 г.
- ^ «Реализация параллельного совместного использования компонентов в приложениях (расширенное)» . Майкрософт. Архивировано из оригинала 10 декабря 2006 года . Проверено 3 января 2013 г.
- ^ «Как мне поделиться данными в моей DLL с приложением или с другими DLL?» . Майкрософт . Проверено 11 ноября 2008 г.
- ^ «Безопасная загрузка библиотек для предотвращения атак с предварительной загрузкой DLL» . Майкрософт . Проверено 16 февраля 2013 г.
- ^ Параллельные сборки (Windows)
Внешние ссылки
[ редактировать ]- Как выбраться из ада DLL на Microsoft TechNet
- Упрощение развертывания и решение ада DLL с помощью .NET Framework на MSDN
- Как избежать ада DLL: введение метаданных приложения в Microsoft .NET Framework , Мэтт Питрек
- Доктор Добб о DLL Hell (подробности на LoadLibraryEx)
- Джоэл об обсуждении программного обеспечения. Архивировано 30 октября 2018 г. на Wayback Machine.
- Статья об аде DLL