Молот и топор 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}. Непосредственно в коде программы необходимо выжечь строку: |