Захист програм від злому, HTML, XML, DHTML, Інтернет-технології, статті

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

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

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

Відладчики. Дозволяють переривати виконання програми при досягненні заздалегідь заданих умов, проводити покрокове виконання програми, змінювати вміст пам’яті і регістрів і т.п. . Найбільш популярним, зручним і потужним є відладчик softice, який при досить примітивному інтерфейсі володіє пристойними можливостями і дуже стабільно працює.
Дизасемблери. Проводять дизасемблювання програми для подальшого вивчення отриманого коду. Один з найбільш популярних – ida. Від дизассемблера досить легко захиститися – зашифрувати або заархівувати програму. Тоді дізассембліруется тільки архіватор або кодіровщік.
Засоби моніторингу. Це набір утиліт, що відстежують операції з файлами, реєстром, портами і мережею.
Засоби пасивного аналізу програми. Показують різну інформацію про програму – витягують ресурси, показують зв’язку, використовувані бібліотеки. Класичний приклад – утиліта depends.exe з комплекту visual studio. Вона показує, які бібліотеки використовуються програмою і які функції імпортуються.
Інші утиліти. Їх велика кількість (можна знайти на диску типу “Все для хакера”, причому в достатку). Це різноманітні редактори, аналізатори …
Найбільш популярні такі програми моніторингу:

filemon – утиліта, що дозволяє вести моніторинг всіх операцій з файлами. Має зручний фільтр, може зберігати звіт у файлі. Тому немає сенсу робити “секретні” файли десь в windows / system – їх елементарно знайти.

regmon – аналог filemon, тільки ведеться моніторинг всіх операцій з реєстром. Аналогічно файлів, безглуздо створювати в реєстрі “секретні” ключі – вони відразу кидаються в очі.

portmon – моніторинг роботи з портами введення / виводу

tcp_view – монітор з’єднань по tcp-ip

regutils – набір утиліт для контролю за реєстром – робить копії реєстру, дозволяє порівнювати копії та переглядати зміни.

Утиліти типу filemon можуть різко спростити злом програми – легко визначити місце, в якому програма звертається до вказаного файлу або ключу реєстру.

Основи побудови захисту – крок за кроком

Як ввести реєстраційний код. Введення пароля або реєстраційного номеру є відповідальною справою – хакер постарається відловити адресу пам’яті, в який буде записаний пароль. Потім на звернення з цього адресою ставиться крапка зупинки (команда bpm в softice), що дозволяє зловити початок процедури перевірки реєстраційного коду. Якщо для введення використовуються стандартні елементи введення windows, то алгоритм дій хакера можна формалізувати і виглядає він приблизно так:

Встановлює точку зупину на зчитування тексту з стандартного елемента вводу (функції getwindowtext, getglgitemtext модуля kernel32)
При виклику цієї функції аналізуємо її параметри і таким чином визначаємо, за якою адресою буде розміщено прочитуване значення і ставимо звернення до цієї області пам’яті точку зупину. А достовірності певного адреси легко переконатися – після виконання функції там з’явиться введена рядок
При спрацьовуванні цієї точки зупину ми потрапляємо в аналізатор введеного значення і або робимо генератор реєстраційних ключів, або ламаємо процедуру перевірки. І те, і інше дуже просто зробити – достатньо тільки вивчити асемблер і 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.


Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*