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

.ABOUT

Witam Wszystkich!
Dzisiaj Crackmes by #EmEs@ cd. Mam nadzieje, ze macie podstawowe
wiadomosci na temat cracku itp. rzeczy. Crackme jest bardzo proste
dlatego na poczatku sprobuj sam. Dobra, czas zaczynac.

Tools: SoftIce, W32Dasm or IDA, Hex WorkShop albo inny hex editor.

.START

Otwieramy crackme i odrazu pojawia sie nam okienko:

 "Unload SoftIce Debugger and Try Again!!!"

Hmm... My raczej tu sie nie posluchamy autora ;-). Odpalamy W32Dasm
albo IDE ( ja opisze na przykladzie wdasm'a ) i dissamplujemy proga.
Wchodzimy do Functions --> Imports, by obejrzec sobie tabele importow.

KERNEL32.CreateFileA			(1)
KERNEL32.ExitProcess
KERNEL32.GetLastError
KERNEL32.GetModuleHandleA
KERNEL32.SetUnhandledExceptionFilter	(2)
USER32.DialogBoxParamA
USER32.GetDesktopWindow
USER32.GetDlgItemTextA
USER32.GetWindowRect
USER32.LoadIconA
USER32.MessageBoxA
USER32.MoveWindow
USER32.SendDlgItemMessageA
USER32.SendMessageA
USER32.SetDlgItemTextA

Jak widzisz tabela importow to spis importowanych fuckcji programu.
Hmm.. Dziwne, prog jest jednym plikiem, a mamy API CreateFileA. Ciekawa jest
takze linia (2). To Api moze sluzyc do wykrycia SI. Zajmijmy sie jednak CreateFileA.
Klikamy na niego 2 razy i widzimy kod:

* Referenced by a CALL at Address:
|:00401000   							<-- wywolana z Entry Point
|
:00401208 89250D304000            mov dword ptr [0040300D], esp
:0040120E 6852124000              push 00401252

* Reference To: KERNEL32.SetUnhandledExceptionFilter, Ord:026Ah <-- hmm...
                                  |
:00401213 E8B2000000              Call 004012CA
:00401218 A311304000              mov dword ptr [00403011], eax
:0040121D 6A00                    push 00000000
:0040121F 6880000000              push 00000080
:00401224 6A03                    push 00000003
:00401226 6A00                    push 00000000
:00401228 6A01                    push 00000001
:0040122A 6800000080              push 80000000

* Possible StringData Ref from Data Obj ->"\\.\SIWDEBUG"	<-- hmm ...                                  |
:0040122F 6800304000              push 00403000

* Reference To: KERNEL32.CreateFileA, Ord:0032h	
                                  |
:00401234 E879000000              Call 004012B2

* Reference To: KERNEL32.GetLastError, Ord:0105h
                                  |
:00401239 E880000000              Call 004012BE
:0040123E 50                      push eax
:0040123F FF3511304000            push dword ptr [00403011]

* Reference To: KERNEL32.SetUnhandledExceptionFilter, Ord:026Ah
                                  |
:00401245 E880000000              Call 004012CA
:0040124A 58                      pop eax
:0040124B 83F832                  cmp eax, 00000032
:0040124E 7409                    je 00401259
:00401250 EB22                    jmp 00401274
:00401252 8B250D304000            mov esp, dword ptr [0040300D]
:00401258 C3                      ret

Jak widac odkrylismy ANTY-SI. Co to jest SIWDEBUG? Jest to vxd SoftIca.
A jak dziala to sprawdzenie. To proste. Jezeli SI jest aktywny to SIWDEBUG
jest zaladowany do pamieci i prog nie moze otworzyc kolejnej wersji. Wtedy prog
wie, ze SI jest uruchomione. Tak samo moze zrobic z vxd SICE, NTICE itd.
Jak to ominac? To takze proste. Otwieramy proga w Hex editorze i szukamy stringu
SIWDEBUG. Teraz zamieniamy go na np. POLSKAPL ;-). Wazne jest by mial tyle samo
liter co SIWDEBUG. Oczywiscie mozna przed tym anty zabezpieczyc na zawsze SI, troche
inna metoda, ale poco pozbywac sie zabawy ;-). Jezeli jestes zainteresowany ANTY-SI,
i zabezpieczeniem SI przed nimi wejdz na stone Zoomka. No i jeszcze
SetUnhandledExceptionFilter - tutaj nie jest on w roli ANTY-SI ( nie ma zadnego
przerwania ). Odpalamy wiec teraz crackme i widzimy prawie to samo co w crkme 0.
Mamy tez podana wiadomosc - 'minimum 10 chars'. Wpisujemy wiec jakis text, tylko
by mial wiecej niz 10 znakow, np. 34512678900. Wchodzimy do SI i zakladamy plapki na
text, czyli bpx GetDlgItemTextA. Po wcisnieciu F11 widzimy:

0167:0040113A  6A1E                PUSH      1E                                
0167:0040113C  6821304000          PUSH      00403021                          
0167:00401141  6A67                PUSH      67                                 
0167:00401143  FF7508              PUSH      DWORD PTR [EBP+08]                 
0167:00401146  E837010000          CALL      USER32!GetDlgItemTextA             
0167:0040114B  A31D304000          MOV       [0040301D],EAX                     
0167:00401150  85C0                TEST      EAX,EAX                            
0167:00401152  7454                JZ        004011A8                           
0167:00401154  83F80A              CMP       EAX,0A                             
0167:00401157  7C4F                JL        004011A8                           

Tutaj, co powinienes wiedziec z poprzedniego tuta, pobierany jest s/n.
Jego dlugosc zapisana jest pod [0040301D]. Dalej jest sprawdzanie
czy cos wpisalismy i czy dlugosc s/n jest wieksza lub rowna 10.

Oki, wiec dalej:

0167:00401157  7C4F                JL        004011A8                           
0167:00401159  55                  PUSH      EBP                                
0167:0040115A  57                  PUSH      EDI                                
0167:0040115B  E86B000000          CALL      004011CB            (1)   <-- hmm...             
0167:00401160  BE3C224000          MOV       ESI,0040223C        (2)              
0167:00401165  E891000000          CALL      004011FB            (3)   <-- cmp ?         
0167:0040116A  85C0                TEST      EAX,EAX             (4)               
0167:0040116C  7406                JZ        00401174            (5)               
0167:0040116E  EB24                JMP       00401194            (6)                

Ciekawy moze byc call z lini (1) wiec go odwiedzimy:

0167:004011CB  BF21304000          MOV       EDI,00403021	 (7)
0167:004011D0  57                  PUSH      EDI                 (8)               
0167:004011D1  803F00              CMP       BYTE PTR [EDI],00   (9)               
0167:004011D4  7423                JZ        004011F9  		 (10)
0167:004011D6  8B07                MOV       EAX,[EDI]           (11)               
0167:004011D8  3573456D45          XOR       EAX,456D4573        \               
0167:004011DD  C1C003              ROL       EAX,03              | kodowanie               
0167:004011E0  86C4                XCHG      AL,AH               | naszego              
0167:004011E2  3511111111          XOR       EAX,11111111        | s/n              
0167:004011E7  C1C802              ROR       EAX,02              |               
0167:004011EA  8BD8                MOV       EBX,EAX             |               
0167:004011EC  86FB                XCHG      BH,BL               |               
0167:004011EE  D1CB                ROR       EBX,1               |               
0167:004011F0  8BC3                MOV       EAX,EBX             /               
0167:004011F2  8907                MOV       [EDI],EAX           <-- podstaw pod orginal               
0167:004011F4  83C704              ADD       EDI,04              <-- nastepne 4 znaki               
0167:004011F7  EBD8                JMP       004011D1            <-- dalej               
0167:004011F9  5F                  POP       EDI                                
0167:004011FA  C3                  RET                                          

Co my tu mamy. W lini (7) do od Edi wpisywany jest offset naszego s/n.
W lini (9) sprawdzane czy esi nie jest rowne 00, a dalej jest procka
kodujaca nasz s/n. Ogolna idea tej procki polega na pobraniu 4 bajtow
z edi (11). Nastepnie te 4 znaki sa kodowane wedlug podanego algorytmy i
zapisywane w miejscu starych znakow. Instrukcja add edi,4  jest po to
by wskazywalo nanastepne znaki i dalej, zapetlenie. W algorytmie podane sa
rozne instrukcje, jezeli chcesz doglebnie wiedziec co one robia zobacz
stronke zoomka. Ja powiem tylko ze instrukcja xchg wymienia wartosci
miedzy rejestrami:

mov eax, 45
mov ebx, 60
xchg eax, ebx

Po wykonaniu tych instrukcji eax bedzie mialo wartosc 60, a ebx 45.
Dobra przechodzimy przez algorytm i wychodzimy z call'a.

0167:00401160  BE3C224000          MOV       ESI,0040223C        (2)
0167:00401165  E891000000          CALL      004011FB            (3)

Do Esi wpisywany jest offset 0040223C. Zobaczmy co tam jest:

016F:0040223C 13 46 2B 27 13 48 36 27-17 12 2C 2C 11 05 2E 63  F+'H6',,.c
016F:0040224C 11 00 26 75 7D 45 6E 74-65 72 20 6D 69 6E 69 6D   &u}Enter minim
016F:0040225C 75 6D 20 31 30 20 63 68-61 72 73 2E 2E 2E 00 55  um 10 chars....U
016F:0040226C 6E 6C 6F 61 64 20 53 6F-66 74 2D 49 63 65 20 44  nload Soft-Ice D

Dobra wchodzimy do Call'a z lini (3):

0167:004011FB  33C0                XOR       EAX,EAX           <-- zerowanie eax 
0167:004011FD  B915000000          MOV       ECX,00000015      <-- ecx == 15
0167:00401202  F3A6                REPZ CMPSB                  <-- poruwnaj Esi i Edi      
0167:00401204  7501                JNZ       00401207          <-- jesli nie rowne skacz        
0167:00401206  40                  INC       EAX               <-- eax+1=1
0167:00401207  C3                  RET                         <-- powrot

Co my tu widzimy? Do ecx wpisywane jest 15h, czyli 21d. W nastepnej instrukcji
porownywane jest 21 znakow spod rejestru edi i esi. Skad wiem, ze 21 znakow?
Mowi o tym rejestr cx. Instrukcja repz, mowi powtarzaj dana instrukcje cx razy.
A powtarza cmpsb, czyli porownuje [ESI] i [Edi]. Wiemy co mamy pod esi, ale co mamy
pod edi. Piszemy

> d edi

Tak, tak to nasz przerobiony serial. Poniewaz stringi nie byly rowne skok pod
0167:00401204 odbyl sie ( flaga Z ustawiona gdy stringi rowne ). Wychodzimy wiec
z call'a :
                
0167:0040116A  85C0                TEST      EAX,EAX             (4)               
0167:0040116C  7406                JZ        00401174            (5)               
0167:0040116E  EB24                JMP       00401194            (6)                

W naszym przypadku eax == 0, poniewarz instrukcja inc (dodaj 1) nie odbyla sie.
Z tego powodu skok z lini (5) odbedzie sie. Zgadnijcie gdzie skacze. Brawo
wygrywasz zegarek ;-), instrukcja skacze do bad boy, czyli informacji
o zlym kodzie. Co wiec zrobic by uzyskac poprawny s/n? Pomysl... Oki juz mowie.
Nasz przerobiony ( przepuszczony przez algo ) s/n musi sie rownac: F+'H6',,.c &u}.
Jakie nasuwaja sie wnioski?

1. s/n musi miec 21 znakow
2. musimy odwrocic algorytm kodujacy
3. musimy przepuscic przez odwrocone algo F+'H6',,.c &u}

Teraz jeszcze jeden raz algo:


0167:004011D6  8B07                MOV       EAX,[EDI]         <-- edi serial                 
0167:004011D8  3573456D45          XOR       EAX,456D4573                       
0167:004011DD  C1C003              ROL       EAX,03                             
0167:004011E0  86C4                XCHG      AL,AH                              
0167:004011E2  3511111111          XOR       EAX,11111111                       
0167:004011E7  C1C802              ROR       EAX,02                             
0167:004011EA  8BD8                MOV       EBX,EAX                            
0167:004011EC  86FB                XCHG      BH,BL                              
0167:004011EE  D1CB                ROR       EBX,1                              
0167:004011F0  8BC3                MOV       EAX,EBX                            
0167:004011F2  8907                MOV       [EDI],EAX                          
0167:004011F4  83C704              ADD       EDI,04                             
0167:004011F7  EBD8                JMP       _dalej 

Aby odwrocic algo nalerzy napisac instrukcje kodujace w odwrotnej kolejnosci
oraz zamienic instrukcje na ich przeciwne odpowiedniki. Oto tabelka:

 instrukcja | instrukcja przeciwna
-----------------------------------
 xor	    | 	xor
 rol	    |   ror
 xchg	    |   xchg
 shl        |   shr
 sal        |   sar
 rcl        |   rcr
 add	    |   sub
 not        |   not

Oki. Czyli algo dekodujace bedzie mialo postac:

__dalej:                             
	CMP       BYTE PTR [EDI],00    ; w edi offset  F+'H6',,.c &u}             
	JZ        __pokaz
	mov	eax,[edi]
	mov	ebx,eax
	rol	ebx,1h
	xchg	bh,bl
	mov	eax,ebx
	rol	eax,02h
	xor	eax,11111111h
	xchg	al,ah
	ror	eax,03h
	xor	eax,456D4573h
	mov	[edi],eax
	add	edi,4h
	jmp	__dalej

Poprawny s/n znajdziemy pod [edi]. Oczywiscie mozemy liczyc po 4 znaki naszego sn
recznie,ale musisz miec wtedy kalkulator z funkcjami rol, ror, xor itp. Mozesz
urzyc do tego Excalibur For Windows 32-bit ( ktory mozna sciagnac chyba z 
http://www.tiac.net/users/dber ). Ma on bardzo wiele funkcji matematycznych, ale
mi sie nie zbytnio podoba. Mozesz tez poszukac jescze innych. Najprostszym jednak
sposobem jest napisanie odpowiedniego proga, np. w Win32asm. Dodam jeszcze, ze
najlepszym sposobem jest napisanie tego stringu w postaci bajtow, np. chr($13),chr($46)
lub w asm:
tabl    db 19,70,43,39,19,72,54,39,23,18,44
	db 44,17,5,46,99,17,00,38,117,125,0

Dlaczego? Poniewa 18 znak to 00 a nie spacja jak widac w okienku danych, a i wiekszosci
znakow nie mozna uzyskac z klawiatury.

Wynikiem programu dekodujacego string jest:

	'bad boy fuck bad girL'

hmm.. Ciekawe haselko... d:)
Wpisujemy to w edit i widzimy:

	'Good Cracker - Congratulation'

.END

Je... Nastepne crackme mamy za soba. Jakby nie patrzec bylo bardzo latwe. Odwrocenie
instrukcji proga to bardzo latwa sprawa ( akurat tutaj ). Kod byl krotki i latwy.
Mam nadzieje, ze wszystko zrozumiales, jezeli nie to mailto: tymon_crk@wp.pl.
Do zobaczenia w nastepnym tutku.

.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.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