stringtranslate.com

Динамически подключаемая библиотека

Динамически подключаемая библиотека ( DLL ) — это общая библиотека в операционной системе Microsoft Windows или OS/2 .

DLL может содержать исполняемый код (функции), данные и ресурсы в любой комбинации.

Расширения файлов

Файл DLL часто имеет расширение файла .dll , но может иметь любое расширение файла. Разработчики могут выбрать использование расширения файла, которое описывает содержимое файла, например, .ocxдля элементов управления ActiveX и .drvдля устаревшего драйвера устройства .

DLL, которая содержит только ресурсы, можно назвать ресурсной DLL . Примерами служат библиотека иконок , иногда имеющая расширение .icl, и библиотека шрифтов , имеющая расширения .fonи .fot. [1]

Формат файла

Формат файла DLL такой же, как и у исполняемого файла (т. н. EXE ), но разные версии Windows используют разные форматы. 32- и 64-разрядные версии Windows используют Portable Executable (PE), а 16-разрядные версии Windows используют New Executable (NE).

Главное различие между DLL и EXE заключается в том, что DLL не может быть запущена напрямую, поскольку операционной системе требуется точка входа для начала выполнения. Windows предоставляет служебную программу (RUNDLL.EXE/RUNDLL32.EXE) для выполнения функции, предоставляемой DLL.

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

Фон

Первые версии Microsoft Windows запускали программы вместе в одном адресном пространстве . Каждая программа должна была взаимодействовать, уступая процессор другим программам, чтобы графический пользовательский интерфейс (GUI) мог выполнять несколько задач одновременно и быть максимально отзывчивым. Все операции на уровне операционной системы предоставлялись базовой операционной системой: MS-DOS . Все службы более высокого уровня предоставлялись библиотеками Windows «Dynamic Link Library». API рисования , интерфейс графических устройств (GDI), был реализован в DLL под названием GDI.EXE, пользовательский интерфейс в USER.EXE. Эти дополнительные слои поверх DOS должны были быть общими для всех запущенных программ Windows, не только для того, чтобы Windows могла работать на машине с объемом оперативной памяти менее мегабайта, но и для того, чтобы программы могли взаимодействовать друг с другом. Код в GDI должен был преобразовывать команды рисования в операции на определенных устройствах. На дисплее он должен был манипулировать пикселями в буфере кадра. При рисовании на принтере вызовы API должны были преобразовываться в запросы к принтеру. Хотя можно было бы обеспечить жестко запрограммированную поддержку для ограниченного набора устройств (например, цветного графического адаптера дисплея, языка команд принтера HP LaserJet ), Microsoft выбрала другой подход. GDI работал бы, загружая различные фрагменты кода, называемые « драйверами устройств », для работы с различными устройствами вывода.

Та же архитектурная концепция, которая позволяла GDI загружать различные драйверы устройств, также позволяла оболочке Windows загружать различные программы Windows, а этим программам — вызывать вызовы API из общих библиотек USER и GDI. Эта концепция называлась «динамическим связыванием».

В обычной неразделяемой статической библиотеке разделы кода просто добавляются к вызывающей программе, когда ее исполняемый файл создается на этапе «связывания»; если две программы вызывают одну и ту же процедуру, процедура включается в обе программы на этапе связывания двух. При динамическом связывании общий код помещается в один отдельный файл. Программы, вызывающие этот файл, подключаются к нему во время выполнения, причем операционная система (или, в случае ранних версий Windows, расширение ОС) выполняет связывание.

Для ранних версий Windows (с 1.0 по 3.11) библиотеки DLL были основой всего графического интерфейса пользователя. Таким образом, драйверы дисплея были просто библиотеками DLL с расширением .DRV, которые предоставляли пользовательские реализации одного и того же API рисования через унифицированный интерфейс драйвера устройства (DDI), а API рисования (GDI) и графического интерфейса пользователя (USER) были просто вызовами функций, экспортируемыми GDI и USER, системными библиотеками DLL с расширением .EXE.

Эта идея построения операционной системы из набора динамически загружаемых библиотек является основной концепцией Windows, которая сохраняется с 2015 года . DLL предоставляют стандартные преимущества общих библиотек , такие как модульность . Модульность позволяет вносить изменения в код и данные в одной автономной DLL, совместно используемой несколькими приложениями, без каких-либо изменений в самих приложениях.

Другим преимуществом модульности является использование общих интерфейсов для подключаемых модулей. Можно разработать единый интерфейс, который позволяет бесшовно интегрировать старые и новые модули во время выполнения в уже существующие приложения без каких-либо изменений самого приложения. Эта концепция динамической расширяемости доведена до крайности в Component Object Model , основе ActiveX .

В Windows 1.x, 2.x и 3.x все приложения Windows совместно использовали одно и то же адресное пространство, а также одну и ту же память. DLL загружалась в это адресное пространство только один раз; с этого момента все программы, использующие библиотеку, обращались к ней. Данные библиотеки были общими для всех программ. Это могло использоваться как косвенная форма межпроцессного взаимодействия или могло случайно повредить разные программы. С появлением 32-разрядных библиотек в Windows 95 каждый процесс выполнялся в своем собственном адресном пространстве. Хотя код DLL может быть общим, данные являются частными, за исключением случаев, когда общие данные явно запрашиваются библиотекой. Тем не менее, большие части Windows 95 , Windows 98 и Windows Me были построены из 16-разрядных библиотек, что ограничивало производительность микропроцессора Pentium Pro при запуске и, в конечном счете, ограничивало стабильность и масштабируемость версий Windows на базе DOS.

Ограничения

Хотя технология DLL является основой архитектуры Windows, у нее есть недостатки.

DLL-ад

DLL hell описывает плохое поведение приложения при использовании неправильной версии DLL. [2] Стратегии смягчения включают:

Общее пространство памяти

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

Функции

Возможность модернизации

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

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

Управление памятью

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

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

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

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

Импорт библиотек

Как и статические библиотеки, библиотеки импорта для DLL отмечены .libрасширением файла. Например, kernel32.dll , основная динамическая библиотека для базовых функций Windows, таких как создание файлов и управление памятью, связана через . Обычный способ отличить библиотеку импорта от настоящей статической библиотеки — по размеру: библиотека импорта намного меньше, так как содержит только символы, ссылающиеся на фактическую DLL, которая должна быть обработана во время компоновки. Тем не менее, обе являются файлами формата kernel32.libUnix ar .

Связывание с динамическими библиотеками обычно осуществляется путем связывания с библиотекой импорта при построении или связывании для создания исполняемого файла. Созданный исполняемый файл затем содержит таблицу адресов импорта (IAT), с помощью которой ссылаются на все вызовы функций DLL (каждая ссылаемая функция DLL содержит свою собственную запись в IAT). Во время выполнения IAT заполняется соответствующими адресами, которые указывают непосредственно на функцию в отдельно загруженной DLL. [3]

В Cygwin/MSYS и MinGW библиотекам импорта традиционно присваивается суффикс .dll.a, объединяющий как суффикс Windows DLL, так и суффикс Unix ar. Формат файла похож, но символы, используемые для обозначения импорта, отличаются ( _head_foo_dllvs __IMPORT_DESCRIPTOR_foo). [4] Хотя его инструментарий GNU Binutils может генерировать библиотеки импорта и ссылаться на них, быстрее ссылаться на DLL напрямую. [5] Экспериментальный инструмент в MinGW под названием genlib можно использовать для генерации библиотек импорта с символами в стиле MSVC.

Разрешение и привязка символов

Каждая функция, экспортируемая DLL, идентифицируется числовым порядковым номером и, опционально, именем. Аналогично, функции могут быть импортированы из DLL либо по порядковому номеру, либо по имени. Порядковый номер представляет собой положение указателя адреса функции в таблице адресов экспорта DLL. Обычно внутренние функции экспортируются только по порядковому номеру. Для большинства функций Windows API в разных выпусках Windows сохраняются только имена; порядковые номера могут меняться. Таким образом, невозможно надежно импортировать функции Windows API по их порядковым номерам.

Импорт функций по порядковому номеру обеспечивает лишь немного лучшую производительность, чем импорт по имени: экспортные таблицы DLL упорядочены по имени, поэтому для поиска функции можно использовать двоичный поиск . Индекс найденного имени затем используется для поиска порядкового номера в таблице Export Ordinal. В 16-разрядной Windows таблица имен не сортировалась, поэтому накладные расходы на поиск имени были гораздо более заметны.

Также возможно привязать исполняемый файл к определенной версии DLL, то есть разрешить адреса импортируемых функций во время компиляции. Для связанных импортов компоновщик сохраняет временную метку и контрольную сумму DLL, к которой привязан импорт. Во время выполнения Windows проверяет, используется ли та же версия библиотеки, и если да, Windows обходит обработку импорта. В противном случае, если библиотека отличается от той, к которой была привязана, Windows обрабатывает импорт обычным способом.

Связанные исполняемые файлы загружаются несколько быстрее, если они запущены в той же среде, для которой они были скомпилированы, и точно в то же время, если они запущены в другой среде, поэтому нет никаких недостатков в связывании импортов. Например, все стандартные приложения Windows привязаны к системным DLL-файлам соответствующего выпуска Windows. Хорошая возможность связать импорты приложения с его целевой средой — во время установки приложения. Это сохраняет библиотеки «связанными» до следующего обновления ОС. Однако это изменяет контрольную сумму исполняемого файла, поэтому это нельзя сделать с подписанными программами или программами, которые управляются инструментом управления конфигурацией, использующим контрольные суммы (например, контрольные суммы MD5 ) для управления версиями файлов. Поскольку более поздние версии Windows отошли от фиксированных адресов для каждой загруженной библиотеки (из соображений безопасности), возможность и ценность связывания исполняемого файла уменьшаются.

Явное связывание во время выполнения

Файлы DLL могут быть явно загружены во время выполнения, этот процесс Microsoft называет просто динамическим связыванием во время выполненияLoadLibrary , с помощью функции API (или LoadLibraryEx). GetProcAddressФункция API используется для поиска экспортированных символов по имени и FreeLibrary– для выгрузки DLL. Эти функции аналогичны dlopen, dlsym, и dlcloseв стандартном API POSIX .

Процедура явного связывания во время выполнения одинакова в любом языке, поддерживающем указатели на функции , поскольку она зависит от API Windows , а не от языковых конструкций.

Отложенная загрузка

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

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

Вопросы компилятора и языка

Дельфи

В исходном файле libraryвместо program. В конце файла в предложении перечислены экспортируемые функции exports.

Delphi не нужны LIBфайлы для импорта функций из DLL; для присоединения к DLL externalв объявлении функции используется ключевое слово для обозначения имени DLL, за которым следует nameимя символа (если он отличается) или indexдля идентификации индекса.

Microsoft Visual Basic

В Visual Basic (VB) поддерживается только связывание во время выполнения; но в дополнение к использованию LoadLibraryфункций GetProcAddressAPI разрешены объявления импортированных функций.

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

При создании DLL в VB IDE позволяет создавать только ActiveX DLL, однако были созданы методы [7] , позволяющие пользователю явно указать компоновщику включить файл .DEF, который определяет порядковую позицию и имя каждой экспортируемой функции. Это позволяет пользователю создавать стандартную Windows DLL с помощью Visual Basic (версии 6 или ниже), на которую можно ссылаться с помощью оператора «Declare».

С и С++

Microsoft Visual C++ (MSVC) предоставляет несколько расширений для стандартного C++ , которые позволяют указывать функции как импортируемые или экспортируемые непосредственно в коде C++; они были приняты другими компиляторами Windows C и C++, включая версии GCC для Windows . Эти расширения используют атрибут __declspecперед объявлением функции. Обратите внимание, что когда функции C доступны из C++, они также должны быть объявлены как extern "C"в коде C++, чтобы сообщить компилятору, что следует использовать связь C. [8]

Помимо указания импортируемых или экспортируемых функций с помощью __declspecатрибутов, они могут быть перечислены в разделе IMPORT или EXPORTS файла, DEFиспользуемого проектом. DEFФайл обрабатывается компоновщиком, а не компилятором, и поэтому он не является специфичным для C++.

Компиляция DLL создаст DLLи LIBфайлы, и . LIBФайл (библиотека импорта) используется для связывания с DLL во время компиляции; он не является необходимым для связывания во время выполнения. Если DLL не является сервером Component Object Model (COM), DLLфайл должен быть помещен в один из каталогов, перечисленных в переменной среды PATH, в системный каталог по умолчанию или в тот же каталог, что и программа, использующая его. DLL сервера COM регистрируются с помощью regsvr32.exe, который помещает местоположение DLL и ее глобальный уникальный идентификатор ( GUID ) в реестр. Затем программы могут использовать DLL, ища ее GUID в реестре, чтобы найти ее местоположение или создать экземпляр объекта COM косвенно, используя его идентификатор класса и идентификатор интерфейса.

Примеры программирования

Использование импорта DLL

В следующих примерах показано, как использовать привязки, специфичные для языка, для импорта символов для связывания с DLL во время компиляции.

Дельфи

{$APPTYPE КОНСОЛЬ}Пример программы ; // импортируем функцию, которая складывает два числа function AddNumbers ( a , b : Double ) : Double ; StdCall ; external 'Example.dll' ;        // основная программа var R : Double ;  begin R := AddNumbers ( 1 , 2 ) ; Writeln ( 'Результат: ' , R ) ; end .      

С

Файл 'Example.lib' должен быть включен (предполагая, что Example.dll сгенерирован) в проект перед статической компоновкой. Файл 'Example.lib' автоматически генерируется компилятором при компиляции DLL. Невыполнение приведенного выше оператора приведет к ошибке компоновки, поскольку компоновщик не будет знать, где найти определение AddNumbers. Файл DLL 'Example.dll' также может быть скопирован в место, где будет сгенерирован файл .exe, с помощью следующего кода:

#include <windows.h> #include <stdio.h>  // Импортируем функцию, которая складывает два числа extern "C" __declspec ( dllimport ) double AddNumbers ( double a , double b );       int main ( int argc , char * argv []) { double result = AddNumbers ( 1 , 2 ); printf ( "Результат: %f \n " , result ); return 0 ; }             

Использование явного связывания во время выполнения

В следующих примерах показано, как использовать возможности загрузки и связывания во время выполнения с использованием языковых привязок API Windows.

Обратите внимание, что все четыре примера уязвимы для атак предварительной загрузки DLL, поскольку example.dll может быть разрешен в место, непреднамеренное автором (если явно не исключено, что каталог приложения идет до местоположений системной библиотеки, и без HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode[9] или HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\CWDIllegalInDLLSearch[10] текущий рабочий каталог ищется до каталогов системной библиотеки), и, таким образом, во вредоносную версию библиотеки. См. ссылку на руководство Microsoft по безопасной загрузке библиотеки: следует использовать SetDefaultDllDirectoriesin kernel32для удаления как каталога приложения, так и текущего рабочего каталога из пути поиска DLL, или использовать SetDllDirectoryWin kernel32для удаления текущего рабочего каталога из пути поиска DLL. [11]

Microsoft Visual Basic

Параметр Явное объявление Функция AddNumbers Lib "Example.dll" _ ( ByVal a As Double , ByVal b As Double ) As Double               Sub Main () Dim Result As Double Result = AddNumbers ( 1 , 2 ) Debug . Print "Результат был: " & Result End Sub           

Дельфи

Пример программы ; {$APPTYPE CONSOLE} использует Windows ; var AddNumbers : function ( a , b : integer ) : Double ; StdCall ; LibHandle : HMODULE ; begin LibHandle := LoadLibrary ( 'example.dll' ) ; if LibHandle <> 0 then AddNumbers := GetProcAddress ( LibHandle , 'AddNumbers' ) ; if Assigned ( AddNumbers ) then Writeln ( '1 + 2 = ' , AddNumbers ( 1 , 2 ) ) ; Readln ; end .                                   

С

#include <windows.h> #include <stdio.h>  // Сигнатура функции DLL typedef double ( * importFunction )( double , double );   int main ( int argc , char ** argv ) { importFunction addNumbers ; double result ; HINSTANCE hinstLib ;       // Загрузить файл DLL hinstLib = LoadLibrary ( TEXT ( "Example.dll" )); if ( hinstLib == NULL ) { printf ( "ОШИБКА: невозможно загрузить DLL \n " ); return 1 ; }       // Получить указатель на функцию addNumbers = ( importFunction ) GetProcAddress ( hinstLib , "AddNumbers" ); if ( addNumbers == NULL ) { printf ( "ОШИБКА: не удалось найти функцию DLL \n " ); FreeLibrary ( hinstLib ); return 1 ; }         // Вызываем функцию. result = addNumbers ( 1 , 3 );   // Выгрузить файл DLL FreeLibrary ( hinstLib );// Отобразить результат printf ( "Результат: %f \n " , result ); вернуть 0 ; } 

Питон

Привязка Python ctypes будет использовать API POSIX в системах POSIX.

импорт  ctypesmy_dll  =  ctypes . компакт-диск . LoadLibrary ( "Example.dll" )# Следующая спецификация метода "restype" необходима для того, чтобы Python понял, какой тип возвращается функцией. my_dll . AddNumbers . restype  =  ctypes . c_doublep  =  my_dll.AddNumbers ( ctypes.c_double ( 1.0 ) , ctypes.c_double ( 2.0 ) ) print ( "Результат:" ,  p )

Модель объекта компонента

Модель компонентных объектов (COM) определяет двоичный стандарт для размещения реализации объектов в файлах DLL и EXE. Он предоставляет механизмы для поиска и версионирования этих файлов, а также независимое от языка и машиночитаемое описание интерфейса. Размещение объектов COM в DLL более легковесно и позволяет им совместно использовать ресурсы с клиентским процессом. Это позволяет объектам COM реализовывать мощные бэкэнды для простых фронтэндов GUI, таких как Visual Basic и ASP. Их также можно программировать с помощью языков сценариев. [12]

Взлом DLL

Из-за уязвимости, обычно известной как перехват DLL, подмена DLL, предварительная загрузка DLL или двоичная установка, многие программы загружают и выполняют вредоносную DLL, содержащуюся в той же папке, что и файл данных, открытый этими программами. [13] [14] [15] [16] Уязвимость была обнаружена Георгием Гунински в 2000 году. [17] В августе 2010 года она получила всемирную огласку после того, как ACROS Security повторно обнаружила ее, и многие сотни программ были признаны уязвимыми. [18] Программы, которые запускаются из небезопасных мест, т. е. из папок, доступных для записи пользователем, таких как каталог Downloads или Temp , почти всегда подвержены этой уязвимости. [19] [20] [21] [22] [23] [24] [25]

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

Ссылки

  1. ^ Корпорация Microsoft. «Создание библиотеки DLL, содержащей только ресурсы». Сетевая библиотека разработчиков Microsoft .
  2. ^ "Конец DLL-ада". Корпорация Microsoft. Архивировано из оригинала 2008-05-06 . Получено 2009-07-11 .
  3. ^ "Понимание таблицы адресов импорта". Sandsprite.com . Архивировано из оригинала 7 ноября 2023 г. . Получено 7 ноября 2023 г. .
  4. ^ "Создание и использование DLL". Библиотека импорта — это обычная UNIX-подобная библиотека .a, но она содержит только крошечную часть информации, необходимую для того, чтобы сообщить ОС, как программа взаимодействует с ("импортирует") dll. Эта информация связана с .exe.
  5. ^ "ld и WIN32". Документация ld .
  6. ^ "Поддержка компоновщика для отложенной загрузки DLL". Microsoft Corporation . Получено 2009-07-11 .
  7. ^ Петруша, Рон (2005-04-26). "Создание Windows DLL с помощью Visual Basic". O'Reilly Media . Получено 2009-07-11 .
  8. ^ MSDN, Использование extern для указания связи
  9. ^ "Порядок поиска динамически подключаемых библиотек". Microsoft Developer Network . Получено 9 февраля 2023 г.
  10. ^ "Доступна новая запись реестра CWDIllegalInDllSearch для управления алгоритмом пути поиска DLL". Поддержка Microsoft .
  11. ^ "Безопасная загрузка библиотек для предотвращения атак предварительной загрузки DLL". Поддержка Microsoft . Получено 28 октября 2019 г.
  12. ^ Сатран, Майкл. «Модель компонентных объектов (COM)». msdn.microsoft.com .
  13. ^ Бьёрклунд, Андреас; Клёвстедт, Йохан; Вестергрен, Свен. «Подмена DLL в Windows» (PDF) . Факультет информационных технологий Уппсальского университета . Архивировано (PDF) из оригинала 7 ноября 2023 г. Проверено 7 ноября 2023 г.
  14. ^ "Атаки предварительной загрузки DLL". msdn.com . Получено 25 марта 2018 г. .
  15. ^ "Дополнительная информация о векторе удаленной атаки DLL Preloading". technet.com . Получено 25 марта 2018 г. .
  16. ^ "Обновление вектора удаленной атаки с предварительной загрузкой DLL". technet.com . Получено 25 марта 2018 г. .
  17. ^ «Двойной щелчок по документам MS Office из проводника Windows может в некоторых случаях запустить произвольные программы». www.guninski.com . Получено 25 марта 2018 г. .
  18. ^ "Binary Planting - Официальный веб-сайт забытой уязвимости. Безопасность ACROS". www.binaryplanting.com . Получено 25 марта 2018 г.
  19. ^ Дорманн, Уилл (4 сентября 2008 г.). «Ковровые бомбардировки и отравление каталогов». Университет Карнеги-Меллона — блог SEI . Архивировано из оригинала 7 ноября 2023 г. Получено 7 ноября 2023 г.
  20. ^ "Dev to Mozilla: Пожалуйста, сбросьте старые процессы установки Windows". theregister.co.uk . Получено 25 марта 2018 г. .
  21. ^ "Gpg4win - Security Advisory Gpg4win 2015-11-25". www.gpg4win.org . Получено 25 марта 2018 г. .
  22. ^ "McAfee KB - McAfee Security Bulletin: исправление безопасности для нескольких установщиков и деинсталляторов McAfee (CVE-2015-8991, CVE-2015-8992 и CVE-2015-8993) (TS102462)". service.mcafee.com . Получено 25 марта 2018 г. .
  23. ^ "fsc-2015-4 - F-Secure Labs". www.f-secure.com . Архивировано из оригинала 31 июля 2017 г. Получено 25 марта 2018 г.
  24. ^ "Уязвимость перехвата порядка поиска DLL ScanNow и ее устаревание". rapid7.com . 21 декабря 2015 г. . Получено 25 марта 2018 г. .
  25. ^ Команда VeraCrypt. "oss-sec: CVE-2016-1281: установщики TrueCrypt и VeraCrypt для Windows допускают выполнение произвольного кода с повышением привилегий". seclists.org . Получено 25 марта 2018 г. .

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