Blog. Just Blog

Как получить список экспортируемых функций DLL

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Сегодня разберем, как получить список экспортируемых функций динамических библиотек. Лично я использую эти данные для формирования баз подсветки синтаксиса и автодополнения редактора Sublime Text. Наверняка можно придумать и другие применения.

Формат PE-файлов, как и таблицы экспорта, неплохо документирован на многих языках, эту информацию легко найти в интернетах. Несмотря на это, FASM про нужные нам структуры ничего не знает. Это привычное явление.
  1. struct LOADED_IMAGE
  2.         ModuleName       dd ?
  3.         hFile            dd ?
  4.         MappedAddress    dd ?
  5.         FileHeader       dd ?
  6.         LastRvaSection   dd ?
  7.         NumberOfSections dd ?
  8.         Sections         dd ?
  9.         Characteristics  dd ?
  10.         fSystemImage     db ?
  11.         fDOSImage        db ?
  12.         fReadOnly        db ?
  13.         Version          db ?
  14.         Links            rd 2
  15.         SizeOfImage      dd ?
  16. ends
  17.  
  18. struct IMAGE_EXPORT_DIRECTORY
  19.         Characteristics       dd ?
  20.         TimeDateStamp         dd ?
  21.         MajorVersion          dw ?
  22.         MinorVersion          dw ?
  23.         Name                  dd ?
  24.         Base                  dd ?
  25.         NumberOfFunctions     dd ?
  26.         NumberOfNames         dd ?
  27.         AddressOfFunctions    dd ?
  28.         AddressOfNames        dd ?
  29.         AddressOfNameOrdinals dd ?
  30. ends
  31.  
  32. IMAGE_DIRECTORY_ENTRY_EXPORT = 0
Парсить файлы можно вручную, но в данном случае лучше поручить всю грязную работу системе. Для загрузки динамической библиотеки в память с целью последующего анализа используется функция MapAndLoad, для выгрузки, соответственно, UnMapAndLoad, но это потом. После удачной загрузки нам становится доступна структура LOADED_IMAGE. Зная адрес загрузки образа в память, при помощи функции ImageDirectoryEntryToData с флагом IMAGE_DIRECTORY_ENTRY_EXPORT получаем адрес секции экспорта.

Экспорт будем обрабатывать по списку функций, которые экспортируются в том числе по имени, а не только по ординалу. Функцией ImageRvaToVa пересчитываем виртуальный адрес AddressOfNames относительно заголовка загруженного образа в виртуальный адрес, таким образом получая адрес в памяти, с которого начинается таблица имен экспортируемых функций.

Затем, узнав количество функций из поля NumberOfNames, поочередно перебираем в таблице указатели на строки с именами функций. Для каждого адреса также надо также выполнять пересчет RVA в VA. Перебор продолжается, пока не достигнем конца таблицы. В виде кода это выглядит примерно так:
  1.         ; Загрузить динамическую библиотеку в память
  2.         invoke  MapAndLoad,dllname,NULL,l_image,TRUE,TRUE
  3.  
  4.         invoke  ImageDirectoryEntryToData,\
  5.                 [l_image.MappedAddress],FALSE,\
  6.                 IMAGE_DIRECTORY_ENTRY_EXPORT,\
  7.                 tmp
  8.         or      eax,eax
  9.         jz      loc_exit
  10.         ; EAX -> ExportDirectory
  11.  
  12.         mov     ebx,eax
  13.  
  14.         ; Получить адрес таблицы экспорта
  15.         mov     [tmp],0
  16.         invoke  ImageRvaToVa,[l_image.FileHeader],[l_image.MappedAddress],\
  17.                 [ebx+IMAGE_EXPORT_DIRECTORY.AddressOfNames],tmp
  18.  
  19.         ; EDI -> таблица экспорта
  20.         mov     edi,eax
  21.         ; Начинаем с первого элемента
  22.         xor     esi,esi
  23. loc_loop:
  24.         ; Вычислить указатель на имя экспортируемой функции
  25.         mov     eax,esi
  26.         shl     eax,2
  27.         add     eax,edi
  28.  
  29.         mov     [tmp],0
  30.         invoke  ImageRvaToVa,[l_image.FileHeader],[l_image.MappedAddress],\
  31.                 [eax],tmp
  32.         ; EAX -> имя экспортируемой функции
  33.  
  34.         ...
  35.         ; действия с полученным именем
  36.         ...
  37.  
  38.         ; Следующая запись
  39.         inc     esi
  40.         ; Все записи обработаны?
  41.         cmp     esi,[ebx+IMAGE_EXPORT_DIRECTORY.NumberOfNames]
  42.         jb      loc_loop
  43.  
  44. loc_exit:
  45.         ; Выгрузить файл
  46.         invoke  UnMapAndLoad,l_image
В приложении пример программы с исходным текстом, которая получает список экспортируемых функций из динамической библиотеки и сохраняет его в файл.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

DLL.Export.Demo.zip (11,622 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 867 | Комментариев: 4

Метки: Assembler
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (28.08.2023 в 00:38):
Этак для каждой dll придется кусок msdn таскать :) Получится типа TypeLib, только еще заковыристей. Хотя соглашусь, было бы неплохо. Но MS изначально этот момент не стандартизировали, а сейчас уже, по прошествии стольких лет, время упущено.
Grey (24.08.2023 в 14:54):
жаль только по аргументам инфы нет
ManHunter (24.08.2023 в 12:13):
Да вообще 99,99% чего бы то ни было уже где-то и кем-то написано. Мне же интересно не "где взять готовое", а "как это работает".
Grey (24.08.2023 в 12:09):
Прикольно!
П.С.
Такой функционал есть у FASM Editor 2.0
Автор уже лет как 10 забросил эту тему.

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0052 сек.) / Память: 4.5 Mb
Наверх