Динамически подключаемая библиотека (DLL) — это обычный исполняемый файл формата PE (Portable Executable), который содержит машинный код, данные и дополнительные ресурсы, предназначенные для совместного использования несколькими приложениями.
Формат PE-файла
Каждый DLL имеет структуру, определённую спецификацией PE: заголовок DOS, заголовок PE, таблицу секций и сами секции. Заголовок хранит информацию о целевой архитектуре (x86, x64, ARM), точке входа, размерах изображения и флагах характеристик.
Основные секции DLL
Секции — это блоки файла, каждому из которых присваивается имя и набор атрибутов (читаемый, записываемый, исполняемый). Наиболее типичные секции в DLL выглядят так:
- .text — исполняемый машинный код функций.
- .data — инициализированные глобальные и статические переменные.
- .rdata — данные только для чтения (строки, константы, таблицы отладки).
- .rsrc — ресурсы: иконки, курсорные изображения, строковые таблицы, манифесты, версии.
- .reloc — информация о перебазировании, необходимая, если DLL загружается по адресу, отличающемуся от предпочтительного.
- .edata — таблица экспорта (экспортируемые функции и переменные).
- .idata — таблица импорта (функции, которые DLL импортирует из других библиотек).
Таблица экспорта и импорта
Экспорт делает функции DLL видимыми для внешних программ. В таблице экспорта хранится:
- имена экспортируемых символов (или их порядковые номера);
- виртуальные адреса функций или данных;
- сопутствующая информация о forward‑экспорте (перенаправлении в другую DLL).
Импорт описывает, какие функции из других DLL нужны текущей библиотеке. Загрузчик Windows использует эту таблицу для подстановки реальных адресов функций после загрузки всех зависимостей.
Ресурсы и метаданные
Секция .rsrc содержит бинарные данные, удобно доступные через API FindResource/LoadResource. Типичные ресурсы:
- иконки и курсоры (RT_GROUP_ICON, RT_CURSOR);
- строковые таблицы (RT_STRING);
- версионная информация (RT_VERSION) с полями FileVersion, ProductVersion, CompanyName и т.д.;
- манифесты (RT_MANIFEST), управляющие визуальными стилями и уровнем привилегий;
- пользовательские данные (RT_RCDATA), которые разработчик может поместить произвольным блоком.
Кроме того, в PE‑заголовке могут находиться директории TLS (Thread Local Storage), конфигурации загрузчика (Load Configuration Directory) и сигнатуры Authenticode, если файл подписан.
Как посмотреть содержимое DLL
Для практического изучения используются бесплатные или коммерческие утилиты, которые читают структуру PE и выводят её в удобном виде:
- Dependency Walker (depends.exe) — показывает импортируемые и экспортируемые функции, зависимости;
- dumpbin /headers и /exports из Visual Studio;
- objdump -p из комплекта MinGW-w64;
- PE Explorer, CFF Explorer или аналогичные GUI‑просмотрщики;
- Встроенная утилита Windows «sigcheck» из Sysinternals показывает подпись и основные сведения;
- Онлайн‑сервисы, например VirusTotal, могут отдать секции и импорты при анализе.
При просмотре обращайте внимание на наличие секции .reloc — её отсутствие может привести к сбоям при загрузке по непредпочтительному адресу, особенно в системах с ASLR.
Ограничения и что не стоит ожидать
DLL не содержит:
- полноценного графического интерфейса — он может быть реализован в ресурсах, но логика UI обычно находится в исполняемом EXE;
- скриптового кода вроде JavaScript или Python — если такие языки используются, они обычно находятся в отдельных файлах или интерпретируются через встроенный движок;
- данных, специфичных для конкретного пользователя — DLL предназначена для совместного использования, поэтому личные настройки хранятся вне неё (в реестре, файлах конфигурации).
Также важно помнить, что изменение содержимого DLL без перекомпиляции (например, правка секции .text через hex‑редактор) почти всегда приводит к нарушению подписи, смещению адресов и краху приложения.
Практический совет
Если вам нужно определить, какая функция экспортируется из DLL, выполните:
- Запустите утилиту dumpbin /exports <имя_файла.dll>;
- Скопируйте список exported names;
- Сопоставьте их с заголовками заголовочных файлов (.h) или документацией библиотеки;
- При отсутствии названий (только порядковые номера) используйте утилиту Dependency Walker, которая покажет zarówno имена, так и ordinals.
Эта последовательность помогает быстро понять, какие функции доступны для связывания через GetProcAddress или импорт в проекте.
Когда стоит обратиться к специалисту
Если вы подозреваете, что DLL повреждена, содержит вредоносный код или не совместима с вашей версией Windows, рекомендуется:
- Проверить цифровую подпись через sigcheck или свойства файла;
- Сравнить хеш файла с известным хорошим образцом;
- Запустить антивирусный сканер;
- При необходимости переустановить пакет, предоставляющий эту библиотеку, вместо ручного исправления файла.
Самостоятельная правка бинарных секций без глубокого знания формата PE чревата нестабильностью системы.
