Данную статью я представляю вниманию новичков для обеспечения защиты своего софта. Защита реализуется путем привязки к железу компа + онлайн проверка.

Наша защита будет состоять из нескольких частей:

  • Генератор серийного номера по системным характеристикам.
  • Генератор ключа авторизации по серийнику
  • Защищаемая программа


Итак… с структурой мы разобрались, теперь нужно определиться к каким параметрам мы будем осуществлять привязку.

Мы сделаем это через WIN Api функции:

  • GetUserName — Имя текущего пользователя.
  • GetComputerName — Имя компутора.
  • GetVolumeInformation — Получение информации о носителе.
  • GlobalMemoryStatus — Информация о используемой системой памяти.

Что бы облегчить вам жизнь, я приведу готовые функции:

function UserName: string;
var
u: pchar;
i: dword;
begin
i := 1024;
u := StrAlloc(Succ(i));
if GetUserName(u, i) then Result := StrPas(u) else Result := '?';
end;

function ComputerName: string;
var
buffer: array[0..255] of char;
size: dword;
begin
size := 256;
if GetComputerName(buffer, size) then
Result := buffer
else
Result := ''
end;

function GetHard: String;
var
VolumeName, FileSystemName: array [0..MAX_PATH-1] of Char;
VolumeSerialNo: DWord;
MaxComponentLength,FileSystemFlags: Cardinal;

begin

GetVolumeInformation('C:\',VolumeName,MAX_PATH,@VolumeSerialNo,
MaxComponentLength,FileSystemFlags, FileSystemName,MAX_PATH);
Result := IntToHex(VolumeSerialNo,8);

end;

function GetMem: String;
var
MyMem: TMemoryStatus;

begin

MyMem.dwLength:=SizeOf(MyMem);
GlobalMemoryStatus(MyMem);
with MyMem do begin
Result:= IntToStr(dwTotalPhys);
end;
end;


Итак, мы получили всю интересующую нас информацию. Теперь мы склеим эти данные в hex строку, что бы конечный пользователь не знал, какие параметры мы используем.
Берем функцию преобразования в 16ричный вид.

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;


Склеим все параметры —

function getSerial:string;
begin
Result := StringToHex((UserName + ComputerName + GetHard + GetMem));
end;


Вывод полученной строки в TEdit

procedure TForm2.Button1Click(Sender: TObject);
begin
Edit1.Text := getSerial;
end;


Мои поздравления, готов модуль получения serial кода.

Генератор регистрационного ключа

Полученый серийник надо шифрануть, что бы жизнь медом не казалась. Используйте любые методы, я приведу пример MD5.
функция шифрации.

function getKey(Serial: string):string;
begin
Result := MD5DigestToStr(MD5String(Serial+'123'));

end;


Теперь кидаем на форму два Tedit и кнопку.
на онклик ставим
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit2.Text := getKey(Edit1.Text); / в первый Edit вставляем серийник, во втором будет зашифрованый вариант(очевидно)
end;


Кейген готов.

Пишем основную программу.

1) Кидаем все функции сбора инфы о компе и генерации серийника из первого модуля.
2) Кидаем функцию шифрации серийника из генератора рег ключа.
Приступим к регистрации программы и онлайн привязки. Кидаем Tedit(для ввода рег ключа) + 2 кнопки
(1 — проверка на валидность рег ключа 2 — коннект к серверу и проверка на наличия записи там)
procedure TForm2.Button1Click(Sender: TObject);
begin
if Edit1.Text = getKey(GetSerial) then ShowMessage('RegOk') else ShowMessage('NoFuckinWay');
end;


При валидности рег ключа — RegOk, если нет, то посылает.
В качестве онлайн проверки будем использовать простейший вариант — txt файл.
Алгоритм — на хосте лежит файл серийник.txt, а в нем же рег ключ. Программа сравнивает содержимое текстовика и ключ, сгенереный программой.
procedure TForm2.Button2Click(Sender: TObject);
begin
if getKey(GetSerial)= IdHTTP1.Get('http://zzzzzz.com/reg/'+GetSerial+'.txt') then ShowMessage('RegOk') else ShowMessage('NoFuckinWay');
end;


Вот и все Осталось вам придумать, куда прописывать то, что программа зарегистрирована.
Я лишь описал наглядный пример, как строятся такие методы защиты… вы можете использовать свои способы привязки, совершенствуя код + верификация через txt самый ненадежный способ. используйте php+mysql и т.д.

Будут вопросы — пишите, но я тут разжевал все до процедур онклика.

Всем удачи в начинаниях.

p.s. Напоминаю, что статья для новичков и является пищей для размышления.

Комментарии (17)


  1. korvint
    00.00.0000 00:00
    +1

    Кстати, а куда прописывать тот факт, что программа зарегистрирована? В реестр, в секретный файл? Или есть более удобные варианты?


    1. freeExec
      00.00.0000 00:00

      Зачем это куда-то прописывать? Сохраняешь код и проверяешь его при запуске.


  1. WondeRu
    00.00.0000 00:00
    +7

    Статья провалялась в песочнице с 2003 года, судя по листингам на Delphi, да и постановке проблемы. А еще понравилось: пишите на php и mysql ))


    1. korvint
      00.00.0000 00:00

      Так это я ее оттуда вытащил, что ли?

      Понадобилось по быстрому привязать тестовую программу к компьютеру. Задал запрос https://yandex.ru/search/?text=как+привязать+программу+к+компьютеру&lr=136871&src=suggest_T

      Первой ссылкой выскочил этот пост из песочницы. Причем оказалось то что надо!


      1. DarthPadla
        00.00.0000 00:00
        +2

        Надеюсь, вы используете полученные знания в качестве общей концепции и не будете использовать "md5 шифрацию" getMem


        1. korvint
          00.00.0000 00:00

          Вы имеете ввиду проблемы привязки к объему памяти?


          1. mrkaban
            00.00.0000 00:00

            У MD5 относительно легкое нахождение коллизий при шифровании, что сводит его уровень защищенности на весьма низкий уровень.


            1. freeExec
              00.00.0000 00:00
              -1

              Зачем тут искать коллизии? Во-вторых, коллизию, чтобы она была названием компа и пользователя, вы не найдёте. Так что в этом плане тут проблемы нет.


    1. bogolt
      00.00.0000 00:00
      +1

      Только хотел спросить как там в начале нулевых а оно и правда оттуда =)


      1. mrkaban
        00.00.0000 00:00

        Пользователь зарегистрирован в 2012 году, видимо тогда и написал статью.


  1. Mirzapch
    00.00.0000 00:00
    +2

    Такая защита отключается за 10-15 минут.

    Код защиты должен быть размазан по коду программы. Серийный номер должен непосредственно участвовать в коде обработки данных программой.

    Подробнее - в книге "Техника защиты компакт-дисков от копирования" Николая Лихачёва.


    1. korvint
      00.00.0000 00:00

      Т.е. проверка введенного серийника в разных местах программы разными процедурами? Или как?


      1. IgorIngeneer
        00.00.0000 00:00

        ну вообще то был когда-то вмпротект - так там наворочено ого как - против дизасемблера внутри ехе виртуальна машина со своей очень сложной системой команд внутри которой и хранится код привязки - да еще и части бинарника ехе кодируются серийником. Вот вроде статья про него https://habr.com/ru/sandbox/26302/


        1. freeExec
          00.00.0000 00:00

          Виртуальная машина не сложная, просто она генерирует тонны мусора и вместо того, чтобы просто сложить два числа, на выходе генерируются 10 операция умножения, деления, вычитания. Это усложняет понимание происходящего, не более.


      1. freeExec
        00.00.0000 00:00

        Только не проверки серийника, а использование его компонентов в логике.
        Утрированный пример: пользователь ввёл дату в программе, мы к ней добавили номер диска и теперь храним и работает с этим значением. Когда нам эта дата снова потребуется, мы вычтем из неё номер диска, но который уже храниться в ключе регистрации. В итоге, если ты просто поменял флаг в проверке регистрации, то на выходе у тебя получится мусор, потому, что ключ и железо не соответствуют друг другу, и программа упадёт.
        И это как минимум тебя заставит разобраться с алгоритмом ключа, а не просто изменить один прыжок.


  1. AlexGorky
    00.00.0000 00:00

    Похожая защита (привязка к оборудованию) реализована в 1С.

    Но там чуть сложнее - флешки не участвуют в списке оборудования, увеличение памяти не считается изменением.


  1. niwir
    00.00.0000 00:00

    Ух, родной паскаль))) пустил скупую слезу)))