====================================================================
$								   $
$		      TuToriaL by Tymon				   $
$		            What:				   $
$		     Crackme 0 by #EmEs@			   $
$								   $
====================================================================

Witam wszystkich!
Dzisiaj zajmjemy si CrackMe 0 by #EmEs@ /AAOCG.
CrackMe to jest bajecznie proste, wiec zanim
przeczytasz tuta sproboj rozwalic je sam.
Nie ma w nim zadnych ANTY-SI PROTECTION, a kodzik
sprawdzany jest w bardzo przystepny dla crackera
sposob ;-). Rozwiazanie go to max 3 min. Tut przeznaczony jest
raczej dla Newbies.

.START

Otwieramy crackme i widzimy, ze mamy podac serial. Bez zadnego
name itd. Wpisujemy cokolwiek i zakladamy plapke na text, czyli
> bpx GetDlgItemTextA oraz
> bpx GetWindowTextA
Oczywiscie przypominam, ze o wiele lepiej napisac sobie macro
w softice, ale ja tego nie opisze, bo wiele osob o tym juz pisalo
(looknij na koniec textu). Wciskamy CrackIt ;-) i ladujemy w SoftIce.
Wcziskamy F11 by przejsc z kodu user32 do kodu crackmesa.

-----Newbies NoTe!!!---------
Musimy wcisnac F11 by wyjsc z user32, poniewaz plapki na text, sa
czescia bibloteki user32. Gdy programista (coder ;-)) wywoluje, np.
GetDlgItemTextA (itp.) to program przechodzi do user32 lub kernel 32.
Po wykonaniu procki wraca do kodu programu. Po nacisnieciu F11
SoftIce wraca do kodu, skad wywolana byla procka.
-----EnD oF NeWbiEs NoTe!!!---

Widzimy wiec kodzik:

0167:0040111A  6A14                PUSH      14                                 
0167:0040111C  680C304000          PUSH      0040300C                           
0167:00401121  6A67                PUSH      67                                 
0167:00401123  FF7508              PUSH      DWORD PTR [EBP+08]                 
0167:00401126  E8D1000000          CALL      USER32!GetDlgItemTextA             
0167:0040112B  A308304000          MOV       [00403008],EAX                     
0167:00401130  85C0                TEST      EAX,EAX                            
0167:00401132  746C                JZ        004011A0                           
0167:00401134  83F801              CMP       EAX,01                             
0167:00401137  7C67                JL        004011A0                           
0167:00401139  55                  PUSH      EBP                                
0167:0040113A  57                  PUSH      EDI                                
0167:0040113B  E883000000          CALL      004011C3                           
0167:00401140  7539                JNZ       0040117B                           
0167:00401142  E88A000000          CALL      004011D1                           
0167:00401147  7532                JNZ       0040117B                           
0167:00401149  E88D000000          CALL      004011DB                           
0167:0040114E  752B                JNZ       0040117B                           
0167:00401150  E890000000          CALL      004011E5                           
0167:00401155  7524                JNZ       0040117B                           
0167:00401157  40                  INC       EAX                          
0167:00401158  6683F800            CMP       AX,00                              
0167:0040115C  7504                JNZ       00401162                           
0167:0040115E  5F                  POP       EDI                                
0167:0040115F  5D                  POP       EBP                                
0167:00401160  EB5A                JMP       004011BC                           
0167:00401162  6A40                PUSH      40                                 
0167:00401164  6898214000          PUSH      00402198                           
0167:00401169  68DB214000          PUSH      004021DB                           
0167:0040116E  FF7508              PUSH      DWORD PTR [EBP+08]                                               
0167:00401171  E898000000          CALL      USER32!MessageBoxA                 
0167:00401176  5F                  POP       EDI                                
0167:00401177  C9                  LEAVE                                        
0167:00401178  C21000              RET       0010                               
0167:0040117B  6A00                PUSH      00                                 
0167:0040117D  6A67                PUSH      67                                 
0167:0040117F  FF7508              PUSH      DWORD PTR [EBP+08]                 
0167:00401182  E899000000          CALL      USER32!SetDlgItemTextA             
0167:00401187  6A10                PUSH      10                                 
0167:00401189  6898214000          PUSH      00402198                           
0167:0040118E  68AF214000          PUSH      004021AF                           
0167:00401193  FF7508              PUSH      DWORD PTR [EBP+08]                 
0167:00401196  E873000000          CALL      USER32!MessageBoxA                 
0167:0040119B  5F                  POP       EDI                                
0167:0040119C  C9                  LEAVE                                        
0167:0040119D  C21000              RET       0010            

Najpierw, poniewaz tuteK jest dla Newbies przesledzimy poczatek:

0167:0040111A  6A14                PUSH      14                                 
0167:0040111C  680C304000          PUSH      0040300C                           
0167:00401121  6A67                PUSH      67                                 
0167:00401123  FF7508              PUSH      DWORD PTR [EBP+08]                 
0167:00401126  E8D1000000          CALL      USER32!GetDlgItemTextA             
0167:0040112B  A308304000          MOV       [00403008],EAX          (1)                
0167:00401130  85C0                TEST      EAX,EAX                 (2)           
0167:00401132  746C                JZ        004011A0                (3)          
0167:00401134  83F801              CMP       EAX,01                  (4)           
0167:00401137  7C67                JL        004011A0     	     (5)

Postac GetDlgItemTextA:

push dlugosc_pobranego_textu
push offset_pod_jakim_zostanie_zapisany_text
push ID_kontrolki_Pola_Edycji ; po tym prog wie z ktorego edita ma pobrac text
push hWnd ; czyli uchwyt do okna
call GetDlgItemTextA ; czyli wywolanie procki pobrania textu

Po wywolani w eax zwracana jest dlugosc pobranego textu.
Sorry, ze pisze to w taki nieprogramistyczny ;-) sposob,
ale chce by jak najwiecej osob zrozumialo.
W lini (1) dlugosc textu zapisywana jest pod 00403008, a
dalej jest sprawdzanie, czy text zawiera jakies znaki
( jezeli eax = 0 skacze pod adres 004011A0 ). Nie chce mi sie
wklejac kodu, powiem wiec tylko, ze jezeli nic niewpiszemy to
program nie zrobi praktycznie nic (nie pokarze sie zaden MessageBox).
W linijkach (5) i (6) robione jest dokladnie to samo. Wlasciwie nie wiem
dlaczego #EmEs@ dodal te instrukcje. ( JL - znaczy: jezeli mniejsze to skacz ).
Ufff, teraz przechodzimy do tego co tygryski lubia najbardziej ;-)

0167:0040113B  E883000000          CALL      004011C3  (6)                    
0167:00401140  7539                JNZ       0040117B  (7)                         
0167:00401142  E88A000000          CALL      004011D1  (8)                         
0167:00401147  7532                JNZ       0040117B  (9)                         
0167:00401149  E88D000000          CALL      004011DB  (10)                         
0167:0040114E  752B                JNZ       0040117B  (11)                         
0167:00401150  E890000000          CALL      004011E5  (12)                         
0167:00401155  7524                JNZ       0040117B  (13)                         
0167:00401157  40                  INC       EAX       (14)                   
0167:00401158  6683F800            CMP       AX,00     (15)                         
0167:0040115C  7504                JNZ       00401162  (16)

i odrazu na poczatku zobaczymy co jest w callu (6):

0167:004011C3  BF0C304000          MOV       EDI,0040300C		(17)
0167:004011C8  33C0                XOR       EAX,EAX                    (18)        
0167:004011CA  812F6D792067        SUB       DWORD PTR [EDI],6720796D   (19)        
0167:004011D0  C3                  RET					(20)

W lini (17) do Edi wpisywana jest wartosc 0040300C. Zobaczmy co sie tam znajduje:
> d 0040300C
W oknie danych powinienes zobaczyc swoj wpisany serial.
Teraz dalej, w lini (18) xorowane jest eax z eax. To znany
i ekonomiczny sposow wyzerowania rejestru. W dzialaniu odpowiada
mov eax, 00000000, ale w bajtach zajmuje mniej. Jak dziala xor ?

         a | b |  wynik 
         ==============
         1 | 1 |    0
         0 | 1 |    1
         1 | 0 |    1
         0 | 0 |    0

Oczywiscie tabelka dotyczy liczb binarnych, czyli w systemie dwojkowym.
xorujac wiec 2 z 3, musimy zamienic liczby na system binarny, czyli

2d = 10b
3d = 11b	d= dec (dziesiatkowy)	b= bin (binarny)

         a | b |  wynik 
         ==============
         1 | 1 |    0
         0 | 1 |    1

czyli: 10b ^ 11b == 01b
	2d ^ 3d	 == 1d	  ^ oznacza xor

Oki, idziemy dalej, czyli do linij (19):

0167:004011CA  812F6D792067        SUB       DWORD PTR [EDI],6720796D   (19)

Tutaj od 4 bajtow z pod [edi] odejmowana jest liczba 6720796D.
Skad wiem, ze od 4 bajtow. Mowi o tym DWORD PTR. Look:

DWORD - 4 bajty  (4 znaki)
WORD  - 2 bajty  (2 znaki)
BYTE  - 1 bajt	 (1 znak)

DWORD PTR znaczy wiec, ze dzialanie dotyczy 4 bajrow spod rejestru EDI ( o
tym mowia nam nawiasy kwadratowe). Czyli od pierwszych 4 znakow twojego s/n
odejmuje 6720796D. U mnie wyglada to tak ( wpisujemy w softice ):

> ? '3451'- 6720796D
	CA14BAC6  <-- wynik

Potem jest wyjscie z calla, czyli instrukcja RET.I widzimy:

0167:00401140  7539                JNZ       0040117B  (7)                         
0167:00401142  E88A000000          CALL      004011D1  (8)                         
0167:00401147  7532                JNZ       0040117B  (9)

Odrazu na poczatku  jest skok JNZ (czyli: Jf Not Z=1). Skok
ten wykona sie wtedy gdy flaga Z nie bedzie ustawiona. Zobacz
gdzie zaprowadzi nas ten skok:
 
0167:0040117B  6A00                PUSH      00                          \       
0167:0040117D  6A67                PUSH      67                           |Czyszczenie 
0167:0040117F  FF7508              PUSH      DWORD PTR [EBP+08]           |pola edycji
0167:00401182  E899000000          CALL      USER32!SetDlgItemTextA      /       
0167:00401187  6A10                PUSH      10                          \       
0167:00401189  6898214000          PUSH      00402198                     |       
0167:0040118E  68AF214000          PUSH      004021AF                     | okienko
0167:00401193  FF7508              PUSH      DWORD PTR [EBP+08]           | badboy
0167:00401196  E873000000          CALL      USER32!MessageBoxA          /      
0167:0040119B  5F                  POP       EDI                                
0167:0040119C  C9                  LEAVE                                        
0167:0040119D  C21000              RET       0010

Ogolnie mowiac sa to instrukcje odpowiedzialne za wyczyszczenie pola
textowego oraz pokazanie odpowiedniej wiadomosci. Zgadnijcie jakiej ;-)
Nie, nie mowi ona o wygranej w lotto ;-). Co zrobic wiec by nie wyswietlal
nam sie ten MessageBox? Juz mowie. Flaga Z zostanie ustawiona tylko wtedy,
gdy w ostatniej operacji wynik wyjdzie 0. Wynika z tego, ze odejmowanie:
4znaki s/n - 6720796D musi rownac sie 0. A zeby byla to prawda musi byc wartoscia
6720796D. Zobaczmy wiec co to za wartosc:

> ? 6720796D
 6720796D 1730181485 "g ym"
 ^^^^^^^^ ^^^^^^^^^^  ^^^^^
 hex	  dec	      ASCII

Czyli pierwsze znaki naszego s/n musza byc 'my g'. Dlaczego odwrotnie.
Rejestry pobieraja znaki w odwrotnej kolejnosci z pamieci, hmm... nie pytaj
dlaczego, poprostu mi uwierz ;-) - lub sprawdz. Identycznie dzieje si
dalej, z drobna roznica, ze dodana jest instrukcja:

0167:004011D1  83C704              ADD       EDI,04

Jak ona dziala? W Esi mamy offset naszego s/n (czyli adres pamieci pod
ktorym zapisal program s/n ). Po dodaniu do niego 4 bedzie wskazywal
nastepne 4 znaki itd. Zobaczmy wiec rozwiazanie (rozwiazanie 3 nastepnych call'ow,
mam nadzieje, ze przesledzisz je sam, bo sa prawie identyczne jak pierszy )

hex	  |ASCII nie odwrocone  |ASCII odwrocone
------------------------------------------------
6720796D  |   g ym		|    my g
206C7269  |    lri		|    irl 
776C7973  |   wlys		|    sylw
21206169  |   ! ai		|    ia !

Co nam powstalo:

 my girl sylwia !

Wpisujemy to w pole edycji i spokojnie przechodzimy przez 4 calle.

0167:00401155  7524                JNZ       0040117B  (a)                         
0167:00401157  40                  INC       EAX       (b)                   
0167:00401158  6683F800            CMP       AX,00     (c)	
0167:0040115C  7504                JNZ       00401162  (d)

Teraz skok z linji (a) nie odbedzie sie, do eax, zostanie dodane 1 (b)
i wtedy skok z linijki (d) odbedzie si. Teraz skacze do poprawnego
mjejsca. Widzimy wiec wspanialy napis:

	@ Good Cracker @
     !!! Congratulation !!!

.END

Crackme 0 zlamane. Jak na takie crcme to troche duzo textu napisalem, ale
chcialem by NewBies wszystko zrozumieli. Bardziej chyba tego wytlumaczyc
sie nieda. Chociaz ... ;-). Ogolnie mam nadzieje, ze wszystko zrozumieliscie,a
jak nie to mailto: tymon_crk@wp.pl.

---UWAGA!---NEWBIES---
Jezeli chcesz zostac crackerem, a nie masz pojecia nawet o asemblerze, nic nie
zrozumiales z tego tuta, to polecam stronki:

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.crackpl.site.pl // stronka upadlej juz grupy CrackPl, szkoda byli dobrzy.
www.witeg.prv.pl    // swietna strona crackme lamacza. Crypto w asm.
------------------------

ThanX to:

	    ZAKONNA, mNICH, BART, Cybult, GED_, ToMKoL, JuBE, CRACKPL, AAOCG