Sachs Marine Aquarium v 0.99H (Beta)
 

by Eddy

 

02/02/2002

UIC's Home Page

Published by Quequero


Bhè, dopo tutto questo è solo ...

Grande eddy, bel tutozzo :) e bellissimo disclaimer :)

un altro mattone nella parete!

....

 
 

....

Difficoltà

(x)Facile ( )Intermedio ( )Avanzato ( )Master

 

Bello sto acquario virtuale! Anche se in pratica non serve a nulla. Bello da usare al posto dei soliti screensavers.


Sachs Marine Aquarium v 0.99H (Beta)
Written by Eddy

 

Introduzione

Ormai i miei tute li trovate sparsi per tutto l'UIC store sotto nomi diversi, prima Gbyte,poi Kurdt e adesso Eddy. Che dire? Mi piace cambiare. Quindi anche se questo nick vi suona nuovo questo non è il mio primo tute.

Tools usati

SoftIce 

HexWorkshop (o un altro HexEditor)

URL o FTP del programma

http://www.fish-byte.com/

Notizie sul programma

Uno splendido screensaver con un acquario virtuale. Nella versione non registrata di pesci c'è ne uno solo e sullo schermo, in basso, appare un riquadro che ci ricorda che abbiamo solo la versione di prova. Premiamo spazio e compare il box di registrazione, e adesso al lavoro.

Essay

 

Già dall'inizio sappiamo che il prog. accetta tre diversi seriali (poi in realtà scopriremo che ne sono di più) uno per la registrazione temporanea (questo ci viene già dato ed è TESTFISH),uno per la registrazione basic (scompare il nag e compaiono altri due pesci) e infine la registrazione deluxe (7 pesci). Come al solito apriamo il Sice, settiamo un bpx sulla funzione GetDlgItemTextA e usciamo con F5. Inseriamo un seriale a caso (es. 666111666) nel box e premiamo il bottone. Sice poppa e dopo essere usciti dal modulo User32 ci troviamo qui:

 

:0040EDCB Call dword ptr [USER32!GetDlgItemTextA]

:0040EDD1 push 00422404 <- qui troviamo la stringa TESTFISH

:0040EDD6 push 00425BBC <- qui invece il nostro seriale

:0040EDDB Call dword ptr [KERNEL32.lstrcmpiA]

:0040EDE1 test eax, eax

:0040EDE3 jne 0040EDEF

:0040EDE5 mov dword ptr [00425DE0], 00000001

:0040EDEF push 00000002

:0040EDF1 call 00402900 <- entriamo qui

:0040EDF6 add esp, 00000004

:0040EDF9 test eax, eax <- controllo su eax
:0040EDFB je 0040EE11

 

Subito notiamo che il seriale viene caricato in memoria, poi troviamo una call seguita da un compare e un salto condizionale. Vediamo un pò cosa c'è nella chiamata! Steppiamo fino ad arrivare qui:

 

 

:0040295B mov word ptr [ebp-0C], ax

:0040295F mov ecx, dword ptr [00425BBC] <- in memoria all'indirizzo 425BBC c'è il nostro seriale, i primi quattro char vengono spostati in ecx...

:00402965 mov dword ptr [ebp-18], ecx <- e da ecx in memoria all'indirizzo puntato da [ebp-18]

:00402968 mov dx, word ptr [00425BC0] <- altri due char in dx...

:0040296F mov word ptr [ebp-14], dx <- e da dx in memoria

:00402973 mov [ebp-1C], 00000000 <- i byte che precedono il seriale appena spostato vengono azzerati

:0040297A jmp 00402985 <- salto

:0040297C mov eax, dword ptr [ebp-1C]

:0040297F add eax, 00000001 <- il salto a 0040297C fa in modo che questi calcoli vengano ripetuti per ogni char, infatti eax viene usato come contatore

:00402982 mov dword ptr [ebp-1C], eax

:00402985 cmp dword ptr [ebp-1C], 00000006 <- controllo sulla lunghezza del seriale

:00402989 jge 004029D1

:0040298B mov ecx, dword ptr [ebp-1C] <- [ebp-1C] punta il valore 0

:0040298E mov dl, byte ptr [ebp+ecx-18] <- primo char in ecx

:00402992 mov byte ptr [ebp-04], dl <- spostato in memoria

:00402995 movsx eax, byte ptr [ebp-04] <- primo char in eax

:00402999 add eax, dword ptr [ebp-1C] <-sommato al contenuto di eax

:0040299C imul eax, dword ptr [ebp-20] <- moltiplicazione

:004029A0 mov dword ptr [ebp-20], eax <- contenuto di eax in memoria

:004029A3 cmp dword ptr [ebp-1C], 00000001

:004029A7 jle 004029B4

:004029A9 movsx ecx, byte ptr [ebp-04]

:004029AD cmp ecx, 0000002D

:004029B0 jne 004029B4

:004029B2 jmp 0040297C

:004029B4 movsx edx, byte ptr [ebp-04] <- da qui ...

:004029B8 cmp edx, 0000007A

:004029BB jg 004029C6

:004029BD movsx eax, byte ptr [ebp-04]

:004029C1 cmp eax, 00000041

:004029C4 jge 004029CF <- a qui, controlla che i caratteri siano compresi tra z e A

:004029C6 mov [ebp-24], 00000001

:004029CD jmp 004029D1

:004029CF jmp 0040297C

:004029D1 cmp dword ptr [ebp-24], 00000000

:004029D5 jne 00402A9D

:004029DB mov ecx, dword ptr [ebp-08]

:004029DE imul ecx, 000000C8

:004029E4 mov eax, dword ptr [ebp-20]

:004029E7 xor edx, edx :004029E9 div ecx

:004029EB mov dword ptr [ebp-20], eax

:004029EE cmp dword ptr [ebp-20], 000F1B30

:004029F5 jbe 00402A01 <- salta

:004029F7 mov edx, dword ptr [ebp-20]

:004029FA shr edx, 1

:004029FC mov dword ptr [ebp-20], edx

:004029FF jmp 004029EE

:00402A01 cmp dword ptr [ebp-20], 000186A0

:00402A08 jnb 00402A14 <- altro salto

:00402A0A mov eax, dword ptr [ebp-20]

:00402A0D shl eax, 1

:00402A0F mov dword ptr [ebp-20], eax

:00402A12 jmp 00402A01

:00402A14 mov ecx, dword ptr [ebp-20]

:00402A17 add ecx, 00000080

:00402A1D mov dword ptr [ebp-20], ecx

:00402A20 mov edx, dword ptr [ebp-20]

:00402A23 push edx

:00402A24 push 004220C8

:00402A29 lea eax, dword ptr [ebp-12]

:00402A2C push eax

:00402A2D call 0041284C <- qui dentro viene generato il seriale

:00402A32 add esp, 0000000C <- qui puntato da esp abbiamo la seconda parte del nostro seriale

:00402A35 mov cl, byte ptr [ebp-12] <- di nuovo puntato da [ebp-12]

:00402A38 mov byte ptr [ebp-04], cl

:00402A3B mov dl, byte ptr [ebp-0D]

:00402A3E mov byte ptr [ebp-12], dl

:00402A41 mov al, byte ptr [ebp-04]

:00402A44 mov byte ptr [ebp-0D], al

:00402A47 movsx ecx, byte ptr [ebp-12]

:00402A4B cmp ecx, 00000030

:00402A4E jne 00402A54

:00402A50 mov [ebp-12], 39

:00402A54 mov [ebp-0C], 00

:00402A58 cmp dword ptr [ebp+08], 00000005

:00402A5C jne 00402A83 <- salto

:00402A5E lea edi, dword ptr [ebp-18]

:00402A61 mov edx, 00425BBC

:00402A66 or ecx, FFFFFFFF

:00402A69 xor eax, eax

:00402A6B repnz

:00402A6C scasb

:00402A6D not ecx

:00402A6F sub edi, ecx

:00402A71 mov esi, edi

:00402A73 mov eax, ecx

:00402A75 mov edi, edx

:00402A77 shr ecx, 02

:00402A7A repz

:00402A7B movsd

:00402A7C mov ecx, eax

:00402A7E and ecx, 00000003

:00402A81 repz

:00402A82 movsb

:00402A83 lea ecx, dword ptr [ebp-18]

:00402A86 push ecx <- qui puntato da ecx possiamo vedere il seriale completo

:00402A87 push 00425BBC <- all'indirizzo 00425BBC il seriale inserito

:00402A8C call [kernel32!lstrcmpi] <- non so assolutamente che fa questo ma alla fine se i due seriali sono uguali in eax rimane il valore 0, almeno credo

:00402A92 test eax, eax <- controllo su eax

:00402A94 jnz 00402A9D <- salta se diverso da 0 cioè se i seriali sono diversi

:00402A96 mov eax, 00000001 <- se sono uguali il salto non avviene ed in eax viene spostato il valore 1

:00402A9B jmp 00402A9F <- salta

:00402A9D xor eax, eax <- eax viene azzerato

:00402A9F pop edi

:00402AA0 pop esi

:00402AA1 mov esp, ebp

:00402AA3 pop ebp

:00402AA4 ret <- ritorna

 

Dopo tutto sto cavolo di codice è ora di qualche spiegazione! Dopo essere stati sballottati di qua e di la, di registro in registro, da registro a memoria, da memorie a registro e cazzi vari i char del seriale vengono sottoposti ai primi controlli. Solo adesso capiamo di che tipo deve essere il seriale. I primi char devono essere delle lettere (:004029B4 e seguenti), quindi il seriale 666111666 non andrebbe bene. Quindi usciamo da Sice, inseriamo nel box un seriale alfabetico e ripetiamo tutto il ciclo. Poi avrete notato che del codice inserito in un primo momento vengono acquisiti solo i primi 6 char mentre il seriale completo ne prevede 12. Infatti quest'ultimo si compone di due parti: la prima quella alfabetica è quella inserita da noi nel box mentre la seconda (numerica) viene generata dal prog. in base alla prima parte. Il seriale completo viene generato nella call all'indirizzo :00402A2D ( noi non ci entreremo dato che il seriale l'abbiamo trovato e non ci vogliamo complicare la vita...non escludo però che saremo costretti a farlo se vogliamo trovare anche il seriale per la registrazione deluxe) ed è visibile già all'indirizzo :00402A86. Poi ci sono le solite istruzioni che non sto a rispiegarvi perché dovrebbero bastare le note che accompagnano il listato.

Adesso vediamo un pò cosa fare per la registrazione deluxe. C'eravamo fermati all'indirizzo 0040EDFB, andando avanti ci troviamo davanti ad un altro compare seguito da un salto. Forse è meglio vedere direttamente le istruzioni e commentarle:

:0040EDF9 test eax, eax
:0040EDFB je 0040EE11 <- salta se il seriale inserito è quello della registrazione deluxe (non nel nostro caso,visto che il seriale che abbiamo appena pescato è quello basic)
:0040EDFD mov dword ptr [00425DE0], 00000002 <- in questo indirizzo viene spostato il valore 2
:0040EE07 push 00000001
:0040EE09 call 00403030 <- con questa call viene azzerato il valore di eax
:0040EE0E add esp, 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040EDFB(C)
|
:0040EE11 push 00000003
:0040EE13 call 00402900
:0040EE18 add esp, 00000004
:0040EE1B mov dword ptr [ebp-08], eax <- o in [ebp-8]
:0040EE1E cmp dword ptr [ebp-08], 00000000 <- 0=0?
:0040EE22 je 0040EE38 <- si
:0040EE24 mov dword ptr [00425DE0], 00000003
:0040EE2E push 00000001
:0040EE30 call 00403030
:0040EE35 add esp, 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040EE22(C)
|
:0040EE38 cmp dword ptr [00425DE0], 00000000
:0040EE3F je 0040EE99 <- non salta
:0040EE41 mov byte ptr [00421D6D], 01
:0040EE48 mov byte ptr [00421D6E], 01
:0040EE4F cmp dword ptr [00425DE0], 00000001
:0040EE56 jne 0040EE6C <- salta

#########

:0040EE6C cmp dword ptr [00425DE0], 00000002
:0040EE73 jne 0040EE89 <- nel caso della registrazione Basic questo salto non avviene

* Possible StringData Ref from Data Obj ->"BASIC registration OK"
|
:0040EE75 push 004223D4
:0040EE7A push 00000092
:0040EE7F mov ecx, dword ptr [ebp+08]
:0040EE82 push ecx
:0040EE83 Call dword ptr [0041D1C4]
:0040EE89 cmp dword ptr [00425DE0], 00000003 <- se il salto avvenisse ci troveremmo qui
:0040EE90 jge 0040EE99
<- altro salto che deve avvenire per ottenere la Deluxe
:0040EE92 xor eax, eax
:0040EE94 jmp 0040EF7B
:0040EE99 cmp dword ptr [00425DE0], 00000003
:0040EEA0 jne 0040EEE7 <- questo invece non deve farci zompare

* Possible StringData Ref from Data Obj ->"DELUXE registration OK"
|
:0040EEA2 push 00422410
:0040EEA7 push 00000092
:0040EEAC mov edx, dword ptr [ebp+08]
:0040EEAF push edx

Ed ecco cosa faremo per ottenere la registrazione deluxe con il seriale per quella basic. Cambieremo queste istruzioni: all'indirizzo 0040EE73 il jne deve diventare un jmp, all'indirizzo 0040EE90 il jge diventerà jmp
e all'indirizzo 0040EEA0 il jne lo sostituiremo con due nop. Adesso però anche se cambiamo questi byte con l'hex editor, registriamo il prog., lo chiudiamo e lo riapriamo ci accorgiamo che abbiamo solo la versione basic e non quella deluxe come ci saremmo immaginati. Infatti il prog. crea nel registro di configurazione una chiave con il seriale che abbiamo inserito (quello basic) ed ogni volta che viene riavviato va a controllarlo e si setta automaticamente in modalità basic. Riapriamo SoftIce, settiamo un bpx su RegQueryValueExA ed apriamo l'acquario, Sice poppa e noi cominciamo a premere F11 (per un bel pò di volte) finche non ci ritroviamo in fish.exe all'incirca a questo punto:

:00403534 		Call [ADVAPI32!RegQueryValueExA] 
:0040353A    	mov dword ptr [ebp-74], eax 
:0040353D		cmp dword ptr [ebp-74], 00000000    
:00403541 		jne 004035B4
:00403543 		push 00000002 
:00403545 		call 00402900 
:0040354A    	add esp, 00000004 
:0040354D 		test eax, eax
:0040354F 		je 0040355B <- questo deve saltare sempre...
:00403551 		mov dword ptr [00425DE0], 00000002 
:0040355B 		cmp dword ptr [00425DE0], 00000000 
:00403562 		je 00403572 
:00403564		mov byte ptr [00421D6D], 01
:0040356B 		mov byte ptr [00421D6E], 01 
:00403572 		push 00000003
:00403574 		call 00402900 
:00403579    	add esp, 00000004 
:0040357C 		test eax, eax
:0040357E 		je 004035B4 <- ...mentre questo no
:00403580 		mov dword ptr [00425DE0], 00000003 
:000 ecc....

Adesso dobbiamo vedere che byte cambiare, prendiamo nota di quelli originali agli indirizzi 40354F e 40357E più qualcuno prima e dopo, andiamo nell' hexeditor li cerchiamo (con find) e li cambiamo con altri! Naturalmente voi sapete quali? Nel caso siate dei NewBies disperati eccoli: sostituite il jz all'indirizzo 40357E (Ofsett 357E nel HexWorkshop) con un bel jmp (740A con EB0A) mentre l'altro jz lo sostituite con due nop (7434 con 9090). Ed ecco tutto! Beh adesso che abbiamo finito con sto lavoro massacrante (anche se credo di averci messo più tempo a scrivere sto tute che a torturate il programma) possiamo dedicarci ai nostri pesciolini tutti allegri, piccolini e colorati, che schifo, se fossi stato al posto del programmatore ci avrei dei bei pirahna o come cavolo si scrive. A presto gente.

Note finali

Sinceramente o già detto troppo e solo adesso mi sono accorto di aver messo nel tute 35 Km di codice, forse ho esagerato visto che il prog. era facile facile. Ma adesso non ho proprio voglia di tagliare delle parti...che palle che siete, se non vi sta bene non lo leggete! :-P

Psichedelic Disclaimer

Vorrei ricordare che il software va comprato e  non fregato, dovete registrare il vostro prodotto dopo il periodo di (s)valutazione. Non mi ritengo responsabile per eventuali danni causati al vostro computer determinati dall'uso di questo tutorial come arma impropria. Questo documento è stato scritto per invogliare i programmatori a non fare più programmi perché tanto noi glieli crackiamo e il consumatore a registrarsi legalmente , e non a fargli fare uso dei tantissimi file crack presenti in rete, infatti tale documento aiuta a comprendere lo sforzo immane  che ogni singolo programmatore ha dovuto portare avanti per fornire ai rispettivi consumatori i migliori prodotti possibili.Questo documento si autodistruggerà entro 5 secondi! Ciao ciao Belli!

Noi reversiamo al solo scopo informativo e di miglioramento del linguaggio AsM. Si e io sono Biancaneve! :-)