• Главная
  • Карта сайта
Не найдено

Захист програм від злому







Головна / Інформаційна безпека / статті


Ця стаття присвячена досить актуальною в даний час тематиці - захист програм від злому і нелегального копіювання. Цій темі присвячено багато статей, одна з найбільш цікавих (з тих, які попалися мені) - стаття "Захист shareware-програм" Володимира Каталова в Компьютерра Online # 240. Він навів ряд порад з написання shareware програм і я не хочу повторюватися - сходіть, почитайте.

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

З невідомої мені причини в більшості сучасних програм дана захист зроблена одноманітно і для її зняття необхідно 10-15 хвилин. У цій статті я постараюся поділитися досвідом в побудові систем захисту. Можу відразу попередити - хорошому хакеру протистояти практично марно, та й не потрібно - при бажанні будь-який захист може бути зламана, це питання часу.

Сучасний хакер має в своєму арсеналі набір різноманітних утиліт для злому.

Їх можна поділити на кілька категорій

  • Відладчики. Дозволяють переривати виконання програми при досягненні заздалегідь заданих умов, виробляти покрокове виконання програми, змінювати вміст пам'яті і регістрів і т.п. Найбільш популярним, зручним і потужним є відладчик SoftICE, який при досить примітивному інтерфейсі володіє пристойними можливостями і дуже стабільно працює.
  • Дизасемблери. Проводять дизасемблювання програми для подальшого вивчення отриманого коду. Один з найбільш потужних і популярних - IDA. Від дизассемблера досить легко захиститися - зашифрувати або заархівувати програму. Тоді дізассембліруется тільки архіватор або кодировщик. Однак той-же IDA має потужний вбудований скриптовой мову, що дозволяє виробляти розшифровку програми
  • Засоби моніторингу. Це набір утиліт, які відстежують операції з файлами, реєстром, портами і мережею.
  • Засоби пасивного аналізу програми. Показують різну інформацію про програму - витягують ресурси, показують зв'язку, що використовуються бібліотеки. Класичний приклад - утиліта DEPENDS.EXE з комплекту Visual Studio. Вона показує, які бібліотеки використовуються програмою і які функції імпортуються.
  • Інші утиліти. Їх велика кількість (можна знайти на диску типу "Все для хакера", причому в достатку). Це різноманітні редактори, аналізатори ...
Найбільш популярні такі програми моніторингу:
  • FileMon - утиліта, що дозволяє вести моніторинг всіх операцій з файлами. Має зручний фільтр, може зберігати звіт в файлі. Тому немає сенсу робити "секретні" файли десь в Windows / System - їх елементарно знайти.
  • RegMon - аналог FileMon, тільки ведеться моніторинг всіх операцій з реєстром. Аналогічно файлів, безглуздо створювати в реєстрі "секретні" ключі - вони відразу кидаються в очі.
  • PortMon - моніторинг роботи з портами введення / виводу
  • TCP_VIEW - монітор з'єднань по TCP-IP
  • RegUtils - набір утиліт для контролю за реєстром - робить копії реєстру, дозволяє порівнювати копії і переглядати зміни.
Утиліти типу FileMon можуть різко спростити злом програми - легко визначити місце, в якому програма звертається до вказаного файлу або ключу реєстру.

Як ввести реєстраційний код. Введення пароля або реєстраційного номера є відповідальною справою - хакер постарається відловити адресу пам'яті, в який буде записаний пароль. Потім на звернення за цією адресою ставиться крапка зупинки (команда BPM в SoftICE), що дозволяє зловити початок процедури перевірки реєстраційного коду. Якщо для введення використовуються стандартні елементи введення Windows, то алгоритм дій хакера можна формалізувати і виглядає він приблизно так:

  1. Встановлює точку зупину на зчитування тексту з стандартного елемента вводу (функції GetWindowText, GetGlgItemText модуля KERNEL32)
  2. При виклику цієї функції аналізуємо її параметри і таким чином визначаємо, за якою адресою буде розміщено прочитуване значення і ставимо звернення до цієї області пам'яті точку зупину. А достовірності певного адреси легко переконатися - після виконання функції там з'явиться введений рядок
  3. При спрацьовуванні цієї точки зупину ми потрапляємо в аналізатор введеного значення і або робимо генератор реєстраційних ключів, або ламаємо процедуру перевірки. І те, і інше дуже просто зробити - достатньо тільки вивчити асемблер і API

Набір цих дій стандартний і мені не раз траплялися докладні керівництва типу "Злом Windows програм - крок за кроком", орієнтовані на просунутого користувача.

Розглянь кілька рішень, які можуть утруднити злом на цьому етапі.

Рада _0. Намагайтеся якомога менше застосовувати стандартні функції (особливо API-шні) і компоненти VCL. Так що Assembler, Assembler і ще раз Assembler ...

Сутність цієї ради сподіваюся очевидна - сучасні дизасемблери вміють розпізнавати стандартні процедури високорівневих мов, а API - взагалі окрема розмова - SoftICE володіє дивовижною можливістю - завантажувати символьні імена для будь-яких зазначених бібліотек (особливо для KERNEL32.DLL) - налагодження різко спрощується, тому що ми бачимо імена викликаються функцій і можемо ставити точки зупину на виклик функцій по їх імені.

Рада 1. Застосовуйте нестандартний спосіб введення пароля.

Найпростіший шлях - написати свій візуальний компонент для введення реєстраційного коду. Він звичайно повинен буде обробляти події від клавіатури, але момент зчитування коду не можна зловити побитими методами. Це вже щось, але є другий спосіб злому, заснований на пошуку введеного коду в пам'яті. Для цього в SoftICE є зручна команда "S стартовий адресу L довжина 'зразок'", яка дозволяє знайти введене значення в пам'яті.

Порада 2. Не зберігайте введений код в одному місці!

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

Порада 3. Не зберігайте введений код відкритим текстом!

Отже, що ж слід зробити. Для початку необхідно завести в програмі 5-10 змінних типу STRING і після введення коду переписати введене значення в них. Робити це краще за все не в одному місці, а розподілити по програмі. Таким чином пошук дасть купу адрес, за якими буде знаходитися введений код. Я в такому випадку поступаю так - по таймеру створюю в динамічної пам'яті нову строкову змінну, пишу в неї код. Потім на наступному спрацьовуванні таймера створюю нову змінну, переписую в неї код, а стару знищую. При певному навику можна заполонити пам'ять значеннями введеного коду і зробити пошук майже марним. Причому таке копіювання можна поєднати з перевіркою коду або емуляцією цієї перевірки. Потім з цим рядками непогано вдіяти будь-які операції - порівняти з чимось ...

Поради 3 і 1 можна об'єднати - створити свій компонент, який дозволить вводити код нестандартним способом з його одночасною кодуванням.

Аналіз реєстраційного коду. Отже, код введено і вжиті заходи для того, щоб його було непросто знайти (хоча знайти його можна, але цей час, навик ...). Тепер наступний крок - аналіз. Тому відразу порада:

Рада 4. Ні в якому разі не аналізуйте код відразу після його введення.

Чим далі пропонується ввести пароль від його аналізу, тим краще. Найрозумніше - після введення коду подякувати користувача за співпрацю і повідомити, що з часом буде виконана реєстрація програми. А аналіз коду зробити, наприклад, через 1-2 хвилини в зовсім іншому місці програми.

Рада 5. Не перевіряйте код тільки в одному місці і не пишіть для перевірки функцію.

Досить знайти і відключити цю перевірку, і захист зламана. Якщо перевірок кілька, вони різні і розподілені за програмою, то злом важко.

Рада 6. Не перевіряйте пароль одним алгоритмом.

Рекомендується розробити 2-3 алгоритму перевірки, наприклад 1-2 цифри повинні ділитися на 3, а 3-7 накладені за будь-якою алгоритму на ім'я користувача повинні дати в сумі 4. Ці дві перевірки здійснюємо в різних місцях з досить великим тимчасовим розносом - зламавши перший метод хакери не буде здогадуватися про існування ще кількох, які проявляться з часом.

Рада 7. Ні в якому разі не слід нічого робити після перевірки. З невідомої причини більшість програм виглядають приблизно так

IF NOT (SuperRegCodeCheck) then Begin ShowMessage ( 'Невірний код, подальша робота неможлива'); halt; end;

У прикладі якась процедура перевіряє код і при розбіжності активно діє, які буквально кричать "ось вона де захист !!". Найкращий крок - почекати день-два (або хоча б хвилин 15). Причому всі дії по перевірці слід якомога далі віднести від видачі повідомлень та інших дій, що вживаються при виявленні неправильного коду.

Рада 8. Відволікаючі маневри.

Крім реальних функцій перевірки коду дуже непогано зробити пару бутафорських - вони будуть викликатися після введення коду, проводити активні маніпуляції з введенням значенням, видавати повідомлення про некоректність введеного коду ... - тобто відволікати увагу від реальної перевірки.

Рада 9. Не зберігайте результатів перевірки в змінної і не використовуйте її для явного згортання функцій незареєстрованої програми.

Класичний приклад порушення цього правила

IF NOT (LegalCopy) then ShowMessage ( 'Збереження працює тільки в зареєстрованій версії') else SaveFile;

Таким чином елементарний аналіз показує, що змінна LegalCopy зберігає результат перевірки і поставивши на неї точку зупину можна виловити саму перевірку. Відредагувавши це значення в пам'яті можна тимчасово зробити копію "зареєстрованої", а установка точки зупину на зміну цієї змінної виведе на місце її перевірки. Та й злом зводиться до того, що функція перевірки коду урізається до двох команд асемблера:

MOV [адреса LegalCopy], 1 RET

Рада 10. (випливає з 9) Не зберігайте результатів перевірки на диску або в реєстрі.

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

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

Загальні поради щодо захисту програм

  • CRC - контрольні суми. Будь-який файл, рядок або блок даних можна захистити контрольною сумою, яку потім можна розрахувати і порівняти з еталоном. При порівнянні з еталоном звичайно слід звістку обережно - см. Перші 11 порад. Отже, рада 12. Захищайте програми і дані контрольними сумами. Це допоможе не тільки від злому, але і захистить програми від вірусу або впровадження троянця.
  • Застосовуйте шифровку програм і даних. Дуже непогано стиснути програму і дані. Я, наприклад, розробив свій власний архіватор - RAR-у і ZIP-у він конкуренції не складе, але стислі їм дані розтиснути дуже непросто, доведеться добряче попрацювати. Та й змінити їх проблематично - доведеться розтиснути, змінити і стиснути.
  • Вилов покрокової налагодження програми. Існує багато способів, я свого часу провів ціле дослідження цього питання під DOS, назбирав і придумав не менше 20 методів, але вони мало прийнятні під Windows. Найпростіший і надійний спосіб - таймер. При роботі програми періодично фіксуємо системний час і розраховуємо час роботи фрагментів коду між ними. І якщо 200-400 команд процесора працюють 2-3 хвилини, то тут є над чим замислитися.
Рада 13. Не визначайте дату і час стандартними способом !! Придумайте що-небудь оригінальне.

Рада 14.Не варто зберігати що-небудь секретне в файлах або реєстрі. Робота з файлами або реєстром може бути детально запротокольовано і проаналізована, і все таємне стане явним.

Рада 15.Не зберігайте нічого важливого відкритим текстом, особливо повідомлення типу "Це незареєстрована версія ...", "Введений пароль не вірний ...".
Вони для хакера - як для бика червона ганчірка, і дійсно - знаходимо таке повідомлення, ставимо точку зупину на звернення до ділянки пам'яті з цим повідомленням і отримуємо можливість спіймати момент видачі цього повідомлення.

Поради щодо створення міток для організації обмеження за часом

Захист "обмеження часу роботи" полягає в тому, що програма яким чином фіксує момент свого першого запуску і працює встановлений час (зазвичай 20-30 днів). Після закінчення цього терміну програма відмовляється запускатися. Як перевірити поточну дату я вже десь тут писав - нестандартним способом, наприклад за датою на файлах реєстру або новоствореного своєму файлі. Весь фокус в іншому - як зафіксувати на комп'ютері дату першого запуску (природно так, щоб изничтожение програми і її повторна установка не давали ефекту). Використання "секретних" файлів в системних папках або зміни в існуючих файлах легко відловити за допомогою FILEMON. Реєстр той же відпадає через REGMON. Інші методи (типу записи в ВООТ сектор ...) теж неприйнятні - не ті часи, по Windows все це не пройде. Найбільш оригінально (на мій погляд) прошити дату в саму програму і постійно оновлювати її на своєму сайті (природно, автоматично). Таким чином відлік неявно йде від моменту завантаження програми з сайту. Є тут правда і мінус - після завершення терміну можна повторно завантажити цю програму і отримати ще 15-20 днів .... З іншого боку це оригінально - користувачеві рано чи пізно набридне викачувати цю програму і він або відмовиться від неї, або купить. Але при цьому варто пам'ятати, що програму можна завантажити кілька разів і порівняти варіанти, виявивши, де лежить дата. Тому варто подбати про те, щоб змінився майже весь файл (наприклад, змінити пару опцій компілятора)

Поради щодо формування реєстраційних кодів

Формування кодів може вестися за такими основними напрямками:

  • Жорстко фіксовані коди, прошиті в програму. Їх зазвичай трохи і їх розголос зводить захист до нуля.
  • Якийсь алгоритм перевірки коду. Трохи краще першого, але лише трохи. Візьміть за приклад код Windows - його знає будь-який користувач
  • Алгоритм перевірки коду, який використовує ім'я користувача. Очевидно, що для кожного імені буде унікальний номер (або номери - їх може бути кілька, залежно від алгоритму). Це вже краще, але нелегальне поширення тримається на егоїзмі зареєстрованих користувачів - ніщо не заважає їм зрадити ім'я / пароль розголосу, але тоді хоча б можна обчислити винуватця і заблокувати його код
  • Алгоритм перевірки коду, який використовує ім'я користувача і деякі унікальні або динамічно змінюються параметри, наприклад інформацію про комп'ютер. Це надійно, дає прив'язку до комп'ютера, але в наше століття постійних апгрейдів дуже незручний.
  • On-Line реєстрація. Полягає в тому, що програма в On-Line зв'язується з сайтом розробників (або компанії, що здійснює продужу софта) і передає туди реквізіти користувача. У відповідь програмі передається реєстраційна інформація. Цей метод може і хороший для ряду програм, але на мій погляд не витримує ніякої критики з двох міркувань:
    1. Ніхто не може гарантувати, що конкретно передасть програма в Інет. А передати вона може все, що завгодно - параметри комп'ютера, паролі, будь-які дані і т.п.
    2. Конкретний користувач може не мати доступу до Інет. Це особливо важливо для програм, робота яких не пов'язана безпосередньо з Мережею. І зареєструвати таку програму його практично ніхто до себе на комп'ютер не пустить (з міркувань п.п. 1)

Рекомендувати тут що-небудь марно, але я наприклад використовую різновиди методу 3.


PS: Як висновок я хочу наголосити на двох моментах:
  • Ця стаття написана в 1998 році і розміщена в Інтернет в 1999. З цього моменту в комп'ютерному світі все змінилося, але основні концепції залишилися. Коли буде час, я напишу нову статтю - з урахуванням появи нових операційних систем.
  • Стаття орієнтована на починаючого читача

Провайдеры:
  • 08.09.2015

    Batyevka.NET предоставляет услуги доступа к сети Интернет на территории Соломенского района г. Киева.Наша миссия —... 
    Читать полностью

  • 08.09.2015
    IPNET

    Компания IPNET — это крупнейший оператор и технологический лидер на рынке телекоммуникаций Киева. Мы предоставляем... 
    Читать полностью

  • 08.09.2015
    Boryspil.Net

    Интернет-провайдер «Boryspil.net» начал свою работу в 2008 году и на данный момент является одним из крупнейших поставщиков... 
    Читать полностью

  • 08.09.2015
    4OKNET

    Наша компания работает в сфере телекоммуникационных услуг, а именно — предоставлении доступа в сеть интернет.Уже... 
    Читать полностью

  • 08.09.2015
    Телегруп

    ДП «Телегруп-Украина» – IT-компания с 15-летним опытом работы на рынке телекоммуникационных услуг, а также официальный... 
    Читать полностью

  • 08.09.2015
    Софтлинк

    Высокая скоростьМы являемся участником Украинского центра обмена трафиком (UA — IX) с включением 10 Гбит / сек... 
    Читать полностью