|
Code
Reversing For Beginners
Rating: Medium-Hard
ProgramName: Winimage.exe
ProgramType: The Disk Image Management Utility
ProgramLocation: Here
ProgramSize: 304 KB zip
Tools Used : Softice Ver.4.01 - Win'95 Debugger, HEdit - Win'95 Hex Editor,
W32Dasm - Win'95 disassembler
Inainte de toate.
Acesta se vrea a fi primul tutorial "la obiect" aparut in e-Rohacker
,si va va da posibilitatea sa vedeti cu ce se confrunta un cracker in
"munca" lui :) so... enjoy.
Autorii programului
spun:
A disk image is a file which is an exact and complete image of a floppy
disk. The image contains information on the disk format and structure,
such as FAT, boot sector, directories, and all files. By using WinImage,
you can create an exact copy of an original disk, including non-standard
capacity and format disks. As an example, you can read a floppy disk and
copy it as one image file to your hard disk. Later, without using the
original floppy disk, you can extract any file from the image - just as
if you had copied the file from the original floppy disk itself. You can
create exact copies of the original disk onto new floppy disks.read images
created by other disk copy utilities:
Wimage (in FdFormat utility) from C.H. Hochstätter
CopyVit from Sébastien Chatard
DrDos 6
OS/2 2.x and 3.x
DCF (Disk Copy Fast) from Chang Ping Lee
DF (Disk Image File Utility) from Mark Vitt
Super-DiskCopy from Super Software
SabDu from S.A. Berman
Disk-RW from K. Hartnegg
DiskDupe from Micro System Design
and the internal Microsoft and Lotus image features and utilities along
with the MFMT sample Windows NT application that comes with the Windows
NT SDK."
Pot sa mai adaug aici ca extrage cu succes fisiere din .bin-uri facute
cu CDrWin.
Trecand peste utilitatea acestui program vreau sa va spun ca l-am gasit
interesant in ceea ce priveste sistemul de generare a parolelor.Totodata
acest program a reprezentat pentru autor o prima mare reusita in domeniul
"serial numbers",practic am deslusit dupa cum veti vedea algoritmul
generarii cheilor necesare inregistrarii.
| |
|
Despre
sistemul de protectie
|
|
|
Cum am luat cunostinta
cu programul..
In cautarile mele nocturne pe web am dat de un program pe care-l cautam
de mult timp..shi dai shi d/l din zori shi pana-n seara...Numai ca poanta
dura-i ca era in format .bin, shi pana m-am prins io ca nu-mi trebuie
CDR ..shi am sat peste acest Winimage a mai trecut o bucata de vreme...
Shi ca toate shareware-le din calc. personal i-a venit shi lu' winimage
ziua sa-i fie facut felul.Am trecut la studierea protectiei care arata
cam like this:in schimbul a 30$ sau cam asha ceva primesti o licenta shi
un cod se deblocare a celor 30 de zile cu care este motorizat in mod normal;in
schimbul a inca pe atat primesti alt cod cu care progrmul se deblocheaza
shi mai mult..:).
Cam asta era tot ceea ce aveam nevoie sa stim..adica contzine cod executabil
vegetativ...care prin diferite metode poate fi trezit la viatza.
Ar fi o gramada de metode de atac..personal prefer crack-ul de tip patch
, adica o modificare minora..1-2 biti acolo shi gata se rezolva problema.Insa
de data aceasta am hotarat sa aleg calea cea grea...descoperirea algoritmului
dupa care programatorii genereaza cheile pe care le distribuie in schimbul
unor anumite sume de bani...Trebuie sa stitzi ca aceasta cale este deosebit
de dificila uneori chiar imposibila pentru oameni ce fac acest lucru din
placere (shi io aici),astfel incat daca suntetzi chiar incepatori va recomand
sa nu va speriatzi prea mult.Experientza se castiga cu timpul lucrand
singur shi invatzand din propriile gresheli,dar shi din ale altora..bla
bla bla...
Trebuie sa recunosc ca acest tutorial depaseste scara de dificultate pe
care mi-am propus sa o promovez shi de aceea ,in cele ce urmeaza ii sfatuiesc
pe cei ce nu au cunostintzele minime ,sa o ia mai de jos ,sau sa astepte
alte cursuri mai ushoare.
Ok sa vedem ce putem
face!
Pentru inceput, ca
sa ne intzelegem in privintza SsoftIce-lui configuratzi-va sirul de initzializare
cu: wd;wr;code on;X;lines 73; wd;;code on;X;lines 73;
Start !
Problema sta in felul urmator in cazul programelor care folosesc serial
numbers:undeva adancin pantecele programului sta bine ascunsa o mica rutina
care stie sa verifice seria pe care i-o introducem.Este ca o masina pe
care incercam s-o furam,nu avem cheia dar putem s-i facem alimentarea
cu curent rupand firele sub bord sau daca avem mult timp la dispozitie
putem chiar fabrica o cheie.Stiind aceste lucruri nu ne ramane decat sa
intram in program , sa identificam acea rutina si fie sa o carpim sa faca
lucruri ce nu le-ar face in mod normal,fie sa incercam sa decoperim modul
cum lucreaza.
Programul nu este impachetat acest lucru fiind de bun augur pentru incepatori
,caci personal tot am pirdut ceva timp pana am fost sigur de acest lucru.
So:
Start;
Porniti programul;
Din meniu ..Option..Registering;
Aveti in fata o casutza
de dialog cu 2 campuri de editare.Incercati sa introduceti un nume oarecare
si o serie la intamplare, apoi datzi Ok. Bang..."Registering information
is invalid".
Asta e de bine (vorbesc de mesajul acesta).El reprezinta legatura programului
(interactiunea cu OS-ul).Ce se intampla de fapt:Windozele este conceput
pe module..el contzine portziuni de executabi prestabilite ,(cum ar fi
ferestrele,o gramada de functzii,etc,)in asha zisele ddl-uri.
Cand un program are nevoie de o fereastra el apeleaza printr-o functzie
o anumita rutina dintr-un astfel de dll ,transmitzandu-i nishte parametrii(dimensiunea
ferestrei,numarul de butoane,culoarea fundalului,etc.)Din SoftIce putem
intercepta aceste functii,shi daca avem norocalegandu-ne-o convenabil
putem fi chiar in apropierea rutinei noastre care face verificarea serieal-ului.
Am ales dupa mai multe incercari sa folosesc BPX hmemcpy , ceea ce se
traduce pauza in executzia functiei hmemcpy.
Deci cum se procedeaza:
Introduceti la name:
crisco
registration code:111111
Ctrl+D zbang apare SoftIcele
la linia de comanda se bate :BPX hmemcpy
atentie trebuie sa avetzi la module incarcate User32.dll shi Kernel32.dll
acest lucru il putetzi face manual editand liniile urmatoare in winice.dat:
EXP=c:\WINDOWS\SYSTEM\USER32.DLL
EXP=c:\WINDOWS\SYSTEM\KERNEL32.DLL
daca nu primitzi nici
o error totul e oki shi punctul a fost acceptat.
tastati F5 pentru a parasi SoftIce-le
apasati Ok pentru inregistrare
ar trebui acum sa fitzi iar in SoftIce...
In
acest moment suntem in kernel!hmemcpy shi trebuie sa tastati F12 de 9
ori pentru a reveni la programul nostru. In fereastra cu codul (tastati
wc o
data shi dispare,shi inca o data ca sa apara, sa vedeti care este) pe
linia inferioara este scrisa zona de care apartine codul executabil. Dupa
al 9-lea F12 pe linie trebuie sa scrie: WINIMAGE
text+002E08D
Trebuie
sa vedeti ceva de genul:
:0042F08F BF183D4400
mov edi, 00443D18 <---aici
dupa 9 ori F12
:0042F08D FFD6
call esi
* Possible Ref to Menu:
WINIMAGMENU, Item: "Create directory..."
|
:0042F094 6A7F
push 0000007F
:0042F096 57
push edi
Trebuie sa intzelegetzi
un lucru..oricat de incalcit ar fi programul..dupa o instructiune Call
intotdeauana trebuie sa iesim tot sub ia;Exemplu :la adresa 42F08D
avem un call ,este
apelata o rutina oarecare la sfarsitul careia exista o instructiune ret
care ne aduce chiar sub call-ul din care
am plecat..in cazul nostru la 0042F08D.
Acestea
fiind spuse punem un bpx
42F08F
tastam apoi bd0
in SoftIce anuland astfel primul bpx care
altfel ar deveni foarte suparator.Procedam apoi ca mai inainte..introducem
iarashi numele shi seria numai ca de aceasta data nu mai intram in SoftIce
pentru a pune BPX hmemcpy caci
tcmai am activat un alt bpx.Cand dam Ok suntem iar in SI.
Putina
teorie Ce s-a intamplat: programul inca nu s-a folosit de rutina,de
noi cautata,pentru a verifica validitatea seriei introduse,deci noi suntem
undeva deasupra acestei rutine; nu avem nimic altceva de facut decat sa
urmam cursul programului ,shi sa incercam sa depistam pe unde se intampla
lucrurile interesante.Call-ul acesta din care tocmai ne-am intors nu face
altceva decat sa citeasca datele introduse de noi in casuta de editare.
De acest lucru va puteti usor convinge tastand debx
in SoftIce imediat dupa ce treceti
de call cu executia programului shi observand continutul registrului ebx
in fereastra wd ;
Cred
ca ati observat deja name:crisco.
Urmarim
evolutia programului pas cu pas tastand F10...
:0042F097 6817080000
push 00000817
:0042F09C FF7508
push [ebp+08]
:0042F09F FFD6
call esi <-----aici se
face citirea parolei false
:0042F0A1 68E8404400
push 004440E8
.......................................
in acest moment tastati d edi shi
veti vedea in wd registration code-ul nostru 111111
:0042F0A6 57
push edi
:0042F0A7 53
push ebx
:0042F0A8 E81C570000 call
004347C9 <-aici vom continua sapaturile
Intrucat la primul
call ce urmeaza acestuia mesajul ca parola e falsa aparea am hotarat sa
intru in acest penultim call ,cel de la adresa: 42F0A8.
Drept
urmare la trecerea peste aceasta linie apasati F8 pentru a intra in acest
Call;urmariti continuarea offsetului corespunzatoare call-ului:
:004347C9
55 push
ebp <-aici vine callul de mai sus
:004347CA 8BEC
mov ebp, esp
:004347CC 81EC00020000 sub
esp, 00000200
:004347D2 56 push
esi
:004347D3 8B7510 mov
esi, dword ptr [ebp+10]
:004347D6 85F6
test esi, esi
:004347D8 57
push edi
:004347D9 7403
je 004347DE
:004347DB 832600 and
dword ptr [esi], 00000000
:004347DE FF750C push
[ebp+0C]
:004347E1 8D8500FFFFFF lea eax,
dword ptr [ebp+FFFFFF00]
:004347E7 50 push
eax <aici in debx e numele si in dedx parola
falsa
:004347E8 E8E0FEFFFF call
004346CD<litere
mari pentru parola falsa
:004347ED FF7508 push
[ebp+08]<deja aici sunt litere mari
Primul lucru interesant
de la intrarea in aceasta rutina se petrece abia la 4347E8 unde este apelata
o rutina ce va transforma literele mici in litere mari:Iata aceasta rutina
(nu
este nevoie sa intrati aici ci doar sa urmariti ce se intampla) asa ca
press F10.
:004346CD 8B442408
mov eax, dword ptr [esp+08]
--[eax] contine ceva de tipul 31313131 sau numele veti vedea mai tarziu...
:004346D1 803820
cmp byte ptr [eax], 20
--verifica primul caracter daca nu cumva e spatiu
:004346D4 7503
jne 004346D9<--sare daca nu este spatiu
la D9
:004346D6 40
inc eax
:004346D7 EBF8
jmp 004346D1
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|
:004346D9 50
push eax
:004346DA FF742408
push [esp+08]
* Reference To: KERNEL32.lstrcpyA, Ord:0302h
|
:004346DE FF1500694400
Call dword ptr [00446900]
:004346E4 FF742404
push [esp+04]
* Reference To: USER32.CharUpperA, Ord:002Fh <--functie
ce transforma in capsuri
:004346E8 FF154C694400
Call dword ptr [0044694C]
:004346EE FF742404
push [esp+04]
:004346F2 E892B2FEFF
call 0041F989
:004346F7 59
pop ecx
:004346F8 C3
ret <-inpoi la 004347ED
si continuam de sub
call-ul cu caps-izarea...pana...STOP..
aici intrati cu F8...
:004347F0
E804FFFFFF
call 004346F9 <AICI SE CALCULEAZA PAROLA
si
iata ce se intampla:
:004346F9 55 push
ebp
:004346FA 8BEC mov ebp, esp
:004346FC 81EC04010000 sub esp, 00000104
:00434702 FF7508 push [ebp+08]
:00434705 8D85FCFEFFFF lea eax, dword ptr [ebp+FFFFFEFC]
:0043470B C745FC4C694700 mov [ebp-04], 0047694C
= "LiG"
:00434712 50 push eax
:00434713 E8B5FFFFFF call 004346CD
--se cheama rutina de mai sus dar pentru nume de
data asta
:00434718 59 pop ecx
:00434719 8D85FCFEFFFF lea eax, dword ptr [ebp+FFFFFEFC]
:0043471F 59 pop ecx
:00434720 50 push eax
* Reference To: KERNEL32.lstrlenA, Ord:0308h
|
:00434721 FF1594684400 Call dword ptr [00446894]
:00434727 33C9 xor ecx, ecx
:00434729 894508 mov dword ptr [ebp+08], eax
:0043472C 85C0 test eax, eax
:0043472E 7E47 jle 00434777
:00434730 53 push ebx
:00434731 56 push esi
:00434732 8DB5FCFEFFFF lea esi, dword ptr [ebp+FFFFFEFC]
:00434738 57 push edi
:00434739 8B7D08 mov edi, dword ptr [ebp+08]
:0043473C 83EE03 sub esi, 00000003
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|:00434772(C)
:0043473F 8BC1 mov eax, ecx <-- si de la capat
:00434741 6A0E push 0000000E
:00434743 99 cdq
:00434744 5B pop ebx
:00434745 F7FB idiv ebx
:00434747 85D2 test edx, edx
:00434749 7503 jne 0043474E
:0043474B 6A27 push 00000027 <--e impins 27 in
stiva
:0043474D 5F pop edi <--si scos in edi
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|:00434749(C)
:0043474E 0FB6540E03 movzx edx, byte ptr [esi+ecx+03] <--"c"=43
:00434753 8D4103 lea eax, dword ptr [ecx+03]
:00434756 0FAFD7 imul edx, edi <-- 27*43=A35
:00434759 0155FC add dword ptr [ebp-04], edx <--
si adunat peste "LiG"
:0043475C 6A0E push 0000000E
:0043475E 99 cdq
:0043475F 5B pop ebx
:00434760 F7FB idiv ebx
:00434762 85D2 test edx, edx
:00434764 7405 je 0043476B
:00434766 8D3C7F lea edi, dword ptr [edi+2*edi] <--edi*3
:00434769 EB03 jmp 0043476E
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|:00434764(C)
:0043476B 6BFF07 imul edi, 00000007
* Referenced by a (U)nconditional or (C)onditional
Jump at Address:
|:00434769(U)
:0043476E 41 inc ecx
:0043476F 3B4D08 cmp ecx, dword ptr [ebp+08]
:00434772 7CCB jl 0043473F<--sus pana se termina
numele
Ce s-a intamplat in rutina asta.. la 43470B domnii programatori s-au gandit
sa inceapa numaratoarea nu de la zero ci dela un oarecare "LiG"
caci L=4C,i=69,G=47; -dar in prealabil la 00434713
capitalizeaza shi literele numelui; Uite care-i treaba...e luata pe rand
cate o litera ...prima era C de la crisco
care in prealabil devenise CRISCO,inmultita
cu ceva (valoarea ei hexa)apoi rezultatul adunat peste "GiL"..(tot
hexa).
|
edi*3
|
(litera)h
|
edi*edx
|
[ebp-4] +edi*edx
initial 4C6947 (GiL)
|
|
27
|
(C)=43
|
A35
|
817347
|
|
75
|
(R)=52
|
257A
|
FB9847
|
|
15F
|
(I)=49
|
6417
|
12FD47
|
|
41D
|
(S)=53
|
15567
|
795249
|
|
C57
|
(C)=43
|
33AC5
|
8E8D43
|
|
2505
|
(O)=4F
|
B6C8B
|
C9F957
|
DONC
,fiecare litera (h) se inmulteste cu un multiplu se 3*27 corespunzator
(prima cu 27,a doua cu 3*27,a treia cu 3*3*27....) rezultatul adaugandu-se
la valoarea exiatenta la momentul respectiv in [ebp-4].Astfel dupa ultima
litera in [ebp -4] se afla chiar numarul de inregistrare.
Dupa terminarea buclei..revenim
sub call-ul 004347F0 si gasim rutina de verificare.
:004347F0 E804FFFFFF call 004346F9
:004347F5 8BF8 mov edi, eax<aici seria-i gata
.........taiat..................................
:00434815 E862FFFFFF call 0043477C <aici din 8--> B shi invers
.........taiat..................................
:0043481C 50 push eax
* Reference To: CRTDLL.strcmp, Ord:01CFh
:0043481D E87E330000 Call 00437BA0 <--verificarea facuta de
:00434822 59 pop ecx CRTDLL
:00434823 85C0 test eax, eax <-a fost sau nu buna seria?
:00434825 59 pop ecx
:00434826 0F84A0000000 je 004348CC <--sare daca e bine
Daca intrati cu F8 in call-ul de la 43482D vetzi vedea clar compararea facuta intre cele
2 serialuri cu functia REPZ CMPSB...
Cum parola introdusa de noi cu siguranta nu era cea buna..:) urmam in continuare cu F10
sirul programului fara a face vreo maodificare.
De fapt intentia e sa aflam ce se intampla mai departe;continuam...
:0043482C 8D8500FFFFFF lea eax, dword ptr [ebp+FFFFFF00]
:00434832 50 push eax
:00434833 8D8748190514 lea eax, dword ptr [edi+14051948]
:00434839 50 push eax <-in stiva
:0043483A 8D8500FEFFFF lea eax, dword ptr [ebp+FFFFFE00]
:00434840 50 push eax
Va reamintesc ca
in edi se afla parola tocmai generata putin mai sus. Observati
acum la 434833 cum
se produce un lucru interesant; seriei noastre ii este adaugat un numar
shi apoi valoarea obtinuta e mutata in registrul eax.
Mai departe...
:00434841 E836FFFFFF call 0043477C<rutina e si la 00434815
:00434846 59 pop ecx
:00434847 59 pop ecx
:00434848 50 push eax
* Reference To: CRTDLL.strcmp, Ord:01CFh <iar functia de comparare
:00434849 E852330000 Call 00437BA0 prin care am mai fost
:0043484E 59 pop ecx
:00434852 7478 je 004348CC <sare daca seria e buna
Aici este clar ca avem de-a face tot cu compararea unui seial number, tinand seama de simetria problemei.
Iata cum faceti sa ajungeti rapid spre exemplu la adresa 015f:434849:
-
Ctrl+D sa intrati in SoftIce..
-
tastati bd* pentru a stinge toate celelalte bpx-uri
-
F5 si introduceti crisco si orice parola apoi iar Ctrl+D
-
bpx hmemecpy ca altfel nu ne ia bpx-ul pe adresa noastra
-
F5 si dati Ok la inregistrare
-
bang sunteti in SI
-
acum bd* sa-l scoateti pe hmemcpy
-
apoi bpx 015f:434849 shi gata
Acum de fiecare data cand aveti nevoie sa ajungeti la o adresa procedati
ca mai sus.Dati in continuare F5 si bang..(pupaza zbarrrr..:)in Si
tocmai pe adresa respectva.Acolo nu va ramane decat sa vedeti ce se afla prin
registrii.Tastand deax vedeti in wd continutul adresei aflate in eax shi care
in cazul de fata trebuie sa fie 145D1311 ceea ce cam aduce cu un serial.
De fapt remarcam apoi acest numar chiar in registrul ecx.Iar in edi este chiar
parola noastra..va mai amintiti.
Inseamna ca 145D1311 este o alta parola.Shi uitandu-neceva mai sus pe unde am
trecut observam ca este generata la adresa 00434833 prin adaugarea numarului
care mai devreme ni se paruse interesant.De ce? Pai uitati-va la el....
14051948 nu seamana cu o data..14-05-1948.
edi+14051948=57F9C9+14051948=145D1311 chiar noua serie
Iata cum deci adunand la prima serie un numar reprezentand cine sti
ce in viata programatorilor s-a creeat un nou serial number care este
apoi comparat cu cel introdus de noi.
Shi sa va mai spun ceva.Daca va uitati in W32Dasm in continuarea programului
mai gasiti 4 chestii din astea:
-
:0043485B 8D8754190617 lea eax, dword ptr [edi+17061954]
-
:00434883 8D8781190510 lea eax, dword ptr [edi+10051981]
-
:004348AB 8D8795190104 lea eax, dword ptr [edi+04011995]
-
:004348D7 81C797190602 add edi, 02061997
Stiind acum cum se determina primul serial care apoi este pus in edi se poate
face un generator de chei.
Iata serial-urile pentru crisco:
-
57F9C9 este cea de baza
-
145D1311
-
175E131D
-
105D134A
-
459135E
-
25E1360
Ar mai fi de vazut ce se intampla in call-ul de la 00434815,dar asta va las pe
voi sa descoperitzi...sau daca nu..exiata si un mail :)
Recapitulare ---din numele introdus programul a generat o prima serie astfel:
-intai a capitalizat toate literele
-pleaca de la prima litera inmultind valoarea hexa cu 27
-aduna valoarea obtinuta peste "GiL" in hexa
-ia litera urmatoare ,produs cu 3*27 tot in hexa
-rezultatul peste ce a iesit din "GiL"+primul nr.
-ia litera urmatoare ,produs cu 3*3*27 tot in hexa
-si tot asha pana la ultima litera....
-verifica seria shi face din 8 B shi invers
-daca prima serie nu e buna si-o fabrica pe a doua cum am vazut mai sus
Ar mai fi un lucru de spus...,ca sunt doua variante de inregistrare:
Standard siProfesional;Nu am descoperit o regula pentru obtinerea uneia
sau a alteia,tot ce va pot spune este ca in cazul seriilor 4 si 6
inregistrarea este generala.
Ata ete.
Uitandu-ma pe About-ul
programului am descoperit ce era cu acel "GiL",chiar autorul
programului Gilles Vollant.
Cat despre acele date ca or fi fost zile de nastere,unele,ca altele
cine stie ce zile istorice,nu prea ne intereseaza.Lucrul buna e daca
v-atzi facut o idee despre ce inseamna un serial number cum e generat
el si cum poate fi dibuit.
Ps:daca shtiti ce
reprezinta vreo data dati un mail shi o pun pe pagina.
Sper ca cele aflate
aici v-au luminat putin in ceea ce priveste "spartul" programelor
, mai multe lucruri in viitoarele eseuri .
|