GIF Movie Gear 3.02
From UIC
Gif Movie Gear 3.02
Contents |
| Infos | |
|---|---|
| Author: | GeO |
| Email: | geuzzo[at]gmail[dot]com |
| Website: | None |
| Date: | 20/08/2004 (dd/mm/yyyy) |
| Level: |
|
| Language: | Italian |
| Comments: | Grazie geo ;p la prox volta attento all'indirizzo ;p |
Introduzione
In questo tute spiegherò come viene verificata l'esattezza del serial inserito e come generare di conseguenza un keygenerator...
Tools
Link e Riferimenti
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...)
|
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:
|: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<br />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:
|: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:
|: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<br />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)
0043F3D2 C3 ret // fine della call(2)
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 =<br />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<br />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)
0043199C 85C0 test eax, eax // and logico eax, eax
0043199E 0F84AD000000 je 00431A51 // se è 0 (zero flag settato) beggar off, se è 1 (zf non <br />settato) crea una chiave nel registro di sistema con user e serial <br />(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:
<nowiki>#include</nowiki> <nowiki><</nowiki>cstdio<nowiki>></nowiki>
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)...
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
I documenti qui pubblicati sono da considerarsi pubblici e liberamente distribuibili, a patto che se ne citi la fonte di provenienza. Tutti i documenti presenti su queste pagine sono stati scritti esclusivamente a scopo di ricerca, nessuna di queste analisi è stata fatta per fini commerciali, o dietro alcun tipo di compenso. I documenti pubblicati presentano delle analisi puramente teoriche della struttura di un programma, in nessun caso il software è stato realmente disassemblato o modificato; ogni corrispondenza presente tra i documenti pubblicati e le istruzioni del software oggetto dell'analisi, è da ritenersi puramente casuale. Tutti i documenti vengono inviati in forma anonima ed automaticamente pubblicati, i diritti di tali opere appartengono esclusivamente al firmatario del documento (se presente), in nessun caso il gestore di questo sito, o del server su cui risiede, può essere ritenuto responsabile dei contenuti qui presenti, oltretutto il gestore del sito non è in grado di risalire all'identità del mittente dei documenti. Tutti i documenti ed i file di questo sito non presentano alcun tipo di garanzia, pertanto ne è sconsigliata a tutti la lettura o l'esecuzione, lo staff non si assume alcuna responsabilità per quanto riguarda l'uso improprio di tali documenti e/o file, è doveroso aggiungere che ogni riferimento a fatti cose o persone è da considerarsi PURAMENTE casuale. Tutti coloro che potrebbero ritenersi moralmente offesi dai contenuti di queste pagine, sono tenuti ad uscire immediatamente da questo sito.
Vogliamo inoltre ricordare che il Reverse Engineering è uno strumento tecnologico di grande potenza ed importanza, senza di esso non sarebbe possibile creare antivirus, scoprire funzioni malevoli e non dichiarate all'interno di un programma di pubblico utilizzo. Non sarebbe possibile scoprire, in assenza di un sistema sicuro per il controllo dell'integrità, se il "tal" programma è realmente quello che l'utente ha scelto di installare ed eseguire, né sarebbe possibile continuare lo sviluppo di quei programmi (o l'utilizzo di quelle periferiche) ritenuti obsoleti e non più supportati dalle fonti ufficiali.