Filehost.ro - gazduire fisiere
HacK32-Prima Pagina
Cauta si vei gasi ! Cere si vei primi !
Nou pe simpatie:
Nicole23
Femeie
25 ani
Bucuresti
cauta Barbat
28 - 65 ani
HacK32-Prima PaginaInregistrareLoginPozeNu sunteti logat. Lista Forumurilor Pe Tematici
HacK32-Prima Pagina / Tutorials /

Micro-tutorial despre cracking

Pagini: 1 Moderat de C8pilu'
#1
Vladu
Incepator
Postari: 3
Un micro-tutorial, pentru cei neinitiati in cracking

Este vorba de un program care trimite e-mailuri la mai multe
adrese de odata (spamming ,indeed  ), dar versiunea
neinregistrata, are o limita de 3 adrese.

Exista doua solutii la problema ta:
1) Se inregistreaza programul
2) Se patchuieste proramul ca sa trimita oricat de multe mesaje, chiar
fiind neinregistrat.

Sigur, metoda mai simpla este metoda 2. Metoda mai frumoasa si mai
utila, insa, este metoda 1 (poate mai are niste nag screenuri, care
dispar la inregistrare, etc).

Voi incerca sa descriu pe scurt metoda de inregistrare generala, care
lucreaza la 90% din programele shareware.

La crackuiala unui program (inregistrarea), planul negru de actiune
este urmatorul:
1. Se incearca inregistrarea cu un cod de inregistrare aiurea
2. Se gaseste functia care face inregistrarea in program:
2.1. Se gaseste punctul unde se citeste codul introdus
2.2. Se gaseste punctul in care se face compararea codului cu
3.1 Daca este codul corect, se inregistreaza programul cu codul
corect
3.2 Daca este un cod generat din codul nostru introdus, se
gaseste in program metoda de transformare a codului introdus
3.2.1. Se scrie o functie generala pentru efectuarea acestei
transformari
3.2.2. Se extrapoleaza functia cu parametrul , pentru a gasi
codul corect de inregistrare.

Voila, nici 4 pasi .
Ei, acesti pasi necesita ceva cunostinte si resurse: cunoasterea
limbajului de asamblare si NuMega Soft-Ice instalat. Eventual si
Borland Pascal sau C sau alt limbaj de nivel inalt, pentru a putea
scrie functia de transformare a codului (si extrapolarea), functie
care poate fi scrisa si in assembler, sau chiar in debug.exe, daca
nu ai nici un compilator prin zona. Voi incerca sa descriu pe scurt
pasii pe rand, straduindu-ma sa fiu cat mai inteles si lipsit de
aiureli si greseli .

Pasul 1:
Este clar: Vom incerca sa inregistram programul cu un cod
invalid. Deobicei, cand selectam 'Register', ne apare un dialog, unde
introducem acest cod [si numele, adresa, etc].

Pasul 2:
Pentru a gasi functia care face inregistrarea, trebuie in primul rand
sa gasim unde se afla parametrii acesteia, sau codul nostru introdus
(alti parametri, ca adresa, etc, nu ne intereseaza, sau ne intereseaza
mai tarziu, in cazul in care acestia participa in transformarea codului
nostru introdus). Dar, ca sa nu ma intind pe 100 de pagini,
sa consideram ca suntem in cazul cel mai simplu, adica programul
jertva va compara codul nostru introdus cu un cod pe care il are scris
in el, adica ceva de genul:
if cod_introdus<>cod_corect then mesaj('Dute-n dracu!') else
mesaj('Thanks for paying $500 for our program');
Ceea ce trebuie sa aflam ca if-ul acesta sa fie false, este
constanta cod_corect. Pentru a putea sa-l aflam, trebuie mai intai
sa gasim in program punctul unde se executa acest if.
Ar fi o idee grozava, daca am putea impune soft-ice-ul sa se opreasca
atunci cand se face vreo operatie cu codul nostru (ca, de exemplu, acest
if).
Pentru aceasta, in soft-ice exista notiunea de breakpoint.
Ei,aceste break-pointuri se pot pune cu o sumedenie de conditii, ca,
de exemplu, executia unei functii API, citirea sau scrierea din/in vreun
port, citirea/scrierea unei adrese din memorie, etc.

Acum, daca am sti adresa variabilei noastre (codul) in memorie, am
putea pune un breakpoint pe accesarea acestei adrese, oprindu-ne chiar
la if-ul multdorit . Asfel, problema ar fi rezolvata.
Cum aflam, insa adresa codului introdus ??? Iarasi, printr-un
breakpoint.
Si anume, vom pune un breakpoint pe functia windows de citire din
dintr-un control. In cele mai multe cazuri, aceasta se realizeaza
prin urmatoarele functii:
GetWindowTextA
GetDlgItemTextA
Iar in soft-ice, pentru a ne opri atunci cand se executa aceasta
functie, se utilizeaza comanda BPX (Breakpoint on execution):
BPX
Ei, noi nu stim care din aceste doua functii este utilizata in program,
deci,
vom pune breakpoint pe ambele. Dar cand? Pai, anume atunci cand
am introdus codul invalid in dialogul de registrare, dar inainte
de a apasa pe OK. Deci, dupa ce am scris tot ce a vrut programul in
dialogul de registrare, nu apasam OK, ci apasam Ctrl-D, pentru a intra
in softice. Aici vom scrie:
BPX GetWindowTextA
BPX GetDlgItemTextA
Cu Ctrl-D iesim din softice inapoi in proramul nostru.
Cand apasam pe OK, ne vom trezi in softice, la inceputul unei
din aceste doua functii, sa zicem, GetWindowTextA. Ce facem
mai departe?
************************************************** *********************
Sa facem o abatere si sa analizam aceasta functie. Declaratia ei in
Win32 API este urmatoarea:

int GetWindowText(int wndhandle, char *buffer, int maxstrLen);

Pentru a chema aceasta functie in C, vom folosi comanda:
result=GetWindowText(myWndHandle, *MyBuffer, 32);
Aceasta inseamna, sa ne dea textul inscris in fereastra cu
ID=myWndHandle, sa-l puna in MyBuffer si sa ia doar 32 de caractere.
Dar cum se cheama aceasta functie in assembler? Parametrii pe care
ii transmitem la functie intr-un limbaj de nivel inalt, se pun pe stack,
care
este un segment de memorie, in care se stocheaza date "una peste alta".
Adresa ultimei bucatele de date aflata pe stack, se afla in
registrul ESP (extended stack pointer). Cand executam comanda
push, procesorul decrementeaza automat valoarea acestui registru cu
marimea
operandului de la push (eg, push EAX, va pune valoarea din EAX, pe stack
la adresa SS:ESP, iar ESP=ESP-4, pentru ca registrul EAX este de 32
biti,
deci 4 bytes). Comanda POP va incrementa registrul ESP cu marimea
operandului...
Bine, sa ne intoarcem la chemarea GetWindowTextA. Pentru a chema
aceasta functie in assembler, va trebui sa executam urmatoarele
instructiuni:
Push 20 ; lungimea stringului in hexazecimal
lea eax,myBuffer ; eax = adresa myBuffer
Push eax ; punem adresa pe stack
Push dword ptr [esi+1D1] ; punem pe stack ID-ul (sau handle-ul)
ferestrei, aflat in memorie la esi+1D1h
CALL USER32!GetWindowTextA ; luam textul...

************************************************** *********************

Pasul 2.1

Acum am inteles (sper) cum este chemata functia in assembler, sa ne
intoarcem
deci in softice (unde ne-am oprit), cand suntem la inceputul functiei
GetWindowTextA, in USER32.DLL. Nu avem nevoie sa vedem cum se citeste
valoarea acesetei functii de catre Windows, deci, ca sa ne intoarcem
in programul nostru, apasand tasta F11. Acum suntem la urmatoarea
instructiune dupa CALL USER32!GetWindowTextA.
Sa examinam putin cu ce parametri a fost chemata aceasta functie
(sa vedem ce s-a pus pe stack), vom vedea ceva de genul:
Push 20 ; lungimea stringului
* Lea eax, [ebp-3C] ; Eax=ebp-3c
mov ecx, dword ptr [esi+2D] ;...
push eax ; adresa buferului
push ecx ; handle-ul...
CALL USER32!GetWindowTextA ; cheama functia..
push 00000000 ; adaoga un zero pe stack...etc
....
cu (*) am marcat punctul interesant. Acum am aflat unde este buferul
nostru, deci unde a fost
luat textul nostru: la ebp-3C.
Daca scriem comanda D EBP-3C (Display Memory at), vom vedea in fereastra
de date din softice
codul pe care l-am introdus. S-ar putea sa nu fie chiar codul, ar putea
fi numele sau adresa
pe care a mai cerut-o. In acest caz, apasam Ctrl-D pentru a ne opri la
urmatoarea chemare
a functiei GetWindowText, pana cand D EBP-3C=codul nostru.

Pasul 2.2

Acum, pentru a vedea ce face programul cu aceasta variabila, va trebuia
punem un breakpoint pe
citirile/scrierile din/in aceasta adresa de memorie. In Soft-Ice,
aceasta se face cu comanda
BPM (Breakpoint on Memory access):
BPM
In cazul nostru adresa este ebp-3c, deci vom scrie:
BPM (EBP-3C)
Apasand Ctrl-D, ne vom opri in momentul in care se manipuleaza datele de
la adresa EBP-3C, si
anume la instructiunle (de exemplu):
0234C001 DEC CX
INC EDI
INC ESI
MOV AL,Byte ptr [EDI] * ; AL=[EDI]
MOV BL,Byte ptr [ESI] ; BL=[ESI]
CMP AL,BL ; if AL<>BL then
JNZ 0234CA4D ; goto 0234CA4D
CMP CX,0 ; If CX<>0 then
JNZ 0234C001 ; goto 0234C001
....

Pentru mine aceasta inseamna urmatoarea comparatie:
again:
CX:=CX-1
EDI:=EDI+1;
ESI:=ESI+1;
If var1[EDI]<>var2[ESI] then goto abort_loop
If CX<>0 then goto again
Pentru ca SoftIce s-a oprit la *, inseamna ca codul nostru se compara cu
ceva. Ceva inseamna,
de fapt codul corect. Care se afla la adresa ESI.

Pasul 3.1.

Deci, pentru a-l vedea, este suficient sa scriem comanda:
D ESI
Scriem pe-o hartiuta codul, scoatem toate breakpointurile pe care le-am
pus:
BC * (clear breakpoint *), iesim din SoftIce, cu Ctrl-D si mai facem o
data
registrarea cu acelasi nume si adresa, dar cu codul corect.

Uite ca am si crackuit programul.

Doar ca sa ma exprim corect: Ceea ce am descris eu aici este cazul
ideal, adica metoda cea
mai simpla de protectie (care, totusi, este utilizata in 80% din
cazuri). Exista metode
foarte complicate de protectie, dar diferenta de complexitate pentru un
cracker adevarat
este doar ceva timp in plus petrecut la crackuirea programului.


 
   
Pagini: 1  
Mergi la