Отладка приложений


         

ваше приложение не может знать


Конечно, ваше приложение не может знать этот адрес заранее, поэтому все вызовы OutputDebugstring направляются через единственный косвенный адрес. Когда программный загрузчик загружает выполняемый файл и связанные с ним DLL-файлы в память, загрузчик устанавливает этот косвенный адрес так, чтобы он соответствовал окончательному адресу загрузки OutputDebugstring. Компилятор заставляет эту косвенную адресацию работать, генерируя переход к косвенному адресу каждый раз, когда код вызывает импортированную функцию. Этот косвенный адрес сохраняется в секции импорта (.idata1) выполняемого файла. Если импорт выполняется через объявление _declspec(dllimport), то вместо косвенного перехода код выполняет косвенное обращение, экономя, таким образом, пару инструкций на вызове функции.

Idata — первый символ в этом имени (i) от англ, import (импорт). — Пер.

При подключении импортированной функции выполняются следующие операции: поиск секции импорта выполняемого файла, поиск адреса конкретной функции, которую вы хотите подключить, и затем запись адреса подключаемой функции на свое место (в коде). Хотя поиск и замена адресов функций могут показаться довольно трудоемким занятием, но тут уж ничего не поделать — так организован РЕ2-формат файлов в Win32.

РЕ - Portable Executable. - Пер.

В главе 10 своей превосходной книги "Секреты системного программирования Windows 95" (Matt Pietrek. System Programming Secrets, — IDG Books, 1995) Мэт Пьетрек описывает метод подключения импортированных функций. Код Мэта просто отыскивает секцию импорта модуля и, используя значение, возвращаемое из вызова функции GetProcAddress, организует циклический просмотр списка импортированных функций. Обнаружив нужную функцию, он перезаписывает адрес подключаемой функции на исходный адрес импортированной функции.

После выхода книги Мэта в этой методике произошло два небольших изменения. Во-первых, когда Мэт писал книгу, большинство разработчиков не объединяло секцию импорта с другими РЕ-секциями. Поэтому, если секция импорта находится в памяти, защищенной от записи (с атрибутом доступа "read-only"), то запись адреса подключения вызывает нарушение доступа.

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