От патча до кейгена - 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-сектора.
|