Перехоплення (інформатика)

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку

Перехоплення (англ. hooking) — технологія для зміни або посилення поведінки операційної системи, або застосунку, чи інших програмних складових, шляхом перехоплення викликів функцій або повідомлень або подій, які передаються між програмними компонентами. Код, який обробляє такі перехоплені виклики функцій, подій або повідомлень називається «гук» (англ. hook).

Перехоплення використовується для різних задач, в тому числі і зневадження і розширення функціональності. Прикладами є перехоплення повідомлень подій клавіатури або миші, перш ніж вони досягнуть застосунку, або перехоплення, які операційна система викликає для того, щоб контролювати поведінку або змінювати функцію програми або іншого компонента. Перехоплення також широко використовується в бенчмаркінгу програм, наприклад, для вимірювання швидкості генерації кадрів в 3D-іграх, де ввід та вивід відбувається через перехоплення.

Перехоплення також може бути використане шкідливим кодом. Наприклад, руткіти, складові програмного забезпечення, використовують перехоплення для фальсифікації викликів API, використання яких вказало б на існування руткіта, і це дозволяє йому (руткіту) залишитись невидимим. Воллхакінг (англ. Wallhack) є ще одним прикладом шкідливої поведінки програм, які спираються на техніку перехоплень викликів функцій у комп'ютерній грі, відображає додаткову інформацію гравцеві, що дозволяє отримати перевагу над іншими гравцями.

Призначення технології перехоплення[ред. | ред. код]

Дуже часто в системному програмуванні виникає задача зміни стандартної поведінки системних функцій. Наприклад, досить цікавим застосуванням даної технології є перевизначення віконної процедури у GUI програм Windows (субкласинг[ru]). Це потрібно, якщо програміст хоче організувати власну обробку будь-якого віконного повідомлення і тільки тоді передати стандартній віконній процедурі. Після субкласингу цикл обробки повідомлень буде виглядати так:

  • ДО субкласингу:
    Повідомлення Windows -> Вікно (віконна процедура)
  • ПІСЛЯ:
    Повідомлення Windows -> Наша віконна процедура -> Вікно (віконна процедура)

Наприклад, в уроках «Iczelion»'а[1] описаний приклад того, як субкласинг може використовуватися для організації контролю вводу в елементи управління. Технології перехоплення потрібні не тільки в цьому випадку, але і, наприклад, для попередньої обробки результатів системних функцій пошуку файлів «FindFirst» і «FindNext», «EnumProcess», яка перераховує процеси в Windows і т. д. Причому в цих цілях такі технології застосовують як антивірусні засоби[2], так і різного роду віруси, руткіти та інші види шкідливого програмного забезпечення.

Дуже часто перехоплення буває важливим для організації та налагодження програм і є однією з основних технологій, застосовуваних в зневаджувачах. В даному випадку ця технологія дозволяє одній програмі контролювати виконання іншої. Для цих цілей передбачений системний виклик «ptrace», який дозволяє підключатися до процесів, відслідковувати значення регістрів у контексті процесу, який зневаджується і в тому числі контролювати інші системні виклики. Він є основою для реалізації такої можливості зневаджувачив як точки зупину. Даний системний виклик добре документований і присутній у всіх головних «*Nix» системах: Linux, FreeBSD, Solaris[3]. Найчастіше використовується спільно з системним викликом «fork», який і викликає «ptrace», вказуючи в параметрах виклику, що запускається дочірній процес. Microsoft Windows також надає для схожих цілей т. зв. DebugAPI[4].

Види перехоплення системних функцій[ред. | ред. код]

Основними методами перехоплення є:

  • Підміна адреси справжньої функції (модифікація IAT[en] таблиць, модифікація SSDT[en]/IDT таблиць)
  • Безпосередня зміна функції (сплайсинг, перехоплення в режимі ядра з модифікацією тіла функції)
  • Безпосередня підміна всього компонента програми/системи (наприклад бібліотеки з цільовою функцією)

Методи можна також розділити за критерієм режиму виконання:

  • Користувацькі (кільця захисту) методи: модифікація IAT таблиць, сплайсинг. Їх особливість в тому, що неможливо щось змінити в поведінці ядра операційної системи та його розширень.
  • Режиму ядра: модифікація SSDT/IDT таблиць, перехоплення в режимі ядра з модифікацією тіла функції. Дозволяє модифікувати структури даних і код будь-якої частини операційної системи та програм.

Сплайсинг[ред. | ред. код]

Сплайсинг (від англ. Splice — «зрощувати або склеювати кінці чого-небудь») — метод перехоплення API функцій шляхом зміни коду цільової функції. Зазвичай змінюються перші 5 байт функції. Замість них вставляється перехід на функцію, яку визначає програміст. Щоб забезпечити коректність виконання операції, програма, яка перехоплює функцію, зобов'язана дати можливість виконатися коду, який був змінений в результаті сплайсингу. Для цього програма зберігає змінену ділянку пам'яті у себе, а після відпрацювання функції перехоплення відновлює змінену ділянку функції і дає повністю виконатися справжній функції.[5]

Особливості технології[ред. | ред. код]

Для того щоб програма могла використовувати дану технологію, вона повинна мати вбудований дизасемблерний рушій і спеціальний дизасемблер довжин[ru], який дозволить знаходити потрібну функцію і коректно її змінювати. Ця технологія вкрай платформно-залежна, а тому потребує ретельного контролю та перевірки системи на відповідність версій, а також перевірки самої функції на відповідність цільової. Системні функції можуть змінюватися при виході патчів і оновлень Windows (особливо Service Pack для Windows), а також в результаті модифікацій з боку інших програм. Помилки при роботі з даною технологією можуть призводити до BSOD. Водночас ця технологія дозволяє здійснювати глобальне перехоплення API функцій, впливаючи таким чином на всі процеси в системі. Починаючи з Windows XP SP2 для підтримки «гарячого патчу» Microsoft змінила стандартний пролог функцій з трьох байт до п'яти (додала mov edi, edi в стандартний пролог push ebp; mov ebp, esp), що дозволяє не проводити аналіз довжин. Довжини в п'ять байт вистачає для заміни прологу на «опкоди» дальнього переходу, а відомий пролог дозволяє коректно передати управління функції, яку підміняють.

Сфери застосування сплайсинга і методи виявлення[ред. | ред. код]

Він застосовується:

  • В ПО, якому необхідно здійснювати функції моніторингу системи;
  • Механізмом гуків в Windows;
  • Різного роду шкідливими програмами. Це основна технологія приховування для руткітів користувацького рівня.

Основний метод виявлення факту сплайсингу — це порівняння машинного коду функції, який перевіряється на сплайсинг, і коду системної функції, отриманого в напевно чистій системі. Також в виявленні сплайсинга функції може допомогти контроль адрес переходу.

Порівняння з іншими технологіями[ред. | ред. код]

  • Зміна IAT таблиць процесу[6]. Дана технологія не дозволяє змінити поведінку самої системної функції, а лише дає можливість «обдурити» вибрану програму, змусивши її використовувати вашу функцію. IAT таблиця — таблиця адрес функцій, імпортованих процесом. Технологія носить лише локальний характер, хоча може бути застосована відразу до групи програм. Може бути досить швидко виявлена ​​через необхідність завантаження DLL[7] в адресний простір цільового процесу. Сплайсинг же, не вимагає DLL і впровадження в чужий процес, володіє можливістю глобального захвату функції. В ньому є ще одна перевага: не всі системні функції імпортуються процесом через IAT. Наприклад, функція може бути завантажена викликом «Getprocaddress». Використання ж безпосередньої модифікації коду функції знімає подібне обмеження.
  • Перехоплення в режимі ядра. Дозволяє перехоплювати будь-які функції, в тому числі і експортовані ядром. Найбільш важкий для виявлення в разі успіху, тому що дозволяє фальсифікувати будь-які дані, що надаються операційною системою. Вимагає написання спеціального компоненту для взаємодії з ядром — драйвера. Може привести до BSOD при неправильному програмуванні в режимі ядра. Може бути виявлений на фазі завантаження драйвера в ядро або при перевірці активних драйверів, а також при перевірці ядра на зміни[8]. Більш важкий у програмуванні метод, ніж сплайсинг, але більш гнучкий, тому що дозволяє перехопити функції самого ядра, а не тільки «WinAPI» функції, які служать лише посередником між ядром і програмою, яка що-небудь запитує у операційної системи.
  • Заміна самої бібліотеки з функцією. Вельми радикальне вирішення проблеми, має ряд істотних недоліків:
  1. Вимагає заміни файлу на диску, що може бути заборонено та припинено самою системою. Наприклад, заміну системних файлів Windows не дозволить виконати захист файлів Windows (WFP)[en], хоча його можна і виключити. Така дія може бути також виявлена при статичному аналізі системи ревізорами.
  1. Потрібна повна емуляція всіх можливостей замінної DLL чи іншого компонента, що дуже занадто навіть у разі відкритості і ускладнюється необхідністю дизасемблювання в разі закритості цільової програми.

Все це показує, що це вельми нераціональний спосіб вирішення проблеми зміни поведінки програми в разі можливості застосування перших двох підходів або сплайсинга.

Перехоплення в режимі ядра[ред. | ред. код]

Він заснований на модифікації структур даних ядра і функцій. Головними мішенями впливу є таблиці:

  • IDT — Таблиця диспетчеризації переривань. Досить важливим для перехоплення є переривання, що обробляє звернення до таблиці служб SSDT (0x2E)[9].
  • SSDT (System Service Dispatch Table) — Таблиця диспетчеризації системних сервісів. Звертаючись до неї, система за номером забороненого сервісу може отримати адресу відповідного сервісу ядра і викликати його. А таблиця SSPT містить загальний розмір параметрів, що передаються системному сервісу.
  • PsActiveprocess — Структура ядра, що зберігає список процесів в системі.
  • IRP[ru] — Таблиця драйвера, яка зберігає покажчики на функції обробки IRP-пакетів.
  • EPROCESS — Структура ядра, що зберігає велику кількість інформації про процес, включаючи, наприклад, PID (ідентифікатор процесу).

Такого роду руткіти називаються DKOM-руткітами, тобто руткітами, заснованими на безпосередній модифікації об'єктів ядра. В руткітах для систем Windows Server 2003 і XP ця технологія була модернізована, так як в цих ОС з'явився захист від запису деяких областей пам'яті ядра[9]. Windows Vista і 7 отримали додатковий захист ядра PatchGuard, однак всі ці технології були подолані руткітописателями[10]. Водночас перехоплення системних функцій в режимі ядра — основа проактивних систем захисту та гіпервізорів.

Інші форми перехоплення[ред. | ред. код]

Можна виділити й інші форми перехоплення:

  • Перехоплення мережевих з'єднань та пакетів[11].
  • Перехоплення паролів. Наприклад, за допомогою шпигунства за клавіатурним введенням за допомогою кейлоггера.

Тут описана лише частина застосувань даної технології.

Приклади програм, що використовують перехоплення[ред. | ред. код]

  • Гіпервізор Xen

Див. також[ред. | ред. код]

Примітки[ред. | ред. код]

  1. Уроки Iczelion'а. Win32 API. Урок 20. субкласинг вікна. Архів оригіналу за 18 жовтень 2012. Процитовано 18 жовтень 2012. 
  2. наприклад: неможливо отримати доступ до процесу Kaspersky Internet Security штатними засобами Windows API, так як відповідні функції перехоплені антивірусом.
  3. Сторінка з man Linux Ubuntu: man сторінка про виклик ptrace Архівовано 21 January 2010[Дата не збігається] у Wayback Machine. і російськомовна версія: Русский переклад на OpenNET
  4. Офіційний опис: The Debugging Application Programming Interface, а також приклади використання: Win32 API. Урок 28. Win32 Debug API I Архівовано 4 March 2010[Дата не збігається] у Wayback Machine.
  5. Цикл статей з перехоплення WindowsAPI функцій від Ms Rem. Архів оригіналу за 23 грудень 2009. Процитовано 31 жовтень 2014. 
  6. Методи доступу і модифікації IAT таблиці досить докладно описані у Хоглунд Г., Батлер Дж. — Руткити: впровадження в ядро Windows. Гл 4 Давнє мистецтво захоплення
  7. Методи впровадження DLL в чужий процес описані досить докладно у Дж. Ріхтера Крістофера Назара Windows via C / C ++. Програмування на мові Visual C ++. Деякі методи впровадження вперше документував сам Дж. Ріхтер
  8. Наприклад, один з перших руткит-детектеров KLISTNER Архівовано 25 July 2010[Дата не збігається] у Wayback Machine.
  9. а б Г. Хоглунд Дж. Батлер Руткіти впровадження в ядро Windows. Глава 4 Давнє мистецтво захоплення
  10. 072/072 / 5.asp вбивство годинного Кріс Касперски, АКА МИЩЪХ Спецвипуск: Хакер, номер # 072, стр. 072-072-5
  11. Наприклад, цим займаються сніфери. Однією з безкоштовних реалізацій захоплення мережевих пакетів є мережевий драйвер рівня NDIS WinPCAP

Література[ред. | ред. код]

  • Джефрі Ріхтер. Windows via C/C++. програмування на мові Visual C++ = en:Windows via C/C++. — СПб : Пітер, 2010. — С. 689-728. — ISBN 978-5-7502-0367-3.
  • Хоглунд Г., Батлер Дж. Руткити: впровадження в ядро Windows = Rootkits.Subverting the Windows kernel. — СПб : Пітер, 2010. — С. 36-58,77-129. — ISBN 978-5-469-01409-6.


Посилання[ред. | ред. код]