Анализ KeygenMe#2 от Paic_Citron

в 14:01, , рубрики: keygenme, reverse engineering, метки: ,

Страница KeygenMe на crackmes.de
You have to find a valid serial.

The only protection is the serial ...!

This is a kind of headache… :D

Good luck
Difficulty: 5 — Professional problem to solve
Platform: Windows
Language: Borland Delphi

Данный keygenme является консольным приложением, поэтому нам не придется искать обработчики нажатий кнопок и прочее. Поэтому ищем условный переход, при выполнении которого нам покажут сообщение об успешном выполнении.

CODE:0040A71D                 mov     edx, offset aSerial ; "Serial: "
CODE:0040A722                 call    Write0LString
CODE:0040A727                 call    @Flush$qqrr15System@TTextRec ; Flush(System::TTextRec &)
CODE:0040A72C                 call    @_IOTest
CODE:0040A731                 mov     edx, offset Serial
CODE:0040A736                 mov     eax, ds:off_40B370
CODE:0040A73B                 call    @ReadLString
CODE:0040A740                 mov     eax, ds:off_40B370
CODE:0040A745                 call    @ReadLn
CODE:0040A74A                 call    @_IOTest
CODE:0040A74F                 mov     eax, ds:Serial
CODE:0040A754                 call    LStrLen
CODE:0040A759                 mov     edi, eax
CODE:0040A75B                 test    edi, edi
CODE:0040A75D                 jle     _end_of_serial
CODE:0040A763                 mov     ds:pos, 1
CODE:0040A76D
CODE:0040A76D _next_char:                             ; CODE XREF: start+2FEj
CODE:0040A76D                 mov     eax, ds:Serial
CODE:0040A772                 mov     edx, ds:pos
CODE:0040A778                 movzx   edx, byte ptr [eax+edx-1]
CODE:0040A77D                 mov     eax, esi
CODE:0040A77F                 call    ProcessCommand
CODE:0040A784                 push    offset test_z   ; a4
CODE:0040A789                 mov     ecx, offset test_y ; a3
CODE:0040A78E                 mov     edx, offset test_x ; a2
CODE:0040A793                 mov     eax, esi        ; a1
CODE:0040A795                 call    GetPosMarker3D
CODE:0040A79A                 cmp     ds:test_x, 2
CODE:0040A7A1                 jnz     _incorrect_pos
CODE:0040A7A7                 cmp     ds:test_y, 4
CODE:0040A7AE                 jnz     _incorrect_pos
CODE:0040A7B4                 cmp     ds:test_z, 4
CODE:0040A7BB                 jnz     _incorrect_pos
CODE:0040A7C1                 cmp     dword ptr [esi+218h], 0Ch
CODE:0040A7C8                 jnz     _incorrect_pos
... вывод сообщения что успешно найден ключ ...
CODE:0040A97B _incorrect_pos:                         ; CODE XREF: start+11Dj
CODE:0040A97B                                         ; start+12Aj ...
CODE:0040A97B                 inc     ds:pos
CODE:0040A981                 dec     edi
CODE:0040A982                 jnz     _next_char
CODE:0040A988
CODE:0040A988 _end_of_serial:                         ; CODE XREF: start+D9j
CODE:0040A988                 mov     eax, ebx
CODE:0040A98A                 call    @WriteLn
CODE:0040A98F                 call    @_IOTest
CODE:0040A994                 mov     eax, ebx
CODE:0040A996                 mov     edx, offset aNanCEstPasBon ; "Nan, c'est pas bon :)"
CODE:0040A99B                 call    Write0LString
CODE:0040A9A0                 call    @WriteLn

Тот же код в синтаксисе Delphi будет выглядеть следующим образом:
Анализ KeygenMe#2 от Paic Citron
Таким образом, для успешного прохождения задания после обработки очередного символа серийного номера координаты некоторой метки должны быть (2, 4, 4) и некоторая переменная должна равняться 12.

Посмотрим что находится в функции GetPosMarker3D (00409D88).
Анализ KeygenMe#2 от Paic Citron
Производится поиск элемента в трехмерном массиве (кубе) у которого выставлен маркер. Тут же можно увидеть размерность куба — 5x5x5.
Каждый элемент куба описывается числом от 0 до 15.
Инициализация куба происходит в функции по адресу 00408D90.
Содержимое инициализированного куба в развернутом виде:
Анализ KeygenMe#2 от Paic Citron

Список возможных значений в элементах куба:

0 обычное поле
1 непроходимое поле (стена)
2 стартовая позиция
3 ключ для прохода через поле с ID = 4
4 поле-триггер с проходом по событию
5 поле-событие для прохода через поле с ID = 6
6 поле-триггер с проходом по событию
7 шлюз в другой уровень
8 повернуть текущий уровень на 90 градусов
9 отправная точка телепорта
A точка назначения телепорта
B поле с константой (1,2,3,6)
C поле с арифметической операцией (+,-,/,*)
D положить результат первым операндом
E посчитать выражение
F выход из куба

Список команд, являющиеся символами из введенного серийного номера, обрабатываемые в функции 0040A2C0:

P двигаться влево (X+1)
I двигаться вправо (X-1)
A двигаться вверх (Y-1)
C двигаться вниз (Y+1)
D двигаться на уровень ниже (Z+1)
U двигаться на уровень выше (Z-1)
- выполнить действие

Необходимыми условиями для команд D и U является расположение маркера в клетке с ID= 7 и наличие такого же приемного шлюза на другом слое по тем же координатам (X, Y).
Команда действия может быть применена при нахождении в поле с ID = 5, 8, B, C, D, E. Обработка действий выполняется в процедуре по адресу 00409FEC.

По сути, внутри этого keygenme находится небольшой пошаговый квест. Основная задача — пройти из поля с координатами (1,0,0) в поле с координатами (2, 4, 4).

Связи в телепортах на четвертом уровне выглядят следующим образом:
Анализ KeygenMe#2 от Paic Citron

Прохождение первых четырех слоев заключается лишь в перемещении по карте. В последнем же пятом слое нужно еще выполнить дополнительное условие для выхода из куба.
Используя набор цифр 1,3,4,6 (поля с ID = B) и арифметических действий +,-,*,/ (поля с ID = C) нужно получить число 12, причем все константы должны быть использованы. Т.е. вариант (3-1)*6 не подходит.
Для использования этого мини-калькулятора надо сначала выполнить действие (команда -) на двух полях с ID = B и одном с ID = C. После этого шагаем на поле с ID = E и выполняем действие. Для использования результата в качестве первого операнда необходимо выполнить действие на поле с ID = D. После всех операций встаем на поле с ID = F.

Код для прохождения первого слоя:
CIIAIPCPPPCCCIIIAIA--AD

Прохождение второго и третьего слоев тесно взаимосвязано, поэтому решение одно на два сразу:
CCCAAAAII---AAPPPDC-AUIIICC---PPAADCI---APUIIPPDIC-PAUIIDIAD

Код для четвертого слоя:
PAICP--CPIUC-ADIICAI-ICAAAAPAD

И наконец для последнего пятого слоя:
CCP-A-II-CC-PP-AAA-II-CCC-PP-AAP-IIII-PCC-P-

Итого имеем серийный номер:
CIIAIPCPPPCCCIIIAIA--ADCCCAAAAII---AAPPPDC-AUIIICC---PPAADCI---APUIIPPDIC-PAUIIDIADPAICP--CPIUC-ADIICAI-ICAAAAPADCCP-A-II-CC-PP-AAA-II-CCC-PP-AAP-IIII-PCC-P-

Вводим его в keygenme и получаем поздравления.
Анализ KeygenMe#2 от Paic Citron

В дополнение к статье два видео прохождения всех слоев куба в бинарном и в псевдографическом видах.

Для анализа содержимого куба после обработки каждого символа была написана простая dll'ка, которая внедрялась в адресное пространство keygenme.

Автор: Veliant

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js