fbpx

Каталог статей

Каталог статей для размещения статей информационного характера

Без рубрики

Крэкинг (вершина айсберга)

Здрастуй читач!
Якщо ви читаєте цю статтю, значить, вам набридло годинами шукати кряк або серійник для нової проги, або взагалі чекати поки він вийде. У цьому (як я сподіваюсь) циклі статей я постараюся описати способи “дослідження захисту програм”, і допомогти вам не чекати милості крэкеров, а самим ламати програми. У першій статті я опишу теорію і деякі терміни, а потім вже приступимо до практики в наступних статтях. І так приступимо!
(Кілька абзаців про асм)
Assembler – (в народі асм) низькорівневий програмування мовою (це значить що він найбільш наближений до машинним кодами тобто один оператор (команда) асма відповідають одному машинного коду).Через це програми на асме виходять максимально швидкі і маленькі. Дуже частину на асемблері пишуться критичні (які на інших мовах дуже повільно виконуються) області коду, а також драйвера. Так, наприклад, с++ (мова високого рівня) є підтримка ассемблерних вставок (тобто до основного коду на с++ можна ще вставити код на асме).
Напевно ви запитаєте, а навіщо нам взагалі цей асм?
З радістю відповім. Справа в тому, що будь-яку скомпилированную програму (.exe) можна представити у вигляді мови асемблера. Саме його ви побачите при розборі програми, а не та мова, на якому вона була написана (звичайно, зараз існують програми, які розпізнаю код, на якому було написано програму, але в більшості своїй вони мало ефективні).
Отже, приступимо власне до асму. Якщо ви зовсім не знайомі з програмуванням, вам це здасться складним, але з часом самі будете дивуватися наскільки все легко (ну приблизно як я зараз :).
(Довго думав з чого почати вирішив почати таки з регістрів.)
Регістр – комірка пам’яті, призначена для тимчасового зберігання інформації. В сучасних ОС застосовуються 32-розрядні регістри.
Основних регістрів не так вже багато, це:
EAX – акумулятор
EBX – база
EDX – регістр даних
ECX – лічильник
Основними я їх назвав (хай вибачать мене гуру асма), тому що вони можуть використовуватися для будь-яких цілей (зберігання даних, результати різних функцій… і т. д.)
Ще чотири регістра (ESI, EBP, EDI, ESP) використовуються в більш вузькому колі (напр. без ESI,EDI не обійтися в строкових операціях), але вони також не менш важливі.
Молодші 16-бітні частини цих регістрів застосовуються як самостійні регістри (у загнув… постараюся пояснити)…
(Трохи історії)
Справа в тому що в часи великого DOS, а не існувало 32-розрядних процесорів і вже тим більше 64-розрядних, камені були 16-розрядні. Відповідно і регістри всі були 16-розрядними, і здогадайтеся, як вони називалися?
Ні, не хз. Називалися вони AX, BX, CX, DX… Відповідно з появою 32-розрядних процов додали частина «Е» і вони стали 32-розрядними. Але звернення залишилося! І тепер регістри поділяються на меншу 16-бітну частина (AX, BX, CX, DX, SI, BP, DI, SP) і велику.
(Поняття про стек)
Стек – це ділянка пам’яті, в яку поміщаються дані і параметри для зберігання.
Дані в стек поміщаються досить специфічно. Спробую пояснити на пальцях.
Припустимо, стек – це стіл, у вас біля столу лежить стос паперів – це дані. І вам треба перемістить папір по одному аркушу в таку ж стос на стіл. Відповідно ви будете брати один листок, і класти на стіл, далі ще один листок, але другий листок ви вже повинні будете класти поверх першого, третій поверх другого… і так далі. Так само і в стеку дані лягають як би один на одного. І діставати їх з стека теж потрібно в зворотному порядку.
Приклади роботи зі стеком я наведу в розділі операторів.
(Оператори)
Оператор – це символічна назва команди зрозуміле людині. З допомогою операторів виробляються різні операції з пам’яттю.
Перерахую ті, що знадобляться знати для крекингу (після крапки з комою буду розставляти коментарі при компіляції (складання) програми ці коментарі не враховуються):
MOV – (еквівалентний операторів присвоєння в мовах високого рівня), цей оператор буде часто вам зустрічатися. З допомогою нього і заносяться дані в регістри або змінні. Вона заносить дані з джерела на приймач, при цьому джерело не змінюється.
MOV EAX, 1 ; тепер в EAX знаходиться число 1
MOV EBX, EAX ; тепер і в EAX і EBX знаходиться число 1
MOV peremen, 15 ; тепер у змінній peremen число 15
У першій рядку EAX був приймачем, а 1 – джерелом. У другій EBX – приймач, EAX – джерело. Ну і в останньому рядку peremen – приймач, 15 – джерело.
CALL – виклик процедури. Процедура може бути, як описано в тілі програми, так і знаходиться в підключається DLL. Після відпрацювання процедури управління повертається на команду, яка йде після CALL. В основному процедури викликаються за допомогою міток:
(Підписи)
Мітка – це символічне посилання, якою позначається початок і кінець процедури. При компіляції мітки замінюються адресою, на якій починається процедура. Мітки в основному зроблені для зручності програміста адже не треба обчислювати кожен адресу, а просто звернутися до мітки. Назва мітки можна давати будь-крім імен зарезервовані компілятором (наприклад, назва оператора). Кінець мітки позначається оператором end.
Наприклад:
start: ; початок мітки
end start ; кінець мітки
А тепер приклад оператора call:
start: mov EAX, 15
mov EBX, EAX ; це ви вже знаєте
end start
vuzov: call start ; а ось це і є виклик процедури
mov assa, EBX ; після процедури EBX буде 15, які і заносяться
в змінну assa.
end vuzov
PUSH – оператор який «штовхає» дані в стек. Саме цим оператором заносяться дані в стек.
POP – оператор яким дані витягуються з стека. Наприклад, функція нам повертає число після відпрацювання в регістр EAX (нехай це буде 20). І для того, щоб зберегти його і надалі використовувати штовхаємо його в стек (PUSH EAX), після працюємо з регістром EAX, так як нам потрібно, а коли знову знадобиться число, яке повернула процедура витягуємо його з стека. Головне в стеку стежити за правильністю вилучення даних, і не заплутатися.
CMP – функція яка віднімає з операнда-получатеся операнд-відправник. Фактично найважливіший оператор для крэкера оскільки саме їм зазвичай порівнюються ключ який сгенерила прога і який ввели при реєстрації. Коли порівнюються числа без знака, прапори нуля (ZF) і перенесення (CF) встановлюються командою CMP в такому порядку:
CF ZF
Получательотправитель 0 0
JMP – оператор який змушує процесор продовжувати виконання команд з нового місця в програмі. Відноситься до групи безумовних переходів.
JNZ – оператор, який відноситься до групи умовних переходів тобто виконується лише при певному умови. Це умова «якщо не одно». Наприклад:
CMP EAX, 0 ; якщо EAX не дорівнює 0 то
JNZ START ; стрибаємо на мітку START.
Ну, ось ніби основні оператори виклав, думаю, цей необхідний мінімум повинен знати кожен крэкер, ну а якщо хочете стати хорошим «дослідником» раджу вам добре вивчити асемблер і вміти програмувати на ньому.
Тепер приступаємо безпосередньо до термінів крекингу.
(Тулзы)
Відладчик – основний інструмент, саме та прога в якій ви побачите асемблерний код аналізованій програми. Сучасні відладчики включають в себе безліч функцій, такі як: покрокове трасування, бряки і багато іншого. Також відладчики показують вміст регістрів і стан прапорів. Я назвав дві основні функції, які вам знадобляться, тепер розберемо їх.
Покрокове трасування – функція, за якої виконання програми виконується крок за кроком, тобто виконується одна рядок програми і вона зупиняється, при натисканні кнопки виконується наступний рядок. Фактично ви керуєте виконання програми.
Брейкпоинт (в народі бряк, ще його називають «точка зупинки», але мені ця назва якось не по душі) – уявіть, що вам потрібно зупиниться в якомусь місці програми, наприклад на двохсотої рядку. Не натискати ж 200 разів по кнопці покрокової трасування (це в кращому випадку). Як же це зробити? Все просто, треба поставити бряк на двохсоту рядок і запустити програму на виконання, відладчик зупиниться на тому рядку, яка вам потрібна автоматично.
На даний момент кращими отладчиками вважаються OllyDbg (Оля) і SoftIce (айс, сайс). Особисто я віддаю перевагу Олю, оскільки вона досить проста в обігу, а функціональністю не поступається сайс, всі приклади я буду наводити в ній. Дістати її в мережі просто і важить вона метрів п’ять, шість (в залежності від складання).
Дізассемблер – теж переводить код програми в асемблерний. Найкращим вважається IDA, але я користуюся Win32Dasm (завантажити теж не проблема).
Пакер – програма для стиснення коду, тим самий, зменшуючи розмір. Наприклад, ви написали програму вагою 20 кб, після стиснення вона важить вже 10 кб (це приблизно, все залежить від мови, на якому написана програма і від стилю програміста). Основними вважаються UPX і платний ASpack (хоч і платне, а тисне гірше UPX). Назвав я всього два, але їх набагато більше.
Криптор – програма, яка теж стискає код, але її основний напрямок це зашифрувати код програми від крэкеров. Основною зараз ASprotect. Також як і пакерів протекторів набагато більше ніж я назвав.
Аналізатор – визначає, чим упакована програма. Часто запакована програма чи ні, можна визначити на око в налагоджувач, але це приходить з досвідом, а поки користуйтеся аналізаторами. Найкращий, це PEID (Також їх безліч, я ґрунтуюся на власному імхо).
Розпакувальник – припустимо, пейд показав, що програма запакована UPX. UPX розпаковується самим же UPX (тобто шукаємо в Інтернеті програму для запаковування в UPX і їй розпаковуємо). Ну а якщо показав ASprotect, тоді є два варіанти: 1. Це розпаковувати вручну. 2. Це завантажити автоматичний розпакувальник, який зробили добрі люди. Як ви розумієте тут кожен випадок особливий, тому нічого не раджу.
Ось і весь початковий набір, також є багато тулз для ручної розпакування та іншого, але я думаю для новачка вони поки не до чого. Так що до наступної статті, в якій зламаємо першу прогу і распакуем файл, запакований UPX’сом.
По всіх зауважень, пропозицій звертатися на аську.
P. S.: Заздалегідь вибачаюся за граматичні помилки.
Автор: Filin
ICQ: 226-300-300
Автор не несе відповідальності за шкоду заподіяну після прочитання цієї статті. Стаття в чисто ознайомлювальних цілях.