Открыть сервис

Таблица экспорта PE-файлов

Таблица экспорта PE-файлов — это структура данных в формате исполняемых файлов Windows (Portable Executable, PE), которая содержит информацию о функциях и переменных, экспортируемых из модуля (DLL или EXE) для использования другими программами. Таблица экспорта является частью каталога данных PE-заголовка (Data Directory) и описывает точку входа в динамически подключаемые библиотеки, обеспечивая связывание и разрешение символов во время загрузки.

Назначение и роль

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

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

Структура таблицы экспорта

Таблица экспорта описывается структурой IMAGE_EXPORT_DIRECTORY, которая содержит следующие ключевые поля:

  • Characteristics — флаги, зарезервированные для будущего использования (в текущих версиях Windows значение равно нулю).
  • TimeDateStamp — время создания таблицы экспорта (обычно совпадает со временем сборки файла).
  • MajorVersion / MinorVersion — версия таблицы экспорта (в большинстве случаев нулевая).
  • Name — относительный виртуальный адрес (RVA) строки, содержащей имя модуля (например, kernel32.dll).
  • Base — базовое порядковое число, с которого начинается нумерация экспортируемых функций.
  • NumberOfFunctions — общее количество экспортируемых функций и переменных.
  • NumberOfNames — количество функций, имеющих символьные имена (всегда меньше или равно NumberOfFunctions).
  • AddressOfFunctions — RVA массива адресов экспортируемых функций (каждый элемент — 4 байта).
  • AddressOfNames — RVA массива указателей на строки с именами функций.
  • AddressOfNameOrdinals — RVA массива порядковых номеров, связывающих имена с адресами.

Механизм разрешения экспорта

Таблица экспорта поддерживает два способа доступа к функциям:

  1. По имени — приложение указывает строковое имя функции. Загрузчик ищет имя в массиве AddressOfNames, получает индекс, затем по индексу обращается к массиву AddressOfNameOrdinals, который содержит порядковый номер, и наконец по номеру получает адрес из массива AddressOfFunctions.
  2. По порядковому номеру — приложение указывает число, равное Base + ordinal. В этом случае загрузчик напрямую обращается к элементу массива AddressOfFunctions с индексом, равным порядковому номеру.

Виды экспортируемых элементов

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

Экспорт может быть организован тремя способами:

  • Экспорт по имени — наиболее распространённый способ, при котором каждая функция имеет символьное имя.
  • Экспорт по порядковому номеру — используется для оптимизации и уменьшения размера таблицы, однако затрудняет использование библиотеки сторонними разработчиками.
  • Смешанный экспорт — часть функций экспортируется по имени, часть только по порядковому номеру.

Расположение в файле

Таблица экспорта находится в разделе .edata (export data), который обычно присутствует в DLL-файлах. В PE-заголовке (структура IMAGE_OPTIONAL_HEADER) в поле DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] хранится RVA и размер таблицы экспорта. При загрузке файла в память система отображает таблицу по этому адресу и использует её для построения внутренней базы экспортируемых символов.

Инструменты для анализа

Для просмотра таблицы экспорта используются следующие инструменты:

  • Dumpbin (утилита из Visual Studio) — команда /exports выводит список экспортируемых функций с их порядковыми номерами и RVA.
  • PE Explorer — графическая утилита для просмотра структуры PE-файлов.
  • CFF Explorer — бесплатный инструмент, позволяющий просматривать и редактировать таблицу экспорта.
  • Python-библиотека pefile — предоставляет программный доступ к структурам PE, включая таблицу экспорта.

Практическое значение

Таблица экспорта важна для:

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

Особенности и ограничения

  • Таблица экспорта не является обязательной для EXE-файлов, но может присутствовать в драйверах и системных модулях.
  • Максимальное количество экспортируемых функций ограничено размером раздела .edata и обычно не превышает нескольких тысяч.
  • Порядковые номера в таблице экспорта не обязаны быть непрерывными — пропуски допустимы, но загрузчик обрабатывает их как несуществующие функции.
  • В 64-битных PE-файлах структура таблицы экспорта идентична 32-битной, однако адреса функций занимают 8 байт, что увеличивает размер массива AddressOfFunctions.