Wash and Go 1.0a by Ptasiek

Cel: Wash&Go 1.0a
Skad: eNTER 4/2000
Narzedzia: SI
Skala trudnosci: [xx----]

Tak sobie siedze przed monitorem wpatrujac sie bezmyslnie w zielony pulpit winshita (mam za slabego kompa na umieszczenie tapety), maturka za miesiac, a ja nawet do podrecznika IV klasy nie zajrzalem bo nie mam. No ale nie ma co sie przejmowac na zapas jakos to bedzie, carpe diem, zyjmy chwila jak mawiali starozytni Grecy. Siedze sobie wygodnie i tak sie zastanawiam, kiedy ostatnio napisalem cosik odkrywczego dla pragnacych wiedzy crackerow. Huh, duzo w rzece wody uplynelo od czasu, gdy ostatni tut opuscil moj komp wedrujac w przesylce emailowej po zakamarkach inetu do zadnych informacji czytaczy, warto wiec sie zabrac do roboty coby nie zostawic na lodzie tych wszystkich biednych newbies czytajacych stare oklaple jush tutory i z zapamietaniem crackujacych produkty firm JZK i MarBitSoftware; dla nieobeznanych w temacie - poziom zabezpieczen w programach ww firm jest zaden, co wiecej ta druga wypuscila na rynek program z bledem uniemozliwiajacym poprawna rejestracje. sic!. Tia, kiepsko wygladaja zabezpieczenia polskiego softu przed crackowaniem. Az plakac sie chce czlowiekowi gdy widzi blyskotliwe rozwiazania zachodnich programistow, o ktore rozbijaja sie wysilki wielu pokolen reverse engineerów. Nie do pomyslenia jest fakt, ze u progu XXI wieku najczesciej spotykanym fragmentem kodu w swojskich produktach jest archaiczny bad/good boy. Polscy programisci, czy tak trudno jest poswiecic pare godzin na pobuszowanie w sieci, tam az roi sie od opisow, schematow i konkretnych przykladow zabezpieczen programowych. Inna sprawa, ze towarzysza im zazwyczaj opisy jak je zlamac, ale w koncu liczy sie szybkosc wykorzystania danej informacji.

Ups. zagalopowalem sie troche, txcior przeznaczony w zamysle do poczatkujacych crackerow zaadresowalem do "profesjonalnych" polskich programistow. Dobrze, ze znaczka nie przykleilem:).

No, to zaczynamy, naszym celem bedzie program Wash&Go 1.0a, wypatrzony na JEDYNEJ plycie kwietniowego eNTERA(4/2000). Daje slowo, ta gazeta coraz bardziej schodzi na psy, najpierw kacik dla linuxowcow (jakby nie mieli swojego czasopisma nota bene tez chyba wydawanego przez lUPUSA), teraz brak plyty i jakies badziewne papierowe dodatki do M$Office. It sux. Dobra, koncze to fuckanie, bo czuje, ze emocje w Was narastaja:)

Program sluzy do czyszczenia dysku z nadprogramowych smieci jakie serwuje nam codzien winshit, i imho gdyby doczekal sie polskiej wersji jezykowej to mialby niezle wziecie na naszym rynku. Do łamania bedziemy uzywali tylko SoftIce'a, u mnie 4.0, no i ew. jakiegos komplikatora do zrobienia keygena. Macie jush to wszystko to zaczynamy. Po odpaleniu proga pokazuje sie nam panel z opcjami, klikamy Information i pokazuje nam sie dialog z polem 'Please insert your KEY here!'. Ok, kasujemy ten napisik i wprowadzamy własny, powiedzmy '3312915' (dla tych, ktorzy za duzo pytaja jush wyjasniam - to numer telefonu na sTRAZ mIEJSKA w moim miescie). Po wpisaniu wchodzimy do SI i zastawiamy pulapki na funkcje API pobierajace txt:

bpx GetWindowTextA i bpx GetDlgItemTextA

Ok, po powrocie na powierzchnie naciskamy przycisk 'Use this key' i ladujemy po wywołaniu GetWindowTextA. Wyjdzmy z tej funkcji naciskajac F12. Hm. podejrzany jest rejestr EAX. Jak wiemy wspomniana funkcja zwraca w nim dlugosc pobranego txtu. Po kilku operacjach na kalkulatorze okazuje sie, ze dlugosc naszego s/n to 7 (slownie siedem) znakow, a wiec jestesmy w zlym miejscu choc o o dobrym czasie:) Ale nie ma co rezygnowac, czas poprostu na bron najciezszego kalibru - hmemcpy. 'Let the combat begin'

Hehe, jush widze wasze spocone twarze, rozbiegane oczy, a w nich strach przed przebijaniem sie przez gaszcz bibiotek systemowych. Spox, nie pekajcie to nie VB tutaj raz dwa wrocimy do kodu programu. A wiec kasujemy poprzednie pulapki bc* i ustawiamy nowa: bpx hmemcpy

Nie zapomnijcie przedtem wpisac seriala bo inaczej bedziecie ladowali w debuggerze za kazdym wpisanym znakiem. Jesli wszystko ok to naciskamy przycisk i... wskakujemy do wnetrza funkcji. Teraz naciskamy pare razy F12, az znajdziemy sie w programie glownym(przypominam, ze informuje o tym wyswietlanie przez SI nazwy programu pomiedzy oknem kodu a linia polecem (przy defaultowych ustawieniach of coz). Teraz patrzymy w EAX, jest 7 wiec znalezlismy sie na dobrym tropie, a konkretnie w środku procedury pobierajacej txt z okienka. Poniewaz znajdujemy sie prawie pod koniec (widac koncowe porzadki - przywracanie stosu i RET) to mozemy sobie pozwolic na odrobine fantazji czyli F12 az przestaniemy widziec koncowy fragment jakichs procedur (czyli wspomiane przeze mnie porzadki). Po tym maratonie znajdziemy sie tutaj:

0137:00449C18  MOV       EAX,[EBP-01D0];	<<lt;tutaj jestesmy
0137:00449C1E  CALL      00403BB0
0137:00449C23  CMP       EAX,06	;	dlugosc naszego sn
0137:00449C26  JLE       00449E15 	;czy mniejsza, rowna 6
0137:00449C2C  LEA       EDX,[EBP-01D0]	;jesli nie to idz dalej
0137:00449C32  MOV       EAX,[EBX+00000A50]
0137:00449C38  CALL      0041CB6C
0137:00449C3D  MOV       EDX,[EBP-01D0]
0137:00449C43  LEA       ECX,[EBP-01D4]
0137:00449C49  MOV       EAX,00449EA0	;txt WASHANDGO
0137:00449C4E  CALL      00438768	;procka rejestrujaca?
0137:00449C53  CMP       DWORD PTR [EBP-01D4],00
0137:00449C5A  JZ        00449E15    ;czy zarejestrowany?

hm. zmiana tego skoku nic nie powoduje, ale rzeczywiscie odpowiada on za stwierdzenie rejestracji, prowadzi on bezposrednio do procedury wyswietlajacej okno 'Wrong key...'. Wiemy jush, ze nasz s/n musi byc dluzszy od 6, przyjrzyjmy sie teraz procedurze spod adresu 449EA0. Jej poczatek to smieci komplilatora, ustawianie obslugi wyjatkow itp. Cos sie zaczyna dziac dopiero odtad:

0137:004387A5  MOV       BYTE PTR [EBP-21],01 ;wyglada to jak flaga
0137:004387A9  LEA       EAX,[EBP-0C]
0137:004387AC  CALL      00403934
0137:004387B1  LEA       EAX,[EBP-20]
0137:004387B4  MOV       EDX,[EBP-08]
0137:004387B7  CALL      004039CC
0137:004387BC  LEA       EAX,[EBP-21]
0137:004387BF  MOV       EDX,[EBP-20]
0137:004387C2  CALL      004385F4
0137:004387C7  MOV       EAX,[EBP-20]
0137:004387CA  CALL      00403BB0
0137:004387CF  MOV       ESI,EAX
0137:004387D1  MOV       EAX,[EBP-20]
0137:004387D4  CALL      00403BB0 ;w eax dlugosc naszego seriala
0137:004387D9  MOV       ECX,00000003
0137:004387DE  CDQ
0137:004387DF  IDIV      ECX ;dlugosc seriala/3
0137:004387E1  TEST      EDX,EDX ;czy jest reszta z dzielenia?
0137:004387E3  JNZ       00438838 ;jesli tak to skacz                             
.............
0137:00438838  MOV       BYTE PTR [EBP-21],00 ;tutaj; czyszczenie flagi
0137:0043883C  CMP       BYTE PTR [EBP-21],00 ; i jej sprawdzenie
0137:00438840  JZ        00438852 

Ok, pod adresem 4387DF nasza dlugosc jest dzielona przez 3. Wynik instrukcji IDIV to eax - wynik dzielenia calkowitego, edx - reszta z dzielenia. EDX bedzie rowne zero tylko wtedy gdy dlugosc sn podzieli sie calkowicie przez 3, czyli gdy bedzie wielkokrotnoscia trojki. Ale nie zapominajmy, ze dlugosc s/n musi byc wieksza od 6. Tak wiec wpisujemy nowy 9 znakowy sn: 331291512 i wracamy do sledzenia kodu.

0137:004387E8  CALL      00403934
0137:004387ED  LEA       EAX,[EBP-1C]
0137:004387F0  CALL      00403934
0137:004387F5  MOV       EBX,00000001
0137:004387FA  LEA       EAX,[EBP-28]
[..]
0137:00438831  INC       EBX
0137:00438832  CMP       ESI,EBX
0137:00438834  JG        004387FA    

Petla sprawdza czy s/n nie zawiera niedozwolonych znakow typu ^, ! i jesli stwierdzi ich wystapienie to zeruje flage rejestracji [EBP-21].

0137:00438842  LEA       ECX,[EBP-10]
0137:00438845  MOV       EDX,[EBP-18] ;string zawierajacy co trzeci
0137:00438848  MOV       EAX,00000015 ;znak s/n liczac od pierwszego
0137:0043884D  CALL      004386A4 ;    procka miejaca nasz s/n
0137:00438852  CMP       BYTE PTR [EBP-21],00
0137:00438856  JZ        00438868 
0137:00438858  LEA       ECX,[EBP-14]
0137:0043885B  MOV       EDX,[EBP-1C]; jw. ale liczac od trzeciego
0137:0043885E  MOV       EAX,00000007
0137:00438863  CALL      004386A4
0137:00438868  MOV       EAX,[EBP-10] ;porownanie wygenerowanych txt
0137:0043886B  MOV       EDX,[EBP-14]
0137:0043886E  CALL      00403CC0
0137:00438873  JZ        00438879                          
0137:00438875  MOV       BYTE PTR [EBP-21],00
0137:00438879  CMP       BYTE PTR [EBP-21],00
0137:0043887D  JZ        0043888A 
.............
0137:004388BE  MOV       EDX,[EBP-2C] ;porownanie I znaku I stringa
0137:004388C1  POP       EAX	;z litera 'W'
0137:004388C2  CALL      00403CC0

Ok, no to mamy jush praktycznie caly schemat, teraz warto sie przyjrzec prockom przerabiajacym oba stringi. Jak widac jest to jeden i ten sam kawalek kodu, ale pobierajacy rozne parametry 15h i 7. Wnetrze procedury , a raczej jego istotny fragment wyglada tak:

0137:004386E8  JLE       00438731                   
0137:004386EA  MOV       EBX,00000001
0137:004386EF  MOV       EAX,[EBP-10]
0137:004386F2  MOV       AL,[EBX+EAX-01] ;do al znak stringu
0137:004386F6  CMP       AL,2D
0137:004386F8  JZ        00438720                                    
0137:004386FA  MOV       EDX,[EBP-10]
0137:004386FD  MOV       EDI,EAX
0137:004386FF  AND       EDI,000000FF
0137:00438705  SUB       EDI,[EBP-04] ;znak minus 15h lub 7h
0137:00438708  CMP       EDI,30	;czy rowne 30h?
0137:0043870B  JGE       00438710 ;jesli wieksze to skacz
0137:0043870D  ADD       EDI,2B ;jesli nie to dodaj 2bh
0137:00438710  LEA       EAX,[EBP-10]
0137:00438713  CALL      00403D80
0137:00438718  MOV       EDX,EDI
0137:0043871A  MOV       [EBX+EAX-01],DL ; i zapisz nowy znak
0137:0043871E  JMP       0043872D                                    
0137:0043872D  INC       EBX
0137:0043872E  DEC       ESI
0137:0043872F  JNZ       004386EF  

Oba wygenerowane stringu sa nastepnie porownywane ze soba. Jesli beda one jednakowe, to zostana zapisane jako NAME uzytkownika (bez uwzglednienia pierwszego znaku 'W' of coz). Czyli klucz nie jest taki bezimienny jakby sie moglo wydawac na poczatku nie widzac okienka na wpisanie name. Wszystko jest jush wylozone jak na tacy, teraz tylko wystarczy sprobowac odwrocic algorytm pamietajac, ze pierwszym znakiem wygenerowanej kombinacji musi byc='W'. Ponadto warto zauwazyc, ze co trzeci znak oryginalnego seriala zaczynajac od drugiego jest nieistotny. Ok, schemat generowania znaku pierwszego stringa wyglada tak

petla:
i:=i+1
znak_s:=stringI[i]
znak_s:=znak_s-15h
jesli znak_s&lt;30h
	znak_s:=znak_s+2bh
koniec_jesli
przerobiony_string[i]:=znak_s
jesli i&lt;dlugosc
	skok petla
koniec_jesli

Zastanowmy sie jak mozna zamienic na bardziej cracker friendly:)

Rozwazmy nastepujace mozliwosci: Pojednynczy znak_s ma wzor:

znak_s:=znak_name+15h ;pierwsza kombinacja
lub
znak_s:=znak_name+15h-2bh czyli znak_s:=znak_name-16h ;druga kombinacja

                                 ZNAK
                                  II
                            druga kombinacja
                czy znak jest dopuszczalny (litera,cyfra)
               I------------------II------------------I
               I                                      I
        nie, wyszedl jakis                        tak, udalo sie
        krzaczek ASCII                                I      
        wobec tego uzywamy piewszej                   I
        kombinacji po przywroceniu znaku              I
	Przywracamy oryginalna wartosc                I
        znaku (czyli dodajemy 16h)                    I
        pierwsza kombinacja                           I
               I                                      I
               I------------------II------------------I
                        zapisz przemielony znak

To samo postepujemy z drugim stringiem pamietajac, ze parametrem zamiast 15h jest 7h. Wezmy dla przykladu name='WPTASIEK'

W(57h)-16h=41h('A')
P(50h)-16h=3Ah(':')+16h+15h=65h('e')
...
AeiVh3Z5
Drugi string:
W(57h)-24h=33h('3')
P(50h)-24h=2ch(',')+24h+7h=57h('W')
...
3W0HZPLR

Teraz sklejamy stringi wstawiajac w nieuzywane miejsca myslniki:

A-3e-Wi-0V-Hh-Z3-PZ-L5-R

No i mamy seriala. Program zapisuje g w pliku licencyjnym WASHANDGO.key w swoim katalogu. Majac tyle danych nie jest jush problemem napisanie keygena.

Niestety sposob zaproponowany przeze mnie ma pewna wade - otoz, nie uwzglednia wszystkich niedozwolonych znakow, dlatego jest lepiej ograniczyc stosowanie tego algorytmu do duzych liter i cyfr. Of coz nic nie stoi na przeszkodzie aby uzupelnic go o te brakujace elementy:)

Uff, dobrnelismy do konca (mam nadzieje, ze ktos to jeszcze czyta?) mysle, ze wszelkie wskazowki tutaj zebrane przedadza sie Wam w crackersiej karierze no i na koniec tradycyjnie za wszelkie szkody spowodowane przez wykorzystanie zawartych informacji do celow innych niz edukacyjne nie odpowiadam. To tak dla formalnosci.

3majcie sie, do nextego razu.
Ptasiek/CrackPL
ptasiek@park.px.pl