crackme Zebra by aLoNg3x/ringzer0
14 stycznia 2oo2 @ 15:57

ho,ho,ho kolejny zwierzak lezy martwy d:P

a teraz "bez owijania w bawelne" d:)
mamy dwa editboxy, do ktorych trzeba cos wpisac [coz za niespodzianka d:)]
na poczatku sadzilem, iz bedzie to kolejne zbezpieczenie name-serial, omylilem
sie jednak srogo - do obydwoch editow trzeba wpisac LICZBY! Aaaa! Dobra, 
skad to wiem? Tak podpowiada mi instynkt lowcy d:P
bpx getdlgitemtexta i lookamy:
btw., okno FPU wlacza sie komenda 'wf'

                 push    ebp          ;stack
                 mov     ebp, esp     ;frame d:)
                 sub     esp, 38h     ;38h bajtow na zmienne lokalne (?)
                 push    [ebp+arg_0]  ;pierwsza wpisana liczba
                 call    atof         ;AsciiToFloat
                 fstp    [ebp+var_8]  ;liczba float zostaje zapisana
                 push    [ebp+arg_4]  ;druga wpisana liczba
                 call    atof         ;znow AsciiToFloat
                 add     esp, 8       ;chyba fix stosu
                 fst     [ebp+var_10] ;znow sejw
                 fmul    [ebp+var_8]  ;pierwsza liczba*druga liczba
                 fldz                 ;zero na stos
                 fcompp  st(1), st    ;czy iloczyn == 0 ?
                 fnstsw  ax           ;rejestr stanu koprocka do ax 
                 sahf                 ;przenosi ah na flagi procesora
                 jnz     short loc_401379 ;iloczyn != 0 lecimy dalej
                 xor     eax, eax         ;iloczyn = 0, koniec
                 jmp     short locret_4013C8 ;bye
                 
oke, wiec obydwie liczby sa konwertowane, za pomoca atof, na floaty.
zadna z nich nie moze byc zerem.
                 
 ; 
 
 loc_401379:                             ; CODE XREF: sub_40134A+29j
                 fld     [ebp+var_8]     ;pierwsza liczba na stos
                 fcomp   [ebp+var_10]    ;porownanie z druga
                 fnstsw  ax              ;j/w
                 sahf
                 jnz     short loc_401388 ;pierwsza != druga, lecimy dalej
                 xor     eax, eax            ;bye
                 jmp     short locret_4013C8
 ; 
 
 pierwsza liczba nie moze rownac sie drugiej
 
 loc_401388:                             ; CODE XREF: sub_40134A+38j
                 fld     [ebp+var_8]     ;pierwsza na stos
                 fsin                    ;sin(pierwsza)
                 fstp    [ebp+var_28]    ;zachowaj wynik
                 fld     [ebp+var_10]    ;druga na stos
                 fsin                    ;sin(druga)
                 fstp    [ebp+var_30]    ;zachowaj wynik
                 fld     [ebp+var_28]    ;pobierz sin(pierwsza)
                 fmul    [ebp+var_30]    ;pomnoz przez sin(druga) 
                 fild    dbl_403030      ;zaladuj stala
                 fmulp   st(1), st       ;sin(x) * sin (y) * stala
                 sub     esp, 8           ;huh?
                 fstp    [esp+40h+var_40] ;wynik jest argumentem dla 
                 call    floor            ;funkcji floor
                 add     esp, 8
                 fstp    [ebp+var_38]     ;zachowaj to co wyjdzie
                 fldz                     ;zero na stos
                 fcomp   [ebp+var_38]     ;porownaj z 'to co wyszlo' d:)
                 fnstsw  ax
                 sahf
                 jnz     short loc_4013C6 ;bye
                 xor     eax, eax
                 inc     eax
                 jmp     short locret_4013C8

Jak dziala funkcja floor? Zaokragla podana liczbe do dolu, z dokladnoscia
do miejsca jednosci.

x/y - pierwsza/druga liczba
sin(x) * sin(y) * 10000000000000000 = 0.cokolwiek

'Cokolwiek' ze wzgledu wlasnie na f. floor.
Na poczatku wydawalo mi sie, ze 0.00000001 i 0.00000002 zalatwia sprawe, niestety
nie jest tak, gdyz:

0.00000001 = 9.999999999999999548e-8
0.00000002 = 1.99999999999999991e-7  

sin1 = 9.999999999999982881e-8
sin2 = 1.999999999999986576e-7
sin1*sin2 = 1.999999999999983274e-14
sin1*sin2*10000000000000000 = 199.9999999999983231
po floor = 199

199 != 0, wiec nie ma gratulacji :(. Troche pomyslalem i doszedlem do wniosku, ze
mniejszych wartosci sinusa nie bedzie miec zadna liczba wieksza od 0.0000001. 
Niestety mniejszych wartosci, np.: 0.0000000000000001 funkcja atof nie akceptuje - 
zwraca jako wynik zero. ehmmmm, jakas dziadowa ta funkcja skoro nie potrafi konwertowac
mniejszych liczb.. eehmmm, moze takie super-male wartosci przedstawia sie w inny sposob?
np. z mantysa na koncu? sprobujmy:

1.0e-18
2.0e-18

ehmmm, mialem racje d:D

Ged_/crackpl
ged@terrorysci.org
