Реферат: Методы перехвата API-вызовов в Win32
Первый способ позволяет реализовывать только сравнительно небольшие по размеру функции-перехватчики, так как код необходимо внедрять в свободные участки DLL – в основном в межсекционное пространство. Другой недостаток – код необходимо писать на ассемблере. Общая идеология работы этого метода та же, что и в Detours. В код целевой функции внедряется команда jmp к функции-перехватчику. Байты, скопированные «из-под» jmp’а, перемещаются в перехватчик (так как перехватчик всё равно пишется на ассемблере, в этом случае его проще сразу совместить с функцией-трамплином). Вот пример реализации этого метода.
В каталоге DriveType0 находится файл kernel32.dll, в котором я сделал следующие исправления (при помощи hiew32.exe):
По адресу 4E02 – локальный адрес .0BFF74E02 (это конец функции GetDriveTypeA) я поместил команду jmp .0BFF71080 – на первое попавшееся свободное место (в исполняемых файлах всегда много свободного места – обычно в концах секций).
По адресу .0BFF71080 (глобальный адрес 1080) я поместил следующий код:
.BFF71080: 3C03 cmp al,003 ;Возвращаем DRIVE_FIXED ? .BFF71082: 750E jne .0BFF71092 .BFF71084: B402 mov ah,002 ;Да. .BFF71086: CD16 int 016 ;/Проверим состояние ScrollLock .BFF71088: 2410 and al,010 ; .BFF7108A: 7404 je .0BFF71090 ;\Светодиодгорит ? .BFF7108C: B005 mov al,005 ;Да. Возвращаем DRIVE_CDROM .BFF7108E: EB02 jmps .0BFF71092 ;Навозврат .BFF71090: B003 mov al,003 .BFF71092: 5F pop edi ;/Возвратиз GetDriveTypeA .BFF71093: 5E pop esi ; (кусок кода, скопированный .BFF71094: 5B pop ebx ; из .0BFF74E02 - .BFF74E06) .BFF71095: C9 leave ; .BFF71096: C20400 retn 00004 ;\ |
Таким образом, когда светодиод ScrollLock не горит, функция GetDriveTypeA работает как обычно, а если горит – то для всех Windows-приложений все локальные диски (у меня это С:\ и D:\) превращаются в CD-ROMы.
ПРИМЕЧАНИЕ Чтобы всё это заработало, необходимо заменить файл C:\Windows\System\kernel32.dll на файл DriveType0\kernel32.dll. Сделать это можно, только загрузив компьютер в режиме MS-DOS, так как kernel32.dll – одна из системных библиотек Windows. Данный пример реализован для Windows 98. Поскольку системные библиотеки меняются в зависимости от версии Windows (и даже от номера билда), то в других операционных системах этот пример работать не будет (его нужно реализовывать для каждой версии kernel32.dll заново). |
Этот способ перехвата – один из самых мощных. Однако в коммерческих продуктах его использовать не удастся, так как он, очевидно, нарушает практически любое лицензионное соглашение.
Другой способ реализации этого метода – использование оберток (wrappers). Суть его в создании собственной DLL с тем же набором экспортируемых функций, что и оригинальная. В качестве примера могу привести следующий вариант реализации вышеприведённого примера:
Системную библиотеку Kernel32.dll переименовываем в kernel31.dll :).
Создаём библиотеку с именем Kernel32.dll, в которой реализована одна функция – GetDriveTypeA (это будет функция-перехватчик), а все остальные функции переадресуем к kernel31.dll (благо компилятор Visual C++ поддерживает переадресацию функций DLL).
Полученную библиотеку помещаем в системный каталог.
При этом функция-перехватчик может вызывать оригинальную функцию из kernel31.dll.
Основным недостатком данного способа является то, что он не годится для DLL, экспортирующих переменные.
Глобальный перехват методом подмены кода DLL в памяти (только Win9X)