
     ******************************* 
    *  CEL  : CrackMe_Newbies       *
    *  AUTOR: TEO                   *
    *  SKILL: NewBies               *
   / ******************************* \
  |-----------made by HADOR-----------|
   \*********************************/


        ---------------------------------------------------------------
	TO BEDZIE DLUUUGI I NUDNY TUT WIEC ZAMIN USIADZIESZ TO HERBATA,
	KAWA, BROWAR CZY CO CHCESZ ;-) 
        ---------------------------------------------------------------

	Uruchamiamy debuger (SI or OllyDbg) ustawiamy plapke 'bpx GetDlgItemTextA'.
	Uruchamiamy program i wpisujemy cos dlugiego (np.) '1234567890' i "OK"


	...caly kod sprawdzajacy poprawnosc hasla znajduje sie ponizej...


 /------------------------------------------------------------------------\
/--------------------------------------------------------------------------\
	    push    0FFh            		
	    push    offset String   		
	    push    64h             		
	    push    [ebp+hDlg]      		
	    call    GetDlgItemTextA
	    test    eax, eax
	    jz      bad_passwd
	    cmp     eax, 10h
	    ja      bad_passwd
	    lea     esi, ds:403008h
	    mov     edx, [esi+4]
	    xor     edx, eax
	    mov     ecx, [esi]
	    xor     ecx, eax
	    add     edx, ecx
	    neg     edx
	    imul    edx, ecx
	    bswap   edx
	    jmp     short loc_401124		;\
	    db 0CDh, 20h			;_\dummycode
loc_401124: xor     edx, 0F890A1F8h
	    jnz     short bad_passwd
	    add     ecx, edx
	    rol     ecx, 3
	    jmp     short loc_401135		;\
	    db 0CDh, 20h			;_\dummycode
loc_401135: xor     ecx, 32B4221h
	    jnz     short bad_passwd
	    add     ecx, 32B4221h
	    add     edx, 0F890A1F8h
	    sub     eax, 5
	    xor     eax, 0Bh
	    jnz     short bad_passwd
	    add     ecx, edx
	    mov     ebx, [esi+8]
	    add     ebx, ecx
	    mov     edx, [esi+0Ch]
	    add     edx, ebx
	    bswap   ebx
	    imul    ebx, edx, 2
	    jmp     short loc_401166		;\
	    db 0CDh, 20h			;_\dummycode
loc_401166: xor     ebx, 95213158h
	    jnz     short bad_passwd
	    rol     edx, 2
	    xor     edx, 0DADADADAh
	    neg     edx
	    bswap   edx
	    imul    edx, ecx, 3
	    jmp     short loc_401182            ;\
	    db 0CDh, 20h			;_\dummycode
loc_401182: xor     edx, 0F333AC4Bh
            jnz     short bad_passwd
            push    20h
            push    offset aGratulacje 		; "Gratulacje"
            push    offset aCrackmesikZost 	; "CrackMesik zostal zlamany"
	    jmp     short loc_4011A4
bad_passwd: push    10h             			
 	    push    offset aNiestety		; "Niestety"
 	    push    offset aPodalesZleHasl 	; "Podales zle haslo"
loc_4011A4: push    hWnd            			
            call    MessageBoxA
	    push    0               			
	    call    ExitProcess
	    leave
	    retn    10h
\--------------------------------------------------------------------------/
 \------------------------------------------------------------------------/


   Teraz najtrudniejsza sprawa, jak to zrobic aby sie nie narobic i aby to 
   dzialalo? No niestety trzeba pomyslec (no i odrazu wlaczyc asma do zabawy) ;]

	
   (1) Czy dlugosc(serial) jest > 16 (czyli dlugosc miedzy 0-16) to bad_passwd.
    
		call    GetDlgItemTextA
    		test    eax, eax
    		jz      bad_passwd
    		cmp     eax, 10h
    		ja      bad_passwd


   (2) Dlugosc serialu nie wieksza niz 16 znakow 
       (zalozmy, ze wynosi 16 ... najwieksza wielokrotnosc 4
        dalsza babranina to potwierdzi)

	    lea     esi, nasz_serial
	    mov     edx, [esi+4]
	    ...
	    mov     ecx, [esi]
	    ...
	    mov     ebx, [esi+8]
	    ...
	    mov     edx, [esi+0Ch]

	    
   (4) Jak juz wiemy ile znakow zacznijmy analize (brak jumpow)...

	(01)	    mov     edx, [esi+4]	; edx = [esi+4]
 	(02)	    xor     edx, eax		; edx = edx xor 16 (eax=16)
 	(03)	    mov     ecx, [esi]		; ecx = [esi]
 	(04)	    xor     ecx, eax		; ecx = ecx xor 16 (eax=16)
 	(05)	    add     edx, ecx 		; edx = edx + ecx
 	(06)	    neg     edx			; neg(edx)
 	(07)	    imul    edx, ecx		; edx = edx * ecx
 	(08)	    bswap   edx			; bswap(edx)
 	(09)	    xor     edx, 0F890A1F8h	; edx=?=0F890A1F8h --> edx=0 !!
 	(10)	    add     ecx, edx		; ecx = ecx + 0 (edx=0)
 	(11)	    rol     ecx, 3		; ecx = ecx rol 3
 	(12)        xor     ecx, 32B4221h       ; ecx=?=32B4221h --> ecx=0 !!

	(13)	    add     ecx, 32B4221h	; ecx = 32B4221h
 	(14)	    add     edx, 0F890A1F8h     ; edx = 0F890A1F8h
 	(15)	    sub     eax, 5		; eax = 16 - 5 = 11
 	(16)	    xor     eax, 0Bh		; eax = 11d xor 11h (11d = 0Bh) --> eax = 0

 	(17)	    add     ecx, edx		; ecx = ecx + edx
 	(18)	    mov     ebx, [esi+8]	; ebx = [esi+8]
 	(19)	    add     ebx, ecx		; ebx = ebx + ecx
 	(20)	    mov     edx, [esi+0Ch]	; edx = [esi+0Ch]
 	(21)	    add     edx, ebx		; edx = edx + ebx
 	(22)	    bswap   ebx			; bswap(ebx)
 	(23)	    imul    ebx, edx, 2		; ebx = edx * 2 (stara wartosc ebx zamazana)
 	(24)	    xor     ebx, 95213158h	; ebx =?= 95213158h --> ebx = 0
 	(25)	    rol     edx, 2		; edx = edx rol 2
 	(26)	    xor     edx, 0DADADADAh	; edx = edx xor 0DADADADAh
 	(27)	    neg     edx			; neg(edx)
 	(28)	    bswap   edx			; bswap(edx)
 	(29)	    imul    edx, ecx, 3		; edx = ecx * 3 (stara wartosc edx zamazana)
 	(30)        xor     edx, 0F333AC4Bh	; edx =?= 0F333AC4Bh --> edx =0


   (5) Wiedzac, ze...

	a) od (01) do (12) test na pierwsze 8 znakow
	b) od (13) do (16) kolejne potwierdzenie na ilosc znakow
	c) od (17) do (30) test na ostatnie 8 znakow.

	...umialbys to odwrocic?...

   (6) Odwracamy pierwsze 4 znaki ;)

	lea esi, serial (serial to bufor na nasze haslo)
 	
 	mov ecx, 0032B4221h        
 	ror ecx, 3			 
 	xor ecx, 16			 		
	mov [esi], ecx	 

	[esi] = "The "

   (7)	Z kolejnymi 4 znakami jest maly problem, gdyz mnozenie
        f([esi]) * g([esi+4]) przepelnia zakres liczbowy i wynik
	zostaje uciety do wielkosci edx.

	Moje rozwiazanie jest (silowe) proste ale czasochlonne (2-5 sekund:) 

	Znalezienie dowolnego ciagu znakow moze spowodowac, ze nasz serial 
	powinien zawierac znaki ktore moby byc ciazko wklepac z klawiatury.
	Dlatego, albo wzrokowo bedziemy sprawdzali czy nam to pasuje, albo
	napiszemy funkcje ktora to za nas sprawdzic (ja wybieram war I).


 	mov ecx, 0032B4221h        
 	ror ecx, 3		 ; Pierwsze 4 znaki serialu
 	;xor ecx, 16		 ;		
	;mov  [esi], ecx	 
        mov edx, ecx

	xor   ecx, ecx	 	;poczatkowy serial
@s:	push  ecx
 	xor   ecx, 16	
  	add   ecx, edx
 	neg   ecx
 	imul  ecx, edx
 	bswap ecx
 	cmp   ecx, 0F890A1F8h
	jnz   @F     
        int   3 		;<-- zatrzymanie sie jesli jest rozwiazanie
@@:     pop   ecx		;<-- pobranie kodu serialu
        loop  @s
        int 3			;<-- koniec przegladania calego zakresu
	
	Mozliwe rozwiazanie:
	- Nex[$F4]
	- Nex[$B4]
	- Nex[$74] - "Next" <-- to brzmi po ludzku (angielsku) :)
	- Nex[$34] - "Nex4"


	[esi+4] = "Next"

   (8) Sprawdzenie (kolejne) dlugosci serialu

	    sub     eax, 5
	    xor     eax, 0Bh
	    jnz     short bad_passwd


	czyli...

	    eax = 0B
	    eax = 0B(11d) + 5 = 10h (16d)
	
	czyli...

	    aby program poszedl dalej eax (dlugosc)
	    serialu powinna byc 16 !!


   (9) Ciag dalszy analizy...


	;lea esi, serial

	mov ecx, 0032B4221h	; ecx = 32B4221h
	mov edx, 0F890A1F8h 	; edx = 0F890A1F8h
	add ecx, edx		; ecx = ecx + edx

	mov ebx, 95213158h	; ebx = 95213158h
	shr ebx, 1  		; ebx = ebx / 2
	mov edx, ebx		; edx = ebx

	mov ebx, [esi+8]	; w zaleznosci jakie [esi+8]
	add ebx, ecx		    
	sub edx, ebx		; takie [esi+c] ;-)
	mov [esi+0Ch], edx	;

	
	Serial: "The Next Of sen."


	..=KONIEC=..

	Jakby cos bylo nie jasne to mail me na 'hador@programmer.net'
	Aczkolwiek, chyba jasniej juz nie mozna :]

	..=GREETING=..

	veneta
 	zenek jajko \  kiedys w koncu
	cauchy      /  znajde czas ;]
	
	all crax0rs from Bart's Forum	


----------------------------end of Tut----------------------------