Natural

natural

Breaking News

Keygenme 1

Keygen Nasıl Yazılır?01.11.2009




Merhabalar, keygen hazırlama konusunda basit bir keygenme ile yazı hazırlamaya devam ediyorum. Amacımız keygen algoritmasını anlamak, analiz etmek, çözmek ve kendi keygenimizi hazırlamak. Bunun için satır satır ilerleyecek ve algoritmayı anlayacağız. Assembly ile keygenimizi hazırlayacağız. Bunun için SCTZine #14 ve #15 deki assembly yazılarını okumanızı ayrıca web sitemizdeki assembly sayfasına uğramanızı tavsiye ederim.
Artık başlayalım. Programımızı PEiD ile kontrol ediyoruz, herhangi bir sıkıştırma yok. Kripto analizide yapıyoruz(PEiD'in pluginlerinden), sorun yok. Devam edelim. Programımızı çalıştıralım. İsim ve Serial bölümü, güzel. Şimdi birşeyler yazıp tamam diyelim. herhangi bir mesaj kutusu ya da hata vermedi. Aklımıza yazalım bunu. Şimdi programımızı Olly ile açalım. Kod(CODE) ekranına sağ tıklayıp "Search For > All referenced text strings" tıklayalım. Açılan pencerede "ASCII "You did it! Now make a keygen =)" " yazan yere çift tıklayın. Biraz daha yukarı çıkın ve aşağıdaki kodlarda olduğumuzu göreceksiniz. Kod satırlarının yanındaki yorum satırlarını okuyunuz:
4011D3|.PUSH 19                                 ; /Count = 19 (25.)
4011D5|.PUSH crackme_.00403096                  ; |Buffer = crackme_.00403096
4011DA|.PUSH 66                                 ; |ControlID = 66 (102.)
4011DC|.PUSH [ARG.1]                            ; |hWnd = 00100526 ('Crackme - not cracked yet',class='FHCF_Crackme')
4011DF|.CALL <JMP.&USER32.GetDlgItemTextA>      ; \GetDlgItemTextA ;seriali alıyor
4011E4|.PUSH 1E                                 ; /Count = 1E (30.)
4011E6|.PUSH crackme_.00403078                  ; |Buffer = crackme_.00403078
4011EB|.PUSH 65                                 ; |ControlID = 65 (101.)
4011ED|.PUSH [ARG.1]                            ; |hWnd = 00100526 ('Crackme - not cracked yet',class='FHCF_Crackme')
4011F0|.CALL <JMP.&USER32.GetDlgItemTextA>      ; \GetDlgItemTextA ;ismi alıyor
4011F5|.CMP EAX,4    ; ismimiz 4 hanemi? az ise hiç algoya sokmuyor
4011F8|.JB SHORT crackme_.00401245  ; bu jump ile dallanıyor
4011FA|.MOV ECX,EAX    ; eax değeri ecx'e atılıyor, eax'te ismimizin kaç hane olduğu var
4011FC|.MOV DWORD PTR DS:[4030C0],ECX  ; ecx'te bu değeri 4030C0 adresine atıyor
401202|.PUSH EDI
401203|.PUSH crackme_.00403051                  ; /Arg2 = 00403051
401208|.PUSH crackme_.00403061                  ; |Arg1 = 00403061
40120D|.CALL crackme_.00401262                  ; \crackme_.00401262 ;bu call içinde birşeyler oluyo F7 ile içine girelim
Yukardaki CALL 'un içine girersek buraya dallanıyoruz:
401262/$ PUSH EBP
401263|. MOV EBP,ESP
401265|. ADD ESP,-4
401268|. XOR EBX,EBX    ; ebx=ebx XOR ebx =0
40126A|. XOR EDX,EDX    ; edx=0
40126C|. XOR EAX,EAX    ; eax=0
40126E|. XOR ECX,ECX    ; ecx=0
401270|. XOR ESI,ESI                            ; crackme_.00401180
401272|. XOR EDI,EDI    ;edi=0
401274|>>MOVSX EAX,BYTE PTR DS:[ECX+403078] ;403078=ismimiz bu adreste
      ;sırayla ismimizin her bir hanesinin hex değeri eax'e atılıyor
40127B|. ADD EBX,EAX    ;ebx=ebx AND eax
40127D|. INC ECX    ;ecx=ecx+1(bu sayaç yazmacı bir bir artarak 
      ;ismimizin diğer hanelerinin alınmasını sağlıyor)
40127E|. CMP DWORD PTR DS:[4030C0],ECX  ;4030C0 adresine ismimizin kaç hane olduğunu atmıştık
      ;o uzunluğu ecx ile karşılaştır
401284|.^JNZ SHORT crackme_.00401274  ;aynı değilse devam
401286|. LEAVE
401287\. RETN 8
Bu CALL sonucunda ismimizin her bir karakterinin hex değeri birbiriyle AND işlemi yapılarak bir sonuç elde ediliyor. Döngü bitince CALL'dan çıkıyoruz ve devam ediyoruz:
401212|.PUSH EBX    ;yukardaki döngünün sonucu ebx'e yazılıp yığına atılıyor
401213|.PUSH crackme_.00403096                  ;  ASCII "112233" ;serial
401218|.CALL crackme_.00401314   ; buaradaki callda hesaplama yapılıyor girelim içine F7 ile
Bu call içinde bir takım hesaplamalar yapılıyor şimdi satır satır inceleyelim:
401314/$  PUSH EBP
401315|.  MOV EBP,ESP
401317|.  PUSH EBX
401318|.  PUSH ESI
401319|.  PUSH EDI                              ; crackme_.00403096
40131A|.  MOV EDI,[ARG.1]                       ; crackme_.00403096; ediye serialimiz atılıyor
40131D|.  MOV ESI,[ARG.1]                       ; crackme_.00403096; aynı şekilde esiyede
401320|> /MOV AL,BYTE PTR DS:[EDI]  ; serialimizin her bir karakterinin hex değeri al'ye atılıyor
401322|. |INC EDI                               ; crackme_.00403096; bir sonraki karakter
401323|. |OR AL,AL    ; al=al OR al
401325|.^\JNZ SHORT crackme_.00401320  ; sıfır değilse devam et
Yukardaki küçük döngünün amacı Acaba kullanıcı serial girdi mi onun kontrolü. Çünkü eğer bir sayı girilmişse bunun bir baytının yine o bayt ile OR işlemine tabi tutulmasının sonucu yine kendisi olacaktır. Ama Serial girilmemişse sonuç 0'dır ve döngüden çıkılır.
401327|.  SUB ESI,EDI                           ;esi=esi-edi ;edi'de serial vardı ama yukardaki döngüde 
      ;ediyi küçülterek içindeki serial bitti ve sıfırlandı
      ;bu çıkarma işlemiyle esi ye aralarındaki farkı yazdıracağız
      ;ancak esi küçük edi büyük değer, sonucu ise aşağıda esiyi
      ;NOT 'layaraktekrar esiye yazdıracağız
401329|.  XOR EBX,EBX    ;ebx=0
40132B|.  ADD EDI,ESI    ;edi=edi+esi; bu toplamanın sonucunda edi'de tekrardan serialimiz olacak
40132D|.  XOR EDX,EDX    ;edx=0
40132F|.  NOT ESI    ;NOT işlemi sonucunda hedefin değerleri tersine döner
      ;yani ikili sistemden konuşursak 1 olur 0, 0 ise olur 1
      ;bu işlemin sonucunda esi'de yaniden bizim serialimizin uzunluğu olmuş olacak
401331|.  JMP SHORT crackme_.00401356  ;koşulsuz 401356 adresine dallan
401333|> /MOV AL,BYTE PTR DS:[EDI]  ;serialin ilk hanesinin hex değerini AL'ye yaz
401335|. |CMP AL,41    ;41 ile karşılaştır(41h = ASCII olarak A harfidir)
401337|. |JB SHORT crackme_.00401345  ;daha altındaysa dallan(serialimizde harf de olabiliyor)
401339|. |SUB AL,57    ;41h dan büyükler için al=al-57
40133B|. |ADC DL,0    ;dl=dl ADC 0
40133E|. |SHL DL,5    ;DL=DL SHL 5
401341|. |ADD AL,DL    ;AL=AL ADD DL
401343|. |JMP SHORT crackme_.00401347
401345|> |SUB AL,30    ;AL=AL-30h
401347|> |LEA ECX,DWORD PTR DS:[ESI-1]  ;ecx=esi-1 (esi'de serial uzunluğu vardı)
40134A|. |AND EAX,0F    ;eax=eax AND 0F (0Fh=16d)
40134D|. |SHL ECX,2    ;ecx=ecx SHL 2
401350|. |SHL EAX,CL    ;eax=eax SHL CL
401352|. |ADD EBX,EAX    ;ebx=ebx + eax
401354|. |INC EDI                               ;edi değerini bir artır
401355|.  DEC ESI    ;esiyi bir azalt
401356|>  OR ESI,ESI    ;buradan başlıyouz;esi= esi OR esi
401358|.^\JNZ SHORT crackme_.00401333  ;esi sıfır değilse devam et
40135A|.  MOV EAX,EBX    ;döngü bitince eax'e ebx değeri atılıyor
40135C|.  POP EDI                               ;  crackme_.00403096
40135D|.  POP ESI
40135E|.  POP EBX
40135F|.  LEAVE
401360\.  RETN 4    ;döngüden çık
Döngüden çıkıp aşağıdaki kodlara devam ediyoruz ancak 2 satır sonra bir karşılaştırma yapılıyor. POP EBX ile yığın(stack)dan bir değer çağrılıyor ve bu değer eax ile yni yukardaki döngüde yaptığımız işlemin sonucu ile karşılaştırılıyor. Yani İsmimizi soktuğumuz döngüden çıkan sonuç bizim gerçek serialimizdi. hemde ham hali(hex hali)
40121D|.POP EBX                                  ;  0013FC78 ;yığından çağırdığı değer daha önce ismimiz ile yapılan döngünün sonucu
40121E|.POP EDI                                  ;  0013FC78
40121F|.CMP EAX,EBX    ;serialden üretilen sonuç ile ismimizden üretilen sonuç burada karşılaştırılıyor
401221|.JNZ SHORT crackme_.00401245  ;patch yapmak ne kadar kolay olur du değil mi :D
401223|.PUSH 40                                  ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
401225|.PUSH crackme_.0040304D                   ; |Title = "wee"
40122A|.PUSH crackme_.00403019                   ; |Text = "You did it! Now make a keygen =)"
40122F|.PUSH 0                                   ; |hOwner = NULL
401231|.CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA
401236|.PUSH crackme_.0040303A                   ; /Text = "Crackme - cracked!"
40123B|.PUSH [ARG.1]                             ; |hWnd = 00100526 ('Crackme - not cracked yet',class='FHCF_Crackme')
40123E|.CALL <JMP.&USER32.SetWindowTextA>        ; \SetWindowTextA
401243|.JMP SHORT crackme_.00401245
401245|>JMP SHORT crackme_.0040125C
401247|>PUSH [ARG.4]                             ; /lParam = B04B4
40124A|.PUSH [ARG.3]                             ; |wParam = 67 (103.)
40124D|.PUSH [ARG.2]                             ; |Message = WM_COMMAND
401250|.PUSH [ARG.1]                             ; |hWnd = 00100526 ('Crackme - not cracked yet',class='FHCF_Crackme')
401253|.CALL <JMP.&USER32.DefWindowProcA>        ; \DefWindowProcA
401258|.LEAVE
401259|.RETN 10
40125C|>XOR EAX,EAX
40125E|.LEAVE
40125F\.RETN 10
O zaman bizde ismimizi soktuğumuz döngüyü alır assemblyde güzelce bir keygen yazarız :)
Peki keygeni nasıl yazacağız? Sormak bile gereksiz çünkü yukarıda crackme bizim ismimizi alıp döngüye soktuğunda çıkarttığı sonuç zaten serialdi. Ben o döngüyü aldım doğrudan assemblyde düzenledim Kaynak kodlarını buradan indirebilirsiniz.
sorularımı cevapsız bırakmayan herkese
sonsuz TEŞEKKÜRLER ........
Öldürmeyen Her Darbe Güce Güç Katar ::: BlueDeviL // SCT
Bu programı kullanarak para kazanıyorsanız lütfen satın alın. Bu yazının yazılma amacı program yazanlara programlarını daha iyi korumaları konusunda yol göstermektir. Lisanssız kullanımda Dokümanı hazırlayan sorumlu değildir.
Diyeceğim şudur ki: Emek verilip de yapılmış bir şeyi çalma, onu satın al.

Blue DeviL
E-Mail: bluedevil@sctzine.com
ICQ: 82503282


Alıntıdır

Hiç yorum yok