++++++++++++++++++++
++++++++++++++++++++
++ =-=-=-=-=-=-=- ++
++ = KMICIC^lFE = ++    
++ =-=-=-=-=-=-=- ++
++++++++++++++++++++
++++++++++++++++++++
				


                                PRESENT :



          **************************************************** 
          ****************************************************
          **                                                **
          **       Tutorial do Duelist's Crackme #2         **
          **                                                **
          ****************************************************
          ****************************************************




yo!


W tutku tym zajmiemy sie dzis drugim crackme Duelista. Posiada ono zabezpieczenie key-file. Oke jedziemy! :)

Przed odpaleniem crackme zobaczmy co tez sam autor ma nam do powiedzenia w pliku dolaczonym do crackme :) Dowiadujemy sie, ze crackme to jest bardziej trudniejsze od jedynki, ktora byla dla newbe :) Poza tym ma zabezpieczenie key-file i zeby je zlamac potrzebna nam bedzie pewna wiedza z tablicy znakow ascii. Tyle o crackme od autora ;) Teraz sami spojrzmy co tez to malenstwo kryje w sobie ;)

Skoro wiemy, ze crackme wymaga key-file to zastawiamy pulapke na createfilea i widzimy takie cos : (listing z IDY)

		
 push    0
 push    offset unk_40216F
 push    3
 push    0
 push    3
 push    0C0000000h
 push    offset aDueCm2_dat  <<-- nazwa pliku
 call    CreateFileA
 cmp     eax, 0FFFFFFFFh
 jnz     short loc_40109A

podpatrujemy offsecik i widzimy nazwe pliku : due-cm2.dat

No to w takim razie zakladamy pliczek w katalogu z crackme i cos tam do niego wpisujemy.

Teraz zalozmy bpx na readfile i znowu uruchommy crackme. Po paru F12 (az dostaniemy sie do odczytu naszego pliku) widzimy :

		
 call    ReadFile
 test    eax, eax
 jnz     short loc_4010B4    <<- jesli cos jest to skok
 jmp     short loc_4010F7    <<- wyjazd


Pod spodem jest :

       xor     ebx, ebx
       xor     esi, esi
 1.    cmp     ds:NumberOfBytesRead, 12h
 2.    jl      short loc_4010F7

1. Porownanie liczby znakow w pliku z 12h (18d)
2. Jesli mniej niz 12h to wypad

Dalej :

 1.   mov     al, ds:Buffer[ebx]
      cmp     al, 0
 2.   jz      short loc_4010D3
 3.   cmp     al, 1
 4.   jnz     short loc_4010D0
 5.   inc     esi
 6.   inc     ebx
 7.   jmp     short loc_4010C1


1. Do al ida kolejne znaki z naszego pliku
2. Jesli koniec to skok
3. Porownanie znaku z 1
4. Jesli nie to skok do punktu 6
5. Jesli byla jedynka to esi jest zwiekszane (wczesniej bylo zerowane)
6. Zwiekszenie ebx
7. Skok do punktu 1

Caly ten kod sprowadza sie do sprawdzenia czy w pliku znajduje sie znak o wartosci 1 (w tablicy Ascii) Jesli tak to esi jest zwiekszane.

Zaraz potem :

 1.   cmp     esi, 2
 2.   jl      short loc_4010F7
 3.   xor     esi, esi
      xor     ebx, ebx

1. Porownanie czy esi = 2
2. Jesli mniej to wypad
3. zerowanie esi i ebx

Czyli po tym kawalku kodu wiemy, ze w naszym pliku musza byc co najmniej dwa znaki o wartosci 1 (W ascii).

Potem jest taki kod :


 1.   mov     al, ds:Buffer[ebx]
      cmp     al, 0
 2.   jz      short loc_4010EF
 3.   cmp     al, 1
 4.   jz      short loc_4010EF
 5.   add     esi, eax
 6.   inc     ebx
 7.   jmp     short loc_4010DC
 8.   cmp     esi, 1D5h
 9.   jz      short loc_401114


1. Do al kolejne znaki z pliku
2. Jesli koniec to skok do punktu 8
3. Porownanie znaku z 1
4. Jesli rowne to skok do punktu 8
5. Dodanie znaku (al) do esi 
6. Zwiekszenie ebx
7. Skok do punktu 1
8. Porownanie esi z 1D5h
9. Jesli zero to git

Co tu sie wyrabia? Ano sa kolejno pobierane nasze znaki z pliku i sa ze soba sumowane (suma hex). Jezeli napotkany znak jest rowny 1 (ascii) to nastepuje skok do punktu 8, w ktorym nasza suma hex jest porownywana z 1D5. I tyle wlasnie ma sie rownac abysmy mogli sie dalej bawic ;)

Czyli na razie wiemy juz, ze w naszym pliku maja byc dwie jedynki (w wartosci hex). Znaki od poczatku, do pierwszej napotkanej jedynki sa sumowane. Nastepnie suma ta jest porownywana z 1D5. 

Czyli krotko mowiac suma hex znakow do pierwszej jedynki ma byc 1D5 ;)

Jest wiele kombinacji. Ja stworzylem taka :

22222222E

Krzaczek ten to nasza jedynka ;) A znaki przed nim tworza w hexach sume 1D5 :) Oke, jedziemy dalej : 

		
 1.   xor     esi, esi
 2.   inc     ebx
 3.   mov     al, ds:Buffer[ebx]
      cmp     al, 0
 4.   jz      short loc_401139
 5.   cmp     al, 1
 6.   jz      short loc_401139
 7.   cmp     esi, 0Fh
 8.   jnb     short loc_401139
 9.   xor     al, ds:Buffer[esi]
 10.  mov     ds:String[esi], eax
 11.  inc     esi
 12.  jmp     short loc_401116


1. Zerowanie esi
2. Zwiekszenie ebx
3. Do al idzie znak po naszym pierwszym krzaczku
4. Jesli koniec to skok
5. Porownanie z jedynka
6. Jesli = to skok
7. Porownanie esi z 0fh (15d)
8. Jesli nie nizej to skok
9. Xorowanie znaku po pierwszej jedynce z pierwszym (potem kolejnym) znakiem przed pierwsza jedynka ;)  
10. Umieszczenie zxorowanej wartosci na miejscu ;)
11. Zwiekszenie esi
12. Skok do punktu 2

Oke. Tak najogolniej mowiac (bo nie chce mi sie za duzo rozpisywac ;) to kolejne znaki po pierwszej jedynce sa pobierane i xorowane z kolejnymi znakami przed pierwsza jedynka. Jezeli kolejny znak to 1 (hex albo dec) to skok dalej. Coz mozna sie domyslec, ze znaki po pierwszej jedynce sa po prostu nasza ksywka ;) Czyli na moim przykladzie wyglada to tak :

  pierwsza jedynka
         |
         |
22222222EKmicic <- druga jedynka
    |       |
   ---      |
suma hex    ---- nasze znaki (ksywa)
 

Ale wykres pierdolnolem ;) Teraz tago ;)

Pierwsza literka po 1, czyli "K" jest xorowana z pierwsza litera przed 1 czyli "2" Potem analogicznie do konca ksywy czyli napotkania drugiej jedynki. Czyli "m" znowu xorowane jest z "2" itd.

No, ale z tego to nam krzaczki wyjda a nie nasza ksywa ;) Zamiast Kmicic musimy wpisac cos co po zxorowaniu da dopiero Kmicica ;)

Czyli "2" trzeba zxorowac z czyms co da nam literke "K" :) 

2^K = y

czyli 

2^y = K :)

Na razie uzyskalem taki efekt :

22222222Ey_[Q[Q

            |
            |
  moja zaxorowana ksywa ;)



Dalej mamy taki kod :


 1.   inc     ebx
 2.   xor     esi, esi
 3.   mov     al, ds:Buffer[ebx]
      cmp     al, 0
 4.   jz      short loc_40114F
 5.   cmp     al, 1
 6.   jz      short loc_40113C
 7.   add     esi, eax
 8.   inc     ebx
 9.   jmp     short loc_40113C
 10.  cmp     esi, 1B2h
 11.  jnz     short loc_4010F7


1. Zwiekszenie ebx
2. Zerowanie esi
3. do al idzie literka po drugiej jedynce
4. Jesli koniec znakow to skok do punktu 10
5. Porownanie z jedynka
6. Jesli rowne to skok do punktu 3
7. dodanie znaku (al) do esi
8. Zwiekszenie ebx
9. skok do punktu 3
10. Porownanie esi z 1B2h
11. Jesli nie rowne to wypad

Czyli ten maly kodzik mowi nam, ze suma hexadymecalna znakow po drugiej jedynce ma wynosic 1B2 :) No problem ;) Moje wartosci :

22222222"


A koncowa wartosc zawartosci pliku mam taka :

22222222Ey_[Q[Q22222222"

Wpisujemy to do pliku i od tej pory napawamy sie rozkosznym widokiem rejestracji na nasz nick (czyli Kmicic ;)


No to by bylo na tyle! :)

Pozdro
Kmicic
