Информация об экспортируемых функциях хранится в секции .edata (обычно в dll файлах). Таблица экспорта имеет следующую структуру:
характеристики
Base
…
NumberOfFunction
NumberOfNames
AddressOfFunctions
AddressOfNames
AddressOfNameOrdinals
Таблица адресов
Таблица
экспорта
MyFunc1 MyFunc3
Таблица имён функций
1 3
Таблица номеров функций
Из dll экспортируется 3 функции, причём 2 из них по имени. Рассмотрим структуру таблицы экспорта.
Характеристики – в нём указывается время и дата создания dll, в них находится RVA, который указывает на строку с именем этой dll.
? Зачем дублируется имя dll?
Ответ: чтобы ускорить, чтобы все данные, которые необходимы, брались из таблицы экспорта.
Начальный номер экспорта для функций, экспортируемый данным модулем, например, если модуль экспортирует с 10, 11, 15, то начальный номер 10.
NumberOfFunction – количество элементов в таблице адресов.
NumberOfNames – количество элементов в таблице имён.
Следующие три поля указывают на соответствующие таблицы.
Таблица адресов функций представляет собой массив двоичных слов, содержащих RVA одной из экспортируемых функций.
Номер экпорта каждой экспортируемой функции совпадает с её положением в массиве. Положение в массиве определяется так: номер экспорта – BASE. Отсчёт номеров экспорта начинается с числа, содержащегося в поле BASE. Номера экспортов могут иметь пропуски.
Пример.
BASE=10
10…13
10 11 12 13
RVA
RVA
Когда загрузчик Win32 выполняет вызов экспортируемой функции по номеру работа производится только с этой таблицей, а именно: по номеру определяется индекс в массиве, и по индексу в массиве определяется RVA соответствующей функции. Рассмотрим таблицы имён функции и номеров. Таблица имён функции представляет собой массив указателей на имена функций. Таблица номеров функции всегда содержит то же количество элементов, что и таблица имён. Таблица номеров представляет собой массив индексов для таблицы адресов функций.
Как производится обработка вызовов функций, экспортируемых по имени.
1) Загрузчик просматривает строки, на которые указывает таблица имён функций, для того чтобы найти имя требуемой функции. Если имя найдено, определяется индекс в таблице имён функций.
2) По найденному индексу из таблицы номеров функций извлекается индекс в таблице адресов функций. Из таблицы адресов извлекается RVA требуемой функции.