Был обычный серый вечер, на часы в гостинной показывали 21:40. До фильма оставался ровно час и я решил заняться делом: что-нибудь поломать. Первым попавшимся под руку диском с шароварой оказался Hard&Soft 9.2001. На нем я обнаружил несколько не ломанных мной ранее программ. Среди них была и Wave Flow 4.1. Установил все как обычно.
Что за прога:
Какой-то звуковой редактор, функций мало, да, я особо не проверял - меня интересовала другая сторона этого дела. В архиве занимает около метра. Написана на Dephi это можно узнать, посмотрев ресурсы. Требования минимальные, так что приступаем.
Начало
Что же мы будем сегодня делать? А сделаем мы два кейгена: один на основе самой проги, второй на Паскале (Вы его не знаете? Тогда учите быстрей)
Проги на Дельфях проще ломать с помощью SoftIce, то мы и делаем. Запускаем прогу, нажимаем на кнопочки Register и Enter Passowrd. Вводим любое имя и код, код лучше взять такой, чтобы точно не встречался в памяти, я беру всегда такой 110022334455. Ну, а имя Fess. Нажимаем Ctrl+Dи вываливаемся в айсе, пишем команду s 0 l -1 "110022334455". Команда означает, что нужно искать строку "1100.." во всей памяти. Она как ни странно нашлась :). Адрес памяти должен начинаться с 8. Ставим бряк на этот адрес командой bpmb адрес rw. Где вместо адрес вписываем ваш адрес. Вводим. Выходим из айса по кнопке F5 или Ctrl+D. Нажимаем Ok и вываливаемся в айсе. Раз восемь делаем F12, пока не дойдем до такого блока команд.
Проходим первую строку, набираем команду d eax. И мы видим введенный код. Идем дальше по F10, проверяя изменяющиеся адреса. По адресу указанному в edx, после прохода выделенной строки мы видим, какую-то строку цыфирек. Это наводит на мысль о том, что это настоящий код. Так и есть, если вам просто нужно сломать, то можете паковать вещи, а я продолжу. Код мы узнали, но как быть, если у Вас сотня друзей, у которых еще по сотне и все хотят зарегить прогу на свое имя. Можно, конечно, поставить бряк на эту строку и каждому выдавать код. А можете сбатцать кейген и давать его всем и пусть нагенерят себе кодов сколько надо. И Вы сможете потратить свое время более логично.
Скорее всего код генерится в процедуре по адресу 47246C. Потому что, если посмотреть на две строчки перед ней, то ясно видно как ей передается в eax наше введенное имя. Значит смотрим в процедуру и пытаемся разобраться в ее назначении. Я, конечно, прокомментирую этот код, но вы попробуйте сами разобраться в его назначении в отладчике.
:00472954 55 push ebp
(...выброшена часть ненужно кода)
:00472981 8B45FC mov eax, dword ptr [ebp-04] < Адрес на имя
:00472984 E8B314F9FF call 00403E3C < Проверка длинны имени, результат в eax
:00472989 85C0 test eax, eax < Проверка длинны
:0047298B 7E13 jle 004729A0 < Если длинна = 0, то гуляй Вася
:0047298D BA01000000 mov edx, 00000001 < Счетчик на 1
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047299E(C)
|
:00472992 8B4DFC mov ecx, dword ptr [ebp-04] < Берем адрес на введенное имя
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047291F(C)
|
:00472995 0FB64C11FF movzx ecx, byte ptr [ecx+edx-01] < Берем символ имени в зависимости от счетчика
:0047299A 03D9 add ebx, ecx < Добавляем к сумме (ebx) код символа
\ В начале ebx=0
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047292E(C)
|
:0047299C 42 inc edx < Увеличиваем счетчик
:0047299D 48 dec eax < Убавляем от длинны имени один
:0047299E 75F2 jne 00472992 < Пока в eax не ноль переход работает
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047298B(C)
|
:004729A0 895DF8 mov dword ptr [ebp-08], ebx < Сохраняем сумму
Далее идут команды сопроцессора (префикс f). Для их понимания желательно иметь книжку с описание команд процессора, у меня это В. Юров "Ассемблер. Специальный справочник". В принципе это можно достать с сайта интела www.intel.com, но там на англицком, а мене русский ближе. Я в кратце объясню, что делает блок кода до 4729B3. Берем сумму из кодов символов имени и умножаем это на 0.8 результат в eax. Честно признаюсь, что в начале забыл про книжку и нашел это опытным путем (методом профессионального тыка).
:004729A3 DB45F8 fild dword ptr [ebp-08] < Преобразование операнда в целочисленном формате
\ в вещественный
:004729A6 DB2DF8294700 fld tbyte ptr [004729F8] < Загрузка в стек вещественного значения (0.8)
:004729AC DEC9 fmulp st(1), st(0) < Умножаем сумму на 0.8, результат в стеке
:004729AE E87100F9FF call 00402A24
[начало процедуры
[:00402A24 83EC08 sub esp, 00000008
[:00402A27 DF3C24 fistp qword ptr [esp] < Результат в вершину стека
[:00402A2A 9B wait
[:00402A2B 58 pop eax < Берем результат из стека в eax
[:00402A2C 5A pop edx
[:00402A2D C3 ret
[конец процедуры
:004729B3 F7E8 imul eax < Умножаем eax на eax, т.е. возводим eax во вторую степень
:004729B5 8BF8 mov edi, eax < Переносим eax в edi
:004729B7 8B45FC mov eax, dword ptr [ebp-04] < В eax адрес памяти указывающий на имя
:004729BA E87D14F9FF call 00403E3C < В eax возвращается длинна имени
:004729BF 03C0 add eax, eax < eax=eax+eax или eax=eax*2
:004729C1 03D8 add ebx, eax < Прибавляем к сумме длинну умноженную на 2
:004729C3 8BC3 mov eax, ebx < eax=ebx
:004729C5 03C0 add eax, eax < eax=eax+eax
:004729C7 03F8 add edi, eax < Прибавляем ко всему этому (eax)
\сумму умноженную на 0.8 во второй степени (edi)
:004729C9 8BC7 mov eax, edi < eax=edi
:004729CB 8BD6 mov edx, esi < В edx адрес памяти куда запишется правильный код
:004729CD E8EE5AF9FF call 004084C0 < Преобразуем полученное (eax) в строку десятичных символов,
\ которая является правильным кодом
В общем, из вышепредставленного видно, что программеры не сильно парились с процедурой генерации настоящего кода и даже начинающий сможет создать кейген. Я решил не сильно париться и написал кейген на Паскале, вот он
PROGRAM KeyGen;{Keygen for WaveFlow 4.1}Uses Crt; {Заявляем об использовании модуля Crt}Var{Блок объявления переменных}
S:String;
N:LongInt;
B:Byte;
Begin{Начало программы}
ClrScr; {Очищаем экран}
WriteLn("KeyGen For WaveFlow 4.1 by Fess [PTDS] URL: vallkor.chat.ru");
{Выводим строку, типа сбацал я}
WriteLn; {Пропускаем строку}Write("Enter name: "); {Просим ввести имя}
ReadLn(S); {Берем имя в переменную S}
N:=0; {Присваиваем сумме начальное значение 0}For B:=1 to Length(S) Do N:=N+Ord(S[B]); {Считаем сумму кодов имени}
N:=SQR(Round(N*0.8) {Сумму умножаем на 0.8 и возводим во вторую степень}
+ (N + Length(S)*2)*2 ); {Прибавляем к сумме длинну умноженную на 2 и все это умножаем на 2}Write("Your Key: ",N); {Выводим получившийся код}If readkey=#0 then; {Ждем нажатия на любую клавишу}End. {Конец программы}
Процедура генерации опробована и проверена!! Так что ошибок нет. Сделана на Turbo Pascal 7.0.
Для имени FessCool код должен быть 408672.
Будем надеятся, что вы все поняли из выше сказанного, если что-то непонятно пишите на мыло. Я помогу!
Послесловие
Спасибо автору за предоставленный для исследования продукт. Было очень интересно. Спасибо фирме Borland за превосходный Паскаль, без которого я жить не могу. :)
Господа Авторы: Ну, как это назвать?!! Очень стандартная защита, короче мусор. Нормальный крэкер сломает ее на несколько минут. Хотите получать деньги делайте защиту лучше! 25 US$ баксов для России это очень много, а крэкеров в России много! Россия рулез!
Братья Крэкеры: Не стоит сильно ругать авторов, они там за бугром не ведают, что творят.
Если Вас заинтересовала или понравилась информация по разработке на Delph - "Кейген для Wave Flow 4.1", Вы можете поставить закладку в социальной сети или в своём блоге на данную страницу: Так же Вы можете задать вопрос по работе этого модуля или примера через форму обратной связи, в сообщение обязательно указывайте название или ссылку на статью!