Здесь:
AddressOfFunctions – RVA (смещение от начала файла)
массива, содержащего RVA функций.
AddressOfNames – RVA массива, содержащего RVA имён
функций.
AddressOfNameOrdinals – RVA массива индексов функций.
Элемент n этого массива содержит индекс в массиве адресов функций, соответствующей n-ному элементу в массиве имён функций.
ПРЕДУПРЕЖДЕНИЕ
Во-первых, элементы этого массива имеют
тип WORD и размер 2 байта.
Во-вторых, MSDN и статья Мэтта Питрека
«Форматы PE и COFF объектных файлов» содержат одну и туже ошибку, относящуюся
к интерпретации содержимого этого массива. Правильно написано в статье
Максима М. Гумерова «Загрузчик PE-файлов» и здесь :)
|
NumberOfFunctions – количество элементов массива
адресов функций.
NumberOfNames – количество элементов массива имён
функций и массива индексов функций.
Base – базовое значение ординала экспортируемых
функций. Для получения индекса функции, экспортируемой по ординалу, надо
вычесть из её ординала значение Base.
В результате, для поиска адреса функции, экспортируемой по имени, нужно сделать примерно следующее (в псевдокоде):
// Ищем в массиве имён функций
совпадающее имя
int nameIndex =
FindFunctionName(AddressOfNames, NumberOfNames, name);
// Получаем соответствующий имени индекс функции
WORD
funcIndex = AddressOfNameOrdinals[nameIndex];
// Получаем RVA функции
DWORD
funcRVA = AddressOfFunctions[funcIndex];
|
ПРЕДУПРЕЖДЕНИЕ
По MSDN и Питреку, последняя строчка
алгоритма должна выглядеть так:
DWORD
funcRVA = AddressOfFunctions[funcIndex - Base];
Где Base – базовое значение ординала.
Как показывает практика, Base вычитать не надо.
|
Код
В конце концов у меня получилось три функции. Первая
находит секцию экспорта: