Введение в защиту Shareware-программ

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

Только не строй иллюзий, защиту, которую нельзя взломать ещё никто не смог написать, даже компании с огромным бюджетом и штатом специалистов в данной области. Поэтому если ты написал что-нибудь стоящее, это всё равно взломают, вопрос только в том сколько времени на это уйдёт. Как говорится, если для Вашей Shareware-программы нет крека, значит ей просто никто не пользуется, ну или почти никто (кол-во пользователей в таком случае совпадает с кол-вом людей, которые заплатили тебе за регистрацию).

Этот факт хорошо известен авторам популярных программ, например, WinRAR, сложно найти более популярную программу русского автора и при этом более простую во взломе, «зарегистрироваться» можно заменой пары байт, но даже если у тебя нет дизассемблера, то достаточно удалить наг-скрин (диалог, который напоминает о том, что это оценочная версия, и не плохо было бы купить лицензию ;-)) из ресурсов (диалог REMINDER) в редакторе ресурсов
(ResHacker, Restorator,etc) и там же поправить заголовок, и больше ничто не будет напоминать тебе о регистрации. Почему же Александр Рошал не напишет более сложную защиту? Всё просто, он прекрасно понимает, что его программа настолько популярна, что даже если он потратит кучу времени на написание сложной системы регистрации, её всё равно взломают в первую же неделю после выхода, если не в первый же день ;-).

Так вот будет ли пользователь пользоваться креком зависит от его менталитета, цены программы и наличия бесплатной техподдержки с твоей стороны в случае регистрации (также могут быть бесплатные обновления). Поэтому 7 раз подумай, нужна ли тебе сложная защита, прежде чем однажды начать её писать. Но если ты всё-таки решил усложнить процедуру взлома, то читай дальше.

Для начала запомни несколько базовых принципов:

— не привлекай внимания к ядру защиты, не надо выводить всякие дурацкие сообщения типа «Спасибо за регистрацию» или «Неверный пароль», это существенно упростит взлом, особенно если ты их выводишь сразу после проверки регистрационных данных, оптимальным вариантом будет отложенная регистрация, т.е. не проверяй регистрационные данные сразу после ввода, просто запомни их и выведи нейтральное сообщение типа «Для завершения регистрации необходим перезапуск программы / перезагрузка компьютера.». Корректность регистрации проверяй при закрытии (OnCloseQuery), либо при открытии программы (OnShow), если данные корректны, то просто сохрани зарегистрированное состояние, как именно – другой вопрос. Например, можно создать файл с зашифрованной регистрационной информацией, как это делает DrWeb, или создать десяток ключей в реестре, а комбинация из значений некоторых из них будет соответствовать зарегистрированному состоянию, а значения других будут случайными. Одного ключа недостаточно, т.к. его легко обнаружить(например, с помощью утилиты RegMon) и перевести в нужное состояние.

— не сравнивай сами пароли, это упростит написание кейгена. Вместо этого следует сравнивать их хеши, полученные при помощи какого-нибудь необратимого алгоритма шифрования (MD5, SHA1, etc). Если ты решил сделать паролем хеш логина, то не забудь использовать шифрование хотя бы несколько раз, при этом попутно выполнять произвольные операции (xor, циклический сдвиг, урезание, замену подстрок, etc.) над строкой текущего хеша, не помешает также сделать паролям привязку к дате, чтобы они со временем устаревали.

— используй exe-упаковщики и протекторы. Кроме уменьшения размера исполняемого файла упаковщики дадут дополнительный бонус твоей системе защиты, так как крекеру, прежде чем перейти к взлому, необходимо распаковать твою программу, поэтому старайся использовать упаковщики, для которых в интернете нет автоматических распаковщиков, уже это отпугнёт многих крекеров. Но не обольщайся, это не даст тебе гарантию от взлома, так как упаковщик добавляет в файл и распаковщик, чтобы перед выполнением программа могла распаковаться в оперативную память, вот тут то её и можно взять тёпленькой и беззащитной, останется только восстановить таблицу импорта, например, при помощи Import REConstructor. Большую защиту тебе дадут протекторы, такие как Armadillo, их защиту весьма трудно снять.

Теперь рассмотрим как взламывают программы, если ты думал, что взлом осуществляется только силой мысли и ручной правкой экзешника в блокноте, то это в корне неверно. Для взлома применяется целая армия специальных утилит:

· декомпиляторы
· дизассемблеры
· отладчики
· вспомогательные утилиты (редакторы PE-заголовков, секций, ресурсов; утилиты мониторинга файловой системы и реестра, утилиты слежения за окнами и вызовами API-функций; HEX-редакторы; автоматические распаковщики; etc.)

Декомпиляторы частично или полностью воссоздают программу на языке высокого уровня, используя лишь исполняемый файл. Декомпиляторы существуют для множества компиляторов: Delphi, .NET, VB, Java, etc. Нас в данный момент интересует Delphi (для C++Builder будет тоже самое), для него есть два декомпилятора: DeDe и exe2dpr.

exe2dpr обладает лишь базовыми функциями, которых, впрочем, для взлома часто бывает достаточно: восстановление всех форм проекта и всех обработчиков событий с их адресами. DeDe кроме этих функций предоставляет встроенный дизассемблер и удобный интерфейс для исследования полученных данных, также он найдёт все используемые классы и модули, распознает VCL процедуры и ещё много чего…

Защититься от декомпилятора, если крекер уже снял упаковщики и протекторы, практически невозможно, поэтому ни в коем случае не помещай проверку регистрационных данных в обработчик OnClick той самой кнопки ОК, которая подтверждает их ввод, — это начало конца твоей защиты, помни об этом! Но не всё так страшно, декомпиляция программ, написанных на Delphi является частичной, поэтому её мало для взлома, после неё необходимо воспользоваться
дизассемблером и/или отладчиком. А радикальным средством от декомпиляторов будет написание программы на Visual C++, для него насколько мне известно декомпилятора не существует (правда существуют сигнатуры для IDA, которые позволят распознать все библиотечные функции).

Дизассемблеры переводят исполняемый файл на язык ассемблера, а также распознают таблицу импорта, строки и ресурсы. Некоторые дизассемблеры включают в себя отладчики. Для защиты от дизассемблера нужно применять шифрование строк и функций, подробнее об этом можно прочитать в статьях tripsin`a в этом и предыдущем номерах журнала. Программы на Delphi слабо используют ресурсы (по сравнению с программами на Visual C++), поэтому хватит шифрования строк, регистрационных и антиотладочных функций.

Отладчики позволяют пошагово выполнять программу, поэтому от них возможно избавляться во время выполнения, при запуске программы надо вызвать зашифрованную функцию, которая прервёт процессы наиболее популярных отладчиков, если они запущены. А т.к. большинство отладчиков позволяет отлаживать уже запущенную программу, то необходимо вызвать ту же функцию и перед проверкой регистрационных данных.

Наиболее популярными отладчиками являются OllyDbg, отладчик, встроенный в IDA и SoftICE. Первые два являются отладчиками уровня пользователя, поэтому для несложной защиты достаточно просто прервать их процессы: OllyDbg.exe, idag.exe, idag64.exe. Это можно сделать, например, такой функцией:

uses Tlhelp32;

function KillTask(ExeFileName: string): integer;
const
PROCESS_TERMINATE=$0001;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
result := 0;
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,
0);
FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FprocessEntry32);
while integer(ContinueLoop) 0 do
begin
if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
UpperCase(ExeFileName))
or (UpperCase(FProcessEntry32.szExeFile) =
UpperCase(ExeFileName))) then
result := Integer(TerminateProcess(OpenProcess(
PROCESS_TERMINATE, BOOL(0),
FProcessEntry32.th32ProcessID), 0));
ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;
Для остановки SoftICE, если он запускается как служба (наиболее частый случай), надо выполнить команду оболочки net stop ntice, например так:

uses ShellAPI;

ShellExecute(0, ‘open’, ‘net’, ‘stop ntice’, nil, SW_HIDE);
Теперь ты знаешь базовые принципы взлома и защиты, так что можешь приступать к написанию защиты, которая сделает взлом твоей программы длительным и увлекательным занятием для крекера.

Понравилась статья? Поделиться с друзьями: