Merhabalar, elime geçen bir “KeygenMe” üzerinden eğitim yazılarımıza devam ediyoruz. Bu yazımda kırma/keygen yazma işlemi ile tutorial yazma işlemini eş zamanlı yapıyorum. Anlatım bozukluğu, ya da “daha kolayı vardı” diyeceğiniz yerler için şimdiden özür dilerim.
Başlayalım.
KeygenMe’yi çalıştırdığımızda herhangi bir onay butonunun olmadığını görüyoruz. Diğer bir deyişle, program öncelikle uygun uzunlukta kullanıcı adı ve parolanın girilmesini kontrol ediyor, bize bu ikisi sağlandıktan sonra “aferin” kutucuğunu çıkartıyor.
İlk iş olarak bu uzunlukların ne olduğunu kontrol edelim.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
401079|. PUSH 30 ;girilen veriyi 004030A0’a yaz 40107B|. PUSH keygen_m.004030A0 401080|. PUSH 3EA 401085|. PUSH [ARG.1] 401088|. CALL <JMP.&user32.GetDlgItemTextA> ;şifreyi oku 40108D|. CMP EAX,10 ;16 karakter mi kontrol et ;hatalıysa dallan: 401090|. JNZ SHORT keygen_m.004010B3 401092|. PUSH 30 ;girilen veriyi 00403050’a yaz 401094|. PUSH keygen_m.00403050 401099|. PUSH 3E9 40109E|. PUSH [ARG.1] ;kullanıcı adını oku 4010A1|. CALL <JMP.&user32.GetDlgItemTextA> 4010A6|. CMP EAX,0D ;13 karakter mi kontrol et ;hatalıysa dallan: 4010A9|. JNZ SHORT keygen_m.004010B3 |
Evet 1001(3E9) ve 1002(3EA) ID numaralı kutucuklarda yapılan kontrolü bulduk ve ilk aşamayı tamamladık. Sırada kutucuklara yazılan metinler için herhangi bir kontol olup olmadığını kontrol etmek.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
401100|. XOR ECX,ECX ;ecx'i 0 la 401102|. MOV EDX,EAX ;eax değerini(kullanıcı adı karakter uzunluğu[0D]) edx'e ata ;403050 adresindeki kullanıcı adının konumunu eax'e ata 401104|> MOV EAX,keygen_m.00403050 ;pointer i ecx değerindeki konuma al 401109|. MOVZX EAX,BYTE PTR DS:[ECX+EAX] 40110D|. CMP AL,5A ;eax'in ecx'inci baytını al ve "Z" ile karşılaştır ;büyükse hataya dallan: 40110F|. JG keygen_m.004011F4 401115|. CMP AL,40 ;eax'in ecx'inci baytını al ve "@" ile karşılaştır ;küçükse hataya dallan: 401117|. JL keygen_m.004011F4 40111D|. INC ECX ;ecx 1 arttır 40111E|. CMP ECX,EDX ;ecx ile edx karşılaştır 401120|.^JNZ SHORT keygen_m.00401104;küçükse döngü başına büyükse çık 401122|. XOR ECX,ECX ;ecx'i 0 la |
Yukarıdaki kontrol döngüsünü örnekle adım adım tekrar edelim:
Kullanıcı adı olarak 13 karakterli “ABCDEFGHIJKLM” yazmış olalım. ecx sıfırlandı. edx 13 değerini aldı. eax de kullanıcı adı değeri var. Pointer, eax değerinin 0’ıncı baytında yanı “A” karakterini oku. “A”(41) , “Z”(5A) dan büyük mü? Değil. Peki “A”(41) , “@”(40) tan küçük mü? Değil. Devam et. ecx’i 1 arttırdık ve ecx 1 oldu. 1, 13’e eşit mi? Değil. Döngüyü başa sar.
Özetle girilen kullanıcı adı 40 ila 5A arasındaki karakterlerden, yani sadece latin alfabesindeki büyük harflerden oluşabilirmiş. Böylelikle en sonunda yazacağımız kullanıcı adı havuzumuzun boyutu belli olmuş oldu.
Devam edelim. Bakalım başka ne kontroller var.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
401122|. XOR ECX,ECX ;ecx'i 0 la ;403050 adresindeki kullanıcı adının konumunu eax'e ata: 401124|> MOV EAX,keygen_m.00403050 ;pointer i ecx değerindeki konuma al: 401129|. MOVZX EAX,BYTE PTR DS:[ECX+EAX] 40112D|. ADD AL,3 ;ecx'inci eax baytına 3 ekle ;4030A0 adresindeki şifreyi konumunu ebx'e ata 40112F|. MOV EBX,keygen_m.004030A0 ;pointer i ecx değerindeki konuma al 401134|. MOVZX EBX,BYTE PTR DS:[ECX+EBX] 401138|. CMP AL,BL ;eax ve ebx baytlarını karşılaştır ;küçükse hataya dallan: 40113A|. JL keygen_m.004011EE 401140|. INC ECX ;ecx'i 1 arttır 401141|. CMP ECX,4 ;ecx 4 mü ;değilse devam: 401144|.^JNZ SHORT keygen_m.00401124 401146|. XOR ECX,ECX ;ecx'i 0 la |
Yukarıdaki kontrol döngüsünü örnekle adım adım tekrar edelim:
Kullanıcı adı olarak 13 karakterli “ABCDEFGHIJKLM” yazmış olalım. Şifre olarak da “1234567890123456” girelim. ecx sıfırlandı. eax de kullanıcı adı değeri var. Pointer, eax değerinin 0’ıncı baytında yanı “A” karakterini oku. 3 ekle (41+3=44 yani “D”). ebx de kullanıcı adı değeri var. Pointer, ebx değerinin 0’ıncı baytında yanı “1” karakterini oku. “D”(44), “1”(31) e eşit mi? Değil. Devam et. ecx’i 1 arttırdık ve ecx 1 oldu. 1, 4’e eşit mi? Değil. Döngüyü başa sar.
Özetle girilen kullanıcı adının ilk dört karakteri özelinde şifrede bir kontrol var. Kullanıcı adının ilk dört karakterinin, sırasıyla, değerinin 3 fazlası; şifrenin ilgili sıradaki karakterinden büyük olamaz.
Oluşturacağımız şifre için ilk kısıtımızı da bulmuş olduk. Devam edelim.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
401146|. XOR ECX,ECX ;ecx'i 0 la ;şifreyi eax e yaz: 401148|> MOV EAX,keygen_m.004030A0 ;şifrenin ecx'inci karakterini al: 40114D|. MOVZX EAX,BYTE PTR DS:[ECX+EAX] ;şifreyi ebx e yaz: 401151|. MOV EBX,keygen_m.004030A0 ;şifrenin (ecx+5)'inci karakterini al 401156|. MOVZX EBX,BYTE PTR DS:[ECX+EBX+5] 40115B|. XOR AL,13 ;eax'deki baytı 13 le xor la 40115D|. CMP AL,30 ;30'dan büyük mü? ;değilse devam: 40115F|. JNB SHORT keygen_m.00401165 401161|. ADD AL,40 ;değere 40 ekle ;40116B ye zıpla: 401163|. JMP SHORT keygen_m.0040116B 401165|> CMP AL,7A ; 401167|. JBE SHORT keygen_m.0040116B; 401169|. SUB AL,20 ; 40116B|> CMP AL,BL ;ebx deki değerden büyük mü? ;büyükse hataya git: 40116D|. JNZ SHORT keygen_m.004011EE 40116F|. INC ECX ;ecx'i 1 arttır 401170|. CMP ECX,2 ;ecx 2 mi ;değilse devam: 401173|.^JNZ SHORT keygen_m.00401148 401175|. XOR ECX,ECX ;ecx'i 0 la |
Özetleyelim. Şifrenin ilk karakterini al. 13 le xor la. 30 dan büyük olmamalı. 40 ekle. Şifrenin 6ncı karakteriyle karşılaştır. Büyükse hataya git değilse aynısını 2 ve 7nci karakter için kontrol et.
Geçelim diğer kontrole:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
401175|. XOR ECX,ECX ;ecx'i 0 la 401177|> XOR EBX,EBX ;ebx'i 0 la ;şifreyi eax e yaz:: 401179|. MOV EAX,keygen_m.004030A0 ;şifrenin ecx'inci karakterini al: 40117E|. MOVZX EAX,BYTE PTR DS:[ECX+EAX] ;şifreyi ebx e yaz: 401182|. MOV EBX,keygen_m.004030A0 ;şifrenin (ecx+8)'inci karakterin al: 401187|. MOVZX EBX,BYTE PTR DS:[ECX+EBX+8] 40118C|. XOR EAX,EBX ;bu iki karakteri xor la 40118E|. CMP AL,30 ;sonuç 30 dan küçük mü? ;öyleyse devam: 401190|. JNB SHORT keygen_m.00401194 401192|. ADD AL,30 ;sonuca 30 ekle 401194|> CMP AL,7A ;sonuç 7A dan büyük yada eşit mi? ;değilse dallan: 401196|. JBE SHORT keygen_m.0040119A 401198|. SUB AL,30 ; 40119A|> XOR EBX,EBX ;ebx'i 0 la ;şifreyi ebx e yaz: 40119C|. MOV EBX,keygen_m.004030A0 ;şifrenin (ecx+A)'ncı karakterin al: 4011A1|. MOVZX EBX,BYTE PTR DS:[ECX+EBX+A] 4011A6|. CMP AL,BL ;sonuçla karşılaştır ;eşit değilse çık: 4011A8|. JNZ SHORT keygen_m.004011EE 4011AA|. INC ECX ;ecx'i 1 arttır 4011AB|. CMP ECX,2 ;ecx 2 mi ;değilse döngüye devam: 4011AE|.^JNZ SHORT keygen_m.00401177 |
Bu döngüde şifremizin 1 ile 9 ve 2 ile 10 uncu karakterleri arasında bir kontrol var. Bu kontrol sonucunda da şifremizin 11 ve 12nci karakterleri bulunuyor. 1 ve 9ncu karakteri alıyor, bunları xor luyor ve sonucu eax’e yazıyor. Çıkan sonuç 30 la kıyaslanıyor. Küçükse 30 eklenip 7A ile kıyaslanıyor ve küçükse devam edilip; eax değerinin, şifrenin 11nci karakterine eşit olması kontrol ediliyor. Aynı işlemler 2 ve 10ncu karakterler ile yapılıp 12nci karakter bulunuyor.
Geldik son ve en basit kontrole:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
4011B0|. XOR ECX,ECX ;ecx'i 0 la ;kullanıcı adını eax a yaz: 4011B2|> MOV EAX,keygen_m.00403050 ;kullanıcı adının ecx'inci karakterini al: 4011B7|. MOVZX EAX,BYTE PTR DS:[ECX+EAX] ;şifreyi ebx e yaz: 4011BB|. MOV EBX,keygen_m.004030A0 ;şifrenin (ecx+C)'inci karakterin al: 4011C0|. MOVZX EBX,BYTE PTR DS:[ECX+EBX+C] 4011C5|. CMP AL,BL ;bu iki karakteri karşılaştır ;aynıysa devam et: 4011C7|. JG SHORT keygen_m.004011EE 4011C9|. INC ECX ;ecx'i 1 arttır 4011CA|. CMP ECX,4 ;ecx 4 mü ;değilse döngüye devam: 4011CD|.^JNZ SHORT keygen_m.004011B2 |
Yukarıdaki kontrol kullanıcı adının ilk 4 karakterinin şifrenin 13,14,15,16ncı karakterleriyle aynı olup olmadığını kontrol ediyor. Bu kadar basit.
Bu işlemler sonucunda deneme için girdiğimiz “ABCDEFGHIJKLM” kullanıcı adına denk gelen şifrelerden birinin “:9345ij89039ABCD” olduğunu buluyoruz.
Tebrikler programı kırdınız :)
Şimdi gelelim keygen yazma işlemine. Bildiklerimizi toparlayalım ve fonksiyonlarımızı oluşturalım.
1- Kullanıcı adı 13 karakterden oluşacak ve sadece büyük latin harflerini içerecek.
2- Kullanıcı adının ilk dört karakterinin, sırasıyla, değerinin 3 fazlası; şifrenin ilgili sıradaki karakterinden büyük olamaz. Buna göre kullanıcı adına yazılabilecek en büyük karakter “Z”(5A) olduğuna göre şifrenin ilk 4 karakterinde bulunabilecek en büyük karakter “]”(5D) olabilir.
3- Şifrenin ilk karakterini al. 13 le xor la. 30 dan küçükse 40 ekle.30dan büyükse 7A ile kıyasla. 7A dan büyükse 20 çıkar, değilse devam et. Şifrenin 6ncı karakteriyle karşılaştır. Aynısını 2 ve 7nci karakter için kontrol et.
4- Şifrenin 1 ve 9ncu karakterini al, bunları xor la ve sonucu eax’e yaz. Çıkan sonuç 30 la kıyasla. Küçükse 30 ekle, 7A ile kıyasla. Küçükse devam et; eax değeri, şifrenin 11nci karakterine eşit olmalı. Aynı işlemler 2 ve 10ncu karakterler ile yap 12nci karakteri bul.
5- Kullanıcı adının ilk 4 karakteri şifrenin son 4 karakteri olacak
Yazdığım KeyGen’e ait Kaynak Kodlar ekte mevcut. Takıldığınız her yerde soru sormaktan çekinmeyin.
Yazı boyunca yaptığımız hatalardan ötürü şimdiden affola.
[dm]160[/dm]
Comments of this post