   _________________________________________________________________________

     JAK ZLAMAC CRACKME 4 massh'a...      
                                        NAPISAL: noname/AAOCG
                                                   <76381@polbox.com>
   _________________________________________________________________________

1. Disassemblujemy program WDasmem i po krotkiej analizie listy
   importowanych funkcji zauwazamy ;-), ze program nie odczytuje
   hasla z rejestru, ani z zadnego pliku, nie ma tez oknienek dia-
   logowych.

   _________________________________________________________________________

2. Znajdujemy miejsce, w ktorym program wyswietla okienko z napisem
   "Great Work!" (o to nam przeciez chodzi ?). Skok do kodu wyswietlajacego
   okienko jest spod adresu 00401218. Procedura zawierajaca ten skok jest
   wywolywana pod 004011E0, skok do niej znajduje sie pod offsetem 004011D9,
   a znowu do tego skoku pod adresem 00401137. Procedura zawierajaca ten
   skok zaczyna sie pod adresem 0040110C (ENTER 0000, 00) i nie ma do niej
   zadnych skokow ;-)...

   _________________________________________________________________________

3. Po doglebnej(!) analizie kodu przekonujemy sie, ze jedyne odwolanie do
   adresu 0040110C jest pod offsetem 00401016. Juz na pierwszy rzut oka
   widac, ze w okolicach tego offsetu jest wypelniana jakas struktura znaj-
   dujaca sie w 00402000. Struktura ta jest pozniej podawana jako parametr
   do funkcji API RegisterClass. Czytajac opis funkcji RegisterClass
   w jakims "API reference" dowiadujemy sie, ze nasza procedura spod adresu
   0040110C to procedura obslugujaca Message'e Windowsa.

   _________________________________________________________________________

4. Ta wlasnie CALLBACK FUNCTION (0040110C) wywoluje (posrednio) procedure
   wyswietlajaca okienko gdy Message jest rowny 0x102. W pliku WINDOWS.INC
   (nie mam pojecia gdzie indziej to mozna znalesc) mozemy przeczytac, ze
   jest to WM_CHAR (przycisniecie klawisza).

   _________________________________________________________________________

5. ...a bezposrednio wywoluje ponizszy kod:

   004011C3  mov eax, dword ptr [ebp+10]      // do eax parametr czyli
                                              // wcisniety klawisz
   004011C6  movzx ecx, byte ptr [004020F5]   // do ecx, licznik
                                                 wcisnietych klawiszy
   004011CD  mov byte ptr [ecx+004020EA], al  // zapisz klawisz do 004020EA
                                                 + licznik klawiszy
   004011D3  dec byte ptr [004020F5]          // zmniejsz licznik
   004011D9  je 004011E0                      // jesli zero przejdz dalej
   004011DB  jmp 0040113D                     // jesli nie czekaj na
                                                 nastepne klawisze

   W wyniku pod adresem 004020EB mamy liste 10 wcisnietych klawiszy, ale
   w odwrotnej kolejnosci... W odwrotnej, bo licznik zmniejsza sie od 10
   do 1.

   _________________________________________________________________________

6. Pod adresem 004011E0 jest wywolanie procedury spod adresu 004011EA.

   _________________________________________________________________________

7. A pod adresem 004011EA:

004011EA  mov byte ptr [004020F5], 0A // ustaw licznik spowrotem
                                         na 10 znakow
004011F1  mov edi, 004020EB           // wcisniete znaki
004011F6  mov esi, 004020F6           // staly tekst
004011FB  movzx eax, word ptr [edi]   // do eax dwa ostatnie znaki
004011FE  not eax                     // dopelnienie dwojkowe
00401200  mov edx, dword ptr [esi]    // do edx 4 znaki "stalego tekstu"
00401202  lea ebx, dword ptr [eax+edx+10101010] // kluczowe obliczenia
00401209  dec ebx                               // tu tez
0040120A  jne 0040121C                          // jesli nie wyszlo zero
                                                   to zle haslo
0040120C  add edi, 00000002                     // kolejne dwa znaki
0040120F  add esi, 00000004                     // kolejne 4 znaki tekstu
00401212  cmp edi, 004020F5                     // juz koniec?
00401218  je 0040121D                           // jesli tak to okienko
                                                   o dobrym hasle
0040121A  jmp 004011FB                          // do poczatku

   _________________________________________________________________________

8. Powyzsza procedura zapisana w innej postaci wygladalaby:

   x - 2 litery
   y - staly tekst

      not(x) + 0x10101010 + y - 1 = 0,           a wiec:
      not(x) = -0x10101010 - y + 1,              i dalej:

          x  = not(-0x10101010 - y + 1)


   Teraz aby uzyskac dwie litery wstarczy, ze w SoftICE wpiszesz:

                                   ~(-EFF05431-10101010+1)

   _________________________________________________________________________

9. Haslo brzmi: surprised?
   Koniedz ;-)

   _________________________________________________________________________
