Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows


Перехват API-вызовов подменой кода


Перехват API-вызовов далеко не новый метод — разработчики пользуются им уже многие годы. Когда сталкиваешься с проблемой, аналогичной той, о которой я только что рассказал, то первое, что приходит в голову, установить ловушку, подменив часть исходного кода. Вот как это делается.

  1. Найдите адрес функции, вызов которой Вы хотите перехватывать (например, ExitProcess в Kernel32.dll).
  2. Сохраните несколько первых байтов этой функции в другом участке памяти.
  3. На их место вставьте машинную команду JUMP для перехода по адресу подставной функции Естественно, сигнатура Вашей функции должна быть такой жс, как и исходной, т. e все параметры, возвращаемое значение и правила вызова должны совпадать.
  4. Теперь, когда поток вызовет перехватываемую функцию, команда JUMP перенаправит его к Вашей функции На этом зтапе Вы можете выполнить любой нужный код.
  5. Снимите ловушку, восстановив ранее сохраненные (в п. 2) байты.
  6. Если теперь вызвать перехватываемую функцию (таковой больше не являющуюся), она будет работать так, как работала до установки ловушки.
  7. После того как она вернет управление, Вы можете выполнить операции 2 и 3 и тем самым вновь поставить ловушку на эту функцию.

Этот метод был очень популярен среди программистов, создававших приложения для 16-разрядной Windows, и отлично работал в этой системе В современных системах у этого метода возникло несколько серьезных недостатков, и я настоятельно не рекомендую его применять. Во-первых, он создает зависимость от конкретного процессора из-за команды JUMP, и, кроме того, приходится вручную писать машинные коды. Во-вторых, в системе с вытесняющей многозадачностью данный метод вообще не годится. На замену кода в начале функции уходит какое-то время, а в этот момент перехватываемая функция может понадобиться другому потоку. Результаты могут быть просто катастрофическими!

WINSOWS 98
В Windows 98 основные системные DLL (Kernel32, AdvAPI32, User32 и GDI32) защищены так, что приложение не может что-либо изменить на их страницах кода. Это ограничение можно обойти, только написав специальный драйвер виртуального устройства (VxD).




Начало  Назад  Вперед