WinImage ovvero uno schema di protezione

deludente -D

Data

by "Evilcry"

 

15/09/2002

UIC's Home Page

Published by Quequero

Sr

W la marshall allora :P, grazie per il tute, ben scritto, la protezione davvero deludente :)

Stronzio a chi?

:-P

....

Home page se presente: www.evilcry.cjb.net
E-mail: [email protected]
Nick, UIN, canale IRC/EFnet frequentato   irc.azzurra.it   #crack-it
 

....

Difficoltà

(Poco più che->) NewBies (*) Intermedio ( )Avanzato ( )Master

 

 

WinImage 6.10 ovvero
uno schema di protezione deludente :-P
Written by Evilcry.

Introduzione

WinImage?? non so nemmeno a cosa serve..... ihihih

Tools usati

-W32dasm (inutile)
-SoftICE o qualunque altro debugger

URL o FTP del programma

www.google.it

Notizie sul programma

Lost in the net. ;-}

Essay

Iniziamo il nostro viaggio nelle viscere di WinImage :)). Dopo aver installato il programma, una simpatica NagScreen ci avvisa che il programma non è registrato, e dopo 30 giorni smetterà di funzionare :)). Le vie per evitare la sua morte sono tante, si potrebbero rimuovere il/ i jump che decidono se sono passati i 30 giorni (metodo mooolto lamero ed antipatico), o trovarci un seriale valido (è la via che preferisco :)). Facciamo partire il programma ed andiamo sull' Item 'Options', nel quale troveremo 'Registering'. Ora avremo davanti a noi il classico Name/Serial :)), quindi inseriamo un nome a caso (io ho messo evilcry) ed un serial a caso (io ho scritto triton). Settiamo ora i canonici (ma come parlo oggi??? ihihi) bpx GetDlgItemTextA e bpx GetWindowTextA poi usciamo da SICE con F5 e clickiamo su 'Register'. Il Sice poppa :)), ora premiamo una volta F12 e ci troveremo davanti, qualcosa del genere:

0042204A mov ebx, 00453B90 ; Viene messo in ebx l' indirizzo del buffer che riceverà il nome

0042204F push ebx

00422050 push 00000816

00422055 push [ebp+08]

00422058 call esi ;Call a Getdlgitemtexta

0042205C mov edi, 00453F00 ;In edi avremo l' indirizzo del buffer per il serial

00422061 push edi

00422062 push 00000817

00422067 push [ebp+08]

0042206A call esi ;Chiamata a getdlgitemtexta

0042206C push 0045386C

00422071 push edi ;Salva il puntatore al serial nello stack

00422072 push ebx ;Salva il puntatore al nome nello stack

00422073 call 0044208A ; Questa call la analizzeremo in seguito... dato che è fondamentale

Fin qui non ci dovrebbero essere problemi :)) , il programma non fa altro che prendere il nome ed il serial inserito (d ebx e d edi per credere), e passarli alla call 00422073. Dopo essere arrivati su questa call premiamo F8 per entrarci dentro. La prima parte della call non è molto utile ai nostri scopi quindi la tralascerò:

/**** CUTTED CALL ****/

004420A2 lea eax, dword ptr [ebp+FFFFFF00] ; Carica in eax il serial

004420A8 push eax ; Salva il serial nello stack , questo perchè sarà il parametro della seguente call

004420A9 call 00441F90

004420AE push [ebp+08]

004420B1 call 00441FBC ;Questa call la analizzeremo a parte

Quando ci troveremo su questa call, premiamo nuovamente F8 per entrarci.

00441F90 mov eax, dword ptr [esp+08] ;Mette in eax il serial

00441F94 jmp 00441F97

Referenced by a (U)nconditional or (C)onditional Jump at Address:

00441F96 inc eax

Referenced by a (U)nconditional or (C)onditional Jump at Address:

00441F97 cmp byte ptr [eax], 20 ;Controlla che l' ennesimo char puntato da eax sia 20 (quindi ne un numero ne una lettera)

00441F9A je 00441F96 ; Se è uguale a 20 salta su ed incrementa di 1 il puntatore al serial

00441F9C push eax ;In caso contrario usa il nostro serial come parametro di lstrcpy

00441F9D push [esp+08] ;Questo è l' output buffer di lstrcpy

Reference To: KERNEL32.lstrcpyA,

00441FA1 Call dword ptr [00446260] ; Chiamata a lstrcpy

Chi conosce un pò di C sicuramente avrà capito cosa fa quest' API, in pratica copia una stringa (il nostro serial :-P), in un' altra locazione (variabile per gli amici :-D).

00441FA7 push [esp+04]

Reference To: USER32.CharUpperA

00441FAB Call dword ptr [004464E4] ;Rende maiuscola una stringa

00441FB1 push [esp+04]

00441FB5 call 00415B9C ;Eccovela spiegata qui di seguito ---->

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

00415B9C push esi

00415B9D mov esi, dword ptr [esp+08] ;Muove in esi il nome

00415BA1 push esi ;Lo salva nello stack (per poi essere usato come parametro di strlen)

Reference To: KERNEL32.lstrlenA

00415BA2 Call dword ptr [0044625C]

00415BA8 jmp 00415BB5

Referenced by a (U)nconditional or (C)onditional Jump at Address:

00415BAA dec eax ;Decrementa di uno la lunghezza

00415BAB cmp byte ptr [eax+esi], 20 ;Controlla che l' ennesimo char puntato da eax sia 20

00415BAF jne 00415BB9 ;Salta se è diverso da 20

00415BB1 and byte ptr [eax+esi], 00

Referenced by a (U)nconditional or (C)onditional Jump at Address:

00415BB5 test eax, eax ;La lunghezza del nome è 0???? (cioè esiste :-D)???

00415BB7 ja 00415BAA ;Se è più grande di zero salta sopra

Referenced by a (U)nconditional or (C)onditional Jump at Address:

00415BB9 pop esi

00415BBA ret

Anche questa call non fa altro che controllare se i caratteri siano uguali a 20. Adesso dopo il RET a 00415bba, entreremo nella call più importante cioè quella che calcola il serial (in parte).

00441FDD lea eax, dword ptr [ebp+FFFFFEF8] ;Viene caricato in eax il nome

00441FE3 push eax ;Il nome è passato come parametro

Reference To: KERNEL32.lstrlenA

00441FE4 Call dword ptr [0044625C]

00441FEA xor ecx, ecx ;Azzera ecx che in futuro sarà usato come contatore

00441FEC test eax, eax ;Controlla che il nome quanto meno esista

00441FEE mov dword ptr [ebp-08], eax ;Mette il nome in ebp-08

00441FF1 jle 00442039 ;Salta se il numero di lettere del nome e minore o uguale a 0

00441FF3 push ebx

00441FF4 push esi

00441FF5 mov esi, dword ptr [ebp-08] ;Muove in esi il nome

00441FF8 push edi ;Salva edi

00441FF9 lea edi, dword ptr [ebp+FFFFFEF8] ;Carica in edi l' indirizzo relativo al nome

00441FFF sub edi, 00000003 ;Sottrai 3 alla locazione del nome

Referenced by a (U)nconditional or (C)onditional Jump at Address:

00442002 mov eax, ecx

00442004 push 0000000E ; passa questo numero ad ebx

00442006 cdq ;Azzera edx

00442007 pop ebx ;adesso abbiamo in ebx 0000000Eh

00442008 idiv ebx ;dividi eax per ebx

0044200A test edx, edx ; controlla che il resto della divisione sia 0

0044200C jne 00442011 ;se il resto è diverso da 0 salta

0044200E push 00000027 ; | equivale a mov esi,00000027h

00442010 pop esi ; | vedi sopra

Referenced by a (U)nconditional or (C)onditional Jump at Address:

00442011 lea eax, dword ptr [ecx+03]

00442014 movzx edx, byte ptr [edi+eax]

00442018 imul edx, esi

0044201B add dword ptr [ebp-04], edx ; In ebp-04 abbiamo dei valori costanti (almeno la prima volta)

0044201E push 0000000E ;Mette E in ebx con il solito metodo

00442020 cdq ;Azzera edx, e si prepara alla divisione

00442021 pop ebx

00442022 idiv ebx ;Divide eax per ebx

00442024 test edx, edx ;Controlla che il resto sia uguale a 0

00442026 je 0044202D ;Se lo è salta

00442028 lea esi, dword ptr [esi+2*esi] ;Carica in esi l' indirizzo relativo a [esi+2*esi]

0044202B jmp 00442030 ;Salta alla prossima semi-routine

Referenced by a (U)nconditional or (C)onditional Jump at Address:

0044202D imul esi, 00000007 ;Moltiplica esi per 7

Referenced by a (U)nconditional or (C)onditional Jump at Address:

00442030 inc ecx ;Incrementa ecx,vi ricordo funge da contatore

00442031 cmp ecx, dword ptr [ebp-08] ;Controlla che ecx sia uguale ad ebp-08, cioè alla variabile dove è stato salvato il valore di ritorno di strlen

00442034 jl 00442002 ;Se ecx è minore di questo valore, ripeti nuovamente il ciclo

00442036 pop edi

00442037 pop esi

00442038 pop ebx

Referenced by a (U)nconditional or (C)onditional Jump at Address:

00442039 mov eax, dword ptr [ebp-04] ;Sposta in eax il seriale parzialmente lavorato

0044203C leave ;Rimette a posto lo stack

0044203D ret ;Esce fuori dalla call

Come avrete visto, la routine non è un granchè di difficile, ma per agli ultra-newbies potrebbe creare un pò di confusione. Dopo una serie di divisioni e moltiplicazioni, otteniamo in ebp-04, il seriale parzialmente lavorato ed anche in chiaro, infatti se fate d ebp-04, lo vedrete il bella mostra, il mio serial è 007EEA66. Fermiii! , non ditemi che siate già andati a provarlo ihihi, se lo avete messo cosi com' è otterrete un messagio d' errore. Perchè mai?, semplice... andate a vedere cosa succede dopo il ret.Inizialmente al serial vengono tolti i primi 2 caratteri, di conseguenza il mio serial corretto è 7EEA66, poi avremo il canonico repz e cmp tra serial correto e quello che abbiamo messo noi, ed un salto condizionato ;-P.

Note per chi vuole fare un keygen.

Per ragioni di spazio non ho messo il keygen che avevo fatto (in masm). Se qualcuno di voi volesse fare un keygen, ricordi che: c'è un valore costante precisamente quello in ebp-04 che è 4c694700 (se non ricordo male) quindi state attenti :)), inoltre come avete potuto vedere, almeno nella prima parte EAX non viene usato quindi se usate qualche API abbiate l' accortezza di fare uno xor eax,eax (ovviamente dopo che vi siete salvati il suo contenuto :-P). Ricordate in oltre la routine che toglie i primi 2 char. Creare un keygen per questo programma è molto semplice (soprattutto se usate Masm/Tasm :-D).Spero di essere stato sufficentemente chiaro ed esauriente, se così non è stato, siete liberi di maillarmi :)).

Note finali

In fine colgo l' occasione per salutare:Quequero, AndreaGeddon, e4m, Slash, Vinci,Quake2^AM, albe, Ntoskrnl, BIGAlex, Littleluk, Speed Strid. I chan #crack-it #asm #pmode e #twotux. E la marshall per i suoi grandiosi ampli :)).

Disclaimer

Vorrei ricordare che il software va comprato e non rubato, dovete registrare il vostro prodotto dopo il periodo di valutazione. Non mi ritengo responsabile per eventuali danni causati al vostro computer determinati dall'uso improprio di questo tutorial. Questo documento è stato scritto per invogliare il consumatore a registrare legalmente i propri programmi, 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.

Noi reversiamo al solo scopo informativo e di miglioramento del linguaggio Assembly .

Capitoooooooo????? Bhè credo di si ;))))