![image](https://habrastorage.org/getpro/habr/post_images/6c8/4e4/0ad/6c84e40adbfff2f290a9a5a799536a43.jpg)
Видим слева в списке функций три функции: start — функция, с которой начинается выполнение программы, DialogFunc — эта функция общается с нами и некоторая функция sub_140001000. Рассмотрим диалоговую функцию. Декомпилируем её Hex Rays-ом.
![image](https://habrastorage.org/getpro/habr/post_images/31b/391/8f1/31b3918f1ac1ef87cfddd05e12a4382c.jpg)
В глаза бросается ветвление условий, согласно которому, если некоторая функция sub_140001000 вернет TRUE, то появится сообщение, информирующее нас о отлично проделанной работе, иначе неверно. Разберем нашу заветную функцию sub_140001000. Если мы пропустим её через декомпилятор, то увидим, что в качестве аргумента передается указатель всего на одно значение. Вероятно, это значение берется из диалогового окна и является вводимым ключом. Теперь рассмотрим ассемблерный листинг. Имеется первая проверка условия верности введенных данных. Если условие выполняется, то программа исполняется дальше, если не выполняется, то идет возврат из подпрограммы.
![image](https://habrastorage.org/getpro/habr/post_images/de4/903/f2c/de4903f2c6d6a60840eec30ea7ddef45.jpg)
Запустим наш crackme под отладчиком. Воспользуемся x64dbg. Поставим breakpoint на нашей первой проверке. В качестве вводимого ключа используем набор цифр 1234567.
![image](https://habrastorage.org/getpro/habr/post_images/a9e/c6a/55e/a9ec6a55e7379fbf2fcedc7bdf1ff07e.jpg)
Как видно, происходит проверка значения регистра edx и числа 13h (в десятичной системе исчисления это 19). Вероятно, это проверка на количество введенных знаков ключа (у нас их 7 и в регистре edx число 7). Попробуем ввести другое количество символов. Запустим отладчик заново. Введем 9 цифр 123456789.
![image](https://habrastorage.org/getpro/habr/post_images/ab5/351/bec/ab5351bec6a9e510b0a1b6ed24121688.jpg)
Похоже, что так оно и есть. Значит наш ключ должен содержать 19 символов. Вводим 19 символов 1234567890123456789 и переходим к следующему этапу проверки.
![image](https://habrastorage.org/getpro/habr/post_images/ffa/562/348/ffa562348acf6323e59a8012bb1aaf01.jpg)
На этом шаге осуществляется проверка каждого пятого символа ключа на равенство значению 2Dh. Дело в том, что число 2Dh — это шестнадцатиричный код символа "-". Т.е. наш ключ должен иметь вид xxxx-xxxx-xxxx-xxxx. Используем в качестве ключа 1234-5678-9012-3456 и переходим к следующему шагу.
![image](https://habrastorage.org/getpro/habr/post_images/69e/5c1/6e3/69e5c16e3dab04c73449954261ddfb03.jpg)
А на следующем шаге происходит проверка символов на числовую принадлежность. Порядок проверки такой: берется символ из ключа (в счет не идут каждый пятый символ ключа) и к его шестнадцатиричному коду прибавляется число -30 и полученный результат сравнивается с числом 9. Если меньше, то на проверку берется следующий символ ключа, если больше, то выводится сообщение, что ключ неверный. Идем дальше.
![image](https://habrastorage.org/getpro/habr/post_images/8ef/513/77b/8ef51377b0ed2890a12348f4558434df.jpg)
На этом шаге осуществляется проверка того, чтобы суммы чисел в блоках были равны. На рисунке выше выделен блок кода, который производит подсчет суммы чисел и область стека, куда эти суммы заносятся. Параллельно суммы блоков суммируются между собой и заносятся в регистр r10. Далее идет деление результата в регистре r10 на 4 (shr r10d,2 — сдвиг на 2 разряда равносилен делению на 4) и сравнение значения из регистра r10 с ранее занесенными значениями в стеке. Отлично. Делаем так, чтобы суммы цифр каждого блока ключа были равны (например 1122-0123-2112-0006) и двигаемся дальше на следующий шаг проверки.
![image](https://habrastorage.org/getpro/habr/post_images/243/490/075/2434900755762d12e176fafc946b1610.jpg)
Участок кода, выделенный на рисунке выше, проверяет, чтобы расположение символов в каждом последующем блоке ключа не совпадало с предыдущим. В итоге наш ключ имеет вид 1478-7814-1478-7814. Проверяем.
![image](https://habrastorage.org/getpro/habr/post_images/802/56e/3d1/80256e3d1c9e2292bab513730c085f0e.jpg)
![image](https://habrastorage.org/getpro/habr/post_images/13a/31f/192/13a31f1928c6f1863ddb2aa3740932d3.jpg)
Отличная работа!
Комментарии (23)
RenatSh
25.08.2016 22:45А существует бесплатный или триальный Hex Rays?
dkv
26.08.2016 07:00В целом, ida здесь лишняя. Основная работа сделана через отладчик и его достаточно. Кстати, а что нынче есть подобное hiew, но для x64?
Ghost_nsk
26.08.2016 09:08Если память не изменяет, в 2013 была проблема с отладкой x64, и файлик видимо не спроста был такой. Думаю задача именно в умении реверсить без отладчика.
Itachi261092
30.08.2016 11:29Отличная статья! А может мне кто нибудь подсказать, насколько реально провести реверс-инжиниринг закрытого кода оси на mp4-плеерах cowon? Проблема в том, что родная ось и оболочка просто безобразны. Хотелось бы иметь возможность как то её кастомизировать. но о её коде вообще ничего не известно. через реверс-инжиниринг возможно разобраться в коде и написать свою кастомную версию прошивки?
dkv
30.08.2016 19:42Так это смотря, что за cowon. Во-первых, для части из них есть Рокбокс. Во-вторых, если для вашего плеера плеера нет Рокбокса, то и спрашивать нужно у комьюнити, почему его нет и как запилить. А в целом — берём полный образ прошивки, прогоняем её через binwalk и чешем репу в зависимости от выхлопа в консоли. Если прошивка закриптована, то ищем способы расшифровать либо снять дамп с памяти самого плеера. Учитывая, что там ARM, а не x86, ассмеблер там будет сильно другой и вот я, например, без декомпилятора его не понимаю вообще.
troyanskiy
Круто!
Возможно я покажусь нубом в этом, хотя, так оно и есть, но нельзя ли просто поменять бинарники в местах, где происходит прыжок если условие не выполняется?
Например с je на jne?
JerleShannara
Это можно, но совершенно некрасиво. Ваш вариант — это «патч» от жадности, вышла новая версия — повторяй заново. Вариант автора — это «кейген», вышла новая версия — ничего не надо делать, если алгоритм ключа не сменили. Плюс вдруг далее где-то проверяется целостность кода, какие-то участки проверки не только проверяют ключ и т.д.
saboteur_kiev
Суть в том, что в статье алгоритм проверки ключа был полностью разбран.
А следовательно собеседование пройдет не тот, кто поменял первый je на jmp, а тот, кто смог разобрать все до конца.
starkelec
Всё правильно подмечено. Реверс-инжиниринг тем и отличается от крэкерства, что подразумевает полный разбор алгоритма защиты, а не его банальный обход безусловным переходом.
REU
«Крекерство» это не только смена переходов, а также кейгенинг, снятие навесных защит и многое другое.
troyanskiy
Это мне понятно, что чем детальнее разберешься как работает программа (кейген), тем больше шансов на получение работы в Лаборатории. У меня вопрос был чисто «спортивный» можно ли вообще подменять условия прыжков в бинарниках. И, судя по ответам, таки можно.
Спасибо!