 X Ŀ B
 O ͻ P
 R  .    .Ŀ .    *    Ŀ Ŀ   . Ŀ  .    *Ŀ   .     * X
ٺ               .۳                     Ŀ
ͼ   * Ŀ    .    ۳ .    Ŀ۳    .  ڿ۳.     .  ͻ
 . Ŀ ۳  Ŀ     Ŀ.. Ŀ ۳ Ŀ Ŀ.
  ۳۳  ۳* .۳*  ۳ ۳*   ۳. ۳ 
 ٳ ۳Ŀ ڿ   Ŀ  ۳  
*. ٳ ۳۳. Ŀ ۳  ڿ..  
 ۳   . ۳  ۳۳ٳ۳   ۳۳ ۳    
        ۳ ٳ۳ .   ڿ   
 Ŀ*       .  .    *  ۳ *      Ŀ     *  ۳* 
. ۳   .                 ۳       . ۳  .     ۳ 
              .              .              ..
members:       *    .       *  members: .            *     .       members:
 *    beanus   dulek      jaro   massh    mig-21 oxcart  zetx
arakus .  coxoc   hannibal  lobix * mauzer    neo  ._r00t_  
ٺ
ͻ   .        .           *     .         .           *   ĿĿĿĿ ͼ
Ŀ official URL: http://beanus.provider.pl/     .         ٳ۳۳۳ 
 E  *     on IRC: #crackpl or #cookiecrk  *          .       C
 X ͼ M
 P  P

Cel: CrackMe #1 by Gustaw Kit (beta1)
Narzedzia: Si x.x , ProcDump x.x, Hiew x.x , disassembler

[Ogledziny]
No wiec odpalamy crackme. Nic. Czyli mamy tu do czynienia z jakas metoda anty SI (no chyba
ze w tym czasie nie masz uruchominonego Si, ale zakladam ze masz (:. No to wzucamy te crackme
do disassma. Co widzimy ? Troszke smiecia, zadnych konkretnych informacji nas interesujacych. Wyglada
to na spakowany program. 

[Sekcja]
Odpalamy ProcDumpa, Ladujemy crackm1.exe do przez Loader`a do Si (of coz Si z IceDump patch - 
ja uzywam wersji 5.17). Juz na poczatku, jeszcze przed cala procedura depakujaca program
znajdujemy pierwsze zabezpieczenie Anty-Si (kod sie troche "slizga" przy trace`ie wiec powoli 
analizujcie - heh te dyrektywy), to juz "odsloniety kod" :

xxx:00406000  55                  PUSH      EBP                               
xxx:00406001  57                  PUSH      EDI                                
xxx:00406002  56                  PUSH      ESI                                
xxx:00406003  52                  PUSH      EDX                                
xxx:00406004  51                  PUSH      ECX                                
xxx:00406005  53                  PUSH      EBX                                
xxx:00406006  66B9EB0B            MOV       CX,0BEB                            
xxx:0040600A  660D05EB            OR        AX,EB05                            
xxx:0040600E  04FC                ADD       AL,FC                              
xxx:00406010  EBFB                JMP       0040600D <-- skok, po ktorym torche sie "przesunie"                          
xxx:00406012  CC                  INT       3                                  
xxx:00406013  EBF3                JMP       00406008 <-- takie samo zachowanie co powyzej                           
xxx:00406015  33C0                XOR       EAX,EAX <-- z pod 406008 ladujemy tutaj - EB0B                           
xxx:00406017  B443                MOV       AH,43                              
xxx:00406019  CD68                INT       68                                 
xxx:0040601B  663D86F3            CMP       AX,F386                            
xxx:0040601F  7507                JNZ       00406028               < --|          
xxx:00406021  FF25E4304000        JMP       [KERNEL32!ExitProcess] <-- jak Si to po tobie         

jak widzimy int 68h we wlasnej osobie no i magiczna liczba 0F386h. Gdy dochodzimy do linii 
xxx:0040601B i zmieniamy zawratosc rejestru ax na 4300 ( r ax=4300), bo taka wartosc jest w 
rejesztstrze gdy nie ma Si w systemie (ale rownie dobze mozesz zmienic ja na inna, rozna od
0F386h). Dobra teraz dochodzimy do procki depakujacej program i skaczace do Entry Point naszego
proga.:

xxx:00406027  BBE8000000          MOV       EBX,000000E8                      
xxx:0040602C  005D8B              ADD       [EBP-75],BL          |             
xxx:0040602F  D581                AAD                            |              
xxx:00406031  ED                  IN        EAX,DX               | w tych okolicach zwnou mamy               
xxx:00406032  BC3B40002B          MOV       ESP,2B00403B         | do czynienia z dyrektywani (:             
xxx:00406037  95                  XCHG      EAX,EBP              |              
xxx:00406038  60                  PUSHAD                         |              
xxx:00406039  3C40                CMP       AL,40                              
xxx:0040603B  0083EA2D8995        ADD       [EBX+95892DEA],AL                  
xxx:00406041  693C4000019557      IMUL      EDI,[EAX*2+EAX],57950100           
xxx:00406048  3C40                CMP       AL,40                              
xxx:0040604A  0001                ADD       [ECX],AL                           
xxx:0040604C  95                  XCHG      EAX,EBP                            
xxx:0040604D  5B                  POP       EBX                                
xxx:0040604E  3C40                CMP       AL,40                              
xxx:00406050  0080BD5F3C40        ADD       [EAX+403C5FBD],AL                  
xxx:00406056  0000                ADD       [EAX],AL                           
xxx:00406058  754D                JNZ       004060A7                  
xxx:0040605A  C6855F3C400001      MOV       BYTE PTR [EBP+00403C5F],01         
xxx:00406061  8DB5683C4000        LEA       ESI,[EBP+00403C68]                 
xxx:00406067  0FB636              MOVZX     ESI,BYTE PTR [ESI]                 
xxx:0040606A  8BFD                MOV       EDI,EBP                            
xxx:0040606C  8D9D693C4000        LEA       EBX,[EBP+00403C69]                 
xxx:00406072  8B1B                MOV       EBX,[EBX]                          
xxx:00406074  8D876D3C4000        LEA       EAX,[EDI+00403C6D]                 
xxx:0040607A  8B00                MOV       EAX,[EAX]                          
xxx:0040607C  03D8                ADD       EBX,EAX                            
xxx:0040607E  8D8F713C4000        LEA       ECX,[EDI+00403C71]                 
xxx:00406084  8B09                MOV       ECX,[ECX]                          
xxx:00406086  3B9D5B3C4000        CMP       EBX,[EBP+00403C5B]                 
xxx:0040608C  7F0A                JG        00406098                           
xxx:0040608E  3B9D573C4000        CMP       EBX,[EBP+00403C57]                
xxx:00406094  7C02                JL        00406098
xxx:00406096  EB06                JMP       0040609E                          
xxx:00406098  803305              XOR       BYTE PTR [EBX],05                  
xxx:0040609B  802B01              SUB       BYTE PTR [EBX],01                  
xxx:0040609E  43                  INC       EBX                                
xxx:0040609F  E2E5                LOOP      00406086                           
xxx:004060A1  83C708              ADD       EDI,08                             
xxx:004060A4  4E                  DEC       ESI                                
xxx:004060A5  75C5                JNZ       0040606C <-- jeden raz wykonuja sie petla                          
xxx:004060A7  8B85643C4000        MOV       EAX,[EBP+00403C64]                 
xxx:004060AD  8B9D693C4000        MOV       EBX,[EBP+00403C69]                 
xxx:004060B3  03C3                ADD       EAX,EBX                            
xxx:004060B5  5B                  POP       EBX                                
xxx:004060B6  59                  POP       ECX                                
xxx:004060B7  5A                  POP       EDX                                
xxx:004060B8  5E                  POP       ESI                                
xxx:004060B9  5F                  POP       EDI                                
xxx:004060BA  5D                  POP       EBP                                
xxx:004060BB  EB02                JMP       004060BF                           
xxx:004060BD  FFE0                JMP       EAX <-- skok do EP (rozpakowanego juz programu)                                
xxx:004060BF  50                  PUSH      EAX                                
xxx:004060C0  B8EBFA0000          MOV       EAX,0000FAEB                       
xxx:004060C5  58                  POP       EAX                                
xxx:004060C6  EBF9                JMP       004060C1

Ok jestesmy 4060BD jesce jeden raz f10 i jestesmy na poczatku wlasciwego programu. Teraz 
przyda sie nam ProcDump i Bhrama Server. Wiec bedac 401000 piszemy pagein B ProcDump32 - Dumper
Server. Teraz ProcDump zapyta nas o nazwe pliku do zapisu (wiez mi lub nie, ale nazwij go tak 
samo jak oryginalny plik - pozniej sie wyjasni). Ok mamy juz rozpakowane crackme. Teraz F5 i juz
nie jestesmy w Si (anty debug byl po drodze ale o tym za chwile). Ok wylaczmy ProcDump`a. Dlaczego ?
Dlatego, ze progiie po drodze bedzie sprawdzal czy uruchomiony jest ProcDump. Na dwa sposoby zostalo
to zrealizowane :

	- znalezienie okna o nazwie odpoiwadajacej nazwie okna ProcDump`a, a pozniej wiadomo.
	  (dwie nazwy)
	- odnalezienie w pamieci pliku ProcDump32.exe 

Znajdowanie okna:

:0040107F BF63214000              mov edi, 00402163
:00401084 33C9                    xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040108E(C)
|
:00401086 803705                  xor byte ptr [edi], 05 <--- to co ponizej ""UwjfA..." kolejno
:00401089 47                      inc edi			jest xorowane przez 1,2.. do 2fh.
:0040108A 41                      inc ecx
:0040108B 83F92F                  cmp ecx, 0000002F
:0040108E 75F6                    jne 00401086

* Possible StringData Ref from Data Obj ->"UwjfAphu67%-F,%4<<=)%4<<<%B(WjH)%Ijwldk%#%Vqjk"
                                        ->"`"
                                  |
:00401090 6863214000              push 00402163 <-- wynikiem tego jest nazwa okna PD32
:00401095 6A00                    push 00000000

* Reference To: USER32.FindWindowA, Ord:0000h
                                  |
:00401097 E80A030000              Call 004013A6
:0040109C 83F800                  cmp eax, 00000000
:0040109F 7405                    je 004010A6  <-- jezeli nie ma idz dalej
:004010A1 E90C010000              jmp 004011B2 <-- cya

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040109F(C)
|

* Possible StringData Ref from Data Obj ->"UwjfAphu67%-F,%B(WjH)%Wl" 
                                  |
:004010A6 BF93214000              mov edi, 00402193 <-- nalogicznie jak wyzej
:004010AB 33C9                    xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004010B5(C)
|
:004010AD 803705                  xor byte ptr [edi], 05
:004010B0 47                      inc edi
:004010B1 41                      inc ecx
:004010B2 83F927                  cmp ecx, 00000027
:004010B5 75F6                    jne 004010AD

* Possible StringData Ref from Data Obj ->"UwjfAphu67%-F,%B(WjH)%Wl"
                                  |
:004010B7 6893214000              push 00402193 <-- troche zmieniona wersja
:004010BC 6A00                    push 00000000

* Reference To: USER32.FindWindowA, Ord:0000h
                                  |
:004010BE E8E3020000              Call 004013A6
:004010C3 83F800                  cmp eax, 00000000
:004010C6 7405                    je 004010CD  <-- idz dalej 
:004010C8 E9E5000000              jmp 004011B2 <-- cya


Odnalezienie procdump.exe :


* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004010E6(C)
|

* Possible StringData Ref from Data Obj ->"UWJFAPHU+@]@"
                                  |
:004010ED BF0F234000              mov edi, 0040230F <-- tu analogicznie jak przy znajdowaniu okna
:004010F2 33C9                    xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004010FC(C)
|
:004010F4 803705                  xor byte ptr [edi], 05
:004010F7 47                      inc edi
:004010F8 41                      inc ecx
:004010F9 83F90C                  cmp ecx, 0000000C
:004010FC 75F6                    jne 004010F4
:004010FE 6A00                    push 00000000
:00401100 6A02                    push 00000002

* Reference To: KERNEL32.CreateToolhelp32Snapshot, Ord:0000h
                                  |
:00401102 E8B1020000              Call 004013B8
:00401107 A3BB214000              mov dword ptr [004021BB], eax
:0040110C C705BF21400028010000    mov dword ptr [004021BF], 00000128
:00401116 B8BF214000              mov eax, 004021BF
:0040111B 50                      push eax
:0040111C A1BB214000              mov eax, dword ptr [004021BB]
:00401121 50                      push eax

* Reference To: KERNEL32.Process32First, Ord:0000h
                                  |
:00401122 E88B020000              Call 004013B2

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040117E(U)
|
:00401127 83F800                  cmp eax, 00000000
:0040112A 7454                    je 00401180 <-- wyjscie
:0040112C FC                      cld
:0040112D BFE3214000              mov edi, 004021E3
:00401132 B000                    mov al, 00
:00401134 B964000000              mov ecx, 00000064
:00401139 F2                      repnz
:0040113A AE                      scasb
:0040113B FD                      std
:0040113C B05C                    mov al, 5C
:0040113E B964000000              mov ecx, 00000064
:00401143 F2                      repnz
:00401144 AE                      scasb
:00401145 83C702                  add edi, 00000002
:00401148 FC                      cld
:00401149 8BF7                    mov esi, edi
:0040114B BFE7224000              mov edi, 004022E7
:00401150 B928000000              mov ecx, 00000028
:00401155 F3                      repz
:00401156 A4                      movsb
:00401157 FC                      cld

* Possible StringData Ref from Data Obj ->"UWJFAPHU+@]@"
                                  |
:00401158 BE0F234000              mov esi, 0040230F
:0040115D BFE7224000              mov edi, 004022E7
:00401162 B90D000000              mov ecx, 0000000D
:00401167 F3                      repz			<-- |
:00401168 A6                      cmpsb			<-- porownanie nazwy procesu z procdump.exe
:00401169 7502                    jne 0040116D		<-- nastepny porcess
:0040116B EB45                    jmp 004011B2		<-- cya

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401169(C)
|
:0040116D B8BF214000              mov eax, 004021BF
:00401172 50                      push eax
:00401173 A1BB214000              mov eax, dword ptr [004021BB]
:00401178 50                      push eax

* Reference To: KERNEL32.Process32Next, Ord:0000h
                                  |
:00401179 E82E020000              Call 004013AC
:0040117E EBA7                    jmp 00401127

Dobra to by bylo na tyle procdumpa. Owszem mozna inaczej ominac te metody ale nie wystarczy 
wylaczyc procdumpa ? Teraz zajmijmy sie dalszym sledzeniem kodu z pominiciem juz procedur 
odpowiedzialnych za procdump`a. A wiec zaczynamy sledzic kod od 401000 czyli EP programu. Na 
samym poczatku daja sie nam we znaki "dyrektywy" (db 0bbh:) i wywolana przez nie drobne 
zamieszanie. Heh kilka linijek ponizej 401000 ukazuje sie naszym oczom funkcja API
SetUnhandledExceptionFilter, no i jej argument (push). Zapewne gdzies w okolicy bedzie sie 
znajdowala instrukcja o kodzie mnemonicznym CC czyli int 3h. Tak. Jest pod 00401021. Odpalamy
hiewa lub inny hex edytor skaczemy do tego adresu i nopujemy - nie tylko int 3h, ale takze
wywolanie funkcji ExitProcess (szczegoly dotyczace tego rodzaju zabezpieczenia ANTY-SI mozna
znalezc w textach GustawaKita - i nie tylko). Wiec nopujemy do adresu 00401029, czyli do 
instrukcji mov esp, dword ptr [00402145] (progie powinien sie juz odpalic). Kolejne linie kodu:

:00401029 8B2545214000            mov esp, dword ptr [00402145]
:0040102F 6835104000              push 00401035
:00401034 C3                      ret


:00401035 6A00                    push 00000000
:00401037 6880000000              push 00000080
:0040103C 6A03                    push 00000003
:0040103E 6A00                    push 00000000
:00401040 6A01                    push 00000001
:00401042 6800000080              push 80000000

* Possible StringData Ref from Data Obj ->"CRACKM1.EXE"
                                  |
:00401047 6857214000              push 00402157 <-- heh nazwa crackme 

* Reference To: KERNEL32.CreateFileA, Ord:0000h
                                  |
:0040104C E885030000              Call 004013D6
:00401051 83F8FF                  cmp eax, FFFFFFFF
:00401054 7429                    je 0040107F <-- do PD
:00401056 A31C234000              mov dword ptr [0040231C], eax <-- zwrucony uchwyt programu
:0040105B 6A00                    push 00000000
:0040105D 6820234000              push 00402320 <-- gdzie
:00401062 6A54                    push 00000054 <-- ile
:00401064 6800104000              push 00401000 <-- z kad
:00401069 FF351C234000            push dword ptr [0040231C] <-- uchwyt

* Reference To: KERNEL32.ReadFile, Ord:0000h
                                  |
:0040106F E856030000              Call 004013CA
:00401074 FF351C234000            push dword ptr [0040231C]

* Reference To: KERNEL32.CloseHandle, Ord:0000h
                                  |
:0040107A E85D030000              Call 004013D

Jak widac nie nadarmo mowilem rozpakowywany plik zapisac pod oryginalna nazwa. Funkcja API
CreateFileA sprawdza czy odpalony jest CRACKME1.EXE. Jezeli 00401054 zajdzie skok to znajdziemy
sie w wyzej opisywanej procedurze sprawdzajacej obecnosc procdump`a w systemie. Jezeli jednak
plik crackme nazywa sie inaczej zostanie zakonczone jego dzialanie CloseHandle. Po drodze, w 
czasie sprawdzania obecnosci procdumpa w systemie, znajduje sie rowniez zabezpieczenie ANTY-TRW,
proste stworzenie plikow o nazwie sterownikow TRW, jezeli takowy plik juz istnieje, czyli TRW 
jest obecny w systemie to proba stworzenia takiego pliku zakonczy sie niepowodzeniem no i 
wyjsciem z crackme :

:004010CD 6A00                    push 00000000
:004010CF 6A03                    push 00000003
:004010D1 6A00                    push 00000000
:004010D3 6A00                    push 00000000
:004010D5 6A00                    push 00000000
:004010D7 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"\\.\TRW"
                                  |
:004010D9 684F214000              push 0040214F

* Reference To: KERNEL32.CreateFileA, Ord:0000h
                                  |
:004010DE E8F3020000              Call 004013D6
:004010E3 83F8FF                  cmp eax, FFFFFFFF
:004010E6 7405                    je 004010ED  <-- dalej
:004010E8 E9C5000000              jmp 004011B2 <-- cya

Teraz mozemy juz wyjsc z Si a naszym oczom ukaze sie okno dialogowe : "... CrackMe #1 by 
GustawKit (beta1)". Wpisujemy w okienku haslo (zgodnie z info doloczonym do crackme) 
skladajace sie z 12 zankow, zastawiamy puapke na HmemCpy i OK. Wychodzimy z funkcji API
GetDlgItemTextA. Wyglada to nastepujaco :

	mov	eax, offset haslo
	mov	bl, [eax]
	mov	ecx, 0CBC00000h	<-- junk!
	ror	bl, 0EBh	<-- = ror bl, 3h
	cld			<-- junk!
	add	edx, ebx
	add	ecx, 0CAC10000h <-- junk!
	or	ch, bl		<-- junk!
	add	al, 00		<-- junk!
	ror	edx, 0A
	inc	eax
	cmp	[eax], 0
	...
	...
	cmp 	edx, 81989591h
	...
	jz	good		<-- uh!
	 
Wlasciwa procedura wyglada tak:
	
	<---->
	mov	eax, offset haslo
	mov	bl, [eax]
	ror	bl, 3h
petla	add	edx, ebx
	ror	edx, 0A
	inc	eax
	cmp	[eax], 0
	...
	<---->
	cmp 	edx, 81989591h
	...
	jz	good


[Protokol]
Teraz zabiezmy sie za to zabezpieczenie. Widzimy, ze autor nie ulatwil nam sprawy (przesunecie
o 10 bitow). Sprobojmy to odwrocic. Potrzebny nam bedzie do tego schemat ilustrujacy przesmiesz-
czanie sie poszczegolnych bitow w obrebie 12 bajtowego hasla.:

x1 - znaczace mmiejsce (2 bity, ktore tak nam utrudniaja zycie)
x2 - 2 najmlodsze bity

			a1	 a2
00000000 00000000 00000000 00000000 

a1	 a2		b1	 b2
00000000 00000000 00000000 00000000

b1	 b2a1       a2  c1	 c2   
00000000 00000000 00000000 00000000

c1	 c2b1       b2a1d1     a2d2       
00000000 00000000 00000000 00000000

				 e2
d1    a2 d2c1       c2b1e1     b2a1
00000000 00000000 00000000 00000000

	 e2			 f2	
e1    b2 a1d1     a2d2c1f1     c2b1			
00000000 00000000 00000000 00000000

       	 f2	    e2		 g2	
f1    c2 b1e1     b2a1d1g1   a2d2c1 
00000000 00000000 00000000 00000000

	 g2	    f2	       e2h2	
g1  a2d2 c1f1     c2b1e1h1   b2a1d1
00000000 00000000 00000000 00000000

      e2 h2	    g2	       f2i2	
h1  b2a1 d1g1  a2 d2c1f1i1   c2b1e1
00000000 00000000 00000000 00000000

      f2 i2       e2h2         g2
i1  c2b1 e1h1  b2 a1d1g1   a2d2c1f1
00000000 00000000 00000000 00000000

....

Po krotkiej analizie tego schematu widzimy, ze pozycja danej pary bitow powtazaj sie cyklicznie.
Z tego scheamtu mozna wywnioskowac, ze 2 najmlodsze bity musza miec wartosc 0 0  przed kazdym
przesunieciem o 10 bitow. Bity z pol oznaczynych x1 po 4 przesunieciach (40 bitow) beda 
najmlodsze. Aby wyszlo nam poprawne haslo nalezy zwracac uwage na:

	- nie wolno odejmowac liczb  ktore spowoduja 'pozyczke' bitow z starszego bajtu
	  Chociaz odejmujac tak dojdziemy do 0 to po przeksztalceniu w crackme wyliczonych
	  wartosci nie otrzymamy 81989591h a inna nieznacznie rozniaca sie wartosc - ta
	  roznica spowodowana jest wlasnie tymi 'pozyczkami' ze straszego bajtu.
	- nalezy zwracac uwage jakie liczby odejmujemy tzn. Nalezy dobierac takie ktore
	  po przesunieciu (rol xx,3h) nie beda nalezaly do przedzialu L=1..1fh \ {0Fh,14h, 16h)
	  gdyz takich wartosci kodu ASCII - znakow nie da sie uzyskac z klawiatury.


Tak wiec:

0110001001 0101100100011000000110 <-- 81989591h rol 0Ah

|10 bitow| {	       Liczba	  | rol 0Ah}
-6h
0110001001 0101100100011000000000 0110001001
-9h
0101100100 0110000000000110000000 0101100100
-24h
0110000000 0001100000000101000000 0110000000
-30h
0001100000 0001010000000101010000 0001100000
-14h
0001010000 0001010100000001001100 0001010000
-50h
0001010100 0000010011000000000000 0001010100
-54
0000010011 0000000000000000000000 0000010011
-13h
0000000000 0000000000000000000000 0000000000
 
 
Wartosci: 13h, 54h, 50h, 14h, 30h, 24h, 9h, 6h =rol 3=> 98h, 0A2h, 82h, 0A0h, 81h, 21h, 48h, 30h

Nasz wynik: 98h, 0A2h, 82h, 0A0h, 81h, 21h, 48h, 30h



ASCII (Dec): 0152 0162 0130 0160 0129 033 072 048


_________________________________________________________________________________________________
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Greetz: CookieCrK & #crackpl

     _r00t_^CookieCrK

   mail:r00t@polbox.com

website: www.cookiecrk.z.pl

 

	 
  
