В статье рассказывается как реализовать защиту своих программ. Статья рассчитана на начинающих программистов, которые хотят защитить свой софт, или ограничить круг пользования. В ней будет рассказано как реализовать привязку программы к железу.
Наша система защиты будет состоять из трех частей.
1. Модуль выдающий серийный номер по которому будет осуществляться проверка.
2. Модуль генерирующий ключ по серийному номеру.
3. Модуль проверяющий корректность ключа для конкретного пользователя.
Начнем по порядку. На данном этапе нам нужно определиться к каким параметрам системы и железа мы будем привязываться.
Из системы мы можем привязаться к имени пользователи, и имени компьютера. Это можно сделать с помощью WinAPI функции GetUserName и GetComputerName.
Приведу готовые функции возвращающие имя пользователя и компьютера:
Код:
function GetCompName: String;
var
Buffer: array[0..255] of Char;
Size: DWORD;
begin
size := 256;
if GetComputerName(Buffer, Size) then
Result := Buffer
else
Result := ''
end;
function GetUsersName: String;
var
Size: Cardinal;
PRes: PChar;
BRes: Boolean;
begin
Size := MAX_COMPUTERNAME_LENGTH + 1;
PRes := StrAlloc(Size);
BRes := GetUserName(PRes, Size);
if BRes then
Result := StrPas(PRes)
else
Result := '';
end;
Из железа мы привяжемся к серийному номеру жесткого диска. Здесь нам пригодится WinAPI функция GetVolumeInformation она определяет информацию о носителе, среди которой присутствует и серийный номер.
Вот уже готовая функция которая использует GetVolumeInformation и возвращает серийный номер указанного тома.
Код:
function GetSerialNumDisk: String;
var
SerialNum: DWORD;
sz,fs: DWORD;
begin
GetVolumeInformation(
'C:\',
nil,
0,
@SerialNum,
sz,
fs,
nil,
0);
Result := IntToStr(SerialNum);
end;
Хочется уточнить что это не серийный номер самого винта а серийный номер раздела. Который меняется при форматировании. Серийный номер самого винта получить гораздо труднее по этому этот метод не рассматривается в данной статье, так как она рассчитана на начинающих.
Мы разобрали функции с помощью которых мы можем получить параметры системы и железа к которым мы будем привязываться. Можно было бы сразу выводить их пользователю и по ним генерировать ключ. Но мы зашифруем эти данные что бы пользователь не мог определить к каким параметрам мы будем привязываться. Какой то специальный алгоритм кодирования мы не будем использовать(так как это займет много места и для начинающих будет не очень понятно), а просто последовательно склеим полученные данные в одну строку, и эту строку преобразуем в шестнадцатеричный вид. Я уже написал функцию которая преобразует строку в шестнадцатеричный вид.
Код:
function StringToHex(str1,Separator:String):String;
var
buf:String;
i:Integer;
begin
buf:='';
for i:=1 to Length(str1) do begin
buf:=buf+IntToHex(Byte(str1[i]),2)+Separator;
end;
Result:=buf;
end;
Теперь объединим все выше описанные функции в одной программе. Я не буду описывать как и какие компоненты накидывать на форму, а приведу исходный код, учитывая что я выше описал все функции, разобраться будет не сложно.
[Ссылки могут видеть только зарегистрированные пользователи. ]
Вот у нас и получилась программа которая выдает серийный номер пользователю.
Теперь пользователь должен передать этот серийник разработчику по которому тот сгенерирует ключ.
Вот мы и подошли ко второй части.
Для генерации ключа мы тоже не будем применять и разрабатывать каких то хитрых алгоритмов. А воспользуемся простыми хеш функциями. Итак что же будет представлять наш ключ. Мы воспользуемся MD5 алгоритмом, дважды получив хэш нашего серийника. Схематично это выглядит так: MD5(MD5(Наш идешник)).
Для получения MD5 хеша строки я использовал модуль MD5.pas я не помню откуда я его качал так как это было давно, но копирайты автора присутствуют в модуле.
Я особо не стал заморачиваться с алгоритмом так как статья обучающая. Вы же можете генерировать ключ любым образом. С использованием того же MD5 можно придумать много чего, например разбивать ид на две части, получать MD5 каждой части, затем склеивать эти два хэша в одну строку и получать MD5 этой строки, или же так ее и оставить, в общем тут как ваша фантазия сыграет.
[Ссылки могут видеть только зарегистрированные пользователи. ]
Ну что же. Ключ мы получили. Теперь реализуем проверку ключа в защищаемой программе.
Третья часть.
В этой части будут использоваться все функции из предыдущих.
Так что я объясню основной алгоритм и прикреплю исходный код.
Тут все довольно просто, защищаемая программа генерирует серийник как в первом пункте, и по этуму серийнику генерирует ключ как во втором пункте, а затем этот ключ сравнивает с ключом введенным в поле и если они равны то программа сообщает об успешной регистрации.
Вот исходный код защищаемой программы:
[Ссылки могут видеть только зарегистрированные пользователи. ]
Также пункт 1 и пункт 3 можно объединить в одной программе, это я оставлю на вас
[Ссылки могут видеть только зарегистрированные пользователи. ]
Данная статья не претендует на самый навороченный метод защита, а лишь показывает пример построения подобных защит. Поэтому в заключение хочу сказать несколько слов по возможному улучшению защиты.
1. Для привязки необходимо использовать как можно больше параметров.
2. Разработать более продвинутые алгоритмы генерации и шифрации как серийника так и ключа.
3. Введенный ключ необходимо где либо сохранять, что бы не вводить его каждый раз.
Вот в принципе и все. Защищайтесь и предохраняйтесь. =)
P.S. Если статья вызовет интерес, то напишу продолжение о том как делать онлайн верификацию с привязкой к железу.
________________ Продаю приват читы для AION Absolute, desteny 3.5, Legend, Cataclysm, Ru, EU, NA Продаю многооконку на R2 Пишу читы на заказ под любые игры. Предложения в ЛС. Все мои читы/программы/статьи тут:http://zhyk.ru/forum/showpost.php?p=38501&postcount=21
Я писал на Delphi 2010, ты скорее всего пытаешься компилить на Delphi 7 из за этого ошибки. Если нужно то сделаю пример на Delphi 7.
Добавлено через 5 минут
P.S. Кстати просто удаляешь строчку Application.MainFormOnTaskbar := True; и все будет работать.
________________ Продаю приват читы для AION Absolute, desteny 3.5, Legend, Cataclysm, Ru, EU, NA Продаю многооконку на R2 Пишу читы на заказ под любые игры. Предложения в ЛС. Все мои читы/программы/статьи тут:http://zhyk.ru/forum/showpost.php?p=38501&postcount=21
Последний раз редактировалось Тигрь; 24.04.2011 в 13:01.
Причина: Добавлено сообщение
Эта строчка влияет только на отображение кнопки в таскбаре. При ее удалении все нормально работает. Закомпилил на 7 делфи.
Delphi 2010 - Это RAD Studio 2010.
________________ Продаю приват читы для AION Absolute, desteny 3.5, Legend, Cataclysm, Ru, EU, NA Продаю многооконку на R2 Пишу читы на заказ под любые игры. Предложения в ЛС. Все мои читы/программы/статьи тут:http://zhyk.ru/forum/showpost.php?p=38501&postcount=21
Я же написал что всего одна строчка удаляется и работает под D7. Ну так как я сегодня очень добрый то вот исходники под D7. [Ссылки могут видеть только зарегистрированные пользователи. ]!
________________ Продаю приват читы для AION Absolute, desteny 3.5, Legend, Cataclysm, Ru, EU, NA Продаю многооконку на R2 Пишу читы на заказ под любые игры. Предложения в ЛС. Все мои читы/программы/статьи тут:http://zhyk.ru/forum/showpost.php?p=38501&postcount=21
Я знаю как с этим быть. Купить книжку по делфи и изучить основные операторы языка.
Хотя модеры нашли более лучший метод =)
Спасибо =)
________________ Продаю приват читы для AION Absolute, desteny 3.5, Legend, Cataclysm, Ru, EU, NA Продаю многооконку на R2 Пишу читы на заказ под любые игры. Предложения в ЛС. Все мои читы/программы/статьи тут:http://zhyk.ru/forum/showpost.php?p=38501&postcount=21
Метод хорош, но написание трех модулей, просьба что-то куда-то вводить пользователя - это не очень хорошо.
Я придумал метод получше, с самопривязкой после первого запуска. Т.е. один раз запустив прогу, на другом компьютере она уже не запустится:
[Ссылки могут видеть только зарегистрированные пользователи. ]
Метод хорош, но написание трех модулей, просьба что-то куда-то вводить пользователя - это не очень хорошо.
Я придумал метод получше, с самопривязкой после первого запуска. Т.е. один раз запустив прогу, на другом компьютере она уже не запустится:
Как бы реклама, ну и фиг с ней. Сразу покажу минусы подобной реализации:
1. Нельзя запаковать программу. Как следствие - простота взлома.
2. Это не привязка к определенному компьютеру в принципе. Так какполучив программу я всегда могу скопировать "чистую" куда нибудь и потом раздавать желающим.
________________
Ни одно доброе дело не остается безнаказанным.
Метод, описанный здесь так же не является сложным для взлома. Подредактировав один байтик можно прогу начисто лишить проверки введенного кода.
Моя реализация и не рассчитана на защиту от взлома проги. В ней показана лишь возможность самомодификации и возможность привязки проги к железу. Хорошая ведь защита от ламера, который купил у вас прогу, но захотел ее кому-то продать еще.
Временный ехешник также можно копировать во временную папку, если что. Ламер не будет знать, что прога что-то делает над собой.
А насчет упаковки - спокойно упаковал UPXом, и добавил секцию. Все работает.
Последний раз редактировалось Dr. MefistO; 31.05.2011 в 20:33.
Метод, описанный здесь так же не является сложным для взлома. Подредактировав один байтик можно прогу начисто лишить проверки введенного кода.
Моя реализация и не рассчитана на защиту от взлома проги. В ней показана лишь возможность самомодификации и возможность привязки проги к железу. Хорошая ведь защита от ламера, который купил у вас прогу, но захотел ее кому-то продать еще.
Временный ехешник также можно копировать во временную папку, если что. Ламер не будет знать, что прога что-то делает над собой.
А насчет упаковки - спокойно упаковал UPXом, и добавил секцию. Все работает.
Ну насчет упаковки - было предположение. Если тест показал что это возможно значит я не прав.
Но ты не понял самого главного. Смотри, ты передаешь мне программу, я ее принимаю, сохраняю у себя две копии. Одну запускаю и пользую, а вторую раздаю всем желающим.
Сделаю еще одно предположение, если в твоей программе есть сравнение текущего MAC-адреса с записанным в программе (пусть шифрованного/хешированного) то кряк опять таки пишется заменой одного байта.
________________
Ни одно доброе дело не остается безнаказанным.
Сделаю еще одно предположение, если в твоей программе есть сравнение текущего MAC-адреса с записанным в программе (пусть шифрованного/хешированного) то кряк опять таки пишется заменой одного байта.
Мак у меня считывается при первом запуске, прошивается в себя. А потом при последующих запусках сверяется с текущим. Да, такую проверку легко снять. Но не в этом суть...
Цитата:
Сообщение от Dinmaite
Но ты не понял самого главного. Смотри, ты передаешь мне программу, я ее принимаю, сохраняю у себя две копии. Одну запускаю и пользую, а вторую раздаю всем желающим.
Хорошо, ты знаешь, например, что прога себя модифицирует. Но если ламер знать не будет. он запустит пару раз, думая, что прога будет у всех работать)
Ну вот собственно по этой причине я отказался от самомодификации. И перешел к онлайн аутентификации (благо программы пишутся под онлайнигры, а значит соединение с интернетом обязано наличиствовать)
PS Сейчас ухожу, дискуссию можно смогу продолжить лишь завтра.
________________
Ни одно доброе дело не остается безнаказанным.
Ну вот собственно по этой причине я отказался от самомодификации. И перешел к онлайн аутентификации (благо программы пишутся под онлайнигры, а значит соединение с интернетом обязано наличиствовать)
Ты имеешь ввиду считывание каких-то данных из инет-источника? И опять же сверка их в проге?
Ты имеешь ввиду считывание каких-то данных из инет-источника? И опять же сверка их в проге?
Без сверки мы все равно ничего не сделаем. Вопрос лишь в том как и где провести сверку. Выглядит примерно так:
1. Отсылаем ключ серверу.
2. Сервер проверяет наличие ключа в базе + проверяет срок годности ключа. Если все нормально сервер передает клиенту ключ-ответ.
(очень слабое место, перехватив ключ-ответ можно склепать локальный сервер, зато есть возможность триала, возможность отключить неугодных и нет дополнительных файлов содержащих ключ)
3. Программа сверяет ключ ответ со сгенерированным ключем (в оригинале у меня попросту валом мусорных функций ведущих обработку ключа, из них одна "настоящая". По задумке сверка ключа математическими методами, что чуть лучше простого if)
4. Если все оккей - запускаемся.
________________ Dinmaite пишет с меня, когда забывает пароль от Dinmaite[work] и сидит не со своего IP.
Ого, пока меня небыло интересную дискуссию начали. Очень все правильно описал динко. Особенно про математический алгоритм проверки ключа, к нормальных защитах так и делается. И интересная мысль о строке годности ключа, если сделать что бы возвращаемый сервером ключ работал только один день, и дата присутствовала в алгоритме кодирования ключа. Затем при дешифрации так же алгоритм использовал дату текущего дня, это вызовет трудность создания локального сервера авторизации.
________________ Продаю приват читы для AION Absolute, desteny 3.5, Legend, Cataclysm, Ru, EU, NA Продаю многооконку на R2 Пишу читы на заказ под любые игры. Предложения в ЛС. Все мои читы/программы/статьи тут:http://zhyk.ru/forum/showpost.php?p=38501&postcount=21