1. Вы находитесь в архивной версии форума xaker.name. Здесь собраны темы с 2007 по 2012 год, большинство инструкций и мануалов уже неактуальны.
    Скрыть объявление

Правильная реализация привязки к компьютеру

Тема в разделе "Pascal/Delphi", создана пользователем Dr. MefistO, 31 май 2011.

  1. Dr. MefistO

    Dr. MefistO Крывіч Глобальный модератор

    Регистрация:
    3 авг 2008
    Сообщения:
    152
    Симпатии:
    254
    Баллы:
    0
    Доброго времени суток.
    Поводом для написания данной статьи послужило отсутствие среди протекторов программ действительно правильной реализации привязки к железу компьютера. Данный способ не защитит даже от начинающего крякера, но от ламера, который захочет поделиться вашей проданной (отданной) ему программой - самое то!)
    Вот, например: берем какой-нибудь протектор с возможностью привязки, и защищаем, например, калькулятор. В итоге, он привяжется только к ВАШЕМУ железу, и откажется запускаться на другом. Но не запускать же протектор у заказчика на компьютере!

    Нужно было действовать так:
    1) программа запускается первый раз, считывает параметры железа, записывает их в себя и работает дальше;
    2) при последующих запусках программа считывает из себя сохраненную контрольную сумму железа, получает текущую сумму, сравнивает, и если есть различие - закрывалась.

    Нам понадобится:
    1) Delphi 7 (для написания программы);
    2) HEX-редактор (я буду использовать WinHEX);
    3) PEiD, или же любая друга программа, в которой можно работать с секциями PE-файла.
    Все программы можно найти на сайте CRACKLAB.RU

    С чего же начать? Для начала нужно найти в инете процедуру считывания контрольной суммы чего-то из железа (я выбрал MAC-адрес, но можно все что угодно - реализация одна и та же будет).

    Такс, мак получили. Но как его запихнуть в самого себя (exe-файл)? Я придумал следующий алгоритм:
    1) копируем самого себя (А) во временный файл (В);
    2) открываем (В) для чтения и записи;
    3) в определенном месте (В) (для этого мы создадим дополнительную секцию в исполняемом файле) читаем байты, и, если они равны нолям, значит записываем туда текущий мак-адрес. Иначе (например, программа уже запускалась), считываем из этой секции ранее записанный мак-адрес и сверяем его с полученным на текущем железе. При различии - закрываем программу;
    4) создаем через код программы (А) бат-файл, который будет удалять (А), переименовывать (В) в (А) и удалять себя;
    5) при закрытии программы выполняем пункт 4;

    В итогде мы получим новый ехешник в котором будет прописан мак-адрес, но с тем же именем, который был в начале;

    Далее... Как создать секцию ресурсов, в которую мы будем что-то записывать?
    Нам нужно открыть скомпилированный EXE-файл в PEiD, в плагинах выбрать Section Tool v1.01, вписать имя секции (например, ".mac32") нажать кнопочку Add New Section, и сохранить в новый файл.
    В списке секций вы увидите вновь созданную. Нам нужно запомнить Raw Adress.
    Теперь открываем новый ехешник в хекс-редакторе, и переходим на этот адрес. Видим немного дальше этого адреса много нулей. Вот сюда мы и будем писать наш мак в пункте 3.

    Ну а теперь реализация...
    Код:
    [B]uses[/B]
      Nb30, ShellApi;
    
    [B]const[/B]
      wraddr = $5b610;
      [COLOR="SeaGreen"]//это адрес, по которому мы будем записывать в EXE-файл мак-адрес[/COLOR]
    
    [COLOR="SeaGreen"]//собственно процедура чтения мак-адреса[/COLOR]
    function GetMACAdress: string;
     var
       NCB: PNCB;
       Adapter: PAdapterStatus;
    
       URetCode: PChar;
       RetCode: char;
       I: integer;
       Lenum: PlanaEnum;
       _SystemID: string;
       TMPSTR: string;
     begin
       Result    := '';
       _SystemID := '';
       Getmem(NCB, SizeOf(TNCB));
       Fillchar(NCB^, SizeOf(TNCB), 0);
    
       Getmem(Lenum, SizeOf(TLanaEnum));
       Fillchar(Lenum^, SizeOf(TLanaEnum), 0);
    
       Getmem(Adapter, SizeOf(TAdapterStatus));
       Fillchar(Adapter^, SizeOf(TAdapterStatus), 0);
    
       Lenum.Length    := chr(0);
       NCB.ncb_command := chr(NCBENUM);
       NCB.ncb_buffer  := Pointer(Lenum);
       NCB.ncb_length  := SizeOf(Lenum);
       RetCode         := Netbios(NCB);
    
       i := 0;
       repeat
         Fillchar(NCB^, SizeOf(TNCB), 0);
         Ncb.ncb_command  := chr(NCBRESET);
         Ncb.ncb_lana_num := lenum.lana[I];
         RetCode          := Netbios(Ncb);
    
         Fillchar(NCB^, SizeOf(TNCB), 0);
         Ncb.ncb_command  := chr(NCBASTAT);
         Ncb.ncb_lana_num := lenum.lana[I];
         // Must be 16 
        Ncb.ncb_callname := '*               ';
    
         Ncb.ncb_buffer := Pointer(Adapter);
    
         Ncb.ncb_length := SizeOf(TAdapterStatus);
         RetCode        := Netbios(Ncb);
         [COLOR="SeaGreen"]//---- calc _systemId from mac-address[2-5] XOR mac-address[1]...[/COLOR]
        if (RetCode = chr(0)) or (RetCode = chr(6)) then
         begin
           _SystemId := IntToHex(Ord(Adapter.adapter_address[0]), 2) + '-' +
             IntToHex(Ord(Adapter.adapter_address[1]), 2) + '-' +
             IntToHex(Ord(Adapter.adapter_address[2]), 2) + '-' +
             IntToHex(Ord(Adapter.adapter_address[3]), 2) + '-' +
             IntToHex(Ord(Adapter.adapter_address[4]), 2) + '-' +
             IntToHex(Ord(Adapter.adapter_address[5]), 2);
         end;
         Inc(i);
       until (I >= Ord(Lenum.Length)) or (_SystemID <> '00-00-00-00-00-00');
       FreeMem(NCB);
       FreeMem(Adapter);
       FreeMem(Lenum);
       GetMacAdress := _SystemID;
     end;
     [COLOR="SeaGreen"]//конец процедуры чтения мак-адреса[/COLOR]
    
    
    [COLOR="SeaGreen"]//эта функция нужна для записи в бат-файл имени файла без пути
    //(нужно для переименования)[/COLOR]
    function ExtractFileNameEx(FileName: string; ShowExtension: Boolean): string;
    var
      I: Integer;
      S, S1: string;
    begin
      I := Length(FileName);
      if I <> 0 then
      begin
        while (FileName[i] <> '\') and (i > 0) do
          i := i - 1;
        S := Copy(FileName, i + 1, Length(FileName) - i);
        i := Length(S);
        if i = 0 then
        begin
          Result := '';
          Exit;
        end;
        while (S[i] <> '.') and (i > 0) do
          i := i - 1;
        S1 := Copy(S, 1, i - 1);
        if s1 = '' then
          s1 := s;
        if ShowExtension = TRUE then
          Result := s
        else
          Result := s1;
      end
      else
        Result := '';
    end;
    [COLOR="SeaGreen"]//конец функции получения имени файла без пути[/COLOR]
    
    
    [COLOR="SeaGreen"]//код кнопки, по нажатию на которую будут производиться основные действия[/COLOR]
    procedure TForm1.btn1Click(Sender: TObject);
    var
    Memory: TMemoryStream;   [COLOR="SeaGreen"]//будем выделять память для чтения основного файла[/COLOR]
    ts: TFileStream;         [COLOR="SeaGreen"]//это для записи в файл изменений[/COLOR]
    buf,buf2: string[18];    [COLOR="SeaGreen"]//переменные для хранения мак-адреса[/COLOR]
    begin
      ts:=TFileStream.Create('newfile.exe',fmCreate); [COLOR="SeaGreen"]//создаем временный файл для последующей записи[/COLOR]
      Memory := TMemoryStream.Create;    [COLOR="SeaGreen"]//выделяем кусок памяти для чтения исполняемого файла[/COLOR]
      try
        Memory.LoadFromFile(ParamStr(0)); [COLOR="SeaGreen"]//читаем в память нашу программу[/COLOR]
        Memory.Seek(wraddr,soFromBeginning);  [COLOR="SeaGreen"]//переходим по адресу, из которого мы будем читать[/COLOR]
                                              [COLOR="SeaGreen"]//значение МАК-адреса[/COLOR]
        Memory.read(buf,18);                  [COLOR="SeaGreen"]//считываем 18 байт (размер мак-адреса) в переменную[/COLOR]
        buf2:=GetMACAdress;                   [COLOR="SeaGreen"]//во вторую переменную получаем настоящий мак-адрес[/COLOR]
        Memory.Seek(wraddr,soFromBeginning);  [COLOR="SeaGreen"]//опять переходим к адресу чтения[/COLOR]
    
        if Length(buf)=0 then begin           [COLOR="SeaGreen"]//если мак в файл раньше не записывался,[/COLOR]
                                              [COLOR="SeaGreen"]//и его длина будет равна нулю,[/COLOR]
        Memory.write(buf2,18);                [COLOR="SeaGreen"]//значит, записываем текущий мак-адрес[/COLOR]
        buf:=buf2;                            [COLOR="SeaGreen"]//приравниваем текущий мак адрес и[/COLOR]
                                              [COLOR="SeaGreen"]//прочитанный из файла[/COLOR]                                     
        end;
    
        Memory.SaveToStream(ts);        [COLOR="SeaGreen"]//сохраняем изменения во временный файл[/COLOR]
                                              [COLOR="SeaGreen"]//newfile.exe[/COLOR]
    
      finally
        Memory.Free;                           [COLOR="SeaGreen"]//очищаем память[/COLOR]
        ts.Free;                               [COLOR="SeaGreen"]//закрываем файл[/COLOR]
        if buf2<>buf then close;               [COLOR="SeaGreen"]//теперь основное:[/COLOR]
                                               [COLOR="SeaGreen"]//если число считанное из файла и[/COLOR]
                                               [COLOR="SeaGreen"]//текущий мак не равны - значит[/COLOR]
                                               [COLOR="SeaGreen"]//закрываем программу[/COLOR]
      end;
    end;
    [COLOR="SeaGreen"]//конец кода кнопки[/COLOR]
    
    
    [COLOR="SeaGreen"]//создание бат-файла при закрытии программы[/COLOR]
    procedure TForm1.FormDestroy(Sender: TObject);
    var f: textFile;                            [COLOR="SeaGreen"]//текстовый файл (бат)[/COLOR]
      FileName: string;                         [COLOR="SeaGreen"]//переменная для хранения имени файла[/COLOR]
    begin
      FileName := changefileext(paramstr(0), '.bat');  [COLOR="SeaGreen"]//даем имя бат-файлу[/COLOR]
      assignFile(f, FileName);                         [COLOR="SeaGreen"]//и создаем его[/COLOR]
      rewrite(f);                                      [COLOR="SeaGreen"]//если файл есть, перезаписываем его[/COLOR]
    
     [COLOR="SeaGreen"]//в бат-запишем следующий код:
     {
      :1
      Erase имя_ехешника-программы
      If exist имя_ехешника-программы Goto 1
      ren newfile.exe имя_ехешника-программы
      Erase имя_бат_файла
     }
    
     //удаляем ехешник, переименовываем временный файл в начальное имя ехешника
     //удаляем бат-файл[/COLOR]
    
      writeln(f, ':1');
      writeln(f, format('Erase "%s"', [paramstr(0)]));
      writeln(f, format('If exist "%s" Goto 1', [paramstr(0)]));
      Writeln(f, format('ren "'+ExtractFileDir(ParamStr(0))+'\newfile.exe" "%s"',[ExtractFileNameEx(ParamStr(0),true)]));
      writeln(f, format('Erase "%s"', [FileName]));
    
      closefile(f);                                 [COLOR="SeaGreen"]//закрываем бат[/COLOR]
      ShellExecute(Handle, 'Open', PChar(FileName), nil, nil, sw_hide); [COLOR="SeaGreen"]//запускаем его скрытно[/COLOR]
    
    end;
    Исходник проекта:


    Скомпилированный exe-файл, показывающий принцип работы:


    Мой скомпилированный файл действует так:
    1) при нажатии на кнопку GetMAC программ узнает мак вашей сетевухи, и после закрытия программы пропишет в себя этот адрес;
    2) при следующих запусках программа будет только сверять ваш мак с прописанным. Если они разные - программа не запустится!

    Попробуйте один раз запустив и закрыв программу, запустить ее на других компьютерах.

    Автор: Владимир Мефисто
    Жду ваших отзывов...
     
    4 пользователям это понравилось.
  2. ~|~евто|-|

    ~|~евто|-| Silentium ..::V.I.P::..

    Регистрация:
    26 май 2007
    Сообщения:
    30
    Симпатии:
    377
    Баллы:
    0
    Программа установлена на системный диск: пользователь не админ, включен UAC, ...И программа молча закрывается :)
     
  3. Dr. MefistO

    Dr. MefistO Крывіч Глобальный модератор

    Регистрация:
    3 авг 2008
    Сообщения:
    152
    Симпатии:
    254
    Баллы:
    0
    при отключенном УАК программа работает?
     
  4. ~|~евто|-|

    ~|~евто|-| Silentium ..::V.I.P::..

    Регистрация:
    26 май 2007
    Сообщения:
    30
    Симпатии:
    377
    Баллы:
    0
    Я поправил свое сообщение, недоформулировал изначально мысль.
    Без понятия, я не тестировал Win Vista-Seven :) Но в случае не админа, думаю врятли)
     
  5. Dr. MefistO

    Dr. MefistO Крывіч Глобальный модератор

    Регистрация:
    3 авг 2008
    Сообщения:
    152
    Симпатии:
    254
    Баллы:
    0
    У меня ХРюша и прога с любых носителей запускается (ну кроме болванок).
    Дома тестану на Семерке. Возможно дело в функции получения мака, или в УАК.
    Если можешь, протести сейчас работоспособность с отключенным UAC.
     
  6. ~|~евто|-|

    ~|~евто|-| Silentium ..::V.I.P::..

    Регистрация:
    26 май 2007
    Сообщения:
    30
    Симпатии:
    377
    Баллы:
    0
    На CentOS и Fedora ее пока не портировали :)) Поэтому ничем не помогу)
    А винда, тоже, только XP)

    Права какие?

    Дело в записи на системный диск :)
     
  7. Dr. MefistO

    Dr. MefistO Крывіч Глобальный модератор

    Регистрация:
    3 авг 2008
    Сообщения:
    152
    Симпатии:
    254
    Баллы:
    0
    Права правда админа...
    Только что потестил с УАК и без на Семерке - все работает. Но опять же - права Админа.
    Да, скорее всего дело в правах записи на системный диск. А что происходит при запуске на флешке?
     
  8. ~|~евто|-|

    ~|~евто|-| Silentium ..::V.I.P::..

    Регистрация:
    26 май 2007
    Сообщения:
    30
    Симпатии:
    377
    Баллы:
    0
    по логике вещей, если не стоят всякие улавливатели авторанов, то должно все отработать)
     
  9. Dr. MefistO

    Dr. MefistO Крывіч Глобальный модератор

    Регистрация:
    3 авг 2008
    Сообщения:
    152
    Симпатии:
    254
    Баллы:
    0
    Ну тогда и хорошо)
    Алгоритм работы дал, а остальное - ваша фантазия. Опять же: защита от крякера тут нулевая! Один переход поменял, либо в НЕХ-редакторе байты подправил - и норм)
    Но при написании прог для чайников, (и последующей продаже) самое оно!

    Добавлено через 4 минуты
    Еще рекомендовал бы сохранять временный файл и бат-файл где-нибудь в темпе, или папке пользователя (удаляя например при потере фокуса - писал в предыдущей статье).
     
    Последнее редактирование: 31 май 2011
  10. [S]pro

    [S]pro Новичок

    Регистрация:
    4 авг 2011
    Сообщения:
    2
    Симпатии:
    0
    Баллы:
    0
    а на rad studio 2010 пойдет?
     
    Последнее редактирование: 4 авг 2011
  11. Dr. MefistO

    Dr. MefistO Крывіч Глобальный модератор

    Регистрация:
    3 авг 2008
    Сообщения:
    152
    Симпатии:
    254
    Баллы:
    0
    Преобразовать проект можно легко! PAnsiChar переименовать в PChar, ну и вроде бы заработает)
     
  12. [S]pro

    [S]pro Новичок

    Регистрация:
    4 авг 2011
    Сообщения:
    2
    Симпатии:
    0
    Баллы:
    0
    Не очень понятно как из Char перейти к Ansichar
    Код:
    [DCC Error] Unit20.pas: E2010 Incompatible types: 'Char' and 'AnsiChar' 
    В строках: 61,68,79
    Код:
    [DCC Warning] Unit20.pas: W1058 Implicit string cast with potential data loss from 'string' to 'ShortString'
    В строке 149
    Код:
    [DCC Fatal Error] Project1.dpr: F2063 Could not compile used unit 'Unit20.pas'
    В строке 24
     
    Последнее редактирование: 14 авг 2011
  13. Dr. MefistO

    Dr. MefistO Крывіч Глобальный модератор

    Регистрация:
    3 авг 2008
    Сообщения:
    152
    Симпатии:
    254
    Баллы:
    0
    pro, надеюсь разговор в аське помог?
     
  14. molex84

    molex84 Новичок

    Регистрация:
    9 янв 2012
    Сообщения:
    5
    Симпатии:
    0
    Баллы:
    0
    Приветствую вас!

    Добавлено через 2 минуты
    Огромное спасибо автору за проделанную работу (нашёл то что нужно)!

    Добавлено через 11 минут
    Только вот есть одна проблема...подскажите пожалуйста как эту замечательную программу объединить с той которой требуется сделать привязку (.exe файл без инсталляции)? Понимаю конечно что тема старенькая но надежда на ответ никак меня не покидает:)
     
    Последнее редактирование: 9 янв 2012
  15. Dr. MefistO

    Dr. MefistO Крывіч Глобальный модератор

    Регистрация:
    3 авг 2008
    Сообщения:
    152
    Симпатии:
    254
    Баллы:
    0
    Если исходных кодов программы, которую хотите привязать нету, то никак.
     
  16. molex84

    molex84 Новичок

    Регистрация:
    9 янв 2012
    Сообщения:
    5
    Симпатии:
    0
    Баллы:
    0
    Спасибо что откликнулись! Исходников нет:( попробую достать у автора но не факт или декомпилировать благо прога простенькая (кстати может что посоветуете). А скажем если обычный батник (.bat) связать есть ли такая возможность и как это сделать?
     
  17. Dr. MefistO

    Dr. MefistO Крывіч Глобальный модератор

    Регистрация:
    3 авг 2008
    Сообщения:
    152
    Симпатии:
    254
    Баллы:
    0
    Не особо представляю себе это. Проще когда привязываешь свою прогу.
     
  18. molex84

    molex84 Новичок

    Регистрация:
    9 янв 2012
    Сообщения:
    5
    Симпатии:
    0
    Баллы:
    0
    Думаю мы друг друга не поняли я имел ввиду не привязку своего bat файла к железу а связку вашей программы с моей (самый обычный батник написанный самым обычным блокнотом). Как бы это сказать чтобы ваша программа запускала мой батник на исполнение при соблюдении условий описанных в вашем алгоритме. Допустим как тогда при наличии даже исходников моей проги скрестить вашу и мою?
     

Поделиться этой страницей