скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

От патча до кейгена - Sanchs Marine Aquarium v0.99L Beta


Автор: Fess

Target: Sanchs Marine Aquarium v0.99L Beta

Tools:

  • Some brains
  • Soft-Ice 3.24
  • Win32Dasm 8.93
  • Любой hex+asm-редактор (я использую QView)

Пролог

Вступление:

Как-то около месяцев трех-четырех назад увидал я на softodrom'e хороший хранитель экрана в стиле "Эмуляция аквариума" и решил его себе закачать. Сказано сделано, скачал, поставил. Но по каким-то причинам он оказался шароварным. Дурацкий наг и возможность пользоваться одной рыбкой меня вдохновила на взлом. Наскоком взять не получилось, а со временем то- гда была напряженка сбацал патч и забыл. Но все возвращается, вот так и я от нечего делать решил вернуться и продолжить работу, как в следствии ок- азалось защита была плохой. Для начинающих крэкеров это в самый раз, и я предлагаю вашему вниманию 4 способа взлома этой программы.

Что за прога:

Один из самых лучших из видимых мной хранителей экрана, такой красоты и маленького размера (архив 1,1 Мб).

Примечание:

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

Вступление

Как я уже писал в прологе взлом будет производится четырьмя разными способами, это

  • Патч
  • Подсмотр кода
  • Написание кейгена на основе самой программы
  • Написание кейгена на Delphi

Патч

Патч это самый легкий способ взлома поэтому профессионалы и мастера в крэке считают его чем-то низким, я тоже стараюсь избегать использовать патч, но раз статья предназначена для начинающих, то не рассмотреть его это преступление. Но у легкости и быстроты патча есть и свои недостатки, по сравнению с серийным номером. Во-первых, это то, что он врядли будет работать с последующими версиями программы, во-вторых, сложно переносить патч, о... вот тут мне подсказывают, что для этого используют crk-файлы, согласен, но если программа запакована exe-паковщиком, то к этому файлу придется добавлять и распаковщик, а они подчас занимают достаточно много места.

Ну что ж приступим.

Программа ничем не запакована и написана на Visual C++. Поэтому сме- щение в файле равно смещению в памяти минус 400000h.

Первое, что нужно сделать это установить программу. Логично скажите Вы и будете правы. Установили? Теперь идем в Настройки Экрана, выбираем наш Screen Saver. И жмем кнопку Настройка. Там видим большое поле, где надо вводить наш код. Введем любой код и нажмем кнопку Enter. Код пропал, а ничего не произошло. Хм, странно. Почитаем текст вокруг. Написано, что можно написать TESTFISH, пишем, вводим и видим надпись: TEMP REGISTRATION OK. Работает. Скорее всего здесь и высветиться информация о правиль- ном номере. Что еще можно прочитать... Так написано, что нужно заплатить им 19,95 американских портретов за Deluxe регистрацию. Ладно, наплевать лучше сразу дизассемблировать, а там посмотрим. Копируем файл fish.scr из каталога Windows в свой каталог, у меня это MUSOR. Дизассемблируем. И ле- зем в директорию найденных в программе строк: StrRef и ищем там, какие- нибудь интересные строки, таковыми оказались:

"BASIC registration OK"
"DELUXE registration OK"
"TEMP registration OK"

Последнюю мы уже видели, а две другие нет. Судя по названиям Deluxe это продвинутая регистрация, а Basic основная. На Basic наплюем, хотя мы еще с ней встретимся в 2 и 3 пункте, а сделаем себя люксами. Два раза тыкаем на строку с Deluxe и оказываемя здесь Прим: все основные строки я выделю таким цветом.


:00411263 8B4D10                  mov ecx, dword ptr [ebp+10]
:00411266 81E1FFFF0000            and ecx, 0000FFFF
:0041126C 81F95A020000            cmp ecx, 0000025A
:00411272 0F85E1010000            jne 00411459
:00411278 833D7493420003          cmp dword ptr [00429374], 00000003
:0041127F 751B                    jne 0041129C

* Possible StringData Ref from Data Obj ->"DELUXE registration OK"
                                  |
:00411281 687C564200              push 0042567C
:00411286 6892000000              push 00000092
:0041128B 8B5508                  mov edx, dword ptr [ebp+08]
:0041128E 52                      push edx

* Reference To: USER32.SetDlgItemTextA, Ord:022Ch
                                  |
:0041128F FF154C024200            Call dword ptr [0042024C]

Так в выделенной строке число по адресу 429374 сравнимается с 3 и если не равно, то идет куда-то дальше, а если равно, то выдает эту строку. Зна- чит надо, чтобы в этой ячейке памяти всегда было 3. Вы можете не согла- ситься со мной, сказав: "Может просто заменить переход после этого сравне- ния и все." Это самая главная ошибка начинающих борьба не с причиной, а со следствием, такой способ может сработать, но редко. Хотя никто Вас не дер- жит попробуйте, может и получится.

Попробуем поискать фрагмент, где в эту ячейку записываются данные, это можно сделать с помощью Soft-Ice. Но зачем крэкеру геморой. Просто поищем строку mov dword ptr [00429374], 00000003. Глядишь, что и всплывет. Найде- но три адреса, вот текст около первого


:00404026 6A03                    push 00000003
:00404028 E8C3F0FFFF              call 004030F0
:0040402D 83C404                  add esp, 00000004
:00404030 85C0                    test eax, eax
:00404032 7434                    je 00404068
:00404034 C7057493420003000000    mov dword ptr [00429374], 00000003

Каждые три раза вызывается эта процедура и если в eax она возвратит не 0, то все хорошо и идет присвоение, если 0, то плохо. Можно, конечно, поменять все jump'ы после этих процедур. И это скорее всего поможет, но я предпочи- таю действовать более тонко, сделать, чтобы процедура всегда возвращала не 0. Можно, конечно, прямо после входа в процедуру поставить ret, ведь скорее всего eax<>0. Процентов 91,2%. Но лучше присвоить eax единицу и выйти. Да- вайте так и сделаем.

Открываем файл qview или hiew. Включаем 32 битный-hex&asm режим. Как это делается я в предыдущих тьюториалах писал. Переходим по адресу 30F0. И вписываем такие строки (после ";" приведена расшифровка строк)


xor eax,eax ;обнулить eax
inc eax     ;увеличить eax на 1
ret         ;выйти из процедуры

Или прямо в hex-режиме начиная с адреса 30F0 пишем 33С040С3 это и будут эти команды.

Теперь можете зайти в настройки и увидеть их совсем другими, а сверху долгожданную надпись Deluxe Version. И пользуйтесь ей до скончанья веков. Жалко, что это только бета, а в нормальной этот патч будет не дейтвителен. Хотя я думаю сломать ее будет так же легко, да и адреса врядли сильно по- меняются. Но уж лучше код, читайте дальше....

Подсмотр кода

Подсмотреть, подслушать это давнее изобретение человека из века в век на этом делали деньги. И мы сегодня заработаем ни много, ни мало 19.95$. Только, к сожалению, Вам их никто не отдаст, но зато программа за эту це- ну станет Вашей. Поехали.

Самая главная задача это найти, где введенный нами код сравнивается с настоящим, сгенереным по каким-то законам с какими-то условиями. В этой главе нам на них превать. Тут вы можете меня осудить, мол сволочь, "тут, наверное, будет вычисляться контрольная сумма, ведь имя-то не вводим.". Я себе позволю сразу Вам заметить это тот редкий случай, когда это не так. Не забудьте включить SOFT-ICE, он нам понадобится подсмотреть код.

Помните мы писали TESTFISH и получали ответ. Да. Тогда давайте посмо- трим откудова вызывается эта строка. Ведь она сравнивается с нашим вве- денным нами кодом. Жмем два раза на TESTFISH и оказываемся здесь. Я чтобы было по понятней понаставлю своих комментариев.


:00411315 6A20             push 00000020 <- считать 20h символов
:00411317 68A48E4200       push 00428EA4 <- сюда
:0041131C 6892000000       push 00000092 <- из нашего поля(т.е. пароль)
:00411321 8B5508           mov edx, dword ptr [ebp+08]
:00411324 52               push edx <- идентификатор окна

* Reference To: USER32.GetDlgItemTextA, Ord:0104h
                             |
:00411325 FF15E0014200     Call dword ptr [004201E0]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411313(C)
|
* Possible StringData Ref from Data Obj ->"TESTFISH"
                                  |
:0041132B 6870564200              push 00425670   <- Адрес строки TESTFISH
:00411330 68A48E4200              push 00428EA4   <- Адрес нашего пароля

* Reference To: KERNEL32.lstrcmpiA, Ord:02FFh <- сравниваем строки
                                  |
:00411335 FF15A0004200            Call dword ptr [004200A0]
:0041133B 85C0                    test eax, eax
:0041133D 750A                    jne 00411349 <- если не равны то переход
:0041133F C7057493420001000000    mov dword ptr [00429374], 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041133D(C)
|
:00411349 6A02                    push 00000002
:0041134B E8A01DFFFF              call 004030F0 <-сравнение на Basic регистрацию
:00411350 83C404                  add esp, 00000004
:00411353 85C0                    test eax, eax
:00411355 7414                    je 0041136B <- если не равно, то переход
:00411357 C7057493420002000000    mov dword ptr [00429374], 00000002
:00411361 6A01                    push 00000001
:00411363 E8D825FFFF              call 00403940
:00411368 83C404                  add esp, 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00411355(C)
|
:0041136B 6A03                    push 00000003
:0041136D E87E1DFFFF              call 004030F0 <- сравнение на Deluxe
:00411372 83C404                  add esp, 00000004
:00411375 8945F8                  mov dword ptr [ebp-08], eax
:00411378 837DF800                cmp dword ptr [ebp-08], 00000000
:0041137C 7414                    je 00411392 <- если не равно, то переход
:0041137E C7057493420003000000    mov dword ptr [00429374], 00000003

Будем надеятся с коментариями все понятно. Как я угадал, где Basic, где Deluxe. Посмотрите на выделенные строки. Если не переходит адресу 429374 записывается значение. А о нем мы говорили, когда делали патч. Так же мы увидели, что наша введеная строка заносится в память по адресу 00428EA4. Кстати, Вы заметили, что процедура у Basic регистрации и Deluxe одна, и различаются только по значению кладущимуся в стэк 2 или 3. Заходим в эту процедуру и ищем, где наш введенный код сравнивается с истинным. "Истина, где-то рядом","как говорил один мой друг, ныне покой- ник". Сразу скажу программа написана на C++ и использует MFC, если, ко- нечно, это вам что-нибудь говорит. Ищем пока не доходим до такого места.


:0040327A 8D4DC8                  lea ecx, dword ptr [ebp-38]
:0040327D 51                      push ecx
:0040327E 68A48E4200              push 00428EA4

* Reference To: KERNEL32.lstrcmpiA, Ord:02FFh
                                  |
:00403283 FF15A0004200            Call dword ptr [004200A0]
:00403289 85C0                    test eax, eax
:0040328B 0F851A010000            jne 004033AB

Видно, что наш код сравнивается с чем-то. Теперь пора взятся за Soft- Ice. Заходим ставим бряк на GetDlgItemTextA строкой bpx GetDlgItemTextA. Из предыдущего фрагмента кода было видно, что именно эта функция исполь- зуется для чтения. Лезем в настройки и вводим такой код: 110022334455. Нажимаем Enter и вываливаемся в Soft-Ice нажимаем F11, чтобы вернуться в тело программы. Удаляем все бряки командой bc * и устанавливаем бряк на адрес 40327E команда bpx 40327E. Нажимаем F5. Но ничего не происходит программа до этого места не дошла. Тогда попробуем символьный код, такой FESSCOOL. Опять вводим и на сей раз вываливаемся, в Soft-Ice на нашем бряке. Даем команду d ecx, чтобы посмотреть, что будет по адресу ecx и видим следующее FESSCO760776. Жмем F5 и опять вываливаемся, опять d ecx и видим FESSCO966395. Рассуждаем логически, первое, программа использует первые 6 символов, введенного кода для генерации остальной части. Второе, эти первые 6 символов обязательно буквы, третье, первый код это скорее всего для Basic регистрации, а второй для Deluxe, поскольку процедура генерации одна.

Попробуем ввести - подходит. Это круто теперь Вы можете получить код для своего имени или его части. И это круто. Можете теперь рассказать всем как вы купили эту программу и получили код, заплатив 20$.

Но хорошего понемножку, и подсмотреть код просто, но что делать, ес- ли, кто-то не знает Soft-Ice можно дать ему свой код, но лучше другой. Каждый раз включать для этого Soft-Ice, ставить бряки и прочее. Неудобно лучше сделать кейген для начала на самой программе. Читайте дальше.

Написание кейгена на основесамой программы

Если в программе можно подсмотреть правильный номер, то написание кей- гена на основе самой программы элементарно просто. Уже в нескольких ма- нуалах я писал, как это сделать.

Мы уже нашли место, где правильный номер сравнивается с нашим. Оста- лось только вывести правильный номер на экран, для этого я обычно ис- пользую функцию MessageBoxA. Ищем любой код с этой функцией. Идем в секцию функций и два раза жмем на USER32.MessageBoxA. И попадаем в такое место.


:00403A46 685C534200              push 0042535C
:00403A4B 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BEh
                                  |
:00403A4D FF1530024200            Call dword ptr [00420230]
:00403A53 33C0                    xor eax, eax

Посмотрите hex представление этой функции и перепишите на бумажку, оно нам понадобиться. Формат функции MessageBoxA такой


push тип текста (обычно 0)
push текст в заголовке
push текст в окне
push идентификатор окна (обычно 0)
call MessageBoxA

Еще раз внимательно посмотрите на предыдущий фрагмент кода, нам надо начиная с 40327D. Написать такие строки, через дефис я буду приводить их hex представление. Запомните адрес MessageBoxA уникален для каждой программы, поэтому я беру его hex представление из самой программы.


push 0          - 6A00
push ecx        - 51
push ecx        - 51
push 0          - 6A00
CallMessageBoxA - FF1530024200
jmp 4033AB      - E91D014000

Джамп после этого всего необходим, чтобы программа не посчитала себя зарегеной, а то как вводить код? Как вы понимаете вываливаться будет 2 раза. Первый Basic код, второй Deluxe-код.

Вот пожалуй и все. Перейдем теперь к написанию настоящего кейгена.

Написание кейгена на Delphi

Сегодня мы покажем класс. Soft-Ice можете отложить в сторонку. Будем писать кейген, ТОЛЬКО опираясь на код в Win32Dasm'e. У каждого внутри есть свой Soft-Ice надо только научиться им пользоваться. Заходим в про- цедуру генерации пароля 4030F0 и анализируем ее.


:004030F0 55             push ebp
:004030F1 8BEC           mov ebp, esp
:004030F3 83EC4C         sub esp, 0000004C
:004030F6 56             push esi
:004030F7 57             push edi
:004030F8 C745B800000000 mov [ebp-48], 00000000  }
:004030FF C745BC01000000 mov [ebp-44], 00000001  } Инициализация переменных
:00403106 C745D800000000 mov [ebp-28], 00000000  }
:0040310D C745C400000000 mov [ebp-3C], 00000000  }
       ;Помните push перед процедурой, так вот он в [ebp+8], а что он значил
       ;помните? Если 2, то это Basic, если 3 - Deluxe.
:00403114 837D0802       cmp dword ptr [ebp+08], 00000002 <-Basic
:00403118 7406           je 00403120
:0040311A 837D0801       cmp dword ptr [ebp+08], 00000001
:0040311E 7507           jne 00403127

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403118(C)
|
:00403120 C745D803000000 mov [ebp-28], 00000003

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040311E(C)
|
:00403127 837D0803       cmp dword ptr [ebp+08], 00000003 <-Наш Deluxe
:0040312B 7406           je 00403133  <-Переходим
:0040312D 837D0805       cmp dword ptr [ebp+08], 00000005
:00403131 7507           jne 0040313A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040312B(C)
|
:00403133 C745D807000000 mov [ebp-28], 00000007 <-Так значит в переменной
                                                  [ebp-28] теперь 7
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403131(C)
|
:0040313A 837D0804       cmp dword ptr [ebp+08], 00000004 <- Не равно
:0040313E 7507           jne 00403147         <- Переходим
:00403140 C745D804000000 mov [ebp-28], 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040313E(C)
|
:00403147 33C0           xor eax, eax                }
:00403149 8945C8         mov dword ptr [ebp-38], eax }
:0040314C 8945CC         mov dword ptr [ebp-34], eax } Обнуление переменных
:0040314F 8945D0         mov dword ptr [ebp-30], eax }
:00403152 668945D4       mov word ptr [ebp-2C], ax   }
:00403156 8B0DA48E4200   mov ecx, dword ptr [00428EA4] } Первые 6 введенных
:0040315C 894DC8         mov dword ptr [ebp-38], ecx   } символов переносят
:0040315F 668B15A88E4200 mov dx, word ptr [00428EA8]   } в память начиная с
:00403166 668955CC       mov word ptr [ebp-34], dx     } [ebp-38]
:0040316A C745C000000000 mov [ebp-40], 00000000
:00403171 EB09           jmp 0040317C

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004031A9(U), :004031C6(U)
|
:00403173 8B45C0         mov eax, dword ptr [ebp-40] } Добавление к счетчику
:00403176 83C001         add eax, 00000001           } цикла единицы
:00403179 8945C0         mov dword ptr [ebp-40], eax }

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403171(U)
|
:0040317C 837DC006       cmp dword ptr [ebp-40], 00000006 <- Проверка все ли
                                                           6 символов обработаны
:00403180 7D46           jge 004031C8
:00403182 8B4DC0         mov ecx, dword ptr [ebp-40]      <- В [ebp-40] счетчик цикла
:00403185 8A540DC8       mov dl, byte ptr [ebp+ecx-38]    <- Берем n-символ
:00403189 8855DC         mov byte ptr [ebp-24], dl        <- Записываем его сюда
:0040318C 0FBE45DC       movsx eax, byte ptr [ebp-24]     <- Опять его берем теперь в eax
:00403190 0345C0         add eax, dword ptr [ebp-40]      <- Добавляем к нему счетчик цикла
:00403193 0FAF45BC       imul eax, dword ptr [ebp-44]     <- Умножаем получившееся на общую сумму в [ebp-44]
:00403197 8945BC         mov dword ptr [ebp-44], eax      <- Записываем в общую сумму
:0040319A 837DC001       cmp dword ptr [ebp-40], 00000001 <- Если символ 1 или 2
:0040319E 7E0B           jle 004031AB                     <- то переходим
:004031A0 0FBE4DDC       movsx ecx, byte ptr [ebp-24]     <- Заносим символ в ecx
:004031A4 83F92D         cmp ecx, 0000002D                <- Сравниваем символ с символом '-'
:004031A7 7502           jne 004031AB                     <- если не равно
:004031A9 EBC8           jmp 00403173                     <- иначе

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040319E(C), :004031A7(C)
|
:004031AB 0FBE55DC       movsx edx, byte ptr [ebp-24]     <- Заносим символ в edx
:004031AF 83FA7A         cmp edx, 0000007A                <- Если код больше 'Z'
:004031B2 7F09           jg 004031BD                      <- переход на выход
:004031B4 0FBE45DC       movsx eax, byte ptr [ebp-24]     <- Заносим символ в eax
:004031B8 83F841         cmp eax, 00000041                <- Если код больше 'A'
:004031BB 7D09           jge 004031C6                     <- переход
                     ; Это и есть сравнение "только большие латинские буквы"

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004031B2(C)
|
:004031BD C745B801000000 mov [ebp-48], 00000001
:004031C4 EB02           jmp 004031C8                     <- Выход с позором

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004031BB(C)
|
:004031C6 EBAB           jmp 00403173    <- Новый виток цикла

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00403180(C), :004031C4(U)
|
:004031C8 837DB800       cmp dword ptr [ebp-48], 00000000
:004031CC 0F85D9010000   jne 004033AB    <- Не переходим
:004031D2 8B4DD8         mov ecx, dword ptr [ebp-28] <- Берем число зависящее
                                 ;от типа регистрации для Deluxe это 7, для
                                 ;Basic это 3
:004031D5 69C9C8000000   imul ecx, 000000C8 <- Умножаем его на C8
:004031DB 8B45BC         mov eax, dword ptr [ebp-44] <- Берем сумму из предыдущего цикла
:004031DE 33D2           xor edx, edx
:004031E0 F7F1           div ecx  <- Eax делим нацело на ecx результат в eax
:004031E2 8945BC         mov dword ptr [ebp-44], eax <- Записываем его в сумму

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004031F6(U)
|
:004031E5 817DBC301B0F00 cmp dword ptr [ebp-44], 000F1B30 <- Если сумма меньше F1B30
:004031EC 760A           jbe 004031F8                     <- переход
:004031EE 8B55BC         mov edx, dword ptr [ebp-44]      }
:004031F1 D1EA           shr edx, 1                       } Делим сумму на 2
:004031F3 8955BC         mov dword ptr [ebp-44], edx      }
:004031F6 EBED           jmp 004031E5                     <- Проверяем заново

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004031EC(C), :00403209(U)
|
:004031F8 817DBCA0860100 cmp dword ptr [ebp-44], 000186A0 <- если сумма больше 186A0
:004031FF 730A           jnb 0040320B                     <- переход
:00403201 8B45BC         mov eax, dword ptr [ebp-44]      }
:00403204 D1E0           shl eax, 1                       } Умножаем сумму на 2
:00403206 8945BC         mov dword ptr [ebp-44], eax      }
:00403209 EBED           jmp 004031F8                     <- Повторяем заново

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004031FF(C)
|
:0040320B 8B4DBC         mov ecx, dword ptr [ebp-44]   }
:0040320E 81C180000000   add ecx, 00000080             } Добавляем к сумме 80h
:00403214 894DBC         mov dword ptr [ebp-44], ecx   }
:00403217 8B55BC         mov edx, dword ptr [ebp-44]
:0040321A 52             push edx

* Possible StringData Ref from Data Obj ->"%d"
                          |
:0040321B 6808524200     push 00425208
:00403220 8D45CE         lea eax, dword ptr [ebp-32]
:00403223 50             push eax                  <- Адрес памяти куда будет записан перевод
:00403224 E8D31E0100     call 004150FC             <- Перевод числа в строку
:00403229 83C40C         add esp, 0000000C
:0040322C 8A4DCE         mov cl, byte ptr [ebp-32] <- Берем первое число
:0040322F 884DDC         mov byte ptr [ebp-24], cl <- Помещаем в [ebp-24]
:00403232 8A55D3         mov dl, byte ptr [ebp-2D] } Заменяем первое на
:00403235 8855CE         mov byte ptr [ebp-32], dl } последнее.
:00403238 8A45DC         mov al, byte ptr [ebp-24] } Заменяем последнее на число
:0040323B 8845D3         mov byte ptr [ebp-2D], al } из буфера, т.е. бывшее первое
:0040323E 0FBE4DCE       movsx ecx, byte ptr [ebp-32] <- Берем первое число в ecx
:00403242 83F930         cmp ecx, 00000030            <- Если число не равно '0'
:00403245 7504           jne 0040324B                 <- Переходим
:00403247 C645CE39       mov [ebp-32], 39             <- Иначе заменяем первое число на '9'

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403245(C)
|
:0040324B C645D400       mov [ebp-2C], 00 <- Закрываем строку
                Теперь по адресу [ebp-32] число прибавив которое к введенной
                строке получится истинный код.

Надеюсь все понятно из моих комментариев. Видите как просто, зачем здесь Soft-Ice. Я сляпал кейген на Delpi. Так как это быстро и просто. Да и Вас загружать не зачем. В нем я умышленно, чтобы не разрасталась статья не привожу проверку на заглавные буквы, т.к. программа воспринимает только заглавные. Если надо будет напишите сами это не сложно. Для создания кей- гена на основной форме нужно поместить два компонента Edit с именами Edit1 и Edit2 (они по умолчанию будут такими). И одну кнопку, имя любое. Затем жмете два раза на кнопку и вставляете этот фрагмент:


if Length(Edit1.Text) >= 6 then // Проверка на длинну
begin
  S := Edit1.Text;
  I := 1;
  Z := 7;
  // Тип регистрации Basic - 3 или Deluxe - 7
  for C := 1 to 6 do
    I := I * (Ord(S[C]) + C - 1);
  Z := Z * $C8;
  I := I div Z;
  while I > $F1B30 do
    I := I div 2;
  while I < $186A0 do
    I := I * 2;
  I := I + $80;
  S := IntToStr(I);
  C := Ord(S[Length(S)]);
  S[Length(S)] := S[1];
  if c = $30 then
    c := $39;
  S[1] := Chr(C);
  Edit2.Text := Edit1.Text + S;
end;

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

Послесловие

Вот и закончена работа потирая руки вы регистрируете программу на себя. Винище льется рекой вы празднуете халявно заработанные 20$.

Хочу надеяться, что эта статья Вас чему-либо научила и помогла в осво- ении этой нелегкой науки.

Снять регистрацию можно, в разделе реестра: HKEY_CURRENT_USER\SOFTWARE\Serenescreen\SereneAquarium Удалив параметр Code.

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

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

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

Все ругательства отправлять в null
Все остальное на lomovskih@yandex.ru

Спасибо за интерес к моему творчеству!

Удачи в Reversing Engeneering!

P.S. Запомните все материалы публикуются только в учебных целях и автор за их использование ответственности не несет!!

P.P.S. Возможно имеют место опечатки, заранее извините!

With best wishes Fess

И да пребудет с вами великий дух bad-сектора.






Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook