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

Отлично!

Комментарии (1)

  • 26 августа 2016 в 04:24

    0

    Полезно, большими отладчиками 64 бита не умею отлаживать, а Оля не поддерживает, пришлось забросить увлечение. При случае испытаю сею программу. В Лаборатории раньше был бесплатный курс, хотели детей брать, но меня тоже пустили, только у меня знания ассемблера слабоваты для совсем лёгкого ориентирования в коде

    Тема брутфорса не однозначна, универсален и не зависит от «прямоты» рук

© Habrahabr.ru