Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #73, ЯНВАРЬ 2005 г.

Молот и топор

Shturmovik (Shturmovik@bk.ru)

Хакер, номер #073, стр. 073-108-1


Очерки о защите программ

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

Смерть стандартам

В качестве памятки скажу, что для создания правильной защиты необходимо забыть о стандартах. Все компоненты нашего приложения должны разрабатываться динамически. Динамическое создание главной формы позволяет обмануть декомпиляторы в духе DeDe. Скопируй из плашки или исходника код динамического создания формы и попробуй скормить DeDe (он тоже присутствует на диске) полученный проект. В результате его работы не получится совершенно ничего информативного :).

Динамическая главная форма

procedure CreateMainForm;

var

MainForm: TForm;

M: TMethod;

begin

Application.CreateForm(TForm, MainForm);

Mainform.Caption:='CrackMe';

Mainform.BorderIcons:=[biSystemMenu];

Mainform.BorderStyle:=bsSingle;

Mainform.Height:=245;

Mainform.Width:=245;

M.Code := @MainFormClick;

M.Data := Pointer(MainForm);

MainForm.OnClick := TNotifyEvent(M);

End;

procedure MainFormClick(Self: TForm; Sender: TObject);

begin

ShowMessage(Self.Caption + ': FormClick!');

end;

Прячем строки

Пионеры в крэкинге всегда начинают свои эпохальные взломы с поиска строковых констант в приложениях, проще говоря, ищут сообщение о неправильном серийнике. Существует несколько способов защиты строк: динамические указатели, ссылки на ресурсы, хранение в dll, шифрование и т.д. Мы рассмотрим шифрование и ссылки на ресурсы. Впервые я увидел описание такой защиты у основателя cracklab.ru bad_guy'я. Код процедуры на плашке прост как int 21h.

Функция защиты строк

function ch(c:byte):string;

begin

ch:=chr(c);

end;

begin

MessageBox(0,PChar(ch(67)+ch(114)+ch(97)+ch(99)+ch(107)+ch(109)+ch(101)),

PChar(ch(67)+ch(114)+ch(97)+ch(99)+ch(107)+ch(109)+ch(101)), mb_Ok);

end.

Из примера видно, что мы храним строковые константы в виде отдельных кодов символов строк, и результатом работы данного кода будет окошко с заголовком и текстом «Crackme». Единственное, что теперь от нас требуется, - это написать программу, которая будет преобразовывать строки в символы. Это самый простой пример, и взломщикам он уже известен, так сказать, в лицо, однако сам алгоритм кодировки символа ты можешь придумать свой, что намного затруднит исследование дизассемблерного листинга программы. На скриншоте изображен наш любимый дизассемблер, который не видит строк «Crackme».

Второй способ заключается в том, что все строки хранятся в ресурсах файла или библиотеки и достаются оттуда динамически по мере необходимости. Для начала надо поместить строки в ресурс. Делается это просто. Создаем файл *.rc (я создал str.rc) и в нем пишем следующие строки:

STRINGTABLE

{ 1, "CrackMe" }

После чего файл сохраняем и компилируем: пишем в командной строке BRCC32 Str.RC, и у нас появляется готовый res.res-файл. Теперь посмотрим, как работать с ресурсом. Для этого, во-первых, надо объявить добавление файла в проект - после объявления файла формы - {$R *.dfm} пишем {$R str.RES}. Непосредственно в коде программы необходимо выжечь строку:

Содержание  Вперед на стр. 073-108-2
<<< НАЗАД ||| ГЛАВНАЯ