|
Патч на Delphi
W32Dasm v9.0b
http://biocyborg.narod.ru/W32dsm9b.zip
[315 KB--ZIP]
TurboLaunch 5.03 http://biocyborg.narod.ru/soft/tlsetup.zip
[1699 KB--ZIP]
В этой статье я расскажу,
как написать кряк на Delphi. Только не
надо кричать, что это полный бред и
стучать кулаком по клавиатуре.
Конечно, мы можем получить громадный
исполнимый файл, который будет даже
больше ломаемой программы, и в
этом случае затея лишена смысла.
Как уменьшить размер
создаваемого Delphi exe-шника? Довольно
часто слышу очень глупый ответ на
этот вопрос: "Никак!". Есть
несколько приемлемых способов
борьбы с проблемой "больших файлов",
генерируемых Delphi. Во-первых, можно
использовать более старую версию Delphi.
Так, например, пустая форма в Delphi 2.0
весит 150 кБ, а в Delphi 6 - около 350 кБ. Во-вторых,
для создания приложений можно
использовать функции WinApi . В-третьих,
существует библиотека Key Object Library,
написанная Владимиром Кладовым,
позволяющая быстро и легко создавать
компактные приложения в Делфи. При
этом не забывайте про UPX и ASPack.
Итак, приступим. Чтобы не
объяснять на пальцах, я выбрал
программку TurboLunch. Взломать её защиту
не сложно. Можно зацепиться, например,
за сообщение, которое появляется при
вводе неправильного
регистрационного кода: "The Registration
Name and Code you entered are not correct. You must type your Name
and Code EXACTLY as it appears on your registration acknowledgement.
Please try again."
Дизассемблируем программу
с помощью W32dasm и найдём
вышеприведённую фразу.
* Referenced by a (U)nconditional
or (C)onditional Jump at Address:
|:004DC1EB(C)
|
:004DC2B1 6A40 push 00000040
* Possible StringData Ref from Code Obj ->"TurboLaunch"
|
:004DC2B3 B9C0C34D00 mov ecx, 004DC3C0
* Possible StringData Ref from Code Obj ->"The Registration
Name and Code "
->"you entered are not correct. "
->"You must type your Name and Code "
->"EXACTLY as it appears on your "
->"registration acknowledgement. "
->" Please try again."
|
:004DC2B8 BACCC34D00 mov edx, 004DC3CC
:004DC2BD A198634F00 mov eax, dword ptr [004F6398]
:004DC2C2 8B00
mov eax, dword ptr [eax]
:004DC2C4 E89BA5FAFF call 00486864
Посмотрим, что у нас по адресу
004DC1EB:
:004DC1E2 8B00
mov eax, dword ptr [eax]
:004DC1E4 E82F090100 call 004ECB18
:004DC1E9 84C0
test al, al
:004DC1EB 0F84C0000000 je 004DC2B1 <= переход к
сообщению о неудаче (если al=0)
:004DC1F1 33D2
xor edx, edx
:004DC1F3 8B8300030000 mov eax, dword ptr [ebx+00000300]
:004DC1F9 E8C2C3F5FF call 004385C0
Чтобы программа поверила в
правильность серийника, в al должна
быть единица. Поэтому мы идём по
адресу 004ECB18 и разбираемся с тем, что
там происходит:
* Referenced by a CALL at
Addresses:
|:004DC1E4 , :004E3F2D , :004E56F6 , :004EA202 , :004EA221
|:004EFD08
|
:004ECB18 8B9068010000 mov edx, dword ptr [eax+00000168]
:004ECB1E 8B8064010000 mov eax, dword ptr [eax+00000164]
:004ECB24 E827570000 call 004F2250
:004ECB29 C3
ret
Из приведённой части кода
видно, что программа обращается к
этой процедуре всякий раз, когда
требуется проверка на
зарегистрированность, будь то диалог
загрузки программы или отображение
информации в окне About.
Можно поступить следующим
образом: в HEX-редакторе с адреса .4ECB18
ассемблируем следующее:
mov eax, 1
ret
В HIEW это делается так: жмём
F4 и выбираем режим Decode. Открытый файл
будет представлен в виде
ассемблерных команд и
соответствующих им опкодов.
Переходим к нужному адресу (F5), и
правим код программы (F3, затем F2 или TAB).
F9 сохраняет изменения.
Рис.1.

Рис.2.

На
рис.1 показан кусок кода программы
перед началом правки (уже нажата F3).
Крайний левый столбец - адреса команд
по оффсету. На рис.2 - результаты
редактирования (цветом выделены
отличия в HEX-коде).
Легко заметить, что мы
изменили в программе пять байт (8B на B8
по адресу EBF18, 90 на 01 по адресу EBF19, 68 на
00 по адресу EBF1A, 01 на 00 по адресу EBF1B и 00
на C3 по адресу EBF1D; байт 00 по адресу EBF1C
остался без изменений).
Теперь всё работает как
надо, если не учитывать, что при
загрузке программы и в окне About
отображается надпись Registered to: и
ничего далее. Сейчас мы это исправим.
Отправимся в реестр по адресу
HKEY_CURRENT_USER\SOFTWARE\TurboLaunch, найдём
строковый параметр RegistrationName и
присвоим ему любое значение,
например, BioCyborG ;-).
Пришло время заняться
написанием патча. Наш кряк должен
делать следующее: патчить исполнимый
файл и автоматически записывать в
реестр имя пользователя, а также
отображать информацию о ходе
процесса.
Примерный вид интерфейса
показан на рис. 3 и рис. 4.
Рис.3. Заготовка проекта

Рис.4 Окончательный вид проекта

Далее
привожу необходимый текст программы
с комментариями.
procedure
TForm1.Edit1Change(Sender: TObject);
begin
// при изменении текста в Edit1
button1.enabled:=true; // активируем кнопку
"Go!"
end;
procedure TForm1.Button1Click(Sender:
TObject); //при нажатии кнопки "Go!"
var
Ch:Char;
F:File of Byte; //F-файловая переменная
R: TRegistry;
File_size: longint;
begin
Assignfile(F,'TurboLaunch.exe'); //связываем
файловую переменную с файлом
//TurboLaunch.exe
{$I-}Reset(F); {I+} // ищем файл TurboLaunch.exe в
текущем каталоге
if ioresult<>0 then
// в случае неудачи
label2.caption:='File not found' // сообщаем, что
файл не найден
else
begin
File_Size:=filesize(F); //
определяем размер файла
if File_Size<>1573888 then // и если он
неправильный
label2.caption:='FileSize is not 1573888 bytes' //
сообщаем об этом
else //
если всё ОК начинаем править файл
begin
if checkbox1.checked=true then
// при необходимости
CopyFile('TurboLaunch.exe','TurboLaunch.exe.bak', true
); // сохраняем BackUp
Seek(F,$000ebf24); {1} //
находим адрес байта в файле
Ch:=Char($b8);
// Ch-новое значение байта
Blockwrite(F,Ch,1);
// правим байт
Seek(F,$000ebf25); {2} //
аналогично патчим остальные байты
Ch:=Char($01);
Blockwrite(F,Ch,1);
Seek(F,$000ebf26); {3}
Ch:=Char($00);
Blockwrite(F,Ch,1);
Seek(F,$000EBF1B); {4}
Ch:=Char($00);
Blockwrite(F,Ch,1);
Seek(F,$000EBF1D); {5}
Ch:=Char($C3);
Blockwrite(F,Ch,1);
R:=TRegistry.Create; //инициализируем
класс; не забудьте добавить модуль
//Registry в uses
R.RootKey:=HKEY_CURRENT_USER; //
устанавливаем "корневой" раздел
реестра
R.OpenKey('SOFTWARE\TurboLaunch',true); //
открываем ключ
R.WriteString('RegistrationName',Edit1.Text); //
записываем в RegistrationName
//строку из Edit1
label2.caption:='All Done ;-)'; // сообщаем,
что всё прошло успешно
end;
end;
closefile(F); // закрываем файл
end;
procedure TForm1.Button2Click(Sender: TObject); //кнопка
"EXIT"
begin
close; // выод
из программы
end;
procedure TForm1.Button3Click(Sender: TObject); //при
нажатии
begin
//кнопки "About"
label2.caption:='Crack made by BioCyborG. www.biocyborg.tk ';
end;
На этом всё. Исходники
патча (для Delphi 2.0) можете скачать
здесь: http://biocyborg.narod.ru/rev/tls.zip
P.S. Я немножко схитрил, когда объяснял
способ взлома. Вместо
mov eax, 1
ret
можно было написать только
ret
т.е. сразу выйти из процедуры
проверки зарегистрированности
программы, и это сработало бы!
© BioCyborG, 2004
Материал
приведён исключительно в
ознакомительных целях. Автор статьи
не несёт ответственности за
использование Вами данной
информации.
|