___________________________________________________________________________________                                                          
                    _________\          |            __________  
                   /          \      __-+-  __      |         /\ 
                  /___________/     /'( |_  )`\     |________/  \
                 |   \       /     / . \/^\/ . \            /   /
                  \   \           /  _)_`-'_(_  \          /   / 
                   \   \         /.-~   ).(   ~-.\        /   /  
                    \   \       /'     /\_/\     `\      /   /   
                     \  /     __  ___  " __"  __  _ _  \/   /    
                      \/     / _)(  ,)  (  ) / _)( ) )  \__/_    
                            ( (_  )  \  /()\( (_  )  \           
                             \__)(_)\_)(_)(_)\__)(_)\_)          
                                ___             __               
                               (  ,\o l a n d  (  )              
                                ) _/ cRACKING   )(__             
                               (_)      gROUP  (____)            
                                    ____     /\                  
                                   /  \     /  \                 
                                  /\   \   /   /                 
                                    \   \ /   /                  
                                     \___\___/                   
_______________________________________________________________________________________

                                CrackPl presents 
                            GodeZip98 cracking tutorial
_______________________________________________________________________________________

Autor:	Ptasiek
Cel:	GodeZip 98
Skad:	Enter 5/99
Czym:	SI
Efekt:	serial&keyGenerator

Wstep:
Wielu newbies crackujac progi z prostymi wrecz sztandarowymi
zabezpieczeniami zazwyczaj szuka poprawnego seriala w pamieci.
Niestety nie zawsze program jest tak uprzejmy i podaje go
nam jak na tacy w oknie danych SI. Sa tez progi, w ktorych
poprawnosc seriali sprawdza sie poprzez przeprowadzenie
na nich jakichs operacji matematycznych i operowania
wynikiem. Jeden z takich progow zostal opisany przeze
mnie wczesniej(BannerShow2). Dzis mam zaszczyt przedstawic
kolejny produkt nie generujacy poprawnego seriala.

GodeZip jest progiem do zarzadzania zzipowanymi plikami.
Posiada licznik uruchomien - limit 25. Rejestruje sie go
przez podanie nr licencji i kodu odblokowujacego.
Brzmi groznie, ale w rzeczywistosci algorytm jest 
banalny.
Uruchamiamy proga z zaladowanym SI. Przechodzimy do 
okienka rejestracyjnego i wpisujemy jakies dane:
licencja:	123123123123
kod	:	qwerty
Wchodzimy do SI (CTRL+D) i ustawiamy breakpointy na
standardowe funkcje API pobierania textu:
bpx getwindowtexta
bpx getdlgitemtexta
Wychodzimy z SI (CTRL+D) i klikamy OK. Zadzialala pulapka
na Getdlgitemtexta.
Spoko, widzimy, ze funkcja ta wywolywana jest dwa razy -
pobieraja one licencje i kod.
Idziemy dalej - krok po kroku, wchodzac do najblizszej
procedury(F8 - gdy step na instrukcji call):

* Referenced by a CALL at Addresses:
|:00402CCA   , :00402F30   
|
:004027CC 55                      push ebp
:004027CD 89E5                    mov ebp, esp
:004027CF 57                      push edi
:004027D0 56                      push esi
:004027D1 53                      push ebx
:004027D2 8B5D08                  mov ebx, dword ptr [ebp+08]
:004027D5 BE1CD34300              mov esi, 0043D31C;(nasza licencja)

* Possible StringData Ref from Code Obj ->"G1111111"
                                  |
:004027DA BF91254000              mov edi, 00402591
:004027DF B809000000              mov eax, 00000009
:004027E4 89C1                    mov ecx, eax
:004027E6 FC                      cld
:004027E7 A800                    test al, 00
:004027E9 F3                      repz
:004027EA A6                      cmpsb;porownanie jej z G1111...
:004027EB 0F843D020000            je 00402A2E;jezeli rowne to skacz

Takich porownan jest jeszcze kilka. W ten prymitywny sposob autor chcial sie 
bez watpienia zabezpieczyc przed crackerami.
No coz nie na wiele mu sie to zdalo. Idziemy dalej:

:00402825 E85AFFFFFF              call 00402784;dziwna procka - uzywa dodatkowego
;rejestru segmentowego - chyba jakis antidebug - ale nie dziala na SI 
;(moze sie myle)
:0040282A 85C0                    test eax, eax
:0040282C 0F8501020000            jne 00402A33
:00402832 803B44                  cmp byte ptr [ebx], 44;w [EBX] nasz kod, a
;konkretnie jego 1-y znak jest porownywany z 'D'
:00402835 0F94C0                  sete al;nadaj al wartosc flagi Z
;jezeli ostatnio porownywane wartosci so rowne to Z=1 w przeciwnym razie
;Z=0
:00402838 0FB6D0                  movzx edx, al
:0040283B 8B4D0C                  mov ecx, dword ptr [ebp+0C];wpisz do [ECX]
;nasza licencje
:0040283E 803947                  cmp byte ptr [ecx], 47;i porownaj 1-y znak licencji
;z 'G' dalej analogicznie jw
:00402841 0F94C0                  sete al
:00402844 25FF000000              and eax, 000000FF;EAX:=EAX AND FF
:00402849 85D0                    test eax, edx;EAX AND EDX - ale zmienia
;tylko znacznik - ww rejestry bez zmian.
:0040284B 0F84D7010000            je 00402A28;jesli Z=1 to skacz
:00402851 E82EFFFFFF              call 00402784

Spostrzezenia:
procka ta, wywolywana jest dwa razy. Prawdopodobnie ten 
drugi CALL przy starcie proga, co by znaczylo, 
ze seriale nie sa przechowywane w postaci zaszyfrowanej 
Dalej 1-y znak licencji porownywany jest z 'G', 
a 1-y kodu z 'D'
potem wykonywane jest EAX AND FF
AND jest logiczna operacja na bitach:
argument1(bit_nr_X)=1 gdy argument1(bit_nr_X)=1 oraz argument2(bit_nr_X)=1. 
W kazdym innym przypadku daje zero.
Przyklady:
0 	AND 	255	=	0
00000000	11111111	00000000
1	AND	255	=	1
00000001	11111111	00000001
128	AND	63	=
10000000	00111111	00000000
A wiec jak wynika z powyzszego numery musza sie zaczynac na 
wskazane litery.
Wyjdzmy wiec z SI i uzupelnyjmy nasze nr o te znaki - 
i wsio od poczatku
G123123123123
Dqwerty
Ok, nastepnie zaczyna sie proces sprawdzania zgodnosci 
licencji z kodem:

:00402858 0F85CA010000            jne 00402A28
:0040285E 0FBE5306                movsx edx, byte ptr [ebx+06];EDX=kod[7]
:00402862 8B4D0C                  mov ecx, dword ptr [ebp+0C]
:00402865 0FBE4101                movsx eax, byte ptr [ecx+01];EAX=licencja[2]
:00402869 83C01E                  add eax, 0000001E;EAX=EAX+1e
:0040286C 39C2                    cmp edx, eax;porownaj EAX i EDX
:0040286E 0F85B4010000            jne 00402A28;jesli rozne to skacz
:00402874 E80BFFFFFF              call 00402784;nic waznego
W tym fragmencie listingu prog bierze siodmy znak kodu i porownuje go
z drugim znakiem licencji powiekszonym o 1e. Konkretnie porownuje ich cody ASCII 
So tutaj i ponizej sa zaleznosci
wymagane przez procke, aby numery byly poprawne. Idziemy w dol zmieniajac flage
przy kazdym skoku az dojdziemy do:

:00402A15 7511                    jne 00402A28
:00402A17 E868FDFFFF              call 00402784
:00402A1C 85C0                    test eax, eax
:00402A1E 7508                    jne 00402A28
:00402A20 B801000000              mov eax, 00000001;EAX=1
:00402A25 EB0E                    jmp 00402A35;skocz do dziekczynnego messageboxa

Cala filozofia opiera sie na spisaniu wszystkich zaleznosci znakow licencji
od znakow kodu i napisac maly keyGen, aby dokonczyc dziela.
Komu nie chce sie zmudnie spisywac dzialan ten ma je spisane ponizej w zalaczonym
source keyGena.:
Generuje on licencje na podstawie kodu, a wiec Twoj nick
nie bedzie widoczny w oknie About.. Mozna opierajac sie
na tym source'u napisac odwrotna funkcje, ale jej wynikami
beda znaki ASCII spoza zakresu widzialnosci wINSHITA.
----------------------
uses crt;
var licencja,kod:string;i:byte;
begin;
licencja[1]:='D';
writeln('The GodeZip98 keyGenerator made by Ptasiek. Enjoy it!');
writeln('Polish crack rulz');
writeln('Enter string');
readln(kod);

insert('D',kod,1);
if length(kod)<16 then
for i:=length(kod)+1 to $f do kod[i]:='a';

licencja[2]:=chr(ord(kod[7])-$1e);
licencja[3]:=chr(ord(kod[6])-$17);
licencja[4]:=chr(ord(kod[3])-$1f);
licencja[5]:=chr(ord(kod[8])-$11);
licencja[6]:=chr(ord(kod[4])-$13);
licencja[7]:=chr(ord(kod[2])-$15);
licencja[8]:=chr(ord(kod[5])-$1d);
licencja[9]:=chr(ord(kod[9])-$1e);
licencja[$e]:=chr(ord(kod[$a])-$1c);
licencja[$f]:=chr(ord(kod[$b])-$18);
licencja[$c]:=chr(ord(kod[$c])-$15);
licencja[$d]:=chr(ord(kod[$d])-$16);
licencja[$b]:=chr(ord(kod[$e])-$1b);
licencja[$a]:=chr(ord(kod[$f])-$1d);
licencja[1]:='G';
clrscr;
writeln;
write('Kod      : ');
for i:=1 to $f do
begin;
write(kod[i]);
gotoxy(wherex-1,wherey-1);
write('_');
gotoxy(wherex,wherey+1);
end;
writeln;
writeln;
write('licencja : ');
for i:=1 to $f do
write(licencja[i]);
end.
--------------------
Dobra, teraz dla sprawdzenia uruchamiamy proga poraz drugi i...
Unregistered - co sie stalo - czyzby nie docenilismy autora, ktory wyposazyl
proga w opcje falszywej rejestracji - A niech sie tam cracker ucieszy.
Ale nigdzie nie wywolywana jest innna procka sprawdzajaca. Wobec tego ustalmy
gdzie przechwywany jest serial. Uruchamiamy regmona i nasz prog.
Ciekawie wyglada plik godezip.ini
Przejrzyjmy go:
(..)
licencenum=
licencekey=
(..)
Co jest?, brakuje danych. Tak jakby prog ich nie wpisal.
Chwila zastanowienia(no, moze dwie chwile)
olsnienie - setup proga polegal jedynie na skopiowaniu
plikow z CD so looknijmy w attrybuty tego pliku 
- no tak tylko_do_odczytu.
Usunmy ow attrybut i zarejestrujmy prog jeszcze raz.
Super dziala! Oto przyklad na banalne rozwiazanie
skomplikowanego z pozoru problemu. Na dzis to juz wszystko 
tradycyjnie jesli masz jakies pytania, uwagi sugestie pisz:
dreadpl@polbox.com

Ptasiek
'Someone was seeking for me. So I came'
8.05.1999
 











