cracokwanie kurs u crack2



 FFFFFFFFFFFF
 HTTP://WWW.UNDERGROUND.ORG.PL FFFFFFFFFF
 ----------------------- FFFFFFFFFFF
 C R A C K FFFFFFFFFFFF
 ---------> 2 <--------- FFFFFFFFFFF
FF
Napisał: mNICH
Data : 20.10.1998
Miejsce: Bielsko-Biala

Yo! Oto moje drugie faq na temat Crackingu ;)
Tym razem zlamiemy zabezpieczenie w malutkim programiku pod
wiele mowiaca nazwa - "Crackme" (ver 1) napisanym przez Cruehead/MiB
Jesli pliczek nie jest dolaczony do faq to szukac na stronie
domowej MiB - server.kibla.org/lusers/mib/
Programik ma dosc proste zabezpieczenie nazwa/kod czyli
kod jest kalkulowany na podstawie nazwy ;).
Podstawy opisalem w czesci pierwszej wiec nie ma po co pisac
tego drugi raz. Chociaz i tak jest to napisane najprosciej jak
umialem ;).

Co bedzie potrzebne :
tylko SoftICE dla W95 no i Crackme v1.0 ;)
przyda sie tez kartka i olowek.

Jesli:
chcesz zadac pytanie/przeslac kase/masz jakies sugestie/
jestes szefem browaru/firmy computerowej to pisz na adres :
tomroy@kki.net.pl lub
tomroy@polbox.com lub
tomroy@friko6.onet.pl ;)

No wiec zaczynamy ;)

----------------------------------------------------------------------------
Na poczatek : przypuszczam ze zainstalowales S-ice'a (SoftICE).
Znasz ASM-a (hmmm...tego to chyba z tekstu nie mozna wywnioskowac ;)) ).
Masz jakiekolwiek pojecie (i tego tez nie ;) ).

1. Uruchamiamy Crackme.exe wchodzimy Help|Register wpisujemy
dowolna NAZWE ponizej dowolny SERIAL
np. ja wypelnilem te pola tak : "tomroy" i "1234567"

2. Wchodzimy do s-ice wciskajac Ctrl+D (mozna ta kombinacje zmienic)
ustawiamy Breakpoint na GetDlgItemTextA

bpx getdlgitemtexta

wychodzimy z s-ice naciskajac Ctrl+d lub F5 lub komenda x
klikamy OK, teraz s-ice powinien sie pokazac.

3. UWAGA! - przerwanie zostalo spowodowane pierwszym polem tekstowym
czyli pobraniem do pamieci NAZWY ("tomroy") nie SERIALA !
naciskamy F11 aby wrocic do programu (poniewaz aktualnie jestesmy w miejscu
skad zostala wywolana funkcja GetDlgItemTextA) - zobaczmy teraz
kilka pol wyzej od miejsca gdzie jestesmy - okno kodu przesuwamy
Ctrl+'strzalka w gore' albo myszka (po prawej stronie jest przewijanie).

PUSH 0B // nie wazne
PUSH 0040218E // WAZNE !!!
PUSH 000003E8 // nie wazne
PUSH DWORD PTR [EBP+08] // nie wazne
CALL USER32!GetDlgItemTextA // miejsce wywolania funkcji

Jestesmy teraz na jednej instrukcji ponizej wywolania funkcji.
Co to jest stos to chyba wszyscy wiemy ;).
wszystkie argumenty PUSH-y (ze tak powiem ;) ) sa argumentami wywolania
GetDlgItemTextA. "Tlumaczac" to na C++ wyglada to tak :
int GetDlgItemTextA(int dialoghandle,int controlid,char *buffer,int maxlen);
| DWORD PT... | | 000003E8 | | 0040218E | | 0B |
Interesuje nas 3 argument czyli wskaznik do jakiegos lancucha znakow.
Ten 3 argument to PUSH 0040218E !! Oczywiscie nie musisz pamietac
ktory to PUSH wystarczy ze sobie wpiszesz

d 0B //nic
d 0040218E //Wow! nasza NAZWA !
....... //dalej nie musisz sprawdzac ;)

UWAGA ! jest jeszcze takie cos : jesli nie jestes pewien
w jakim miejscu w pamieci jest aktualnie nasz SERIAL lub NAZWA
mozemy to sprawdzic tak:

s 0 L FFFFFFFFFF "3459310"

Ta komenda szuka w pamieci komorki z dana wartoscia ("3459310").
0 to poczatkowy adres , L nie ma specjalnego znaczenia ale
trzeba wpisac ;) , FFFFFFFFFF to koncowy adres (czyli przeszukiwannie
od 0 do FFFFFFFFFF) , "3459310" to wartosc ktorej szukamy - ale
uwazaj jesli twoj SERIAL jest np. taki "1234567" to S-ice
prawdopodobnie znajdzie kilka/kilkanascie/kilkadziesiat/kil...
miejsc w pamieci gdzie zawarta jest ta wartosc !!! wiec aby
znalezc ta wlasciwa daj jakis "egzotyczny" SERIAL np. taki
jaki dalem w przykladzie do komendy .

Teraz za kazdym razem gdy program bedzie chcial pobrac
nasza NAZWE odwola sie do komorki pamieci o adresie 0040218E !!
Zapisujemy sobie adres tej komorki na kartce: nazwa - 0040218E

4. Teraz naciskamy F5 (aby wyjsc s s-ice i pozwolic programowi aby
sie dalej wykonywal), pamietamy ze mamy ustawiony breakpoint
na GetDlgItemTextA i to ze program juz wczytal NAZWE. No wiec
wychodzimy i ... znowu jestesmy w s-ice, teraz przerwanie spowodowal
SERIAL (nie NAZWA). Postepujemy tak samo jak przy NAZWIE -
a) F11
b) Przechodzimy (Ctrl+strz. w gore) kilka linii w gore ... znowu
te PUSH-e ;) ...

PUSH 0B
PUSH 0040217E
PUSH 000003E9
PUSH DWORD PTR [EBP+08]
CALL USER32!GetDlgItemTextA

sprawdzamy co sie kryje za argumentem (to jest adres)
drugiego PUSH-a czyli:

d 0040217E

wow! nasz SERIAL ;)

c) zapisujemy sobie adres SERIALA na kartce
argument drugiego PUSH-a (jesli nie pamietasz ktory to
komenda ): SERIAL - 0040217E

5. No, mamy teraz dwa adresy (zapisane na kartce) gdzie przechowywane
sa nasze dane: NAZWA i SERIAL. Ustawmy sobie dwa breakpointy na odwolaniu
do pamieci - komenda :

bpm 0040218E //nazwa
bpm 0040217E //serial

Teraz za kazdym razem gdy program bedzie chcial cos zrobic z naszymi
danymi to siegnie do powyzszych adresow, a wtedy s-ice sie pojawi ;).
Mozemy juz wylaczyc breakpoint na funkcji GetDlgItemTextA :

bd 0

Nie usuwamy go komenda bo gdy sie pomylimy podczas sledzenia kodu
i bedziemy musieli od nowa wszystko robic to mozemy go
wtedy latwo wlaczyc komenda .
Zobaczmy teraz jakie mamy breakpointy komenda :

bl

Powinno nam sie pojawic takie cos:

00) * BPX USER32!GetDlgItemTextA
01) BPMB #0030:0040218E RW DR2
02) BPMB #0030:0040217E RW DR2

Tam gdzie gwiazdka to breakpoint wylaczony (nie usuniety!)

6. Wiemy juz jak mamy ustawione te breakpointy.
Teraz pozwalamy programikowi wykonywac sie (Ctrl+d lub F5)
Dlugo sie na robi, bo oto znow jestesmy w s-ice.
Patrzymy do okna komend (tam gdzie wpisujemy komendy):

Break due to BPMB #0030:0040218E RW DR2

Czyli - patrzymy na kartke z adresami - 0040218E - to przeciez
nasza NAZWA ! acha... wiec teraz program pobral nasza NAZWE
i bedzie cos z nia robil !

7. Zobaczmy teraz gdzie sie znalezlismy :

0137:00401383 MOV AL,[ESI] (1) <------|-|
0137:00401385 TEST AL,AL (2) | |
0137:00401387 JZ 0040139C (3) | |
0137:00401389 CMP AL,41 (4) | |
0137:0040138B JB 004013AC (5) | |
0137:0040138D CMP AL,5A (6) | |- petle
0137:0040138F JAE 00401394 (7) | |
0137:00401391 INC ESI (8) | |
0137:00401392 JMP 00401383 (9) <------| |
0137:00401394 CALL 004013D2 (10) |
0137:00401399 INC ESI (11) |
0137:00401391 JMP 00401383 (12) <--------|

Liczba przed dwukropkiem (0137 - segment) moze byc inna na twoim
komputerze!
Jestesmy w linijce (2), program odwolal sie do naszej NAZWY
w linijce ponad ta na ktorej jestesmy, czyli w linii nr. (1).
instrukcja (1) "wklada" bajt wskazywany przez [ESI] do nizszej
polowki rejestru AX czyli AL. Uwaga! przypomnienie : to co
sie znajduje w AL znajduje sie takze w AX czy EAX !!!
Zobaczmy wiec co kryje sie pod ESI ?

d esi

spojzcie na okno danych - co widzimy ? - nasza NAZWE ! ... tzn. ze
w ESI jest adres naszej NAZWY !
Spojzmy na powyzszy kawalek kodu jeszcze raz tyle ze calosciowo.
Mozna latwo zobaczyc ze jest to najzwyklejsza petla!
Zanim dalej bedziecie czytac sprobojcie sami zorientowac sie
co jest robione przy kazdym obiegu petli ??????
........
........
No wiec wiecie ? ... dla tych co jeszcze nie wiedza :
Linijka (2) sprawdza czy w rejestrze AL jest wartosc (w AL jest wartosc
kolejnego znaku w naszej NAZWIE - pamietamy ze adres naszej NAZWY jest
w ESI - a jak widac przy kazdym obiegu petli wartosc ESI jest
inkrementowana ( ESI:=ESI+1 ) czyli co kazdy obieg w AL jest wartosc
kolejnego znaku!) wieksza od 0 (od NULL)
Jezeli jest NULL (to znaczy koniec stringu - naszej NAZWY) petla jest
konczona i wykonywana jest nastepna instrukcja za petla.
Koniec petli powoduje skok za petle czyli linijka (3) (JZ-skok jesli zero).
No a teraz zobaczmy na instrukcje (4) ... dlaczego rejestr AL jest
porownywany z wartoscia 41 ??? heh... zobaczcie na tablice kodow ASCII
co to jest 41 ??? ... jest to kod hexadecymalny litery 'A' ! ... czyli
kazdy znak jest porownywany z litera 'A'... jezeli znak (wartosc hex)
jest mniejszy od 'A' czyli znak jest jakas cyfra albo znaczkiem (nie
litera!) programik skacze (5) (JB - skok jesli ponizej) pod adres
004013AC ... zobaczmy co jest pod tym adresem - jest tam kilka
PUSH-y i CALL jesli przejdziemy przez ten CALL (F10) to program
sie konczy i program wyswietla komunikat ze wprowadzilismy
zle haslo !. Jaki z tego wniosek ? - kazdy znak musi byc litera!
(no... kazdym znakiem "wiekszym" od 'A' ;) ).
No dobra co dalej ? ... patrzymy na linijke (6) ... ooo! znowu
AL jest porownywane z jakas wartoscia - 5A ... znowu zerkamy
do tablicy ASCII - co to jest 5A ? ... To jest 'Z' !
Co tu jest robione ? - porownywane jest AL z 5A i jesli wieksze
to skok (7) (JAE - skok gdy powyzej lub rowne) do 00401394 ...
mozemy przyjac ze skok nastapi gdy znak jest mala litera !!!
skok jest do linijki (10). Za chwilke przeanalizujemy ten CALL.
Ale teraz jeszcze co gdy warunek nie jest spelniony -
czyli znak jest duza litera.
jezeli nie spelniony to program przechodzi do linijki (8)
co tu jest robione ? -
ESI jest inkrementowane, czyli powiekszone o 1 (ESI:=ESI+1)
tzn. ze ESI pokazuje teraz na kolejny znak w naszej NAZWIE !!!.
W linijce (9) nastepuje skok do poczatku petli - i wszystko od nowa ;).
A teraz co sie dzieje jesli warunek w (7) jest spelniony
(czyli gdy aktualnie analizowany znak w NAZWIE jest mala litera)
i nastepuje
skok do (10) czyli do CALL-a.
Aby to zrozumiec musimy wejsc do wnetrza tej funkcji (wywolanej CALL-em).
Naciskamy pare razy F10 az podswietli nam sie linia z CALL-em (10).
Teraz naciskamy F8 ... i jestesmy wewnatrz funkcji !

RET //nie wazne
SUB AL,20 (13)
MOV [ESI],AL (14)
RET (15)

Powinienes sie domyslic co tu sie dzieje! ...
no wiec tak : od wartosci rejestru AL odejmowana jest wartosc 20 -
linijka (13) po co ??? ... przypuscmy ze aktualnie
analizowany znak (w AL) to 'k' (jeden ze znakow w twojej NAZWIE),
co sie stanie jesli od 'k' ('k'= 6B) odejmiemy 20
(oczywiscie 20h tzn. 20 hexadecymalnie) - 6B-20=4B a 4B='K' ,
nastepnie wartosc w AL (linijka (14)) jest podstawiana do [ESI], czyli
oryginalna wartosc tam zapisana zostaje zamieniona
wartoscia 'K' , a co bylo przedtem w [ESI] ??? ... oczywiscie
'k' ... wiec to co robi ta funkcja to zamienia wszystkie male litery
w naszej NAZWIE na duze !!!
No i (15) to wyjscie z funkcji i powrot do miejsca z kad zostala wywolana.
Po wyjsciu z funkcji jestesmy w linii (11), czyli instrukcja INC ESI -
oczywiscie inkrementuje ona ESI (ESI:=ESI+1) teraz ESI pokazuje,
na nastepny znak w naszej NAZWIE.
no i (12) to skok znowu do poczatku petli. Petla jest dotad powtarzana
dopoki ESI nie pokazuje na NULL, wiec jesli wartoscia komorki o adresie
ESI jest NULL (koniec stringu - naszej NAZWY) petla zostaje przerwana
i przenosimy sie do 0040139C (JZ 0040139C).
I tyle tlumaczenia z powodu jednej krotkiej operacji na stringu,
tzn. zamienienia kazdej litery w NAZWIE z malej na duza ;).
Uffff ! ale namieszalem ;) ... ale mam nadzieje ze zrozumiales ...
jesli nie to sie nie przejmuj tylko przeczytaj powoli jeszcze raz ;).
Ta operacja jest czesto wykorzystywana w zabezpieczeniach typu
nazwa-kod.

7. No wiec jestesmy teraz przy 0040139C.
Zobaczmy co my tu mamy:

POP ESI
CALL 004013C2

Pierwsza instrukcja sciaga ze stosu jakas wartosc i wklada ja do
ESI ... po co? ... zobacz
jaka jest instrukcja zaraz przed nasza dlugo analizowana petla
powiekszajaca litery - PUSH ESI - wiec teraz jest - POP ESI -
wiec sciagamy ze stosu adres naszej NAZWY !
Zaraz potem jest wywolywana funkcja 004013C2 - musimy
zagladnac do jej wnetrza :

0137:004013C1 RET //nie wazne
0137:004013C2 XOR EDI,EDI (16)
0137:004013C4 XOR EBX,EBX (17)
0137:004013C6 MOV BL,[ESI] (18) <---|
0137:004013C8 TEST BL,BL (19) |
0137:004013CA JZ 004013D1 (20) |- petla
0137:004013CC ADD EDI,EBX (21) |
0137:004013CE INC ESI (22) |
0137:004013CF JMP 004013C6 (23) <---|
0137:004013D1 RET (24)

hmmm... moze teraz odgadles co robi ta funkcja ;) ??? ... jak nie
to ja teraz przeanalizujemy.
Najpierw instrukcje (16) i (17) heh... powinienes wiedziec co
one robia ;). XOR jest bardzo czesto stosowana instrukcja przy
roznych zabezpieczeniach !!!. Jest to tzw. wykluczajaca sie alternatywa
... nie przerazaj sie nazwa ;) ... o co tu chodzi ? ... to jest tak :
porownywane sa bity z pierwszego operandu i drugiego jesli sa przeciwne
(1 i 0) to w wyniku bit ma wartosc 1, w przeciwnym przypadku ma 0.
Wynik zapisywany jest w operandzie pierwszym !
oto tabelka ktora pamietamy z matmy:

a | b | c
==========
1 | 1 | 0
0 | 1 | 1
1 | 0 | 1
0 | 0 | 0

No dobra ale mogles pomyslec po co sa porownywane te same rejestry ???
Odp. : w wyniku tych dwoch instrukcji zerowane sa rejestry EDI i EBX
dlaczego? pomysl ... poniewaz gdy XOR-owane sa dwa te same rejestry,
to maja one w sobie wartosci z takim samym rozstawieniem bitow !
wiec nigdy zaden wynik XOR-owania bitow nie bedzie mial wartosci 1 !!!
i w rezultacie EDI i EBX zostana wyzerowane !!!
Nastepna jest linijka (18), co robi?
wklada do BL wartosc wskazywana w ESI ... a co my mamy w ESI ???
pamietasz ze zaraz przed wywolaniem funkcji w ktorej teraz jestesmy
program sciagnal ze stosu wartosc i wlozyl ja do ESI ! na a co
bylo z kolei na stosie ??? - byl tam wskaznik do stringu z nasza
NAZWA !. Z tego wniosek - co robi instrukcja? - bierze pierwszy
znak z naszej NAZWY i wklada go do dolnej polowki rejestru EBX
czyli BL !. Linijka (19) - Tutaj sprawdzane jest czy w BL jest
jakas wartosc rozna od 0 (od NULL), jezeli nie ma to znaczy ze
jest to koniec naszej NAZWY (kazdy string konczy sie znakiem NULL !!!)
- nastepuje skok (JZ-skok jesli rowne 0) (linijka (20))
do (24), a jest to powrot do miejsca wywolania funkcji (RET).
Natomiast gdy wartosc w BL jest rozna od zera to nie nastapi
skok ! - zostanie wykonana instrukcja (21), a teraz co ona robi :
Jak pamietamy EDI i EBX zostaly wyzerowane ... teraz przy kazdym
obiegu petli do BL (dolna czesc EBX) zaladowana zostaje wartosc
kolejnego znaku z naszej NAZWY. Zmierzam do tego iz, przy
kazdym obiegu petli do wartosci trzymanej w EDI zostaje dodana
wartosc kolejnego znaku z naszej NAZWY !!! w linijce (22) inkrementowane
jest ESI (wskaznik przestawiany jest na nastepny znak), no i przez
linijke (23) petla przebiega znowu ;).
Gdy przejdziemy przez cala NAZWE to wykonywana jest instrukcja (24)
i powrot do miejsca wywolania funkcji. Co jest efektem calej
tej funkcji ??? ... to ze teraz w EDI siedzi suma wszystkich
znakow (ich wartosci hexadecymalnych) naszej NAZWY !!!!!
SHIT !!! znowu niezle namieszalem ... niestety nie jestem uzdolniony
polonistycznie ... SORRY ! ;))

8. Po tej funkcji ktora omowilem powyzej sa te oto instrukcje :

XOR EDI,00005678 (25)
MOV EAX,EDI (26)

No a co jest teraz robione ??? ...
Jak pamietamy w EDI siedzi suma wszystkich znakow naszej NAZWY
(juz po powiekszeniu wszystkich liter !!!), teraz ta suma
jest XOR-owana z wartoscia 00005678 w linijce (25), nastepnie
ta zXOR-owana wartosc idzie do EAX - linijka (26).
np. dla mojej NAZWY "tomroy", sa takie wartosci :
suma liter ("tomroy" zostal oczywiscie zamieniony na "TOMROY" !!!)
to : 000001EA natomiast po zXOR-owaniu z 00005678 w EAX mam
cos takiego : 00005792 (u ciebie zobacz w lewym gornym rogu - w oknie
rejestrow - na wartosc rejestru EAX (cos takiego - EAX=xxxxxxxx))
|------------------------------------------------------------------|
|teraz zapisz sobie ta wartosc na kartce (ta po zXOR-owaniu) !!!!! |
|------------------------------------------------------------------|
9. Tym sposobem przeszlismy przez czesc programu gdzie odbywa
sie manipulacja na NAZWIE (nie na KODZIE) heh... mysleliscie
ze to koniec ??? ooo ... to musze was rozczarowac ;))

10.Naciskamy teraz F5 lub Ctrl+d ... znowu pojawil sie s-ice
w oknie komend widzimy co spowodowalo przerwanie wykonywania programu :

Break due to BPMB #0030:0040217E RW DR2

Zerknijmy na nasza kartke z adresami : adres 0040217E to
adres w pamieci gdzie przechowywany jest nasz SERIAL !
Jak chcesz mozemy sprawdzic:

d 0040217E

Oczywiscie w oknie danych otrzymamy nasz SERIAL !
No dobra przechodzimy teraz do kolejnej analizy kodu .... hmmmm
zobaczmy gdzie sie teraz znalezlismy (UWAGA ! musimy sobie
uzmyslowic ze jestesmy teraz WEWNATRZ jakiejs funkcji !!!
wskazuje na to instrukcja RET kilka/kilkanascie linijek nizej -
bedzie nam to potrzebne do pozniejszej analizy !!! - wiec
to sobie zapamietaj !!!):

0137:004013E2 MOV AL,0A <----|
0137:004013E4 MOV BL,[ESI] |
0137:004013E6 TEST BL,BL |
0137:004013E8 JZ 004013F5 |
0137:004013EA SUB BL,30 |- petla
0137:004013ED IMUL EDI,EAX |
0137:004013F0 ADD EDI,EBX |
0137:004013F2 INC ESI |
0137:004013F3 JMP 004013E2 <----|

No, a teraz powiem wam tylko ze powyzszy kawalek kodu
zamienia nasz SERIAL z liczby dziesietnej np. moj "1234567"
na hexadecymalna (szesnastkowa) - w moim przypadku - "0012D687"
I wynik umieszcza w EDI ! ale wiecej wam nie powiem i SAMI
musicie dojsc do tego jak to jest robione ... nie bede
przeciez podawal wam wszystkiego na tacy !!! ;)).

11.To wy sie zastanawiajcie nad powyzszym kodem ... a ja
przejde no nastepnych instrukcji :

XOR EDI,00001234 (27)
MOV EBX,EDI (28)

Heh ... co my tu mamy ? ... w linijce (27) mamy XOR-owanie ...
ale czego z czym ??? ... tak, tak, zgadles ! ... w EDI mamy
przeciez wartosc hexadecymalna naszego SERIALA , a wiec
ta wartosc jest XOR-owana z taka smieszna liczba jak 00001234,
i wynik umieszczany jest z powrotem w EDI !!! No a w linijce
(28) widzimy dobrze nam znana instrukcje MOV, co ona robi ? ...
jak sie juz pewnie domysliles przenosi (kopiuje) nasz
zhexadecymalizowany (ze tak powiem ;) ) i zXOR-owany SERIAL
do rejestru EBX !!! Dla mojego SERIALA ("1234567") aktualna
wartosc w rejestrze EBX (i EDI) to 012C4B3 !!!

12.przechodzimy pare linijek dalej (F10) (UWAGA! przeszlismy
przez instrukcje RET tzn. ze wyszlismy wlasnie z funkcji !!!)
az do ujzenia ponizszego
kodu :

POP EAX (29)
CMP EAX,EBX (30)
JZ 0040124C (31)
CALL 00401362 (32)

Eh ... tym razem nie zostawie was na lodzie i razem
przeanalizujemy powyzszy kod ;). No wiec tak ...
w linijce (29) jest instrukcja sciagajaca COS ze stosu
i wkladajaca TO do EAX ... no tak, ale co my mamy na stosie ???
odp. i teraz wlasnie ma znaczenie to ze bylismy przed chwila
w funkcji - nie widzielismy tam zadnych PUSH-y !!! ...
Zobaczmy na chwile na linijki powyzej linii (29) :

PUSH EAX (a1)
PUSH 0040217E (a2)
CALL 004013D8 (a3)
ADD ESP,04 (a4)

Od razu powiem ze instrukcja (a3) to wlasnie wywolanie
tej funkcji o ktorej ostatnio tak duzo mowie !!!
w linijce (a1), to co jest w rejestrze EAX jest wkladane
na stos ... a teraz wazne pytanie co my do cholery mamy
w tym EAX ??? Odp. pamietasz jak kazalem Ci zapisac
na kartce wynik kilku operacji na naszej NAZWIE (np. dla
mnie to bylo : 00005792) ??? to wlasnie siedzi w EAX (przed
wywolaniem funkcji (a3)) ... heh ... a wiec wartosc EAX nie
zmienila sie od czasu ostatniej operacji na NAZWIE !
Bo chyba widzisz ze w tej funkcji ktora kazalem
Ci samemu przeanalizowac jest jakas operacja zwiazana z EAX.
Ta funkcja to oczywiscie (a3) (jej adres to argument CALL-a).
A wiec wiemy ze w linijce (a1) na stos jest kladziony wynik
operacji na naszej nazwie (00005792) !!! a teraz co w linijce
(a2) ??? - no pewnie wiesz czego to jest adres (argument PUSH-a)?
jesli jeszcze nie to zobacz na kartke ... albo sprawdz :

d ds:0040217E

(DS-data segment) nie musielismy pisac "ds:" ale dla pewnosci
lepiej napisac ;). Heh ... no i co wam wyszlo ... oczywiscie
nasz SERIAL ! Jak teraz wyglada stos ??

|--------------------------|
| nasz SERIAL | //1234567
|--------------------------|
| wynik operacji na NAZWIE | //00005792
|--------------------------|

Z tego wynika ze na samej gorze stosu znajduje sie nasz SERIAL !!!
No potem wywolanie funkcji (a3) (ta ktora kazalem Ci przeanalizowac) -
to juz znamy ;). A teraz co jest robione w (a4) ???
Chyba wiemy ze ESP (stack pointer) to wskaznik stosu !
przed instrukcja (a4)
ESP pokazuje na poczatek stosu (nasz SERIAL) ale po dodaniu
do niego 04, na co pokazuje ??? ... oczywiscie na wynik
operacji na NAZWIE (dla mnie - 00005792) !!!
OK. rozumiesz ? ... to przechodzimy dalej.

Przechodzimy z powrotem do analizy linijek (29)(30)(31)i(32) :
w linijce (29) jest sciagana wartosc
ze stosu i wkladana do EAX... teraz juz wiemy co sciagamy -
jest to koncowy wynik operacji na NAZWIE (00005792)
bo przeciez program przestawil ESP !!!
Natomiast linijka (30) to jakies porownanie ... ale czego
z czym ? ... juz wiemy co mamy w EAX ... a co w EBX ??? -
Zobacz na linijke (28) !!! A wiec w EBX mamy koncowy
wynik wszystkich operacji na SERIALU ! ...
podsumujmy - W rejestrze EAX mamy koncowy wynik wszystkich
operacji na NAZWIE, a w EBX mamy tez koncowy wynik tyle ze
na SERIALU, te dwie wartosci sa porownywane (30) i
jesli sa rowne to nastepuje skok (31) (JZ-skok jesli zero, instrukcja
CMP ustawia flage (bit - 1) Z, jesli argumenty sa rowne!) w
przeciwnym wypadku wykonywany jest CALL (32) ... powiedzmy
najpierw co robi ta funkcja kryjaca sie pod CALL-em - wypisuje
ona informacje ze wprowadziles zly SERIAL !!! hmmm ... zastanowmy
sie jak obejsc ten CALL .... hehe to proste wystarczy zamienic
JZ 0040124C na JNZ 0040124C albo cos podobnego ... ale nie
o to tu chodzi, poniewaz autor zastrzegl ze patche nie
sa dozwolone !!! wiec musimy odgadnac prawidlowy SERIAL
na podstawie naszej NAZWY, nie mozemy zmieniac kodu programu ;).

Jezeli EBX jest rowne EAX to
wprowadzilismy poprawny kod !!! Tzn. ze jezeli nasz SERIAL
po zamienieniu go na liczbe haxadecymalna i zXOR-owaniu go
z 00001234 - jest rowny - sumie wszystkich liter naszej NAZWY po
przeksztalceniu kazdej litery z malej na wielka, a potem
zXOR-owaniu tej sumy z liczba 00005678 - to wprowadzilismy
poprawny SERIAL !!!!!! hmmm.... to zastanowmy sie taraz
jak wyliczyc ten prawidlowy SERIAL - do tego musze przypomniec
jak dziala XOR : UWAGA! teraz uwazac ... XOR jest czesto
stosowany przez programistow do oprogramowania zabezpieczen
w programach, poniewaz cechuje go tzw. odwrotnosc tzn.
jezeli :

a XOR b = c np. a= 10011101
b= 10110000
--------
c= 00101101

to wedlug tabeli prawdy (podalem ja wczesniej) :

c XOR b = a c= 00101101
b= 10110000
--------
a= 10011101

c XOR a = b c= 00101101
a= 10011101
--------
b= 10110000

Jest to BARDZO wazna zaleznosc !!!

13.Teraz juz latwo wykalkulujemy nasz (prawidlowy) SERIAL !
Pomysl ! co musisz teraz zrobic aby otrzymac ten upragniony
SERIAL ??? ... heh ... prawidlowym SERIALEM jest ten ktory
po zamienieniu na liczbe hexadecymalna i zXOR-owaniu jej
z 00001234 da nam wynik koncowej operacji na naszej NAZWIE
(dla mnie - dla "tomroy" - 00005792) !!! czyli pamietajac
ze instrukcje XOR cechuje odwrotnosc, SERIAL mozemy
obliczyc tak: hmmm...jak by to wyjasnic - Poprostu Musimy
!----------------------------------------------------------------!
!Odwrocic operacje ktore zostaly wykonane na naszym SERIALU, !
!(tylko teraz SERIALEM prawidlowym jest 00005792 - a dokladniej !
!mowiac jest to jakby wartosc prawidlowego !
!SERIALA po wykonaniu na nim operacji !
!przeksztalcenia na liczbe HEXadecymalna i zXORowaniu z 00001234)!
!czyli najpierw odXOR-owac (wartosc 00005792) z 00001234, !
!otrzymamy hexadecymalna !
!reprezentacje prawidlowego kodu, a potem zwyczajnie zamienic !
!wynik ktory otrzymalismy na jego decymalna (dziesietna) !
!reprezentacje !!!!!!!!!!! !
!----------------------------------------------------------------!
XOR-ujemy otrzymana wartosc operacji na NAZWIE
(00005792) (EAX) z wartoscia ktora zostala zXOR-owana z
hexadecymalna reprezentacja naszego SERIALA, czyli 00001234 !!!
W S-ice robimy to tak :

? 00005792 ^ 00001234

Znaczek ^ oznacza XOR-owanie.
? - ta komenda jest uzywana do roznych celow (jest dosc przydatna)
Oczywiscie zamiast mojej wartosci - 00005792 wpisz swoja
(Ta co Ci kazalem bezwzglednie zapisac na kartce, nawet
ujalem ja w ramke, ale praktycznie to mozesz ja teraz zobaczyc
w oknie rejestrow pod rejestrem EAX=xxxxxxxx)
hmmm... co otrzymalismy (w oknie komend) ??? - takie cos :

000045A6 0000017830 "E~"
HEX DEC ASCII

Ale co nam to dalo ? ... Tam gdzie jest pod spodem HEX, to
jest prawidlowy SERIAL w postaci hexadecymalnej !!! teraz
powinnismy zamienic ta wartosc na dziesietna ale ...
S-ice zrobil juz to za nas !!! i tam gdzie mamy pod
spodem DEC to jest POPRAWNY SERIAL - Dla mnie :

|------------|
| 0000017830 |
|------------|

HURRA !!! ... mamy nasz upragniony SERIAL, teraz mozemy
opuscic zera (te 5 na poczatku), zapisac go na kartce,
wyjsc z S-ice (przedtem wylaczyc wszystkie Breakpointy),
i wpisac do pola z NAZWA - nasza NAZWE no i nasz SERIAL
wykalkulowany na podstawie NAZWY, czyli dla mnie :

tomroy i 17830

Klikamy OK ... i otrzymamy komunikat "Great work mate!"
(Swietna robota !!!) ;)) ....
hehe tzn. ze wreszcie dobrnelismy do konca ;)))))))))
Mozecie taraz isc na Pivo i oblac swoj pierwszy
zlamany program ;)).

Podsumowanie :

hmmm ... jakby sie teraz na to wszystko papatrzec to
wyglada to strasznie skomplikowanie - ale to jest
naprawde bardzo proste ... zlamanie tego programiku
zajelo mi okolo 15-20 min. - Wam jak macie opis to
wystarczy 3-4 min ;).
Co? ... Jeszcze nie jestescie przekonani, ze to bardzo proste ???
to zrobmy krotkie podsumowanie z planem :

1. Uruchamimy Crackme wpisujemy NAZWE i SERIAL
2. Wchodzimy do S-ice (Ctrl+d)
2. Ustawiamy breakpoint (bpx) na GetDlgItemTextA
3. Wychodzimy z S-ice ... OK ... i znowu jestesmy w S-ice
4. Ustawiamy breakpointy (bpm) na 0040218E i 0040217E
5. Naciskamy F5 ... ogladamy kod ... acha, program zamienia
kazda mala litere w naszej NAZWIE na duza.
6. Potem widzimy ze program sumuje kazda litere z naszej
NAZWY (jej hexadecymalny kod i to gdy jest juz duza litera!!!)
7. Ta suma jest XOR-owana z 00005678
8. Wynik tego XOR-owania idzie do EAX - ale my i tak
zapisujemy ta liczbe na kartce !
9. Potem nasz SERIAL jest zamieniany na liczbe Haxadecymalna
10. Ten hexadecymalny SERIAL jest XOR-owany z 00001234
11. Wynik XOR-owania SERIALA idzie do EBX
12. Te dwa wyniki (EAX i EBX) sa porownywane, jesli pasuja
to zanczy ze nasz SERIAL byl prawidlowy
13. Korzystajac z wlasnosci instrukcji XOR, odXOR-owujemy
to co jest w EAX z 00001234 i otrzymujemy szesnastkowa
reprezentacje poprawnego SERIALA, od razu S-ice pokazuje nam
ta wartosc jako dziesietna i ... otrzymujemy wlasciwy SERIAL !!!

I co? ... prawda ze proste ;))
Jesli jeszcze czegos nie kapujesz to znasz moj adres ... mozesz
zapytac ;).
Teraz sprobuj sciagnac CrackMe v2.0 (na stronie MiB-a)
i sproboj zarejestrowac,
ma tez bardzo proste zabezpieczenie ... tyle ze nie
nazwa/kod ale sam numer rejestracyjny, mam nadzieje
ze nie bedziesz mial zbyt duzo klopotu z tamtym
zabezpieczeniem ;))
POWODZENIA !!!

----------------------------------------------------------------------------
Linki (UWAGA! wszystkie strony po angielsku!) :

Lord Caligo - cracking.home.ml.org/ Duzy zbior roznych narzedzi
i innego crackerskiego stuffu

MiB - server.kibla.org/lusers/mib/ Kilka dobrych FAQ i
kilka dobrych programikow Crackme
wraz z rozwiazaniami

+Fravia - fravia.org/ bardzo dobra strona czlonka +HCU
bardzo duzo opisow zlaman

ASM tutorials - www.la-online.com/assembly.htm Duzo faq dotyczacych ASM-a

+Greythorne - home.sol.no/reopsahl/files/assem.htm ciekawa strona
o Crackingu i ASM

Reszte poszukaj - jest troche linkow na powyzszych stronach,
jesli znasz jakas polska strone crackerska, a moze sam zakladasz,
bo przydala by sie strona z najnowszymi narzedziami i dobrym transferem ;).
oczywiscie Mail me !!!

Wyszukiwarka

Podobne podstrony:
cracokwanie kurs musk1[1]
cracokwanie kurs u crack3
cracokwanie kurs GetRight331
cracokwanie kurs katcd
cracokwanie kurs VCLCRK
cracokwanie kurs ftpcontr
cracokwanie kurs winpopplus
cracokwanie kurs winzip70
cracokwanie kurs tutorial2
cracokwanie kurs Tiger
cracokwanie kurs janio1
cracokwanie kurs How to XARA 3D
cracokwanie kurs WINFAX
cracokwanie kurs ?Plus
cracokwanie kurs locus32
cracokwanie kurs ?lphi5

więcej podobnych podstron