Методи перехоплення API-дзвінків у Win32 - Інформатика, програмування
Ігор В. Філімонов
Перехоплення системних функцій операційної системи – прийом, відомий давно. Зазвичай перехоплюється деяка системна функція з моніторингу чи зміни її поведінки. За часів DOS програмісти перехоплювали програмні переривання (int 21h, int 16h, int 10h). З приходом Win16 були потрібні кошти для перехоплення API-функцій. І, нарешті, з появою Win32 засоби перехоплення ще раз еволюціонували, підлаштовуючись під нову систему. Операційні системи сімейства Windows ніколи не містили вбудованих засобів, спеціально призначених для перехоплення системних функцій. І зрозуміло чому – таки це трохи хакерський прийом. Тому перехоплення зазвичай здійснюється «підручними засобами», і його реалізації потрібно чітко представляти багато глибинні аспекти пристрою та функціонування операційної системи.
У цій статті розглядаються методи реалізації перехоплення системних API-функцій у 32-розрядних операційних системах Windows. Розглядаються особливості реалізації перехоплення Win9X (Windows 95/98/98SE/ME) і WinNT (Windows NT/2000/XP/2003).
Особливості організації пам'яті у Windows
Оскільки перехоплення майже завжди пов'язані з модифікацією пам'яті (або коду функції, що перехоплюється, або таблиць імпорту/експорту), то для його здійснення необхідно враховувати особливості архітектури пам'яті WinNT і Win9X.
Адресний простір будь-якого процесу у Win9Х можна розділити на три розділи:
Молодші два гігабайти (00400000-7FFFFFFF) – код і дані режиму користувача (в діапазоні 00000000-003FFFFF розташовані розділи для виявлення нульових покажчиків і для сумісності з програмами DOS і Win16);
Третій гігабайт – для загальних файлів, що проектуютьсяв пам'ять (MMF) і системних DLL.
Четвертий гігабайт – для коду та даних режиму ядра (тут розташовується ядро операційної системи та драйвери).
Всі ці відмінності суттєво впливають на способи реалізації перехоплення функцій, розташованих у системних DLL.
Перехоплення можна розділити на два типи: локальні (перехоплення в межах одного процесу) та глобальні (у масштабах усієї системи).
Локальний перехоплення з використанням розділу імпорту
void CAPIHook::ReplaceIATEntryInOneMod(PCSTR pszCalleeModName,
PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller)