Gif Movie Gear 3.02

Data

by "|GeO|"

 

20/08/2004

UIC's Home Page

Published by Quequero


Qualche frase che ti piace se vuoi, non è obbligatorio

Grazie geo ;p la prox volta attento all'indirizzo ;p

Qualche frase che ti piace se vuoi, non è obbligatorio

....

E-mail: [email protected]
|GeO| su #traduzioni e #crack-it (AzzurraNet)

....

Difficoltà

(X)NewBies ( )Intermedio ( )Avanzato ( )Master

 

Gif Movie Gear 3.02
Written by |GeO|

Introduzione

In questo tute spiegherò come viene verificata l'esattezza del serial inserito e come generare di conseguenza un keygenerator...

Tools usati

-OllyDBG
-W32dsm

URL o FTP del programma

Il programma in questione lo potete reperire al seguente indirizzo: http://www.moviegear.com

Notizie sul programma

Questo programma serve per eseguire svariate operazioni su immagini gif (mettere lo sfondo trasparente, ricavare filmati .avi da una serie di immagini etc. etc.) e consiste in uno shareware a tempo (30 giorni) con nagscreen e scritte del tipo: "immagine generata da un prog demo etc etc", registrabile una volta in "possesso" di user e serial validi...  

Essay

Ecco la routine del check del serial (in base all'user, logicamente...)


* Reference To: USER32.GetWindowTextA, Ord:015Eh
|
:00431969 mov ebx, dword ptr [00448348]
:0043196F push eax
:00431970 call ebx
:00431972 lea edx, dword ptr [esp+000000C4]

* Possible Reference to Dialog: DialogID_0064
|
:00431979 push 00000064
:0043197B push edx

* Possible Reference to Dialog: DialogID_0091, CONTROL_ID:0450, ""
|
:0043197C push 00000450
:00431981 push esi
:00431982 call edi
:00431984 push eax
:00431985 call ebx
:00431987 lea eax, dword ptr [esp+000000C4]    <-- serial
:0043198E lea ecx, dword ptr [esp+60]    <-- user
:00431992 push eax    <-- mette il serial nello stack
:00431993 push ecx    <-- mette l'user nello stack
:00431994 call 00431590    <-- call(1) alla routine per il serial

Ecco la CALL1:




* Referenced by a CALL at Addresses:
|:004316D9 , :00431994
|
:00431590 push ebx
:00431591 push ebp
:00431592 mov ebp, dword ptr [esp+10]    <-- mette in ebp il serial
:00431596 push esi
:00431597 push edi
:00431598 cmp byte ptr [ebp+00], 6D    <-- primo char = m
:0043159C jne 00431642    <-- altrimenti beggar off
:004315A2 cmp byte ptr [ebp+01], 67    <-- secondo char = g
:004315A6 jne 00431642    <-- altrimenti beggar off
:004315AC cmp byte ptr [ebp+02], 33    <-- terzo char = 3
:004315B0 jne 00431642    <-- altrimenti beggar off
:004315B6 cmp byte ptr [ebp+03], 37    <-- quarto char = 7
:004315BA jne 00431642    <-- altrimenti beggar off

* Possible Indirect StringData Ref from Data Obj ->"mvg21951736"
|
:004315C0 mov ebx, 0044D4C4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004315E6(C)
|
:004315C5 mov edx, dword ptr [ebx]    <-- mette in edx "mvg21951736"
:004315C7 or ecx, FFFFFFFF    <-- ecx = FFFFFFFF
:004315CA mov edi, edx    <-- mette "mvg21951736" in edi
:004315CC xor eax, eax    <-- azzera eax
:004315CE repnz    <-- decrementa ecx finché edi non è = 0
:004315CF scasb
:004315D0 not ecx    <-- not su ecx (n° char serial + 1)
:004315D2 dec ecx    <-- ecx = n° char del serial
:004315D3 mov edi, edx    <-- mette in edi "mvg21951736"
:004315D5 mov esi, ebp    <-- mette in esi il serial
:004315D7 xor eax, eax    <-- azzera eax
:004315D9 repz
:004315DA cmpsb
:004315DB je 00431642    <-- non salta mai
:004315DD add ebx, 00000004    <-- 0044D4C4 + 00000004 = 0044D4C8
:004315E0 cmp ebx, 0044D4C8    <-- ebx = 0044D4C8
:004315E6 jl 004315C5    <-- impossibile, confronta due stringhe uguali
:004315E8 cmp byte ptr [ebp+04], 73    <-- quinto char = s
:004315EC jne 004315EF    <-- altrimenti non incrementa ebp (lascia in ebp 5 char invece di 4)
:004315EE inc ebp    <-- incrementa ebp

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004315EC(C)
|
:004315EF add ebp, 00000007    <-- lascia in ebp gli ultimi 4 o 5 char (primi 5 + altri 3 o 2 non importa --> il fatto che ne prenda 3 o 2 dipende se il 5° char è o meno "s")
:004315F2 push ebp    <-- li mette nello stack
:004315F3 call 0043F3C8    <-- call(2)

Ecco la CALL2:



* Referenced by a CALL at Addresses:
|:0041120C , :00411243 , :004112BE , :0041146A , :004114A8
|:00411530 , :0041247C , :004124C2 , :004124E5 , :0043136F
|:004315F3 , :004355AA , :0043A7AC , :0043AB1C
|
:0043F3C8 push [esp+04]
:0043F3CC call 0043F33D    <-- altra call(3)


Ecco la CALL3:




* Referenced by a CALL at Addresses:
|:0043F3CC , :004465BE , :004465EC , :00446617
|
:0043F33D push ebx
:0043F33E push ebp
:0043F33F push esi
:0043F340 push edi
:0043F341 mov edi, dword ptr [esp+14]    <-- mette in edi gli ultimi 4 char del serial

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043F371(U)
|
:0043F345 cmp dword ptr [0044E24C], 00000001    <-- 0044E24C = 01
:0043F34C jle 0043F35D    <-- salta sempre
:0043F34E movzx eax, byte ptr [edi]
:0043F351 push 00000008
:0043F353 push eax
:0043F354 call 0044166F
:0043F359 pop ecx
:0043F35A pop ecx
:0043F35B jmp 0043F36C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043F34C(C)
|
:0043F35D movzx eax, byte ptr [edi]    <-- mette il char in eax

* Possible StringData Ref from Data Obj ->" ((((( "
->" H"
|
:0043F360 mov ecx, dword ptr [0044E040]    <-- mette in ecx "0044E040"
:0043F366 mov al, byte ptr [ecx+2*eax]    <-- al = 44E040 + (char * 2)
:0043F369 and eax, 00000008    <-- and fra eax e 8 (se finisce per 8 viene 8, altrimenti 0)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043F35B(U)
|
:0043F36C test eax, eax    <-- and logico (qui eax deve essere 0)
:0043F36E je 0043F373    <-- (se = 8 non salta, se è 0 ok e salta)
:0043F370 inc edi    <-- (incrementa edi e così legge il char dopo)
:0043F371 jmp 0043F345    <-- (ricomincia il ciclo, che si ripete finché eax non è 0, dipende dal char)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043F36E(C)
|
:0043F373 movzx esi, byte ptr [edi]    <-- mette l'ultimo char del serial letto in esi
:0043F376 inc edi    <-- incrementa edi di 1
:0043F377 cmp esi, 0000002D    <-- se è uguale a 2D beggar off
:0043F37A mov ebp, esi    <-- mette in ebp l'ultimo char del serial letto
:0043F37C je 0043F383    <-- non deve saltare
:0043F37E cmp esi, 0000002B    <-- se è uguale a 2B elimina il char da edi
:0043F381 jne 0043F387

[...]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043F381(C)
|
:0043F387 xor ebx, ebx    <-- azzera ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043F3B8(U)
|
:0043F389 cmp dword ptr [0044E24C], 00000001    <-- 0044E24C = 01
:0043F390 jle 0043F39E    <-- salta sempre
:0043F392 push 00000004
:0043F394 push esi
:0043F395 call 0044166F
:0043F39A pop ecx
:0043F39B pop ecx
:0043F39C jmp 0043F3A9

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043F390(C)
|

* Possible StringData Ref from Data Obj ->" ((((( "
->" H"
|
:0043F39E mov eax, dword ptr [0044E040]    <-- mette "0044E04A" in eax
:0043F3A3 mov al, byte ptr [eax+2*esi]    <-- al = eax + (2 * esi) -> esi = char
:0043F3A6 and eax, 00000004    <-- se eax termina per 4 o 8, allora rimane 4, altrimenti 0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043F39C(U)
|
:0043F3A9 test eax, eax    <-- and logico
:0043F3AB je 0043F3BA    <-- se eax = 0 salta, se è 4 no
:0043F3AD lea eax, dword ptr [ebx+4*ebx]    <-- eax = ebx + (4 * ebx) -> al 1° ciclo ebx = 0
:0043F3B0 lea ebx, dword ptr [esi+2*eax-30]    <-- ebx = char + [(2 * eax) - 30]
:0043F3B4 movzx esi, byte ptr [edi]    <-- mette in esi il char dopo del serial
:0043F3B7 inc edi    <-- aumenta edi (per leggere il char dopo al prossimo ciclo)
:0043F3B8 jmp 0043F389    <-- ricomincia il ciclo

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043F3AB(C)
|
:0043F3BA cmp ebp, 0000002D    <-- ebp (quart'ultimo char) deve essere diverso da 2D
:0043F3BD mov eax, ebx    <-- mette ebx (frutto dei calcoli precedenti) in eax
:0043F3BF jne 0043F3C3    <-- se ebp != 2D ok e salta
:0043F3C1 neg eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043F3BF(C)
|
:0043F3C3 pop edi
:0043F3C4 pop esi
:0043F3C5 pop ebp
:0043F3C6 pop ebx
:0043F3C7 ret    <-- fine della call(3)



-----------------------------------------------------------------------



:0043F3D1 59 pop ecx
:0043F3D2 C3 ret     <-- fine della call(2)





-----------------------------------------------------------------------




:004315F8 8B542418 mov edx, dword ptr [esp+18]    <-- mette l'user in edx
:004315FC 83C404 add esp, 00000004
:004315FF 8BFA mov edi, edx    <-- copia l'user in edi
:00431601 33C9 xor ecx, ecx    <-- azzera ecx
:00431603 8A12 mov dl, byte ptr [edx]    <-- mette in dl il primo char del serial
:00431605 BEDF0B0000 mov esi, 00000BDF    <-- mette BDF in esi
:0043160A 84D2 test dl, dl    <-- se l'user è vuoto (primo char = 0x00, ovvero terminatore nullo...)
:0043160C 7426 je 00431634    <-- salta al confronto fra esi ed eax che risulteranno diversi (esi = n con n diverso da 0 e eax = 0)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00431632(C)
|
:0043160E 0FBED2 movsx edx, dl    <-- mette dl (primo char dell'user) in edx
:00431611 41 inc ecx    <-- incrementa ecx
:00431612 0FAFD1 imul edx, ecx    <-- moltiplica edx (char) per ecx (n° char) (risultato in edx)
:00431615 03F2 add esi, edx    <-- somma edx(char * numero char) a BDF (BDF solo per il primo ciclo)
:00431617 81FEBE170000 cmp esi, 000017BE    <-- confronta esi con 17BE
:0043161D 7E06 jle 00431625    <-- se è uguale o minore salta
:0043161F 81EEBE170000 sub esi, 000017BE    <-- altrimenti sottra 17BE a esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043161D(C)
|
:00431625 83F90A cmp ecx, 0000000A    <-- confronta ecx con 10
:00431628 7E02 jle 0043162C    <-- se ecx è uguale o minore salta
:0043162A 33C9 xor ecx, ecx    <-- altrimenti lo azzera

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00431628(C)
|
:0043162C 8A5701 mov dl, byte ptr [edi+01]    <-- viene messo in dl il char dopo
:0043162F 47 inc edi    <-- viene aumentato di uno edi
:00431630 84D2 test dl, dl    <-- se dl non è 0 (terminatore nullo di fine stringa), non salta
:00431632 75DA jne 0043160E    <-- ricomincia il ciclo

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043160C(C)
|
:00431634 3BF0 cmp esi, eax    <-- confronta esi con eax (se il serial è corretto devono essere uguali)
:00431636 750A jne 00431642    <-- se non sono uguali salta (beggar off)
:00431638 5F pop edi
:00431639 5E pop esi
:0043163A 5D pop ebp
:0043163B B801000000 mov eax, 00000001    <-- se sono uguali (serial corretto) setta eax = 1
:00431640 5B pop ebx
:00431641 C3 ret    <-- fine call(1)



* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0043159C(C), :004315A6(C), :004315B0(C), :004315BA(C), :004315DB(C)
|:00431636(C)
|
:00431642 5F pop edi
:00431643 5E pop esi
:00431644 5D pop ebp
:00431645 33C0 xor eax, eax    <-- se non sono uguali (serial non corretto), eax = 0
:00431647 5B pop ebx
:00431648 C3 ret    <-- fine call(1)




--------------------------------------------------------------------------





:00431999 83C408 add esp, 00000008
:0043199C 85C0 test eax, eax    <-- and logico eax, eax
:0043199E 0F84AD000000 je 00431A51    <-- se è 0 (zero flag settato) beggar off, se è 1 (zf non settato) crea una chiave nel registro di sistema con user e serial (programma correttamente registrato)
:004319A4 8D542410 lea edx, dword ptr [esp+10]
:004319A8 8D44240C lea eax, dword ptr [esp+0C]
:004319AC 52 push edx
:004319AD 50 push eax
:004319AE 6A00 push 00000000
:004319B0 683F000F00 push 000F003F
:004319B5 6A00 push 00000000
:004319B7 6814ED4400 push 0044ED14
:004319BC 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"Software\gamani\GIFMovieGear\2.0"
|
:004319BE 68F8B34400 push 0044B3F8
:004319C3 6801000080 push 80000001

* Reference To: ADVAPI32.RegCreateKeyExA, Ord:015Fh
|
:004319C8 FF150C804400 Call dword ptr [0044800C]
:004319CE 8D7C2460 lea edi, dword ptr [esp+60]
:004319D2 83C9FF or ecx, FFFFFFFF
:004319D5 33C0 xor eax, eax
:004319D7 8B54240C mov edx, dword ptr [esp+0C]
:004319DB F2 repnz
:004319DC AE scasb
:004319DD F7D1 not ecx

* Reference To: ADVAPI32.RegSetValueExA, Ord:0186h
|
:004319DF 8B1D18804400 mov ebx, dword ptr [00448018]
:004319E5 51 push ecx
:004319E6 8D4C2464 lea ecx, dword ptr [esp+64]
:004319EA 51 push ecx
:004319EB 6A01 push 00000001
:004319ED 50 push eax

* Possible StringData Ref from Data Obj ->"RegName3"
|
:004319EE 6898D44400 push 0044D498
:004319F3 52 push edx
:004319F4 FFD3 call ebx
:004319F6 8DBC24C4000000 lea edi, dword ptr [esp+000000C4]
:004319FD 83C9FF or ecx, FFFFFFFF
:00431A00 33C0 xor eax, eax
:00431A02 F2 repnz
:00431A03 AE scasb
:00431A04 F7D1 not ecx
:00431A06 8D8424C4000000 lea eax, dword ptr [esp+000000C4]
:00431A0D 51 push ecx
:00431A0E 8B4C2410 mov ecx, dword ptr [esp+10]
:00431A12 50 push eax
:00431A13 6A01 push 00000001
:00431A15 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"RegCode3"
|
:00431A17 68A4D44400 push 0044D4A4
:00431A1C 51 push ecx
:00431A1D FFD3 call ebx
:00431A1F 8B54240C mov edx, dword ptr [esp+0C]
:00431A23 52 push edx

* Reference To: ADVAPI32.RegCloseKey, Ord:015Bh
|
:00431A24 FF1500804400 Call dword ptr [00448000]






Ora ci vuole un bel keygenerator.

Ricapitolando: i primi quattro char devono essere mg37, se il quinto è "s" indica un tipo di licenza site (site license), che implica alcuni privilegi, se non è "s" indica una licenza "normale", gli altri tre sono indifferenti (sia che ci sia s che no) ma gli ultimi quattro devono rispondere ad alcuni requisiti (come prima, indipendentemente da s...) che spiegherò con l'aiuto del keygenerator scritto da me...



Allora, ecco il keygenerator:


#include
#include
using namespace std;

FILE *in = fopen("user.txt","rb");
FILE *out = fopen("serial.txt","wt");

void main(void){

        int c, e, ecx, eax= 0;
        int esi = 0xBDF;
        char edx;

        cout << "Inserire il numero di lettere dell'user: ";
        cin >> c;

        c++;

        for(ecx=1; ecx < c; ecx++){

            fread(&edx,1,1,in);

            e = edx * ecx;
            esi += e;

            if(esi>0x17BE){
                esi -= 0x17BE;
            }

            else
                if(ecx==10){
                    ecx = 0;
                }
        }

        eax = esi;

        fprintf(out,"%s","mg37sGEO");
        fprintf(out,"%i",eax);

        fclose(in);
        fclose(out);
}

In pratica, replica i calcoli che il programma fa sull'user. Allora, come avrete già capito guardando la routine per il serial (ve lo ripeto, dato che sono sicuro che l'avete saltato xD), il valore hex della lettera dell'user (EDX) viene moltiplicato per il numero della lettera (ECX) e viene sommato questo valore (la variabile "e", non corrisponde a nessun registro, ma è solo una variabile transitoria che ho usato per comodità) viene sommato a ESI, che al primo ciclo già vale 0xBDF. Poi ESI viene confrontata con il valore hex 0x17BE e, se è superiore, le viene sottratto 0x17BE. Se ECX vale 10, viene azzerato. Le ultime quattro cifre del serial sono il risultato in decimale di quei calcoli che vengono eseguiti sull'username (ringrazio pnluck per aver avuto questa splendida intuizione!!). Quindi alla fine dei calcoli sull'user, il programma stamperà nel file serial.txt la stringa "mg37sGEO" (lo so, sono un lamer ad averci messo "GEO" :D) seguita dal corrispondente decimale del risultato dei calcoli sull'username (che è in EAX)...

                                                                                                                 |GeO|

Note finali

Ringraziamenti e saluti:

-Un salutone a tutte le gnocche croate!!

-Un grazie ad AndreaGeddon per il suo beta-reading e i suoi pareri sui miei modesti tutes.

-Ringrazio pnluck per la sua geniale intuizione riguardante il keygen e per il suo aiuto in altre occasioni!

-Saluto tutti gli studenti della UIC e i frequentatori di #crack-it e #asm

Disclaimer

Questo readme/tutorial è solo a scopo dimostrativo/informativo, non mi assumo nessuna responsabilità per le vostre azioni nè tantomeno per eventuali danni (diretti o indiretti che siano) causati dall'applicazione di quanto trattato qui.

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