"Translator / Ceviri 7.0" |
|
|
|
|
|
Araçlar:
|
|
|
Dongle lar hakknda hiç yazım olmadığını görünce bir tane yazıyım dedim.Bu yazıda HASP3 koruması olan bir programı patch etmeyi ve daha sonra dongle'ı emule etmeyi öğrenicez.
|
|
Bu programı Kadıköyden almıştım sanırım adam şey demişti iyi bir translator ama belli süreden sonra çalışmıyomuş hep geri iade ediyo dedi bana.Eve geldim ve programla uğraşmaya başladım bendeki password ile korunan versiyonuydu.Password şeması biraz karşıktı.Belli bir yere geldikten sonra canım sıkıldı gereksiz bir sürü delphi kodunu çevirmekten sıkıldım.Bilsag'ın sitesine gittim ve ne var ne yok diye baktım.Sitelerinin update kısmına gittiğimde update edilmiş iki tip exe olduğunu gördüm.Birisi klasik password korumalı diğer ise Dongle korumalı idi.Direkt dongle korumalı olanı çektim ve v6'nın üstüne yükledim.Programa çevir dediğimde program anahtarı yerinde değil diyordu.Tamam işte başlıyoruz.
Program yüklenirken system klasörüne hasp*.* dosyaları yüklendi.Demekki HASP dongle ile karşı karşıyayız.Bu dongle eski olduğundan Hasp3 olduğunu düşünebiliriz.Programı kırmaya geçmeden önce dongle nedir nasıl çalışır biraz bilgi vermek istiyorum.
Dongle nedir?
Dongle printer portuna takılan bir hardwaredir.Programcı dongledan gelen cevaba göre programı çalıştırıp çalıştırmıycağına karar verir.Bu kontrol çağrıları dongle'ın en zayıf noktasıdır.Eğer sizde orjinal dongle varsa bunu kırmak çok kolaydır.İlk başta dongle'ı takarsınız.Kontrol de dongle dan gelen bilgileri yazarsınız.Sonra orayı emule edersiniz.Eğer elinizde dongle yoksa iş biraz zorlaşabilir ama yinede biraz uğraşarak geri dönüş değerleri bulunailir.Çünkü genelde programcılar dongle ile koruduğunda programlarının kırılmıycağını sanırlar.Oyüzden basite kontroller yaparlar.Mesela
cmp ax,111 jne badboy
Uğarşamaya gerek yok çünkü adam dongle'ın cevabını direkt karşılaştırmış.Peki hasp dongle lar nasıl kırılır Softice ile nasıl breakpoint koycaz ?
Dongle Krılması
Hasp'ın mantığını anlamak için en iyisi HASP SDK'sını download etmek içindeki manual ve örnekler yeterince doyurucu.O yüzden ben size işin mantığını ve birkaç basit servisin ne işe yaradığını söyliycem.Program hasp() fonksiyonunu değişik parametrelrele çağırarak dongle ile haberleşir.Bu fonksiyonun formatı şu şekildedir.
hasp (Service, SeedCode, LptNum, Password1, Password2,Par1, Par2, Par3, Par4) şimdi bunlar ne demek ona bakalım Service:adından da belli olduğu gibi çağrılacak fonksiyon
SeedCode:Bu kod değişkendir programcı istediği gibi oynayabilir.
LptNum:Printer portu Password1:Dongle Password 1 Password2:Dongle Password 2 Par1:Fonksiyon Sonuc1 Par1:Fonksiyon Sonuc1 Par1:Fonksiyon Sonuc1 Par1:Fonksiyon Sonuc1
Şimdi bir kaç temel servis ve Fonksiyon sonuçlarına bakalım.
1.1 Service
Service Name Operation
-------------------------------------------------------------------------
1 IsHasp Hasp Bağlımı
dönen Par1 0 HASP yok
1 HASP bulundu
-------------------------------------------------------------------------
2 HaspCode Verilen seed code için geriye değerleri bulur
dönen Par1/2/3/4 Dönen Code1/2/3/4
-------------------------------------------------------------------------
3 ReadWord MemoHasp'dan bir word okur
dönen Par2 1 word
Par3 Durum
-------------------------------------------------------------------------
4 WriteWord MemoHasp'a bir word yazar
dönen Par3 Durum
-------------------------------------------------------------------------
5 HaspStatus Hasp'ın tipini belirler
Hangi porta bağladığı
Memory büyüklüğü
dönen Par1 1 MemoHasp-1
4 MemoHasp-4
0 Diğer tip
Par2 0 HASP-3
1 MemoHasp-1/MemoHasp-4
3 TimeHasp
5 TimeHasp-4
Par3 Paralel port nosu
------------------------------------------------------------------------
Bizim yapacağımız programın hangi servisleri kullandığını bulmak ve doğru şekilde patch yapmak.SoftICEnın loader'ı ile load export menüsüne tıklaıyıp hasp32bc.dll yükleyin.hasp() fonksiyonun bu dll içersinde bulunuyor.Daha sonra Ceviri.exe yi açıyoruz.Load module ile yüklüyoruz.Bize hata mesajı felan vericek o önemli değil debug kodu olmadığını söylüyo ki normal bizim için debug versiyonunu koycak değiller adamlar öyle değil mi :).Softice'a geçtiğiniz zaman bpx hasp yazın ve F5 tuşu ile çıkın.Karşınıza şu satırlar geelcektir.
0167:00499E76 XOR EAX,EAX 0167:00499E78 MOV [EBP-08],EAX 0167:00499E7B PUSH DWORD 004CF638 ;Par4 0167:00499E80 PUSH DWORD 004CF634 ;Par3 0167:00499E85 PUSH DWORD 004CF630 ;Par2 0167:00499E8A PUSH DWORD 004CF62C ;Par1 0167:00499E8F PUSH DWORD [004CF61C] ;Password 2 0167:00499E95 PUSH DWORD [004CF618] ;Password 1 0167:00499E9B PUSH DWORD [004CF620] ;LptNum 0167:00499EA1 PUSH DWORD [004CF628] ;SeedCode 0167:00499EA7 PUSH BYTE +01 ;Service 1 yani IsHasp 0167:00499EA9 CALL `HASPBC32!hasp` 0167:00499EAE CMP DWORD [004CF62C],BYTE +00 ;Hasp bağlımı 0167:00499EB5 JNZ 00499EBE ;bağlı ise zıpla 0167:00499EB7 XOR EDX,EDX ;hasp yok 0167:00499EB9 MOV [EBP-08],EDX 0167:00499EBC JMP SHORT 00499F18 0167:00499EBE PUSH DWORD 004CF638 ;Par4 0167:00499EC3 PUSH DWORD 004CF634 ;Par3 0167:00499EC8 PUSH DWORD 004CF630 ;Par2 0167:00499ECD PUSH DWORD 004CF62C ;Par1 0167:00499ED2 PUSH DWORD [004CF61C] ;Password 2 0167:00499ED8 PUSH DWORD [004CF618] ;Password 1 0167:00499EDE PUSH DWORD [004CF620] ;LptNum 0167:00499EE4 PUSH DWORD [004CF628] ;SeedCode 0167:00499EEA PUSH BYTE +05 ;Service 5 yani HaspStatus 0167:00499EEC CALL `HASPBC32!hasp` 0167:00499EF1 CMP DWORD [004CF634],BYTE +00 ;Paralel Port Nosu ? 0167:00499EF8 JNZ 00499F01 ;0 değilse devam et 0167:00499EFA XOR ECX,ECX 0167:00499EFC MOV [EBP-08],ECX 0167:00499EFF JMP SHORT 00499F18 ;dongle yok 0167:00499F01 CMP DWORD [004CF630],BYTE +00 ;dongle HASP3 mü ? 0167:00499F08 JNZ 00499F13 0167:00499F0A MOV DWORD [EBP-08],01 0167:00499F11 JMP SHORT 00499F18 0167:00499F13 XOR EAX,EAX 0167:00499F15 MOV [EBP-08],EAX 0167:00499F18 CMP DWORD [EBP-08],BYTE +63 0167:00499F1C JNZ 00499F2A ;eğer port 63 de değilse yeinden kontrol et 0167:00499F1E PUSH DWORD [EBP+08] 0167:00499F21 CALL 0049BF34 ;bu call dongle'a yeniden bakıyor. 0167:00499F26 POP ECX 0167:00499F27 MOV [EBP-04],EAX 0167:00499F2A MOV EDX,[EBP-08] 0167:00499F2D SUB EDX,BYTE +01 0167:00499F30 JNC 00499F72 0167:00499F32 XOR ECX,ECX 0167:00499F34 MOV [004CF660],ECX 0167:00499F3A MOV [004CF65C],ECX 0167:00499F40 MOV [004CF654],ECX 0167:00499F46 MOV [004CF650],ECX 0167:00499F4C MOV [004CF64C],ECX 0167:00499F52 MOV [004CF648],ECX 0167:00499F58 MOV EAX,[EBP+08] 0167:00499F5B MOV EDX,[EAX+036C] 0167:00499F61 MOV DWORD [EDX+0158],01 0167:00499F6B XOR EAX,EAX 0167:00499F6D JMP 0049A04A 0167:00499F72 PUSH DWORD 004CF638 ;Par4 0167:00499F77 PUSH DWORD 004CF634 ;Par3 0167:00499F7C PUSH DWORD 004CF630 ;Par2 0167:00499F81 PUSH DWORD 004CF62C ;Par1 0167:00499F86 PUSH DWORD [004CF61C] ;Password 2 0167:00499F8C PUSH DWORD [004CF618] ;Password 1 0167:00499F92 PUSH DWORD [004CF620] ;Lpt Num 0167:00499F98 PUSH DWORD [004CF628] ;Seed Code 0167:00499F9E PUSH BYTE +02 ;Service 2 HaspCode 0167:00499FA0 CALL `HASPBC32!hasp` 0167:00499FA5 CMP DWORD [004CF62C],BYTE +00 ;Geriye dönen değerler 0 0167:00499FAC JZ 00499FC9 0167:00499FAE CMP DWORD [004CF630],BYTE +00 ; değilse devam et 0167:00499FB5 JZ 00499FC9 0167:00499FB7 CMP DWORD [004CF634],BYTE +00 0167:00499FBE JZ 00499FC9 0167:00499FC0 CMP DWORD [004CF638],BYTE +00 0167:00499FC7 JNZ 00499FE0 0167:00499FC9 MOV EDX,[EBP+08] 0167:00499FCC MOV ECX,[EDX+036C] 0167:00499FD2 MOV DWORD [ECX+0158],01 0167:00499FDC XOR EAX,EAX 0167:00499FDE JMP SHORT 0049A04A 0167:00499FE0 MOV EAX,[004CF634] ;Par3 eax ta 0167:00499FE5 SUB EAX,[004CF638] ;Par3-Par4 0167:00499FEB MOV EDX,[004CF62C] ;Par1 edx te 0167:00499FF1 SUB EDX,[004CF630] ;Par1-Par2 0167:00499FF7 SUB EAX,EDX ;Par3-Par4-Par1-Par2 0167:00499FF9 MOV ECX,[EBP+08] 0167:00499FFC MOV EDX,[ECX+036C] 0167:0049A002 MOV ECX,[EDX+0144] ;ecx burda 2 oluyor 0167:0049A008 ADD ECX,ECX ;ecx=4 0167:0049A00A CDQ 0167:0049A00B IDIV ECX ;eax'ı 4 e böl 0167:0049A00D MOV [EBP-0C],EAX ;eax'ı sakla 0167:0049A010 CMP DWORD [EBP-0C],0461 ;eğer sonuç 461 değilse dongle yok 0167:0049A017 JNZ 0049A031 0167:0049A019 MOV EAX,[EBP+08] 0167:0049A01C MOV ECX,[EAX+036C] 0167:0049A022 XOR EAX,EAX 0167:0049A024 MOV [ECX+0158],EAX 0167:0049A02A MOV EAX,01 ;dongle var eax a 1 ver ve dön 0167:0049A02F JMP SHORT 0049A04A 0167:0049A031 MOV EDX,[EBP+08] 0167:0049A034 MOV ECX,[EDX+036C] 0167:0049A03A MOV DWORD [ECX+0158],01 0167:0049A044 XOR EAX,EAX ;dongel yok eax a 0 ver ve dön 0167:0049A046 JMP SHORT 0049A04A 0167:0049A048 XOR EAX,EAX 0167:0049A04A MOV ESP,EBP
Aslında yazı burda bitebilir.Biz bu fonksiyondan eğer 1 dödürebilirsek program dongle'ın takılı olduğunu sanacaktır.Fakat her yeni versiyonda biz yeniden mi exeyi patchliycez ?.Bence daha iyi bir yol bulmamız lazım.En iyisi dongle'ı emule edip bunu hasp32bc.dll ye yazmak.Bu iş biraz karmaşık gelebilir.O yüzden çok dikkatli bir şekilde takip etmenizi öneririm.Şimdi olayı tekrardan bir değerlendirelim.Öncelikle teoriyi geliştirelim.
Teori: Yapmak istediğimiz şey hasp fonksiyonu çağrıldığında geriye her zaman bizim istediğimiz cevapları göndermek.Yani eğer IsHaspPresent derse biz 1 yolluycaz vs...
Nasıl yapılabilir ?: Dll yi patch edicez ve export edilen bu fonksiyonu değiştirecez.Kolay gibi gözüküyor.
Problemler: Dll de checksum var yani kendini kontrol ediyor.Direkt olarak HaspCall'ını değiştirmeye çalışırsanız haspbc32.dll hata veriyor.Bu yüzden başka bir yöntem bulmamız lazım.
Teori 2: Dll de oldukça boş yer var biz eğer dll de kendi rutinimiz için bir yer ayırırsak ve o callı patch etmezsek belki bunu başarabiliriz.
Deneme: Yine bpx hasp ile programı açıyoruz.SoftICE durduğunda Hasp32bc.dll yi F8 ile trace edin.
0167:005700CF PUSH EBP 0167:005700D0 MOV EBP,ESP 0167:005700D2 PUSH EAX 0167:005700D3 PUSH EBX 0167:005700D4 PUSH ECX 0167:005700D5 PUSH EDX 0167:005700D6 PUSH EDI 0167:005700D7 PUSH ESI 0167:005700D8 MOV ESI,[EBP+1C] 0167:005700DB MOV EDI,[ESI] 0167:005700DD MOV EBX,00 0167:005700E2 MOV EBX,[EBP+08] 0167:005700E5 MOV BH,BL 0167:005700E7 MOV BL,00 0167:005700E9 ADD EBX,[EBP+10] 0167:005700EC MOV EAX,[EBP+0C] 0167:005700EF MOV ECX,[EBP+14] 0167:005700F2 MOV EDX,[EBP+18] 0167:005700F5 CMP BH,32 0167:005700F8 JC 00570103 0167:005700FA NOP 0167:005700FB NOP 0167:005700FC NOP 0167:005700FD NOP 0167:005700FE MOV ESI,[EBP+28] 0167:00570101 MOV EAX,[ESI] 0167:00570103 MOV ESI,[EBP+20] 0167:00570106 MOV ESI,[ESI] 0167:00570108 PUSH EBP 0167:00570109 CALL 0057201E ;eğer bu call'ı istediğimiz yere yönlendirirsek iş biter. 0167:0057010E POP EBP 0167:0057010F MOV EDI,[EBP+1C] 0167:00570112 MOV [EDI],EAX
Şimdi kendi emulator kodumuzu koymak için hasp32bc.dll 'de boş yer arıyalım.Ben 66F8h adresine yerleştirmeyi uygun buldum.Şimdi emulator kodumuzu yazmaya geldi.
Şimdi tekrar düşünelim bizim emulator'un yapacağı şey eğer servis 1 ise 1 i geri döndürecek.Eğer Servis 5 ise Par1 ve Par2 0 olucak Par 3 de 1 olucak.Eğer servis 2 ise de yukarıda verilen algoritmayı tutacak sayıları yazıcaz.Biz şu denklemi sağlıycak değerleri arıyoruz
Par3-Par4-Par1-Par2 /4 = 461
Bu yüzden eğer biz Par3'ü 461'in dört katı alır ve diğerlerini sıfır yaparsak bu denklem sağlanmış olur.Ama burda yine bir problem ile karşı karşıyayız.Biz Par* lerin ne olduğunu bilmediğimiziçin programcılar bu Par* lar ile yeni bir algoritma yapabilir ve bizim patch yine suya düşebilir.Bizim gerçek Par* ları bulmamız lazım.Araştırıyoruz.... Ve bulduk.Hasp3'un algoritması yıllar önce çözüldü yani verilen password ve seed codelara göre Par* ları biz bulabiliyoruz.Bunu yapan bir program zencrack2.cjb.net adresinde var ama adamlar include ların ismini yazmamışlar yani eğer C den anlamıyosanız compile edemezsiniz. :) Ya da CrackZ'ın icedump için Hasp plugini var onunla da hesaplanabiliyor.Ben hesapladım ve gerçek return değerlerinin şunlar olduğunu buldum
Par1: 3590
Par2: 1E3B
Par3: 5464
Par4: 2B8B
Şimdi teoriyi pratiğe dökme zamanı.Bu fonkisyon çağrılırken bh da servis nosu oluyor.Par1 eax da Par 2 ebx Par3 ecx Par4 de edx de bulunuyor.Bu bilgiler den sonra emulatorumuzu yazabiliriz.
cmp bh,1 ; Service1 mi istendi ? (IsHAsp) jnz @holahop ;diğer servislere git mov ax,1 ;Hasp var be kardesim :) ret ;geriiiii dön ! @holahop: cmp bh,5 ;Sevice 5 mi istendi ? (HaspStatus) jnz @abidik ;Değilse mutlaka Service 2 dir mov ax,0 ;Par1=0 ;MemoHasp değil mov bx,ax ;Par2=0 ;Hasp3 mov cx,1 ;Par3=1 ;Paralen port No ret ;geriiiii dön ! @abidik: mov ax, 3590h ;Par1 mov bx, 1e3bh ;Par2 mov cx, 5464h ;Par3 mov dx, 2b8bh ;Par3 ret ;geriiiii dön !
Bu kodu 66F8 ya yazalım.Şimdi patch ettiğimiz dll olduğundan bunda ki RVA offset mantığı biraz değişiktir.Size burda bunu da anlatarak yazıyı uzatmak istemiyorum.00570109 deki call'ı değiştirmek için şu değişiklikleri yapın
Offset Original Patched 70Ah 10h EAh 70Bh 1Fh 5Fh
Eğer değim şekilde patch etmişseniz program hatasız şekilde de çalışacaktır.Kontrol etmeniz açısından orjinal ve patch edilmiş dosyayı karşılaştırıp bir text dosyasına yazdım.Burdan bakabilirsiniz.
İşte bu kadar bir yazımız daha bitti.Umarım bu size dongle lar hakkında ufak ta olsa bir bilgi vermiştir.Dongle larla ilgili daha kapsamlı yazıları http://zencrack2.cjb.net ve http://tsehp.cjb.net adreslerinden bulabilirsiniz.
|
|
Bu yazıda yazım yanlışları hatta bilgi hatası olabilir.Eğer bir yanlış bulursanız bana email atın düzeltmeye çalışırım.Bir programı eğer gerçekten kullanıyorsanız, programı satın almayı düşünün.Micro$oft programlarını - bırakın satın almayı - kullanmayı bile düşünmeyin.