Уроки Iczelion'а



Урок 6. Таблица импорта - часть 4


OriginalFirstThunk IMAGE_IMPORT_BY_NAME FirstThunk

IMAGE_THUNK_DATA ---> Function 1 <--- IMAGE_THUNK_DATA

IMAGE_THUNK_DATA ---> Function 2 <--- IMAGE_THUNK_DATA

IMAGE_THUNK_DATA ---> Function 3 <--- IMAGE_THUNK_DATA

IMAGE_THUNK_DATA ---> Function 4 <--- IMAGE_THUNK_DATA

... ---> ... <--- ...

IMAGE_THUNK_DATA ---> Function n <--- IMAGE_THUNK_DATA

Теперь вы должны понять, что я имею ввиду. Пусть вас не смущает название 'IMAGE_THUNK_DATA': это всего лишь RVA структуры IMAGE_IMPORT_BY_NAME. Если вы мысленно замените слово IMAGE_THUNK_DATA на RVA, вы поймете это. Количество элементов в массиве OriginalFirstThunk и FirstThunk зависит от колчества функций, импортируемых PE из DLL. Hапример, если PE-файл импортирует 10 функций из kernel32.dll, Name1 в структуре IMAGE_IMPORT_DESCRIPTOR будет содержать RVA строки "kernel32.dll" и в каждом массиве будет 10 IMAGE_THUNK_DATA.

Следующий вопрос таков: почему нам нужно два абсолютно одинаковых массива? Чтобы ответить на это вопрос, нам нужно знать, что когда PE-файл загружается в память, PE-загрузчик просматривает IMAGE_THUNK_DATA'ы и IMAGE_IMPORT_BY_NAME и определяет адреса импортируемых функций. Затем он замещает IMAGE_THUNK_DATA'ы в массиве, на который ссылается FirstThunk настоящими адресами функций. Поэтому когда PE-файл готов к запуску, вышеприведенная картина становится такой:

OriginalFirstThunk IMAGE_IMPORT_BY_NAME FirstThunk

| |

IMAGE_THUNK_DATA ---> Function 1 Address of Function 1

IMAGE_THUNK_DATA ---> Function 2 Address of Function 2

IMAGE_THUNK_DATA ---> Function 3 Address of Function 3

IMAGE_THUNK_DATA ---> Function 4 Address of Function 4

... ---> ... ...

IMAGE_THUNK_DATA ---> Function n Address of Function n

Массив RVA'ов, на который сслыется OriginalFirstThunk остается прежним, так что если возникает нужда найти имена функций импорта, PE-загрузчик сможет их найти.

Hадо сказать, что некоторые функции экспортируются через ординалы, то есть не по имени, а по их позиции. В этом случае не будет соответствующей структуры IMAGE_IMPORT_BY_NAME для этой функции в вызывающем модуле. Вместо этого, IMAGE_THUNK_DATA этой функции будет содержать ординал функции в нижнем слове и самый значимый бит (MSB) IMAGE_THUNK_DATA'ы будет установлен в 1. Hапример, если функция экспортируется только через ординал и тот равен 1234h, IMAGE_THUNK_DATA этой функции будет содержать 80001234h. Микрософт предоставляет константу для проверки MSB, IMAGE_ORDIANAL_FLAG32. Он имеет значение 80000000h.




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