Методи перехоплення 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)

if (pImportDesc == NULL)

return; //Тут її немає

//Знайдемо потрібний модуль

for (; pImportDesc->Name; pImportDesc++)

PSTR pszModName = (PSTR)((PBYTE) hmodCaller + pImportDesc->Name);

if (lstrcmpiA(pszModName, pszCalleeModName) == 0)

if (pImportDesc->Name == 0)

return; //Жодна функція не імпортується

(PIMAGE_THUNK_DATA)((PBYTE) hmodCaller + pImportDesc->FirstThunk);

//Переберемо всі функції, що імпортуються

for (; pThunk->u1.Function; pThunk++)

BOOL fFound = (*ppfn == pfnCurrent); //Його шукаємо?

if (!fFound && (*ppfn > sm_pvMaxAppAddr))

// Якщо не знайшли, то пошукаємо глибше.

// Якщо ми у Win98 під відладчиком, то

PBYTE pbInFunc = (PBYTE) * ppfn;

if (pbInFunc[0] == cPushOpCode)

fFound = (*ppfn == pfnCurrent);

// Дозволимо запис до цієї сторінки

VirtualProtect(ppfn, sizeof(ppfn), PAGE_EXECUTE_READWRITE, &dwDummy);

WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew,

VirtualProtect(ppfn, sizeof(ppfn), dwDummy, &dwDummy);

//Тут цієї функції не знайшлося

При реалізації цього методу слід враховувати, що виклики з бібліотеки DllMain, в якій знаходиться функція, що перехоплюється, перехопити не вдасться. Це пов'язано з тим, що перехоплення може бути здійснено тільки після закінчення LoadLibrary, а до цього часу DllMain вже буде викликана. Звичайно, можна написати свій варіант LoadLibrary (приклади завантаження DLL «вручну» існують) і здійснювати перехоплення між завантаженням DLL та викликом DllMain, але це дуже ускладнює завдання.

Основною перевагою даного методу є те, що він однаково реалізується як Win9X, так і WinNT.

У Windows NT функції Module32First і Module32Next не реалізовані, і для перерахування модулів процесу замість них доведеться скористатися функціями PSAPI.dll.

Локальне перехоплення за допомогою зміни функції, що перехоплюється (тільки WinNT)

Існує безліч прикладів цього методу. Я розгляну метод, який пропонує Microsoft – Detours library.

Detours – це перша офіційна бібліотека, призначена для перехоплення функцій (не лише системних, а й будь-яких інших). До основних понять Detours відносяться:

цільова функція (target function) - функція, перехоплення якої здійснюється;

функція-перехоплювач (detour function) - функція, що заміщає перехоплювану;

функція-трамплін (trampoline function) – функція, що складається із заголовка цільової функції та команди переходу до решти коду цільової функції.

Trampoline у ​​перекладі з англійської - "батут", проте словосполучення "функція-трамплін" більш точно передає логіку її роботи.

Таким чином, якщо цільова функція має наступний заголовок: