Reverse engineering тестового crackme від Лабораторії Касперського v2.0

В продовження мого попереднього розбору «Reverse engineering тестового crackme від Лабораторії Касперського». Знайшов на просторах інтернету ще один варіант crackme від Лабораторії Касперського. Автор застосував брутфорс для його вирішення. Цей грубий «крякерский» метод нам тут не підійде. Нас цікавить розбір алгоритму перевірки ліцензійного ключа. Можна, звичайно, зробити величезну вибірку правильних ключів і спробувати знайти закономірність, але мені здається, що краще трохи пореверсить. І так почнемо. Початок у crackme таке ж, як і в попередній статті: ключ повинен містити 19 символів, кожен 5-ий символ повинен бути "-" і всі символи повинні бути цифрами. Перейдемо до цікавого. Використовуємо в якості пробного ключа 1234-5678-9012-3456.

image
У виділеній ділянці коду міститься алгоритм перевірки блоків ключа. Розглянемо його докладно.
000000014000106E | movsx eax,byte ptr ds:[r9] 
 
0000000140001072 | add al,byte ptr ds:[r9+1]
 
0000000140001076 | add al,byte ptr ds:[r9+2]
 
000000014000107A | movsx ecx,byte ptr ds:[r9+3]
 
000000014000107F | add eax,ecx
 
0000000140001081 | add eax,ecx
 
0000000140001083 | add eax,ecx
 

На цій ділянці коду виконується операція підсумовування шістнадцяткові коди символів блоку в такому порядку — складаються перші три символи блоку ключа (а точніше — їх шестнадцатиричные коди) і до цій сумі три рази додається код останнього символу блоку (наприклад, якщо наш перший блок ключа 1234, то ця сума буде виглядати так 31h+32h+33h+34h+34h+34h=132h) і далі це число заноситься в акумулятор (RAX). Далі йде ключова рядок коду
0000000140001091 | lea ecx,dword ptr ds:[rcx+rax-150]
 

Ця рядок заносить в ECX результат наступної операції: RCX зберігається код останнього символу блоку і до цього коду додається значення, що зберігається в RAX, а як ми пам'ятаємо, там зберігається результат операції з попереднього кроку. Після, з цієї суми віднімається 150h. На нашому прикладі це виглядатиме так: 34h+132h-150h=16h. Далі це значення заноситься в стек наступним рядком:
0000000140001098 | mov dword ptr ds:[rbx-4],ecx
 

І таку операцію програма проводить з кожним блоком ключа, паралельно підсумовуючи результати, які заносять в стек даних, в регістрі r10. Після того, як всі результати будуть занесені в стек і їх сума поміщена в регістр r10, програма розділить вміст регістра r10 на 4 (shr r10d,2) і перевірить на рівність кожне занесене значення в стек з результатом, отриманим від ділення. Якщо значення будуть рівними, то перевірка виконується далі, якщо ж ні, то програма скаже, що ключ невірний. За результатами даного аналізу ми маємо наступне — результати обчислень, згідно алгоритму за адресою 140001091, по кожному блоку повинні бути рівні один одному. Якщо ми спробуємо ключ 1234-1234-1234-1234, то перевірка пройде цей крок і почнеться останній етап перевірки:

image
Цю ділянку коду здійснює контроль, щоб розташування символів у кожному наступному блоці ключа не збігалося з розташуванням символів в попередньому блоці. Згенеруємо ключ, відповідно до зроблених висновків. Спробуємо 9870-5781-1872-7503

image
image
Відмінно!
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.