Приветствую сообщество! Давным давно, в 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)


  1. troyanskiy
    25.08.2016 19:04
    +2

    Круто!
    Возможно я покажусь нубом в этом, хотя, так оно и есть, но нельзя ли просто поменять бинарники в местах, где происходит прыжок если условие не выполняется?
    Например с je на jne?


    1. JerleShannara
      25.08.2016 19:09
      +3

      Это можно, но совершенно некрасиво. Ваш вариант — это «патч» от жадности, вышла новая версия — повторяй заново. Вариант автора — это «кейген», вышла новая версия — ничего не надо делать, если алгоритм ключа не сменили. Плюс вдруг далее где-то проверяется целостность кода, какие-то участки проверки не только проверяют ключ и т.д.


    1. saboteur_kiev
      25.08.2016 19:15
      +6

      Суть в том, что в статье алгоритм проверки ключа был полностью разбран.
      А следовательно собеседование пройдет не тот, кто поменял первый je на jmp, а тот, кто смог разобрать все до конца.


      1. starkelec
        26.08.2016 02:58
        +2

        Всё правильно подмечено. Реверс-инжиниринг тем и отличается от крэкерства, что подразумевает полный разбор алгоритма защиты, а не его банальный обход безусловным переходом.


        1. REU
          26.08.2016 11:31

          «Крекерство» это не только смена переходов, а также кейгенинг, снятие навесных защит и многое другое.


      1. troyanskiy
        26.08.2016 09:51

        Это мне понятно, что чем детальнее разберешься как работает программа (кейген), тем больше шансов на получение работы в Лаборатории. У меня вопрос был чисто «спортивный» можно ли вообще подменять условия прыжков в бинарниках. И, судя по ответам, таки можно.
        Спасибо!


  1. dymanoid
    25.08.2016 19:58
    +4

    сдвиг на 2 байта равносилен делению на 4

    Сдвиг на 2 байта (вправо) равносилен делению на 65536. Вероятно, имелся ввиду сдвиг на 2 бита (разряда).


    1. starkelec
      26.08.2016 02:56

      Да, вы совершенно правы. Я описался. Речь идет о двух разрядах.


  1. RenatSh
    25.08.2016 22:45

    А существует бесплатный или триальный Hex Rays?


    1. 0xcffaedfe
      25.08.2016 22:50

      Нет, либо карженный, либо купленный


    1. Deosis
      26.08.2016 06:59
      +4

      Реверс-инженеры патчат бинарники новой версии из предыдущей.


      1. xaizek
        27.08.2016 15:16

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


    1. xaizek
      27.08.2016 15:16

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


      1. RenatSh
        27.08.2016 15:51
        +1

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


        1. xaizek
          27.08.2016 17:04

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


  1. dkv
    26.08.2016 07:00

    В целом, ida здесь лишняя. Основная работа сделана через отладчик и его достаточно. Кстати, а что нынче есть подобное hiew, но для x64?


    1. Ghost_nsk
      26.08.2016 09:08

      Если память не изменяет, в 2013 была проблема с отладкой x64, и файлик видимо не спроста был такой. Думаю задача именно в умении реверсить без отладчика.


      1. REU
        26.08.2016 11:33
        +3

        Не было проблем.


        1. Ghost_nsk
          26.08.2016 12:35

          Просветите чем в то время для этого пользовались?


          1. REU
            26.08.2016 13:17

            IDA


            1. REU
              26.08.2016 13:23

              В 5.5 или даже в 5.2 можно было отлаживать х64.


  1. Itachi261092
    30.08.2016 11:29

    Отличная статья! А может мне кто нибудь подсказать, насколько реально провести реверс-инжиниринг закрытого кода оси на mp4-плеерах cowon? Проблема в том, что родная ось и оболочка просто безобразны. Хотелось бы иметь возможность как то её кастомизировать. но о её коде вообще ничего не известно. через реверс-инжиниринг возможно разобраться в коде и написать свою кастомную версию прошивки?


    1. dkv
      30.08.2016 19:42

      Так это смотря, что за cowon. Во-первых, для части из них есть Рокбокс. Во-вторых, если для вашего плеера плеера нет Рокбокса, то и спрашивать нужно у комьюнити, почему его нет и как запилить. А в целом — берём полный образ прошивки, прогоняем её через binwalk и чешем репу в зависимости от выхлопа в консоли. Если прошивка закриптована, то ищем способы расшифровать либо снять дамп с памяти самого плеера. Учитывая, что там ARM, а не x86, ассмеблер там будет сильно другой и вот я, например, без декомпилятора его не понимаю вообще.