# Часть 19

[\[Используемые материалы\]](https://github.com/yutewiyof/intro-rev-ida-pro/tree/e1367e11cc661f3d69c02ae5f733b7dd168bc5ab/.gitbook/assets/files/19.zip)

В этой главе, у нас уже достаточно знаний и умений, чтобы реверсить оригинальный крекми **CRUEHEAD**а. Поэтому открываем его в **ЗАГРУЗЧИКЕ**, выключая опцию **MANUAL LOAD**. Исходный файл не упакован, так что нет необходимости загружать его вручную.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1LwWFlu6J9v6Xjp%2F01.png?generation=1563265881858370\&alt=media)

Загрузчик остановился здесь. В нашем случае, поскольку это не консольное приложение, то нужно не только анализировать функцию **MAIN**. Мы знаем, что в оконных приложениях существует **ЦИКЛ**сообщений, который обрабатывает взаимодействие пользователя с окном, его выполненные щелчки, нажатия клавиш, движения мыши и т.д. и согласно каждому действию пользователя, цикл запрограммирован для выполнения различных действий с помощью этого кода.

Уже знаем, что первую вещь, которую мы должны сделать - это попробовать найти строки. Если из этого ничего не выйдет, мы должны искать **API** функции или функции, которые использует программа. В нашем случае, строки хорошо видны. Так что будем следовать этому пути.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGWC3KuEIIzBNKqg%2F19-02.png?generation=1563215346864996\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGWEYE-EYplSWA_O%2F19-03.png?generation=1563215346934346\&alt=media)

Я могу видеть перекрёстные ссылки с помощью нажатия на клавишу **X** или **CTRL + X**

После нажатия на эту клавишу, видно, что существует две перекрестные ссылки на эту строку.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGWGQ9YhHupSyZWi%2F19-04.png?generation=1563215347095472\&alt=media)

Давайте посмотрим первую из них.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGWIGC_8Q0iRP9Wz%2F19-05.png?generation=1563215348017435\&alt=media)

Я закрашиваю этот блок в красный цвет, так как из-за этих инструкций происходит ошибка или плохое сообщение.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1NDrX-ij5mBRtSX%2F06.png?generation=1563265889016958\&alt=media)

Давайте посмотрим, как в него можно попасть из программы.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1NRvaaWgRhl6JpC%2F07.png?generation=1563265881799387\&alt=media)

Из этой картинки видно, что соседний блок должен вести в хорошее сообщение. Давайте посмотрим, что внутри этой функции по адресу **0x40134D**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1N_2r6xMozF-zGc%2F08.png?generation=1563265881495999\&alt=media)

После закрашивания, листинг будет выглядеть так.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1NiAOlZu4JSp9ea%2F09.png?generation=1563265881550610\&alt=media)

Другая перекрёстная ссылка на строку **NO LUCK** указывает сюда.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1NtylWpiPms1GC-%2F10.png?generation=1563265881981700\&alt=media)

В другое плохое сообщение можно попасть отсюда.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1O4vKLzS1-eKptQ%2F11.png?generation=1563265881654701\&alt=media) ![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGWWgCcxbYZpZ0TG%2F19-12.png?generation=1563215346901538\&alt=media)

Видим, что аргумент, который передаётся в эту функцию, это адрес (**OFFSET, СМЕЩЕНИЕ, прим. Яши**) глобальной переменной, которую мы будем называть **STRING**. Если сделаем щелчок по этой переменной, то перейдём к адресу где она размещена в программе.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGWYhbuIYFoc44ld%2F19-13.png?generation=1563215347690702\&alt=media)

Видно, что это буфер длиной **3698** байт расположенный по адресу **0x40218E** находящийся в секции **DATA**.

Он имеет две ссылки. Чтобы увидеть, где в коде идёт работа с этой переменной, нажимаем **X**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGW_TrIw0-GPQ-l6%2F19-14.png?generation=1563215347015685\&alt=media)

Видим, что существует перекрёстная ссылка, которая ведёт сюда.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1OpDFz_uN7VRYVN%2F15.png?generation=1563265881773345\&alt=media)

**API** Функция **GetDlgItemTextA** используется для ввода каких либо данных в программу. Давайте посмотрим информацию про неё в **MSDN**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1P-ontcmQJR5u_0%2F16.png?generation=1563265882299025\&alt=media)

Из описания понимаем, что функция помещает в буфер некоторый текст, который введён в контрол с помощью клавиатуры.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGWfrvay4VlxqUWC%2F19-17.png?generation=1563215347166159\&alt=media)

Видно, что существует две записи с тем же дескриптором **HWND**. Следовательно, я предполагаю, что они должны быть полями для ввода имени пользователя и пароля, которые поступают в крэкми, когда мы нажимаем кнопку в окне **REGISTER**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1PL8-tJfGQL8G9C%2F18.png?generation=1563265882099641\&alt=media)

Также, видно, что они имеют такие номера контрола **nIDDlgItem** : **0x3E8** и **0x3E9**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1PSfATdkHNlDY5X%2F19.png?generation=1563265881545449\&alt=media)

Используя программу **GREATIS WINDOWSE**, можно получить информацию о тех окнах, над которыми находится курсор. Взять её можно здесь.

<http://www.greatis.com/wdsetup.exe>

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LmttNQEDVFe8xU3AeuW%2F-Lmttt-I-8EvSC47toHg%2F20.png?generation=1566487075553295\&alt=media)

Я вижу, что верхний **EDIT BOX CONTROL** равен **0x3E8**, а нижний - **0x3E9**.

Также, я могу переименовать буферы, в которые попадают введённые строки. Первый будет называться **STRING\_USER**, а второй **STRING\_PASSWORD**. Оба допускают только максимум **0x0B**символов, несмотря на то, что имеют буферы намного больше.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1Pau3u1CVE9BMwm%2F21.png?generation=1563265883371009\&alt=media)

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

Мы уже видели, что программа обрабатывает буфер **STRING\_USER** здесь.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1PmcdT5LnWIx52l%2F22.png?generation=1563265881540698\&alt=media)

Давайте анализировать, что программа делает здесь с этим буфером, но прежде, мы можем изменить имена функций, так как по-видимому первая обрабатывает буфер **STRING\_USER**, а вторая функция обрабатывает буфер **STRING\_PASSWORD**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1PyemUChxsPsjms%2F23.png?generation=1563265881524759\&alt=media)

Сейчас давайте анализировать функцию **PROCESA\_USER**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1Q9kMa8H5XbwfHC%2F24.png?generation=1563265881804089\&alt=media)

При переименовании переменной, я использую то же самое имя, которое выбрала **IDA**, хотя я мог бы написать **P**\_**STRING**\_**USER**, так как это также указатель на буфер.

С помощью **SET TYPE** я меняю тип функции и её аргументы и обращаю внимание, чтобы аргументы распространились в комментарии.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1QKr6va3PuW19G4%2F25.png?generation=1563265881402264\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1QVx5BS6aNTUDrB%2F26.png?generation=1563265881816271\&alt=media)

Видно, что существует **ЦИКЛ**, который будет читать **БАЙТЫ** буфера **STRING\_USER**. **ЦИКЛ** будет повторяться, пока он не будет равен нулю, т.е. пока не закончится строка и тогда программа сможет перейти на **ЗЕЛЁНУЮ** стрелку.

Здесь Вы видите **ЦИКЛ**. Он увеличивает **ESI**, чтобы читать побайтно каждый символ буфера **STRING\_USER**, и сравнивает каждый из них с числом **0x41**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGWxqN_9hh5IcWj6%2F19-27.png?generation=1563215347112467\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1QsXOJ5RQrOnrF_%2F28.png?generation=1563265882073354\&alt=media)

Мы можем сделать правый щелчок по числу **0x41** и изменить его на символ **A**, который является символом **ASCII** для этого значения.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGX0IExBemMJszIN%2F19-29.png?generation=1563215349053810\&alt=media)

Если значение в **AL** ниже, чем символ **A**, программа перебросит нас в зону **NO LUCK**. Если мы посмотрим в таблицу **ASCII**, увидим, что программа не принимает числа в имени **ПОЛЬЗОВАТЕЛЯ**, а только буквы, так как они больше или равны **A**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGX26W1PLvTIN4L7%2F19-30.png?generation=1563215347674773\&alt=media)

Так что, программа проверяет, чтобы все символы буфера **STRING\_USER** были больше чем **0x41**, т.е. больше или равны символу **A**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGX4K3ZVeTDxH16Y%2F19-31.png?generation=1563215348780073\&alt=media)

Программа, также, с помощью инструкции **JNB** проверяет, чтобы символ был не ниже символа **Z** и если это так передаёт управление на **БЛОК** по адресу **0x401394**. А если иначе, берет следующий символ и повторяет цикл.

Таким образом, программа обрабатывает все заглавные символы за исключением **Z**. Если символ больше или равен **Z**, то программа переходят в блок по адресу **0x401394**. Давайте посмотрим, что там делает программа.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGX6Yk4wZVmteb87%2F19-32.png?generation=1563215347558562\&alt=media)

Я назвал эту функцию **RESTA\_20**, потому что это то, что она делает. Если символ больше символа **Z**, программа вычитает из него число, сохраняет результат и выходит из функции.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1RpzkYMIicw-NJP%2F33.png?generation=1563265881823739\&alt=media)

Другими словами, если вы введете символ с кодом **0x61**, что является маленькой буквой "**a**", программа вычтет из значения **0x20**, и получится значение **0x41**, что является большой буквой "**A**". Программа делает то же самое со всеми символами, которые больше или равны **Z**.

Если символ равен **Z**, то вычитая из него значение **0x20**, получим результат **0x3A**, что является символом двух точек "**:**"

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1Rz3Z_5wxFrq1zl%2F34.png?generation=1563265882284446\&alt=media)

Вопрос таков. Можем ли мы уже создать скрипт для **PYTHON**, чтобы получить кейген?

```python
user=raw_input()
largo=len(user)

if (largo > 0xB):
    exit()

USERMAY=""
for i in range(largo):
    if (ord(user[i]) < 0x41):
        print "CARACTER INVALIDO"
        exit()
    if (ord(user[i]) >= 0x5A):
        USERMAY+= chr(ord(user[i])-0x20)
    else:
        USERMAY+= chr(ord(user[i]))

print "USER",USERMAY
```

Мы видим, что скрипт делает то же самое, что и программа. Он берет по одному символы строки **ПОЛЬЗОВАТЕЛЯ** и сравниваем их с кодом **0x41**. Если символ меньше, он говорит нам, что это недопустимый символ и переносит нас на **ВЫХОД**. Но если он больше или равен **0x5A**, то программа вычитает из него **0x20** и добавляет его к строке **USERMAY**.

Мы видим, что если я введу имя **pePP**, программа транслирует его в имя **PEPP**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1S9GniK49OWijls%2F35.png?generation=1563265881422663\&alt=media)

А если я ввожу символ **Z**, скрипт преобразовывает его в символ **":"** как мы и говорили выше.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGXEbssw9LeVDFZf%2F19-36.png?generation=1563215349741865\&alt=media)

До этого момента, скрипт делает то же самое, что и программа. Посмотрим, что делает программа после выхода из **ЦИКЛА**. Она продолжает выполняться здесь.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGXG1ak26LiXeFpm%2F19-37.png?generation=1563215350797681\&alt=media)

Когда крекми найдёт символ, который равен нулю, он покинет **ЦИКЛ** и перейдёт к блоку по адресу **0x40139C**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1Sb6j2aovwyEnFJ%2F38.png?generation=1563265881774309\&alt=media)

Видим, что перед увеличением **ESI**, крекми **КЛАДЕТ** его в стек, чтобы сохранить исходное значение, которое указывает на начало строки, и затем с помощью инструкции **POP ESI** программа восстанавливает регистр **ESI**, перед тем как войти в функцию по адресу **0x4013С2**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1Sm_kmZW_bIvFjY%2F39.png?generation=1563265881632203\&alt=media)

Мы видим, что это **ЦИКЛ**, который складывает все байты, поэтому я буду называть его **SUMATORIA**(**СУММА**), так что мы можем добавить этот блок в наш скрипт.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGXM7MqfHuoCzu-r%2F19-40.png?generation=1563215348259845\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGXOKjGHhD49Jbv0%2F19-41.png?generation=1563215347186712\&alt=media)

Скрипт суммирует все байты и печатает сумму.

Чтобы проверить правилен ли скрипт, я помещаю **BP** на следующей строке после вызова функции **SUMATORIA** и ввожу **pepe** в поле **user** и **989898** в поле **password**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGXQGHKu_MkKUMm3%2F19-42.png?generation=1563215347212892\&alt=media)

И вижу, что получается сумма равная **0x12A**, так что всё работает правильно.

В этой строке, сумма **XOR**ится с помощью ключа **0x5678**, поэтому я добавляю это выражение также в скрипт.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1TQLFiRe66_khB5%2F43.png?generation=1563265882608555\&alt=media)

Если я выполню эту строчку, скрипт про**XOR**ит сумму и результат будет такой же, как и в программе.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1TbmB8GFTragbRK%2F44.png?generation=1563265881698148\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1Tl-51fnTuomxUb%2F45.png?generation=1563265881306389\&alt=media)

Затем крекми переносит результат из **EDI** в регистр **EAX** и выходит из этого блока.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1Twao-DBrAYro23%2F46.png?generation=1563265882733161\&alt=media)

Затем программа **ПОМЕЩАЕТ** регистр **EAX** в стек и восстанавливает его с помощью инструкции **POP EAX** перед окончательным сравнением. Другими словами в инструкции **CMP EAX**, **EBX**, первым членом будет это значение, которое поступает из функции **PROCESA\_USER**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGX_EvEMFhYjEbum%2F19-47.png?generation=1563215352375713\&alt=media)

Сейчас давайте посмотрим, что программа будет делать с паролем в функции **PROCESA\_PASS**.

Войдя в неё, мы увидим такой код.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGXbdvP57QTmh9xD%2F19-48.png?generation=1563215351605845\&alt=media)

Здесь программа считывает каждый байт и помещает его в регистр **BL** и вычитает из этого значения число **0x30**, которое остается в регистре в **EBX**, затем умножает **EDI** на **0x0A** и суммирует полученное значение с **EBX**.

Я дополняю следующую часть скрипта с помощью этого кода.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1US909zPBHmlAY_%2F49.png?generation=1563265881889016\&alt=media)

Я не ввожу пароль с клавиатуры. Я просто так его тестирую, потому что в кейгене, мы просто вводим пользователя, но я вижу, что если мой пароль равен например числу **989898**.

**SUM2**, это переменная, в которой хранится сумма умноженная на **0xA** и затем к ней прибавляется очередной байт, из которого вычитается значение **0x30**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1UbFypRTwr9IKRi%2F50.png?generation=1563265881548911\&alt=media)

Выполнив скрипт, я вижу, что для пароля **989898** у меня получается результат **f1aca**, что является **HEX** значением строки **989898**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1UmTDsvMfiV1pgA%2F51.png?generation=1563265881538513\&alt=media)

Всё это в нашем скрипте может сводиться в конвертирование строки в **HEX** с помощью функции **HEX()**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGXjrbn5nzJCnDI0%2F19-52.png?generation=1563215347705226\&alt=media)

Скрипт даёт мне точно такой же результат.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGXlwxJ9uNqK3F-Y%2F19-53.png?generation=1563215348355543\&alt=media)

Наконец, скрипт **XOR**ит этот результат с помощью ключа **0x1234** и выходит из блока, чтобы сравнить результат со значением, которое возвратила функция **PROCESA\_USER** в **EAX**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGXn3Fim95PrbLVS%2F19-54.png?generation=1563215349536253\&alt=media)

Так что общая формула будет такой:

**HEX(пароль) ^ 0x1234 = XOR**

Где **XOR** - это результат, который вернула функция **PROCESA\_USER**.

Немного изменим уравнение:

**HEX(пароль) = XOR ^ 0x1234**

Другими словами, если я **XOR**ю результат ключом **0x1234**, я уже почти получаю ответ.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1VUZ6X7LvB2tcC6%2F55.png?generation=1563265881642179\&alt=media)

Если запустим скрипт со строкой **PEPE**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGXrKuzOesH0oY5O%2F19-56.png?generation=1563215351566987\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGXtNOs9Orp9jEi1%2F19-57.png?generation=1563215347792055\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2Fsync%2F1464a7eeb0a48e2fa291f557c14d5cdfddcbc378.png?generation=1617135494346852\&alt=media)

Теперь, у нас уже есть кейген. И нет необходимости преобразовывать результат в десятичную форму, потому что **PYTHON** уже сделал это преобразование.

Здесь я копирую код в кейген.

```python
sum = 0
user = raw_input()
largo = len(user)
if (largo > 0xB):
    exit()
USERMAY = ""
for i in range(largo):
    if (ord(user) < 0x41):
        print "CARACTER INVALIDO"
        exit()
    if (ord(user) >= 0x5A):
        userMAY += chr(ord(user) - 0x20)
    else:
        USERMAY += chr(ord(user))

print "USER",USERMAY

for i in range(len(userMAY)):
    sum += ord (userMAY)

print "SUMATORIA", hex(sum)

xoreado= sum ^ 0x5678

print "XOREADO", hex(xoreado)

TOTAL= xoreado ^ 0x1234

print "PASSWORD", TOTAL
```

Даже в редких случаях с символом **Z**, получаем такой результат:

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1W3eHqt3QXNkcjb%2F59.png?generation=1563265881784992\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGXzb40oxexwZglh%2F19-60.png?generation=1563215347653028\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGY0B2EZ6umb1R13%2F19-61.png?generation=1563215347005829\&alt=media)

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

До следующей главы, друзья.

Автор оригинального текста — Рикардо Нарваха.

Перевод и адаптация на английский язык — IvinsonCLS.

Перевод и адаптация на русский язык — Яша Яшечкин.

Перевод специально для форума системного и низкоуровневого программирования - WASM.IN

22.10.2017

[**Источник: ricardonarvaja.info**](http://ricardonarvaja.info/WEB/IDA%20DESDE%20CERO/CURSO%20DE%20IDA%20TUTES/19-INTRODUCCION%20AL%20REVERSING%20CON%20IDA%20PRO%20DESDE%20CERO.docx)
