# Глава 14

Прежде всего я собираюсь объяснить, как решается крэкми, над которым мы начали работать в главе 13.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-66d2195235d83caadeafd3b9f89e3b3ea18f92ae%2F1.png?alt=media)

Это mielecrackme [\[ссылка\]](https://github.com/yutewiyof/intro-cracking-with-ollydbg/blob/master/.gitbook/assets/files/1/mielecrackme1.zip), загруженный в OllyDbg, и его точка входа. Посмотрим, какие функции API используются с помощью SEARCH FOR-NAME (LABEL) IN CURRENT MODULE.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-e73beab52b6e4b8ba35e7623855b6f59a8730277%2F2.png?alt=media)

Вот список найденных api-функций.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-69685d5611ecd6a2f4ed7175adbab458ea32e14e%2F3.png?alt=media)

Среди них указаны самые важные: GetWindowTextA, использующаяся при вводе серийного номера, lstrcmpA, которая встречалась в предыдущей главе и используется для сравнения строк, и MessageBoxA, отображающая сообщение о том, верен ли серийный номер или нет.

Мы можем установить BPX на эти функции, чтобы произошла остановка, когда будет введён неверный серийный номер, но в данном случае, который весьма прост, можно сделать всё гораздо быстрее, если посмотреть СТРОКИ, используемые программой.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-4c9adb2aa20e752d17bddda0e5a89c238a04071d%2F4.png?alt=media)

Выполнение SEARCH FOR – ALL REFERENCED TEXT STRINGS даёт нам список строк, которые использует крэкми.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-09d9f58e386881087d7bc03eafda943370b0d828%2F5.png?alt=media)

Здесь видим как строку, отображающуюся как в успешном случае, так и строку, показывающуюся в случае неудачи. Если сделаем на какой-нибудь из них двойной клик мышью, то окажемся в окрестностях MessageBoxA. Попробуем сделать двойной клик на "YOU ENTERED THE RIGHT PASSWORD" ("Вы ввели правильный пароль").

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-ef999344d7433cdbce4fa373758c26d719c79fec%2F6.png?alt=media)

Оказались в соответствующем месте.

Сначала идёт GetWindowTextA, считывающая серийный номер, который мы напечатали, затем lstrcmpA, сравнивающая считанный номер с правильным, а затем, если они верны, MessageBoxA показывает "YOU ENTERED THE RIGHT PASSWORD", а если нет, то происходит переход к другому MessageBoxA, отображающему "YOU SHOULD TRY AGAIN, IT'S SO EASY" ("Попробуй ещё раз, это же так просто").

Установим BPX на вызове lstrcmpA, чтобы посмотреть, что она сравнивает.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-b59eec9b5f94beac67a4fe706746fabfe6dddff0%2F7.png?alt=media)

Запустим программу с помощью F9.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-bf74474a5320c201ded0d4e18d0f5ce436e8cda5%2F8.png?alt=media)

Выскочило окно ввода серийного номера. Введём в него что-нибудь вроде 989898.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-c508bee4e886ab5120b5678866bf62335cc7618c%2F9.png?alt=media)

Нажмём кнопку CHECK, чтобы сработал установленный нами BPX.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-fe01335a446881d85756deee280184bd5493be0a%2F10.png?alt=media)

Видим, что OLLY показывает и параметры функции, которые являются двумя сравниваемыми строками, в данном случае сравниваются строки "989898" и "cannabis".

Чтобы выполнить вызов этой API-функции, нажмём F8.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-cc42fb3d06a0d15b4285c2a7bc6fc67a67109318%2F11.png?alt=media)

В EAX помещается результат, равный FFFFFFFF или -1, а это означает, что строки не одинаковые.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-beff6a2c8572ef1252c1f60d6308d0c5c8c1a683%2F12.png?alt=media)

В результате этого сравнения флаг Z неактивен и инструкция JNZ выполняет переход, т.к. флаг Z равен нулю (вспомним, что JNZ совершает переход, если флаг Z равен нулю, а JZ, наоборот, если флаг Z активен, т.к. равен 1).

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-1d1282f58d452e3be80451e8774a663ec4b08031%2F13.png?alt=media)

Раз мы делаем переход, то получаем сообщение с ошибкой, но зато теперь мы знаем, что сравнение происходит со словом "cannabis", то есть это и есть верный серийный номер. Снова продолжим выполнение программы.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-32a1c2cd21811a0d5307debf3a563768990bbd97%2F14.png?alt=media)

Нажав на "ОК", снова вернёмся в окно ввода серийного номера и напечатаем правильный – "cannabis".

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-8a9947f83f40c58a5a66b0c2080fc248256b6feb%2F15.png?alt=media)

Нажмём кнопку CHECK, и срабатывает BPX.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-a2676def7e73c20c214dc196b36425348d742257%2F16.png?alt=media)

Видим, что будут сравниваться две одинаковые строки. Жмём F8, чтобы выполнить вызов API-функции..

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-f1a043239829f533997cc8553a40d4a901567a71%2F17.png?alt=media)

Обе строки были равны, и в EAX был сохранён результат функции – ноль, что активирует флаг Z.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-d94de058d7220267026b0ed9c499be591a27de5c%2F18.png?alt=media)

И поэтому JNZ не будет совершать переход.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-4dbe1916fdc1ea02cf9681fd0e9fd3d619578dd7%2F19.png?alt=media)

А раз так, то как только мы продолжим выполнение программы, отобразится окошко, сообщающее о том, что мы ввели верный серийный номер.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-ff1c7def97998fe8514a00658efb78e2eb200431%2F20.png?alt=media)

Это и есть решение крэкми из главы 13. Хе-хе, серийным номером является слово "cannabis".

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

В следующем случае уже не производится прямого сравнения серийного номера с введённой строкой. Откроем крэкми crackmeeasy [\[ссылка\]](https://github.com/yutewiyof/intro-cracking-with-ollydbg/blob/master/.gitbook/assets/files/14/crakmeeasy.7z) в OllyDbg.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-09aff2092cdd2f9ec4cdbf384b90273f574ced64%2F21.png?alt=media)

Мы уже знаем, как посмотреть используемые API-функции. В списке также есть GetDlgItemTextA, на который мы и установим BPX.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-68003cc08ed6b2612662734a1204fd0e415a66b3%2F22.png?alt=media)

В commandbar’е напечатаем:

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-0cad0deb3fb1b3b2d4b5437c2c703f4fcc15d7a2%2F23.png?alt=media)

Теперь запустим программу с помощью F9, и откроется окно ввода серийного номера.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-bd2ef605dc3a8a4a38a5f10d53b4f55c1f38e338%2F24.png?alt=media)

Напечатаем неверный серийный номер.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-157323c2f75bd2c8cb354c75b4cff21ea2a52f2e%2F25.png?alt=media)

Кликнем по кнопке "Check" и попадём на вызов нужной нам функции.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-f95777d55aeb4c6c4869d6d80a5382e0c33e2bf4%2F26.png?alt=media)

Посмотрим, какие параметры в стеке.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-f8ab8bf18ecd5055e7683b72f3539c11dfb1b0b7%2F27.png?alt=media)

Здесь видим буфер, в котором сохраняется неправильный серийный номер, отметим эту строку, затем правый клик мышью и FOLLOW IN DUMP.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-e23a33950ce1e37863be425b4e41ec9fa03fc3d0%2F28.png?alt=media)

Буфер пуст, так как функция ещё не запустилась, поэтому выберем DEBUG-EXECUTE TILL RETURN.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-861d1d2d72e5f51a4381fbfd2ef399c423c89260%2F29.png?alt=media)

Это приведёт к выполнению функции, которое остановится на инструкции RET.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-6d3ffa9468bb0595ac5547446042baf28fff8378%2F30.png?alt=media)

Нажмём F7, чтобы вернуться в программу.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-7c0e26fd0c0681481b0e8ad11db677c0d664699e%2F31.png?alt=media)

И видим, что в буфере окажется введенный нами неверный серийный номер.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-a5d68fc6c08a97d4a5b541aee6d4c223a91c28fb%2F32.png?alt=media)

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

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-bd1ab8a8fd250a8b5cdd345a07fc2a28bc7877f7%2F33.png?alt=media)

Здесь в EAX помещается число 401222, которое является адресом, указывающем на строку, содержащую число-константу.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-3b35646ddc10cb0e8ddf03f4dbc38820b8cf4af3%2F34.png?alt=media)

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-41cc188044777f83d541c156ce5a0c57a806975e%2F35.png?alt=media)

На следующей строке, где EAX равен 401222:

```
MOV EDX,DWORD PTR DS:[EAX]
```

Это, на самом деле, всё равно, что:

```
MOV EDX,DWORD PTR DS:[401222]
```

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-a22c23340f13b287d49215c49aa239b6e934f86d%2F36.png?alt=media)

То есть содержимое памяти по адресу 401222 перемещается в EDX.

Олли показывает, что это первые 4 байта числа 10445678951.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-4c89901fda925599d408f5c6adcab33f5250c260%2F37.png?alt=media)

Выполнение строки с помощью F7 перемещает их в EDX (они всегда перемещаются в регистр в порядке, обратном тому, как они располагались в памяти).

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-d5818e673e2f0fed17bb96567529c9638152d7e5%2F38.png?alt=media)

На следующей строке байты, находящиеся в EDX, перемещаются в `[EBP-30]`.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-70ad5568265de9c0b21c81eb49f59a11800c678a%2F39.png?alt=media)

Из пояснений Олли видно, что `[EBP-30]` на моей машине – это 240f9e4. Поищем это значение в DUMP’е.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-f5b04055fef8a4e5978ab051b404a6647f061e4a%2F40.png?alt=media)

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-7ba328c1cc6b76e06df93f4d039fe97ef7d17148%2F41.png?alt=media)

F7 копирует байты, находящиеся в EDX.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-db97609d88976c22f54b3509ab1c7c376b1d8f40%2F42.png?alt=media)

После чего

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-9f7a82bd8715f2baec32006640d298325605cf0b%2F43.png?alt=media)

в EDX перемещаются следующие 4 байта числа-константы.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-7365fe9360f72d899f1493d62e4890011552ee0b%2F44.png?alt=media)

Пояснения Олли показывают, что `[eax+4]` содержат 401226, и выполнение инструкции с помощью F7 перемещает следующие 4 байта в EDX.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-2102b19ab16ea5c74830ca827c85b6187bf27ddd%2F45.png?alt=media)

И копируется продолжение того, что копировалось ранее.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-ebe3fccbfeae11fd1d39730b462e87d2e942b0b8%2F46.png?alt=media)

В действительности происходит вот что: этот номер копируется по 4 байта в другую часть памяти.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-c2b4e37ef957f86a23833c25e032d07455688313%2F47.png?alt=media)

И наконец копируются последние 4 байта.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-b2005fc5b03812889477f89f8b5678019913231c%2F48.png?alt=media)

Наконец-то номер скопирован полностью.

Видим, что чуть ниже находится вызов функции memset. Посмотрим её параметры с помощью OllyDbg.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-a721d5d52615de8de055dc8f397d4f9035a6e289%2F49.png?alt=media)

Здесь три значение (n, c и s).

* s – начальный адрес
* n – количество байтов, которых нужно заполнить требуемым значением
* c – значение, которым будет заполняться указанная область памяти

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-2a1e3bb7f9894785ef3005952a4d98579066c9fb%2F50.png?alt=media)

В стеке находятся вышеуказанные параметры: область памяти по адресу 240f9f0 продолжительностью в 8 байт должна быть заполнена нулями.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-53820450941f2c748ad9d0e668c4590aecedb711%2F51.png?alt=media)

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

Ещё ниже находится вызов lstrlen, которая считает длину строки, адрес которой задаётся непосредственно до вызова самой функции.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-67ee0d77744fabb30c602ad42d5d43462715176a%2F52.png?alt=media)

В стеке находятся следующие параметры:

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-59561f214b74857d97c5dcdde873c055f526e86a%2F53.png?alt=media)

То есть будет вычислена длина строки, которая начинается по адресу 240f9E4, что является адресом уже известного нам числа, хех.

F8, и происходит выполнение strlen, а в EAX возвращается длина строки.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-76099f3cbe712ae597fd9f5b88601ecf4ab27bda%2F54.png?alt=media)

Видим, что размер равен 0B, то есть 11 в десятиричной системе, что является длиной нашего номера.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-47883fdfcd033c0da6e1fc4c8d7c47d678410271%2F55.png?alt=media)

Здесь LEA перемещает в EDX значение EAX минус 1, то есть 0A.

На следующей строке происходит сравнение 0A с содержимым `[EBX-10]`, то есть с нулём.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-4c2659affcd2f0a343094c07e0cb07cd0a2ddd9b%2F56.png?alt=media)

И раз ноль меньше чем 0A, то переходим на 401360.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-b445ec4af61b4cd912623109e79ef11d541ceb54%2F57.png?alt=media)

На следующей строке в EAX помещается указатель на наш неверный серийный номер, и поэтому когда нажмём на F7, то EAX будет указывать на "98989898".

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-b4ef2833eb91c0b4a9bc3e0ae9c8771b6064025b%2F58.png?alt=media)

На следующей строке перемещаем в EDX ноль.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-a33edb205cb7c4e5dae3ec01a86364a60353b43b%2F59.png?alt=media)

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-aba210d639a78090f9afce68391f888608463be0%2F60.png?alt=media)

На следующей строке

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-c6ece03683ca59de9d10f0ab9f3cb8e5b74d95f7%2F61.png?alt=media)

Так как EAX указывает на начало неверного серийного номер, прибавляем к нему EDX (который изначально равен нулю) для создания цикла, каждый увеличивает значение EDX на 1 (1, 2, 3 и т.п.), чтобы получить все байты неверного серийного номера по одном в указанном цикле.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-c116faaec863fa09e25f5911dc18696961cd103f%2F62.png?alt=media)

Как мы уже знаем, MOVSX переместит байт в EDX и если он положителен, то заполняет остаток регистра нулями, а если отрицателен – ‘F’.

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

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-3c7e65d49088348bf488b46ca8bd2105f2b8b584%2F63.png?alt=media)

Следующая строка с LEA.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-254a5eb97cf1a0b614c19c58458441358019d3cd%2F64.png?alt=media)

EDX равен 39, вычитаем из него 14 и с помощью LEA помещаем результат непосредственно в EAX.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-25a58670fdebe428cf75ab07a548824638a14aa5%2F65.png?alt=media)

То есть в результате произведённых операций получили 39 (шестнадцатиричное значение первого символа моего серийного номера), отняли от него 14 и результат, равный 25, поместили в EAX.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-733a95af2e1fbad60f734ac873261dce3bc6324c%2F66.png?alt=media)

Следующая строка перемещает значение, находящееся по адресу EBP-30 (на моей машине равное 240f9E4, и оно указывает на начало номера-константы), в EDX.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-4f3ebec1c49daee988aad1db9c4e2956ca7cea29%2F67.png?alt=media)

Нажмём F7.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-ab7a9d0f29a214fc907639580fcf7d5fb0f0db71%2F68.png?alt=media)

EDX указывает на начало номера-константы.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-3069cbea449bfda00a4e4f59aef493707978edff%2F69.png?alt=media)

Далее видим, что в ECX перемещается сначала значение равное нулю, а затем при каждом новом проходе оно увеличивается, чтобы ECX+EDX указывали на разные байты номера-константы.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-18ced74c40f03a737456c9a8bc7dcc2f1d0910a2%2F70.png?alt=media)

Здесь видим, что ECX теперь содержит ноль, а EDX указывает на начало номер, поэтому в данном случае в EDX будет помещён первый байт номера, дополнительная информация о котором выводится в пояснении OllyDbg.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-87a8c6c0d9d00a3dccb920435849c5f179fe72e0%2F71.png?alt=media)

Пояснение говорит, что 31 соответствует ‘1’ в кодировке ASCII, что является первой цифрой номера-константы.

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-63fed703b85c67ace2aec3bf44f728755de3c958%2F72.png?alt=media)

Здесь мы дошли до сравнение, где участвуют:

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-e126d3cdebba86257e7f27820182b17f44013b76%2F73.png?alt=media)

В EAX находится значение 25 (значение первого байта неверного серийного номера (39), от которого было отнято значение 14), а в EDX первый байт номера-константы или 31.

А потому видим, что

```
CMP EAX,EDX
```

на самом деле является

CMP (ПЕРВЫЙ БАЙТ НЕПРАВИЛЬНОГО СЕРИЙНИКА– 14), ПЕРВЫЙ БАЙТ НОМЕРА-КОНСТАНТЫ

```
CMP 25,31
```

И поскольку разность между этими двумя операндами равна нулю, то флаг Z не активируется и выполняется переход JNZ.

Мы вводили неверный серийный номер, а сравнение может дать верный результат, если будет введён правильный серийный номер, чтобы сравниваемые значения были верны.

CMP (ПЕРВЫЙ БАЙТ ПРАВИЛЬНОГО СЕРИЙНИКА– 14), 31

Это и есть условие, при котором сравниваемые значения будут равны.

ПЕРВЫЙ БАЙТ ПРАВИЛЬНОГО СЕРИЙНИКА-14 = ПЕРВЫЙ БАЙТ НОМЕРА-КОНСТАНТЫ

Поэтому

ПЕРВЫЙ БАЙТ ПРАВИЛЬНОГО СЕРИЙНИКА = ПЕРВЫЙ БАЙТ НОМЕРА-КОНСТАНТЫ + 14

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-c7abee2cf4d0d7bb7f7863cad021ead444a60685%2F74.png?alt=media)

ПЕРВЫЙ БАЙТ ПРАВИЛЬНОГО СЕРИЙНИКА = 31 + 14

ПЕРВЫЙ БАЙТ ПРАВИЛЬНОГО СЕРИЙНИКА = 45, что соответствует "E" в ASCII.

То есть первая буква серийного номера равна E.

Эта побайтовая проверка повторяется в цикле до конца.

ПЕРВЫЙ БАЙТ ПРАВИЛЬНОГО СЕРИЙНИКА = ПЕРВЫЙ БАЙТ НОМЕРА-КОНСТАНТЫ + 14

ВТОРОЙ БАЙТ ПРАВИЛЬНОГО СЕРИЙНИКА = ВТОРОЙ БАЙТ НОМЕРА-КОНСТАНТЫ +14

ТРЕТИЙ БАЙТ ПРАВИЛЬНОГО СЕРИЙНИКА = ТРЕТИЙ БАЙТ НОМЕРА-КОНСТАНТЫ +14

Вот таким образом.

Применим этот алгоритм для каждого байта, прибавляя 14 и получая значение байта, соответствующее верному серийному номеру.

```
31 30 34 34 35 36 37 38  10445678
39 35 31 00 00 00 00 00  951.....
```

```
31 + 14 = 45 это буква **E** в ASCII
30 + 14 = 44 это буква **D** в ASCII
34 + 14 = 48 это буква **H** в ASCII
34 + 14 = 48 это буква **H** в ASCII
35 + 14 = 49 это буква **I** в ASCII
36 + 14 = 4A это буква **J** в ASCII
37 + 14 = 4B это буква **K** в ASCII
38 + 14 = 4C это буква **L** в ASCII
39 + 14 = 4D это буква **M** в ASCII
35 + 14 = 49 это буква **I** в ASCII
31 + 14 = 45 это буква **E** в ASCII
```

Поэтому правильный серийный номер следующий:

`EDHHIJKLMIE`

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

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-c15d1489a1b6fa52940c10a951d1dab51065537c%2F75.png?alt=media)

Нажмём "Check".

![](https://2931627293-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LnwCNY88kcGMCQxNdy6%2Fuploads%2Fgit-blob-e6e966f181ba19d50d1a40dd09ccc7c1084a96b2%2F76.png?alt=media)

Мы рассмотрели как выполняется цикл сравнения, как формировались значения, как последовательно перебирались байты номера-константы и неверного серийного номера и исходя из чего выдавалось сообщение о корректности или некорректности введённого серийного номера.

Этот крэкми не такой простой как предыдущий, но думаю, что вам полезно попрактиковаться, чтобы играть в эти игры лучше.

Ок, прилагаю к этой части крэкми "Splish" [\[ссылка\]](https://github.com/yutewiyof/intro-cracking-with-ollydbg/blob/master/.gitbook/assets/files/14/Splish.7z), попробуйте найти серийный номер, захардкоденный в нём.

\[C] Рикардо Нарваха, пер. Aquila
