==========================================================================
$								         $
$		            TuToriaL by Tymon			  	 $
$		                  What:				         $
$		           CrAckMe 3.o by Ryba			         $
$								         $
==========================================================================		      

		      _______\      (((      /_______
		   _____\____ \     | ,\    / ____/_____
		 ____\______ \_\    | __\  /_/ ______/____
		___\_______ \__\\___| |___//__/ _______/___
		  \_______ \__ \ \v v v v/ / __/ _______/
 		     \____\___\_\_\!crk!/_/_/___/____/
		              /  / \v v/ \  \
		             |__/  /\v/\  \__|
		               |__/ /|\ \__|
		                 |_/\_/\_|

.AboUt

Crackme nie posiada zadnych metod ANTY-SI. Spakowane FSG, ktory
nie przeszkadza podczas lamania.

T00LS:	SoftIce, kalkulator

Witam wszystkich, ktorym sie nudzi i jak widac nie maja co robic d:).
Dzisiaj na warsztat idzie Crackme 3.o by Ryba. Nie ukrywam, ze crackme
jest dosyc fajne. Nie ma tu zadnych metod ANTY-SI, a sam prog spakowany
jest F[ast] S[mall] G[ood], czyli FSG. Paker nie przeszkadza w lamaniu
proga. Ogolnie jedyna przeszkoda sa instrukcje koprocesora. Dobra koniec
smecenia zaczynamy.

.StaRt

Na poczatku pamietaj, ze okno FPU uruchamja sie komenda wf. Jest to
bardzo wazne, bo inaczej nie bedziesz widzial co robia instrukcje.
Otwieramy crackme i widzimy takie cos:

	Name:
	[	]
	S/n:
	[  ten kawalek s/n nazwe 'a'  ]-[    ten 'b'   ]-[  a ten 'c'  ]

Zakladamy standard czyli bpx GetDlgItemTextA, naciskamy Register i ladujemy
w SI.

017F:00401B71  E870020000          CALL      USER32!GetDlgItemTextA     <- pobierz name
017F:00401B76  85C0                TEST      EAX,EAX                            
017F:00401B78  0F8443010000        JZ        00401CC1                           
017F:00401B7E  6849314000          PUSH      00403149                           
017F:00401B83  50                  PUSH      EAX                                
017F:00401B84  68CD304000          PUSH      004030CD                           
017F:00401B89  E872F4FFFF          CALL      00401000                    <- MD5(name)       
017F:00401B8E  6A14                PUSH      14                                 
017F:00401B90  6835314000          PUSH      00403135                           
017F:00401B95  6A68                PUSH      68                                 
017F:00401B97  FF3571304000        PUSH      DWORD PTR [00403071]               
017F:00401B9D  6A14                PUSH      14                                 
017F:00401B9F  6821314000          PUSH      00403121                           
017F:00401BA4  6A67                PUSH      67                                 
017F:00401BA6  FF3571304000        PUSH      DWORD PTR [00403071]               
017F:00401BAC  6A14                PUSH      14                                 
017F:00401BAE  680D314000          PUSH      0040310D                           
017F:00401BB3  6A66                PUSH      66                                 
017F:00401BB5  FF3571304000        PUSH      DWORD PTR [00403071]               
017F:00401BBB  E826020000          CALL      USER32!GetDlgItemTextA       <- pobierz s/n a
017F:00401BC0  E821020000          CALL      USER32!GetDlgItemTextA       <- ---"---	 b
017F:00401BC5  E81C020000          CALL      USER32!GetDlgItemTextA       <- ---"---	 c

Tutaj pobierany jest text z okienka i generowany hash MD5 z name.
Ta wiadomosc jest potrzebna do zrobienia keygena, ale ja nie opisze
tego w tym tutku.

017F:00401BCD  BE0D314000          MOV       ESI,0040310D                       
017F:00401BD2  E869020000          CALL      00401E40                           
017F:00401BD7  84C0                TEST      AL,AL                  <- czy a = ''           
017F:00401BD9  0F85FA000000        JNZ       00401CD9       	    <- bye!                    
017F:00401BDF  DD1D59314000        FSTP      REAL8 PTR [00403159]               
017F:00401BE5  BE21314000          MOV       ESI,00403121                       
017F:00401BEA  E851020000          CALL      00401E40                           
017F:00401BEF  84C0                TEST      AL,AL                  <- czy b = ''            
017F:00401BF1  0F85E2000000        JNZ       00401CD9               <- bye!           
017F:00401BF7  DD1561314000        FST       REAL8 PTR [00403161]               
017F:00401BFD  BE35314000          MOV       ESI,00403135                       
017F:00401C02  E839020000          CALL      00401E40                           
017F:00401C07  84C0                TEST      AL,AL                  <- czy c = ''            
017F:00401C09  0F85CA000000        JNZ       00401CD9               <- bye!    

Tutaj prog sprawdza, czy wpisalismy cos w kazde okienko i czy sa to liczby (dotyczy s/n)
A dalej:

017F:00401C0F  DD1D69314000        FSTP      REAL8 PTR [00403169]	<- c ze stosu
017F:00401C15  DD0561314000        FLD       REAL8 PTR [00403161]	<- b na stos 
017F:00401C1B  DEC9                FMULP     ST(1),ST             	<- b*b
017F:00401C1D  6A04                PUSH      04
017F:00401C1F  DB0424              FILD      DWORD PTR [ESP]      	<- 4 na stos
017F:00401C22  DD0559314000        FLD       REAL8 PTR [00403159] 	<- a na stos
017F:00401C28  DD0569314000        FLD       REAL8 PTR [00403169]  	<- c na stos
017F:00401C2E  DEC9                FMULP     ST(1),ST             	<- a*c
017F:00401C30  DEC9                FMULP     ST(1),ST            	<- a*c*4
017F:00401C32  DEE9                FSUBP     ST(1),ST        		<- b*b - 4ac
017F:00401C34  D9FA                FSQRT                     		<- pierwiastek z wyniku

Wynik pierwiastka oznacze p.

017F:00401C36  DD0561314000        FLD       REAL8 PTR [00403161]       <- b na stos        
017F:00401C3C  D9E0                FCHS                                 <- (-b)        
017F:00401C3E  D8E1                FSUB      ST,ST(1)                   <- (-b-p)       
017F:00401C40  6A02                PUSH      02                                 
017F:00401C42  DB0424              FILD      DWORD PTR [ESP]            <- 2 na stos        
017F:00401C45  DD0559314000        FLD       REAL8 PTR [00403159]       <- a na stos        
017F:00401C4B  DEC9                FMULP     ST(1),ST                   <- a*2        
017F:00401C4D  DEF9                FDIVP     ST(1),ST                   <- (-b-p)/2a  (wyn1 )        
017F:00401C4F  DD0561314000        FLD       REAL8 PTR [00403161]       <- b na stos        
017F:00401C55  D9E0                FCHS                                 <- (-b)         
017F:00401C57  D8C2                FADD      ST,ST(2)                   <- (-b+p)        
017F:00401C59  6A02                PUSH      02                                 
017F:00401C5B  DB0424              FILD      DWORD PTR [ESP]            <- 2 na stos        
017F:00401C5E  DD0559314000        FLD       REAL8 PTR [00403159]       <- a na stos        
017F:00401C64  DEC9                FMULP     ST(1),ST                   <- 2*a       
017F:00401C66  DEF9                FDIVP     ST(1),ST                   <- (-b+p)/2a  (wyn2 )       
017F:00401C68  83C40C              ADD       ESP,0C                             
017F:00401C6B  DF0549314000        FILD      WORD PTR [00403149]     <- MD5(name) na stos
017F:00401C71  D8D9                FCOMP     ST(1)                   <- porownuje MD5 z wyn2       
017F:00401C73  DFE0                FSTSW   AX                                   
017F:00401C75  9E                  SAHF                                         
017F:00401C76  7A61                JP        00401CD9                           
017F:00401C78  740D                JZ        00401C87                <- jezeli rowne
									sprawdz wyn1        
017F:00401C7A  DF0557314000        FILD      WORD PTR [00403157]     <- MD5(name)+14         
017F:00401C80  D8D9                FCOMP     ST(1)                   <- cmp MD5+14 z wyn2        
017F:00401C82  DFE0                FSTSW   AX                                   
017F:00401C84  9E                  SAHF                                         
017F:00401C85  7552                JNZ       00401CD9                <- if no then fuck off
									else sprawdz wyn1          
017F:00401C87  DF0557314000        FILD      WORD PTR [00403157]     <- MD5(name)+14 na stos        
017F:00401C8D  D8DA                FCOMP     ST(2)                   <- cmp MD5(name)+14, wyn1           
017F:00401C8F  DFE0                FSTSW   AX                                   
017F:00401C91  9E                  SAHF                                         
017F:00401C92  7A45                JP        00401CD9                          
017F:00401C94  740D                JZ        00401CA3                <- yeeh it's good code          
017F:00401C96  DF0549314000        FILD      WORD PTR [00403149]     <- MD5(name) na stos           
017F:00401C9C  D8DA                FCOMP     ST(2)                   <- cmp MD5(name) z wyn2           
017F:00401C9E  DFE0                FSTSW   AX                                   
017F:00401CA0  9E                  SAHF                                         
017F:00401CA1  7536                JNZ       00401CD9                <- if no bad code else ...

Tak przedstawia sie cale sprawdzanie seriala w crackme. Nalezy tu jeszcze
wpomniec co to jest to MD5. Bardzo ogolnie mowiac jest to algorytm wedlug
ktorego na podstawie danej wartosci wyliczny zostaje unikalny hash, np.:

 string do zaszyfrowania:	Tymon
 MD5(Tymon)			426286F8BC36D1BC8541B3597BF68B83

W okienku w crackme zobaczysz jednak wartosc nie odwrocona, np. dla 'Tymon'
F8866242BCD136BC59B34185838BF67B, ale to nie wazne. Jezeli jestes bardziej
tym zainteresowany to poszukaj w necie textow na temat kryptografii.
Mozesz odwiedzic takze b.d. strone WitkaG/xt. 
Zobaczmy teraz nasz kodzik. Nic wam to nie przypomina? Moze inaczej to
rozpisze:

p(ierwiastek) = sqrt(b*b - 4ac)	// sqrt - pierwiastek z ...
wyn1 = (-b-p)/2a
wyn2 = (-b+p)/2a

a sprawdzenie przedstawja sie w taki sposob:

if 		wyn2 = MD5(name)	or	wyn2 = MD5(name)+14
	then

 sprawdz czy 	wyn1 = MD5(name) 	or	wyn1 = MD5(name)+14

if wszystko sie zgadza then good code.

Nadal nie wiecie co wam to przypomina ;-) Oczywiscie to nic innego jak
rownanie kwadratowe. Przeciez p to nic innego jak delta.
Teraz powinniscie juz sami obliczyc poszczegole czeci s/n, a jak nie
to juz mowie ( pisze ;)).

Wprowadze teraz pewne oznaczenia:

x1 = MD5(name)
x2 = MD5(name)+14

Najprostszym sposobem jest podstawienie pod wyn1, x1, a pod wyn2, x2.
Nie bedzie to jednak dobre rozwiazanie dla wszystkich nick'ow, poniewaz
moze pojawic sie problem ze znakiem. Lepszym sposobem jest rozwiazanie
rownania dla delta = 0. Zatem ...

delta = b^2 - 4ac	/ ^ - do potegi
0 = b^2 - 4ac
4ac = b^2
c = (b^2)/4a

dalej:

x1 = -b/2a	or	x2 = -b/2a	/ dla delta = 0 jest tylko jedno rozwiazanie
					/ pamietacie to z matmy, prawda? ;-)
b = -x1*2a	or	b = -x2*2a

a - oczywiscie bedzie liczba dowolna.

Majac juz gotowe wzory na obliczenie s/n, moge obliczyc go dla nick Tymon.

x1 = -30984	// MD5(name)
x2 =  31734	// MD5(name)+14

a = 34512	// dowolna liczba

b = -x1*2a		or	b = -x2*2a
b = -(-30984)*2*34512	or	b = -31734*2*34512
b = 2138639616		or	b = -2190407616

c = (b^2)/4a
c = (2138639616^2)/4*34512	or c = (-2190407616^2)/4*34512
c = (2138639616^2)/138048	or c = (-2190407616^2)/138048
c = 33131804931072		or c = 34755197643072

i mamy poprawny s/n

Name: Tymon
S/n:  34512-2138639616-33131804931072 albo 34512--2190407616-34755197643072

Jak widzisz dla kazdego a mozna wygenerowac dwa s/n, a dla kazdego name
nieskonczenie wiele. Liczby ze znakiem '-' normalnie wpisujemy z tym
znakiem do okienka.

.eNd

I kolejne crcme mamy za soba. Bylo nawet b. dobre. Ciekawy pomysl. Ja ostatnio
zajmuje sie prawie tylko crackmesami i czesto maja one sterotypowe zabezpieczenia.
Dobrze jak ktos wpadnie na ciekawy sposob zabezpieczenia swego softu ( rownanie
kwadratowe :)). Oki, jak zawsze, jakies pytania, chec podzielenia sie kasa,
masz za duzy dom d:) mailto: Tymon_crk@wp.pl. Do zipa powinien byc dolaczony keymaker
wraz z kodami zrodlowymi, wiec nie powinno byc pytan. Do zobaczenia w przyszlosci.

.LinKZ

www.cracking.pl       // texty na karzdy temat
www.zoomek.prv.pl     // strona zoomka, najlepsza jezeli chodzi o asm. Znajdziesz
		      // tu opisy wielu sztuczek ANTY-SI
www.ctrl-d.prv.pl     // strona Barta, crack news
www.crackmes.prv.pl   // najlepsza strona dla praktyki. Siagaj crackmes i tutki, a dosc
		      // szybko zrozumiesz o co biega.
www.witeg.prv.pl      // swietna strona crackme lamacza. Crypto w asm.
rp2k.host.sk  	      // he .. he .. REVOLUTiON PROJECT

.tHaNX t0:

	ZAKONNA, Smola, Ged_, WiteG, Cybult, BART, ToMKoL, Ryba (for this crcme)