Уроки Iczelion'а



Урок 7. Таблица экспорта - часть 3


RVA of Name 4 <-->Index of Name 4

... ...... <--> RVA of Name N Index of Name N

Если у нас есть имя экспортируемой функции и нам требуется получить ее адрес в модуле, мы должны сделать следующее.

  • Перейти к PE-загрузчику
  • Прочитать виртуальный адрес таблицы экспорта в директории данных
  • Перейти к таблице экспорта и получить количество имен (NumberOfNames)
  • Параллельно просмотреть массивы, на который указывают AddressOfNames и AddressOfNameOrdinals, ища нужно имя. Если имя найдено в массиве AddressOfNames, вы должны извлечь значение в ассоциированном элементе массива AddressOfNameOrdinals. Hапример, если вы нашли RVA необходимого имени в 77-ом элементе массива AddressOfNames, вы должны извлечь значение, сохраняемое в 77-ом элементе массива AddressOfNameOrdinals. Если вы просмотрели все NumberOfElements элементов массива и ничего не нашли, вы знаете, что имя находится не в этом модуле.
  • Используйте значение из массива AddressOfNameOrdinals в качестве индекса для массива AddressOfFunctions. Hапример, если значение pавно 5, вы должны извлечь значение 5-го элемента массива AddressOfFunctions. Это значение будет являться RVA функции.

Сейчас мы можем переключить наше внимание на параметр nBase из структур. Вы уже знаете, что массив AddressOfFunctions содержит адреса всех экспортируемых символов в модуле. И PE-загрузчик использует индексы этого массива, чтобы найти адреса функций. Давайте представим ситуацию, что мы используем индексы этого массива как ординалы. Так как программист может указать любое число в качестве стартового ординала в .def-файле, например, 200, это значит, что в массиве AddressOfFunctions должно быть по крайней мере 200 элементов. Хотя первые 200 элементов не будут использоваться, они должны сущетствовать, так как PE-загрузчик может использовать индексы, чтобы найти правильные адреса. Это совсем нехорошо. Параметр nBase существует для того, чтобы решить эту проблему. Если программист указывает начальным ординалом 200, значением nBase будет 200. Когда PE-загрузчик считывает значение в nBase, он знает, чт первые 200 элементов не существуют, и что он должен вычитать от ординала значение nBase, чтобы получить настоящий индекс нужного элемента в массиве AddressOfFunctions. Используя nBase, нет надобности в 200 пустых элементах.




Содержание  Назад  Вперед