Reverse engineering тестового crackme от Лаборатории Касперского

Приветствую сообщество! Давным давно, в 2013 году на Хабре был опубликован пост «Reverse engineering на собеседовании: как мы нанимаем на работу». В нём был предложен тестовый crackme для претендентов на позицию вирусного аналитика. Убедившись, что полного разбора тестового файла в интернете нет, я решил написать свой разбор. Итак, приступим. Crackme 64-разрядный. Запустим его в IDA Pro.

image


Видим слева в списке функций три функции: start — функция, с которой начинается выполнение программы, DialogFunc — эта функция общается с нами и некоторая функция sub_140001000. Рассмотрим диалоговую функцию. Декомпилируем её Hex Rays-ом.

image

В глаза бросается ветвление условий, согласно которому, если некоторая функция sub_140001000 вернет TRUE, то появится сообщение, информирующее нас о отлично проделанной работе, иначе неверно. Разберем нашу заветную функцию sub_140001000. Если мы пропустим её через декомпилятор, то увидим, что в качестве аргумента передается указатель всего на одно значение. Вероятно, это значение берется из диалогового окна и является вводимым ключом. Теперь рассмотрим ассемблерный листинг. Имеется первая проверка условия верности введенных данных. Если условие выполняется, то программа исполняется дальше, если не выполняется, то идет возврат из подпрограммы.

image

Запустим наш crackme под отладчиком. Воспользуемся x64dbg. Поставим breakpoint на нашей первой проверке. В качестве вводимого ключа используем набор цифр 1234567.

image

Как видно, происходит проверка значения регистра edx и числа 13h (в десятичной системе исчисления это 19). Вероятно, это проверка на количество введенных знаков ключа (у нас их 7 и в регистре edx число 7). Попробуем ввести другое количество символов. Запустим отладчик заново. Введем 9 цифр 123456789.

image

Похоже, что так оно и есть. Значит наш ключ должен содержать 19 символов. Вводим 19 символов 1234567890123456789 и переходим к следующему этапу проверки.

image

На этом шаге осуществляется проверка каждого пятого символа ключа на равенство значению 2Dh. Дело в том, что число 2Dh — это шестнадцатиричный код символа "-". Т.е. наш ключ должен иметь вид xxxx-xxxx-xxxx-xxxx. Используем в качестве ключа 1234-5678-9012-3456 и переходим к следующему шагу.

image

А на следующем шаге происходит проверка символов на числовую принадлежность. Порядок проверки такой: берется символ из ключа (в счет не идут каждый пятый символ ключа) и к его шестнадцатиричному коду прибавляется число -30 и полученный результат сравнивается с числом 9. Если меньше, то на проверку берется следующий символ ключа, если больше, то выводится сообщение, что ключ неверный. Идем дальше.

image

На этом шаге осуществляется проверка того, чтобы суммы чисел в блоках были равны. На рисунке выше выделен блок кода, который производит подсчет суммы чисел и область стека, куда эти суммы заносятся. Параллельно суммы блоков суммируются между собой и заносятся в регистр r10. Далее идет деление результата в регистре r10 на 4 (shr r10d,2 — сдвиг на 2 разряда равносилен делению на 4) и сравнение значения из регистра r10 с ранее занесенными значениями в стеке. Отлично. Делаем так, чтобы суммы цифр каждого блока ключа были равны (например 1122-0123-2112-0006) и двигаемся дальше на следующий шаг проверки.

image

Участок кода, выделенный на рисунке выше, проверяет, чтобы расположение символов в каждом последующем блоке ключа не совпадало с предыдущим. В итоге наш ключ имеет вид 1478-7814-1478-7814. Проверяем.

image

image

Отличная работа!

Комментарии 23

    +2
    Круто!
    Возможно я покажусь нубом в этом, хотя, так оно и есть, но нельзя ли просто поменять бинарники в местах, где происходит прыжок если условие не выполняется?
    Например с je на jne?
      +3
      Это можно, но совершенно некрасиво. Ваш вариант — это «патч» от жадности, вышла новая версия — повторяй заново. Вариант автора — это «кейген», вышла новая версия — ничего не надо делать, если алгоритм ключа не сменили. Плюс вдруг далее где-то проверяется целостность кода, какие-то участки проверки не только проверяют ключ и т.д.
        +6
        Суть в том, что в статье алгоритм проверки ключа был полностью разбран.
        А следовательно собеседование пройдет не тот, кто поменял первый je на jmp, а тот, кто смог разобрать все до конца.
          +2
          Всё правильно подмечено. Реверс-инжиниринг тем и отличается от крэкерства, что подразумевает полный разбор алгоритма защиты, а не его банальный обход безусловным переходом.
            0
            «Крекерство» это не только смена переходов, а также кейгенинг, снятие навесных защит и многое другое.
            0
            Это мне понятно, что чем детальнее разберешься как работает программа (кейген), тем больше шансов на получение работы в Лаборатории. У меня вопрос был чисто «спортивный» можно ли вообще подменять условия прыжков в бинарниках. И, судя по ответам, таки можно.
            Спасибо!
          +4
          сдвиг на 2 байта равносилен делению на 4

          Сдвиг на 2 байта (вправо) равносилен делению на 65536. Вероятно, имелся ввиду сдвиг на 2 бита (разряда).
            0
            Да, вы совершенно правы. Я описался. Речь идет о двух разрядах.
            0
            А существует бесплатный или триальный Hex Rays?
              0
              Нет, либо карженный, либо купленный
                +4
                Реверс-инженеры патчат бинарники новой версии из предыдущей.
                  0

                  Ошибся веткой.

                  0

                  Есть Evaluation Version и бесплатная IDA v5.0 (старая версия).

                    +1
                    Вроде бесплатная IDA не содерджит Hex Rays
                      0

                      А, т.е. Hex Rays это ещё и сам декомпилятор называется. Всегда считал IDA и Hex Rays двумя названиями одного и того же, а декомпилятор отдельным. Тогда ошибся.

                  0
                  В целом, ida здесь лишняя. Основная работа сделана через отладчик и его достаточно. Кстати, а что нынче есть подобное hiew, но для x64?
                    0
                    Если память не изменяет, в 2013 была проблема с отладкой x64, и файлик видимо не спроста был такой. Думаю задача именно в умении реверсить без отладчика.
                      +3
                      Не было проблем.
                        0
                        Просветите чем в то время для этого пользовались?
                          0
                          IDA
                            0
                            В 5.5 или даже в 5.2 можно было отлаживать х64.
                    0
                    Отличная статья! А может мне кто нибудь подсказать, насколько реально провести реверс-инжиниринг закрытого кода оси на mp4-плеерах cowon? Проблема в том, что родная ось и оболочка просто безобразны. Хотелось бы иметь возможность как то её кастомизировать. но о её коде вообще ничего не известно. через реверс-инжиниринг возможно разобраться в коде и написать свою кастомную версию прошивки?
                      0
                      Так это смотря, что за cowon. Во-первых, для части из них есть Рокбокс. Во-вторых, если для вашего плеера плеера нет Рокбокса, то и спрашивать нужно у комьюнити, почему его нет и как запилить. А в целом — берём полный образ прошивки, прогоняем её через binwalk и чешем репу в зависимости от выхлопа в консоли. Если прошивка закриптована, то ищем способы расшифровать либо снять дамп с памяти самого плеера. Учитывая, что там ARM, а не x86, ассмеблер там будет сильно другой и вот я, например, без декомпилятора его не понимаю вообще.

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое