| 
                          C@T
                         | 
                        
                          Дата: Воскресенье, 02.12.2012, 01:11 | Сообщение # 1
                         | 
                       
                      
                        
                           
                          
                            Авторитетный
                           
                          
                          Зарегистрирован: 06.03.2010
                          
                            Группа: Модераторы
                           
                          
                            Сообщений: 265
                           
                          
                            Статус: Offline
                           
                         | 
                        
                          Предисловие 
                           
                          данная статья не была заранее подготовленной, идея ее написать появилась у меня сегодня после того как увидел один пост на форуме и вспомнил как с друзьями мы убирали привязку у программ друг друга   статья написано как можно более понятно, так как большинство посетителей нашего форума новички в программировании, и прошу не серчать за излишнюю подробность думаю вам будет интересно почитать   
                           
                          на форуме один из посетителей сделал прозьбу о том как сделать привязку программке   
                          итак начнем, первое правда что мне пришлось сделать это скачать дэлфи, так как, увы, давно на нем не писал, а наш ресурс узко специализированн   
                           
                          после того как устанавили дэлфи нужна программка которую мы будем привязывать   
                          и мы ее пишем 
                          
                            
                            
                              Code
                             
                            
                               
                              unit Unit1; 
                               
                              interface 
                               
                              uses 
                                 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
                                 Dialogs, StdCtrls; 
                               
                              type 
                                 TForm1 = class(TForm) 
                                   Button1: TButton; 
                                   Edit1: TEdit; 
                                   procedure Button1Click(Sender: TObject); 
                                 private 
                                   { Private declarations } 
                                 public 
                                   { Public declarations } 
                                 end; 
                               
                              var 
                                 Form1: TForm1; 
                               
                              implementation 
                               
                              {$R *.dfm} 
                               
                              procedure TForm1.Button1Click(Sender: TObject); 
                              begin 
                                 ShowMessage(Edit1.text); 
                              end; 
                               
                              end. 
                             
                            
                           
                            
                           
                          дальше нам нужна программка которая скажет нам наш HardID , на который мы будем привязывать, в данном примере будем привязывать к ID логического диска, правда да, оно при переустановке системы меняется, но все же, пойдет   
                           
                          
                            
                            
                              Code
                             
                            
                               
                              unit Unit1; 
                               
                              interface 
                               
                              uses 
                                 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
                                 Dialogs, StdCtrls; 
                               
                              type 
                                 TForm1 = class(TForm) 
                                   Button1: TButton; 
                                   Edit1: TEdit; 
                                   procedure Button1Click(Sender: TObject); 
                                 private 
                                   { Private declarations } 
                                 public 
                                   { Public declarations } 
                                 end; 
                               
                              var 
                                 Form1: TForm1; 
                               
                              implementation 
                               
                              {$R *.dfm} 
                               
                              procedure TForm1.Button1Click(Sender: TObject); 
                              var 
                              VSNum, dw1, dw2: DWORD; 
                                 szTemp: array[0..MAX_PATH] of char; 
                              begin 
                                 GetWindowsDirectory(szTemp,MAX_PATH); 
                                 GetVolumeInformation(PAnsiChar(szTemp[0]+':\'), nil, 0, @VSNum, dw1, dw2, nil, 0); 
                                 Edit1.Text := IntToHex(VSNum,16); 
                              end; 
                               
                              end. 
                             
                            
                           
                            
                           
                          суть привязки в том что бы просто сравнить прописанный в проге HardID с HardID на запущенной системе и если ID не совпадают, то завершить программу 
                          пишем процедуру которая будет это делать   
                           
                          
                            
                            
                              Code
                             
                            
                               
                              procedure pegging(); // спасибо гуглу за перевод 
                              var 
                                 myID:DWORD; 
                                 VSNum, dw1, dw2: DWORD; 
                                 szTemp: array[0..MAX_PATH] of char; 
                              begin 
                                 myID := $003C7FD842; 
                               
                                 GetWindowsDirectory(szTemp,MAX_PATH); 
                                 GetVolumeInformation(PAnsiChar(szTemp[0]+':\'), nil, 0, @VSNum, dw1, dw2, nil, 0); 
                                 if( VSNum <> myID) then 
                                 begin 
                                   TerminateProcess(GetCurrentProcess(), 0); 
                                 end; 
                              end; 
                             
                            
                           
                          вызываем ее при запуске программы 
                           
                          
                            
                            
                              Code
                             
                            
                               
                              procedure TForm1.FormCreate(Sender: TObject); 
                              begin 
                                 pegging(); 
                              end; 
                             
                            
                           
                          в итоге если мы запустим программу на другом компьютере она завершится 
                          но не все так хорошо насколько кажется, ведь если сделать такую привязку в реальном программном продукте, то привязку очень быстро уберут   
                          если мы откроем наш ехе файл дэбагерром(например OllyDbg) , то сможем легко найти импорт функции TerminateProcess и увидить где он вызывается 
                           
                            
                           
                          дальше если взглянуть выше по коду будет видно прыжок, а точнее условный переход на вызов TerminateProcess 
                          
                            
                            
                              Code
                             
                            
                               
                              CMP EBX,DWORD PTR SS:[EBP-4] 
                              JE SHORT crack.00453882 
                             
                            
                          сразу становится понятно что это сравнение нашего ключа с ключем на локальной систем, если ключ подходит, то продолжается выполнение программы, если же нет, то программа завершается 
                          прыжок происходит командой JE , для того что бы убрать привязку достаточно лишь изменить условие перехода на обратное, а т.е JE поменять на JNZ(или JNE) 
                           
                            
                           
                          для того что бы усложнить поиск нужного участка кода, который отвечает за проверку на HardID можно избавится от вызова TerminateProcess, например 
                           
                          
                            
                            
                              Code
                             
                            
                               
                              procedure pegging(); 
                              var 
                                 myID:DWORD; 
                                 VSNum, dw1, dw2: DWORD; 
                                 szTemp: array[0..MAX_PATH] of char; 
                              begin 
                                 myID := $003C7FD822; 
                               
                                 GetWindowsDirectory(szTemp,MAX_PATH); 
                                 GetVolumeInformation(PAnsiChar(szTemp[0]+':\'), nil, 0, @VSNum, dw1, dw2, nil, 0); 
                               
                                 asm 
                                   mov eax,myID 
                                   mov ebx,dw2 
                                   sub eax,VSNum 
                               
                                   push offset @metka 
                                   add esp,eax 
                                   ret 
                                   @metka: 
                                 end; 
                               
                              end; 
                             
                            
                           
                          в данном примере отсутствует даже сравнение как таковое, здесь все происходит так,в регистр eax записывается ID с которым нужно сравнивать(айди компьютера на котором программа должна запустится) 
                          в регист ebx заносится ID локального компьютера 
                          дальше считается разница между eax b ebx (между первым и вторым ID) , и результат записывается в eax, в итоге если первый и второй ID равны то в eax окажется ноль, иначе какое то число 
                          дальше в стек заносится адрес метки завершения привязки и к регистру esp добавляется значение регистра eax, и получается если eax не равен нулю то работа программы будет нарушена, и дальше при выполнении команды ret программа вызовет исключение, ошибку, а если в eax будет 0 то программа как работала так и будет работать 
                          в данном коде можно даже убрать все что идет после add esp,eax , и привязка все равно будет работать 
                           
                          такую привязку будет чу чуть сложнее найти и вылечить, но все равно возможно, для большего усложнения ее обнаружения можно убрать GetVolumeInformation из импортов и сделать поиск адреса функции через GetProcAddr   
                          но все равно это не даст надежной защиты и программу можно будет взломать в течении пары часов 
                          по моему самым лучшим способом привязать программу это совместить привязку и крипт, что бы для того что бы найти код привязки его и весь остальной код программы нужно было бы еще расшифровать, а этот процесс достаточно долгий для пошагового выполнения вручную  
                          
                         | 
                       
                      
                        |   | 
                        
                          
                         | 
                       
                     
                   |