Serinin bu yazısında seviyeyi bir basamak arttırıp,crack konusunu işlemeye devam ediyoruz.Teknik konuların sıkıcılığını olayı
									hikayeye dökme ve araya espriler katma yöntemiyle en aza indirmeye çalışıyoruz.Bu seferki hikayemiz Çilingir Cemal
									hakkında, gelsin hikayemizin başlıkları:
								
								Nesiller boyu süren baba mesleğiydi çilingirlik.İşlerinin hep en iyisi olmuşlardı ama 21. yüzyılda az kazandıran mesleklerden
									biriydi artık.Cemal memnun değildi halinden,hayalleri vardı ve bu hayaller için ihtiyacı olan şey paraydı.Öğrenmişti, bu mesleğin de
									teknolojik hali vardı,çok daha iyi paralar kazandıran.Çok pahalı programları alıp kırıyorsun,ondabir fiyatına satıyorsun demişti bir
									cracker arkadaşı.Bilgisayarı hep oyun için kullanan Cemal, öğrenmeye başlamıştı bile teknolojik çilingirliği...
								Keygen Nedir?
								Bir önceki yazımızda incelediğimiz programda doğrulamayı sağlayan sadece bir pin numarası (6161) vardı. Değindiğimiz yöntemlerden biriyle
									bu sayıyı (anahtarı) bulduğunuz an işlem tamamlanıyordu.Gerçek hayatta bu kadar kolayını zor bulursunuz demiştik.Zor örneklere baktığımızda karşımıza bir anahtar değil,birçok matematik işlemi sonrası oluşturulan daha karmaşık anahtarlar çıkıyor.
								Buna verebileceğimiz örneklerden biri Maykrosoft amcanın bütün ürünlerinde kullandığı Product Key olarak isimlendirdiği anahtarlar olabilir.
									Mesela kullandığım Windows 7 Pro'nun ürün anahtarı RBXXX-FFXXX-6DXXX-83XXX-YHXXX [müsadenizle birazını değiştirip yazayım :)].Akla gelen ilk şey,
									ben bu anahtarı girdiğimde program bunu doğrulayabiliyorsa demek ki bazı matematiksel hesapları yapıp kontrol ediyor,doğal olarak bu işlemleri bilen
									birisi ya da bu iş için yazılacak başka bir program bu kontrolu geçebilecek birçok anahtar oluşturabilir.
								Bahsedilen anahtarları oluşturabilen programlara Anahtar Oluşturucu, Key Generator kısaca keygen deniyor.Teorik kısmını anladık
									şimdi işi pratiğe dökelim ve bunlardan bir tanesini hep beraber yapalım.
								Kurbanımızı Tanıyalım
								Kurban olarak kullanacağımız programımız crackmes.de adresine üye olan (üyelik ücretsiz) herkesin indirebileceği
									cm1 by lagalopex isminde bir program.Üye olarak giriş yaptıktan sonra cm1 olarak aratınca ilk sırada geliyor zaten.
									Programı indirdik,unzip edip çalıştırıyoruz:
								ka@ka-vm ~/keygen $ ./cm1
									
Hello ka, lets see what you've done so far...
									
ka@ka-vm ~/keygen $ echo $?
									
1
									
ka@ka-vm ~/keygen $ file cm1
									
cm1: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped
									
ka@ka-vm ~/keygen $ ldd cm1
									
linux-gate.so.1 =>  (0xb77ad000)
									
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75eb000)
									
/lib/ld-linux.so.2 (0xb77ae000)
									
ka@ka-vm ~/keygen $ strings cm1
									
...
									
Hello %s, lets see what you've done so far...
									
%s/.key_%s
									
Seems you've got it ;)
									
ka@ka-vm ~/keygen $ readelf -s cm1
									
Symbol table '.dynsym' contains 12 entries:
									
Num:    Value  Size Type    Bind   Vis      Ndx Name
									
0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
									
[!]  1: 00000000   301 FUNC    GLOBAL DEFAULT  UND getpwuid@GLIBC_2.0 (2)
									
2: 00000000   406 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.0 (2)
									
3: 00000000   414 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.0 (2)
									
4: 00000000    57 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.0 (2)
									
[!]  5: 00000000    17 FUNC    GLOBAL DEFAULT  UND getuid@GLIBC_2.0 (2)
									
6: 00000000    59 FUNC    GLOBAL DEFAULT  UND snprintf@GLIBC_2.0 (2)
									
[!]  7: 00000000   122 FUNC    GLOBAL DEFAULT  UND open@GLIBC_2.0 (2)
									
8: 0804874c     4 OBJECT  GLOBAL DEFAULT   14 _IO_stdin_used
									
9: 00000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
									
[!] 10: 00000000   122 FUNC    GLOBAL DEFAULT  UND read@GLIBC_2.0 (2)
									
11: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
								
								Dikkatimizi çeken noktalara bir bakalım.Mesela program kullanıcı adımı biliyor,sadece Hello demek için mi acaba?Ayrıca kullanılan fonksiyonlara
									bakınca anlıyoruz ki dosya açıp,içeriğini okuyor, kullanıcı hakkında bilgiler alıyor.Başına ünlem işareti koyduğum fonksiyonları bilmemiz lazım.Bilmediğimiz
									fonksiyonlar hakkında bilgiyi man komutuyla veya Google amca sayesinde öğrenip incelemeye devam ediyoruz.
								ka@ka-vm ~/keygen $ strace ./cm1
									
execve("./cm1", ["./cm1"], [/* 32 vars */]) = 0
									
...
									
open("/home/ka/.key_ka", O_RDONLY)      = -1 ENOENT (No such file or directory)
									
exit_group(1)
								
								Programı debuggerda incelemeye başlamadan anlıyoruz ki kullanıcının home dizininde .key_kullanıcı_adı
									isminde bir dosya olması gerekiyormuş.Dosyayı oluşturup sonucu görelim.
								ka@ka-vm ~/keygen $ echo ka >~/.key_ka
									
ka@ka-vm ~/keygen $ ./cm1
									
Hello ka, lets see what you've done so far...
									
ka@ka-vm ~/keygen $ echo $?
									
2
									
ka@ka-vm ~/keygen $ strace ./cm1
									
execve("./cm1", ["./cm1"], [/* 32 vars */]) = 0
									
...
									
open("/home/ka/.key_ka", O_RDONLY)      = 3
									
read(3, "k", 1)                         = 1
									
exit_group(2)                           = ?
								
								İlk kontrolu geçmeyi başardık ama dosyamızı açıp ilk karakteri okur okumaz 2 koduyla çıktığına göre şimdi de anahtar dosyamızda
									neler yazması gerektiğini belirlememiz gerekiyor.Bunun için emektar ayıklayıcımız olan gdb'ye başvuruyoruz.
								ka@ka-vm ~/keygen $ gdb -q cm1
									
Reading symbols from /home/ka/keygen/cm1...(no debugging symbols found)...done.
									
(gdb) disas main
									
=> 0x080484eb <+23>: call   0x80483e0  [user id değerimiz?]
									
(gdb) p/s $eax
									
$1 = 1000
									
=> 0x080484f4 <+32>: call   0x80483a0  [id 1000 bilgileri /etc/passwd dosyasından gelsin]
									
	(gdb) x/xw $eax
									
	0xb7fc3d0c: 0x0804a008
									
	(gdb) x/s 0x0804a008
									
	0x804a008:  "ka"
									
	=> 0x0804850a <+54>: call   0x80483d0  [Hello mesajımız geliyor]
									
	=> 0x08048537 <+99>: call   0x8048400  [Key dosyasını aç]
									
	(gdb) x/s $ebx
									
	0xbfffe9b6: "/home/ka/.key_ka"
									
	=> 0x0804855a <+134>:  jne    0x804863c  [Açabildiysen ne ala 360dan devam ederiz]
									
	0x08048560 <+140>: jmp    0x8048682  [Dosya yoksa 430dan güle güle kısmına]
									
	=> 0x08048644 <+368>:  call   0x8048410  [1 karakter okumayı dene,sonuç eax registerına]
									
	0x08048649 <+373>: add    esp,0x10
									
	0x0804864c <+376>: dec    eax        [Okuma başarılıysa eax 1 olmalı,değeri düşür]
									
	0x0804864d <+377>: je     0x8048565  [0 olmalı lazım, o zaman 145den devam]
									
	=> 0x08048565 <+145>:  mov    dl,BYTE PTR [ebp-0x11]    [Okuduğun karakteri dl (edx 8 bit) taşı]
									
	0x08048568 <+148>: mov    eax,edx
									
	0x0804856a <+150>: mov    BYTE PTR [ebp-0x1021],dl  [Okuduğun karakter sonra lazım olucak,sakla]
									
	0x08048570 <+156>: sub    eax,0x2a                  [Karakterin hex değerinden 0x2a çıkart]
									
	0x08048573 <+159>: cmp    al,0x5                    [5 ile karşılaştır (yine çıkartma işlemi)]
									
	0x08048575 <+161>: ja     0x804867d       [Eğer büyükse 425den güle güle,değilse ?]
								
								Görüldüğü üzere satır satır çözüm yapılınca karmaşık kodlar,sanki şiir okurmuşcasına zevkli hale geliyor [Devamı çok fena,azıcık gaz lazım :)].
									Şimdi kullanabileceğimiz karakterleri belirleyip,her karakterin kontrol mekanizmasına olan etkisini de çözünce keygen yazmaya başlayabiliriz.
									Anlayacağınız inceleme bitmedi,daha yeni başlıyor.
								Doyamadım Kara Gözlüm
								
									cmp al,0x5 öğrendiğimiz üzere karşılaştırma işlemi, işlemcinin al registerındaki değerden 5 çıkartıp sonucu tekrar al registerına
									yazmasıyla oluyor.ja yani Jump If Above, eğer yüksekse atla şartına takılmamak için kullanabileceğimiz karakterleri belirleyelim:
								ka@ka-vm ~ $ python -c 'print "\x2a\x2b\x2c\x2d\x2e\x2f"' [Pythondan yardım alıyoruz]
									
*+,-./        [0,  1,  2,  3,  4,  5 <-çıkartma işlemi sonrası kalan sonuçlar]
								
								Python yardımıyla karakterleri öğrendik,şimdi de karakterlerin başımıza ne işler açtığını kontrol ediyoruz:
								=> 0x804857b :  movzx  eax,al
								
0x804857e :  jmp    DWORD PTR [eax*4+0x80487a4] [Çıkartma işleminden kalan sonuca göre atla]
								
(gdb) x/6xw 0x080487a4 [Atlanacak adresleri öğrenelim]
								
0x80487a4:  0x0804858f (*)  0x08048585 (+)  0x080485bc (,)  0x0804859b (-)
								
0x80487b4:  0x0804867d (.)  0x080485a5 (/)
								
=> 0x0804858f <+187>:  add    esi,0x5  [esiye 5 ekle,karşılaştır,219a atla]
								
0x08048592 <+190>: cmp    BYTE PTR [ebp-0x102d],0x2a
								
0x08048599 <+197>: jmp    0x80485af 
								
=> 0x08048585 <+177>:  inc    esi  [esiyi 1 arttır,karşılaştır,219a atla]
								
0x08048586 <+178>: cmp    BYTE PTR [ebp-0x102d],0x2b
								
0x0804858d <+185>: jmp    0x80485af 
								
=> 0x080485bc <+232>:  push   ecx  [Abovvvvv,detaylı açıklama aşağıda]
								
0x080485bd <+233>: lea    ecx,[ebp-0x11]
								
0x080485c0 <+236>: push   0x1
								
0x080485c2 <+238>: push   ecx
								
0x080485c3 <+239>: push   edi
								
0x080485c4 <+240>: call   0x8048410 
								
0x080485c9 <+245>: add    esp,0x10
								
0x080485cc <+248>: dec    eax
								
0x080485cd <+249>: jne    0x804867d 
								
0x080485d3 <+255>: movzx  eax,BYTE PTR [ebp-0x11]
								
0x080485d7 <+259>: cmp    eax,esi
								
0x080485d9 <+261>: jne    0x804867d 
								
0x080485df <+267>: mov    eax,DWORD PTR [ebp-0x1028]
								
0x080485e5 <+273>: mov    ecx,DWORD PTR [ebp-0x102c]
								
0x080485eb <+279>: mov    edx,DWORD PTR [eax]
								
0x080485ed <+281>: movsx  eax,BYTE PTR [edx+ecx*1]
								
0x080485f1 <+285>: cmp    esi,eax
								
0x080485f3 <+287>: jne    0x804867d 
								
...
								
=> 0x0804867d <+425>:  mov    edx,0x2 [Bizi direk çıkışa gönderdiği için . karakterini kullanmıyoruz]
								
=> 0x0804859b <+199>:  dec    esi  [Esiyi 1 azalt,karşılaştır,219a atla]
								
0x0804859c <+200>: cmp    BYTE PTR [ebp-0x102d],0x2d
								
0x080485a3 <+207>: jmp    0x80485af 
								
=> 0x080485a5 <+209>:  sub    esi,0x5  [Esiden 5 azalt,karşılaştır,eşit değilse 343den]
								
0x080485a8 <+212>: cmp    BYTE PTR [ebp-0x102d],0x2f
								
0x080485af <+219>: jne    0x804862b [Eşitse buradan devam et]
								
								Karakterlerin neler yaptığına bakalım.Nokta karakteri direk şutlama operasyonu yaptığı için onu kara listeye aldık.Yıldız karakteri
									esi registerının mevcut değerini 5 arttıyormuş,artı karakteri 1 arttırıyormuş,eksi karakteri 1 azaltıyormuş,slash karakteri de 5 azaltıyormuş.
									Peki ama nedir bu esinin günahı?Bu sorunun cevabını virgül karakterinin işlemlerinde görücez ama çoğunda 219a şartsız atlama kısmını da
									halletmemiz lazım.Ne var bu 219ta?
								=> 0x080485af <+219>: jne    0x804862b    [Atlamadan önceki karşılaştırma eşit değilse 343e atla]
								
0x080485b1 <+221>: inc    ebx    [Ebx arttır]
								
0x080485b2 <+222>: cmp    ebx,0x5    [5 ile karşılaştır]
								
0x080485b5 <+225>: jbe    0x8048630  [Eğer daha az veya eşitse 348e,]
								
0x080485b7 <+227>: jmp    0x804867d  [Yok değile şartsız güle güle kısmına]
								
								Programı detaylı incelemeden anlaşılması zor,noluyoo abi yaa dedirten ama aslında gayet basit bir durum var.Anahtar dosyamızda bir karakteri
									5 defadan fazla kullanırsak booommmmm.Tamamdır bu detayı da kenara yazıp,meşhur virgül karakterimiz ne işler çeviriyor onu çözüyoruz.
								=> 0x080485bc <+232>: push   ecx
								
	0x080485bd <+233>: lea    ecx,[ebp-0x11]
								
	0x080485c0 <+236>: push   0x1
								
	0x080485c2 <+238>: push   ecx
								
	0x080485c3 <+239>: push   edi
								
	0x080485c4 <+240>: call   0x8048410 
								
	0x080485c9 <+245>: add    esp,0x10
								
	0x080485cc <+248>: dec    eax
								
	0x080485cd <+249>: jne    0x804867d 
								
								Bu kısmı incelediğimizde görüyoruz ki virgül karakteri kullandığımız zaman,esiye herhangi bir müdahele yok.Fakat virgül karakterinden sonra
									kesinlikle bir karakter daha olmalı,yoksa kapıya gidiyoruz.
								0x080485d3 <+255>:  movzx  eax,BYTE PTR [ebp-0x11]
								
0x080485d7 <+259>: cmp    eax,esi
								
0x080485d9 <+261>: jne    0x804867d 
								
								Zurnanın zırt dediği noktalardan birisi 255. satırda gerçekleşiyor.Virgülden sonra okunan karakterinin değeri,esi değeriyle aynı olmak zorunda.
									Buradan anlıyoruz ki önce esiyi uygun değere getirmemiz gerekiyor.Tabii izin verilen karakterleri 5 defadan fazla kullanamıyoruzu unutmadan.Diğer
									kontrollerle devam edelim.
								0x080485df <+267>:  mov    eax,DWORD PTR [ebp-0x1028]
								
0x080485e5 <+273>: mov    ecx,DWORD PTR [ebp-0x102c]
								
0x080485eb <+279>: mov    edx,DWORD PTR [eax]
								
0x080485ed <+281>: movsx  eax,BYTE PTR [edx+ecx*1]
								
0x080485f1 <+285>: cmp    esi,eax
								
0x080485f3 <+287>: jne    0x804867d 
								
0x080485f9 <+293>: inc    ecx
								
0x080485fa <+294>: mov    DWORD PTR [ebp-0x102c],ecx
								
0x08048600 <+300>: cmp    BYTE PTR [edx+ecx*1],0x0
								
0x08048604 <+304>: jne    0x804861a 
								
								Kontrol üstüne kontrol yapan programımız bu seferde özene bezene hazırladığımız esi değerini başka bir eax değeriyle karşılaştırıyor,yine eşit
									değillerse meşhur kapıyı gösteriyor.Bu değeri incelediğimizde karşımıza Hello dediği kullanıcı adımız çıkıyor.Anlaşılan anahtar dosyasında
									kullanıcı adımız olmaz zorunda.300. satırda yapılan karşılaştırmada kullanıcı adımızın bir sonraki karakteri kontrol ediliyor.Eğer kullanıcı adımızın sonuna geldiysek kontrol
									devam ediyor,yok sonuna gelinmediyse işlem 326. satırdan devam ediyor.
								0x08048606 <+306>:  push   edx
								
0x08048607 <+307>: lea    eax,[ebp-0x11]
								
0x0804860a <+310>: push   0x1
								
0x0804860c <+312>: push   eax
								
0x0804860d <+313>: push   edi
								
0x0804860e <+314>: call   0x8048410 
								
0x08048613 <+319>: add    esp,0x10
								
0x08048616 <+322>: test   eax,eax
								
0x08048618 <+324>: jne    0x804867d 
								
								Bu masum satırlardan anladığımız üzere, anlıyoruz değil mi, kullanıcı adı bitmeden anahtar dosyasında okunacak başka karakter kalmadıysa yine acı
									sonla karşı karşıyayız.Peki karakter varsa ne oluyor, 326. satırda onu inceleyelim.
								0x0804861a <+326>:  mov    edx,0xa      [Hex 0xa,yani 10 ne iş?!]
								
	0x0804861f <+331>: mov    eax,esi
								
	0x08048621 <+333>: mov    ecx,edx
								
	0x08048623 <+335>: xor    edx,edx
								
	0x08048625 <+337>: div    ecx      [Bölme işlemi var!]
								
	0x08048627 <+339>: mov    esi,eax      [Esiye müdahele var,dağılın!]
								
	0x08048629 <+341>: jmp    0x8048630 
								
								Assemblyde bölme işlemi biraz kafa kurcalayıcıdır,google amcadan aratıp öğrenebilirsiniz.Yukarıdaki işlemde esi değeri eax registerına taşınıp
									10 ile bölünüyor,bölüm değeri eax registerından esiye taşınıyor.Yaniii ilk karakterden sonra esi değerine sıfırdan başlamıyoruz.10a bölme
									işleminden sonraki bölümü ikinci karakter değerimizden düşürüp ona göre esiyi ayarlıyoruz.
								Bitti arkadaşlar,bilmem kaç kontrolden sonra herşeyi doğru yaptıysanız,aşağıdaki kontrolle "Kaptın sen bu işi" mesajını alıyor ve bir sonraki başlıkta
									keygenimizi yazıyoruz.
								0x08048653 <+383>:  mov    edx,DWORD PTR [ebp-0x1028]
								
0x08048659 <+389>: mov    ecx,DWORD PTR [ebp-0x102c]
								
0x0804865f <+395>: mov    eax,DWORD PTR [edx]
								
0x08048661 <+397>: xor    edx,edx
								
0x08048663 <+399>: cmp    BYTE PTR [eax+ecx*1],0x0
								
0x08048667 <+403>: jne    0x8048682 
								
								Böööö geldi artık diyor,özetleyip geçiyoruz.Bak bakalım arkadaş, kullanıcı adının bütün karakterlerini işleme sokup,bütün kontrollerden
									adam akıllı geçebilmiş mi?Geçmiş ise ver mesajı:
								0x0804866c <+408>:  push   0x804878a
								
0x08048671 <+413>: call   0x80483b0 
								
(gdb) x/s 0x0804878a
								
0x804878a:  "Seems you've got it ;)"
								
								Çilingir Cemal Keygen v0.1
								Cemal işi gücü bıraktı teknolojik çilingirliğe kafayı taktı ama keygen yapabilmesi için bir de programlama dili bilmesi lazım.Neyse ki
									bu azimle Pythonu da öğrendi ve keygeni yazmaya başladı.Önce kuralları bir tekrarlayalım:
								
									- Kullanıcı ismini öğren,dosya oluştur
- Kullanıcı isminin her harfinin ascii değerini bul
- İzin verilen karakterlerle (max 5 defa) rakama ulaş,virgül koy,harfi yaz
- Bulduğun değeri 10a böl,böleni bir sonraki harfin değerinden düşür
- Kullanıcı ismini bitirince dosyayı kaydet
Önce keygenimizle anahtar dosyamızı oluşturuyor,sonra da programımız tekrar deniyoruz.Görüldüğü üzere sonuç, MUTLU SON..
								ka@ka-vm ~/keygen $ ./cckeygen.py
								
Çilingir Cemal Keygen v0.1
								
[!] ka [!] kullanıcısı için işlemler başlatılıyor...
								
Dosya açıldı,karakterler hazırlanıyor...
								
İşlemler tamamlandı,dosya hazır.
								
ka@ka-vm ~/keygen $ ./cm1
								
Hello ka, lets see what you've done so far...
								
Seems you've got it ;)
								
ka@ka-vm ~/keygen $