Troviamo il seriale in GIF Movie Gear 2.51 |
|
|
|
by "AndreaGeddon " |
|
|
|
|
Altro tutorial indicato ai newbies, il serial è molto semplice da trovare e può essere un buon allenamento |
||
UIC's form |
|
UIC's form |
Difficoltà |
(x)NewBies (x)Intermedio ( )Avanzato ( )Master |
Vediamo cosa fa l'algoritmo e generiamoci un serial valido, e vediamo anche come crakkarlo.
Trovaimo il seriale di GIF Movie Gear 2.51
Tools usati |
- RegMon
- APIspy
URL o FTP del programma |
Dunno... me lo ha passato un amico.
Notizie sul programma |
Un animatore di GIF semplice e rapido. Il programma consiste in un solo file eseguibile di 362k. Ha una scadenza a tempo, della durata di 30 giorni.
Essay |
PUNTO PRIMO: IL CRACKING
Per prima cosa vogliamo crakkarlo per fargli credere di essere registrato anche con un seriale fake. Poi vedremo come rubare un seriale.
La prima cosa da fare è breakare su GetWindowTextA.
:00428FFB call ebx
call a getwindowtexta:00428FFD lea eax, dword ptr [esp+78]
:00429001 push 00000064
:00429003 push eax
:00429004 push 00000450
:00429009 push esi
:0042900A call edi
:0042900C push eax
:0042900D call ebx
di nuovo getwindowtexta:0042900F lea ecx, dword ptr [esp+78]
carica il Nome in ecx:00429013 lea edx, dword ptr [esp+14]
carica il serial in edx:00429017 push ecx
li salva:00429018 push edx
e li passa alla call :00429019 call 00428D90 call a una serie di calcoli:0042901E add esp, 00000008
aggiungi 8 allo stack pointer:00429021 test eax, eax
controlla eax:00429023 je 004290CF
se eax=0 il codice era errato, quindi salta
Se avete inserito un serial finto, il jump vi manderà ad eseguire la message box di errore. Se non eseguite il jump, alcune ricge sotto si vede che vengono fatte delle chamate al registro, viene creata una chiave e vi vengono impostati 2 valori (nome e serial). Noppando il salto alla linea 00429023 il programma accetterà per buono il serial finto, e lo scriverà nel registro. Però non è ancora finita. Infatti ci sono altri controlli. Se riavviamo il prog ci dice di registrare, se andiamo su help->about ci dice di registrare. Evidentemente ci sono altri controlli. Carichiamo il regmon ed avviamo il programma. Vediamo che tra le ultime chiavi lette ci sono anche quelle corrispondenti a nome e serial, cioè:
HKEY_CURRENT_USER\Software\gamani\GIFMovieGear\2.0\RegName
HKEY_CURRENT_USER\Software\gamani\GIFMovieGear\2.0\RegCode
Vengono chiamate una volta sola. Adesso dopbbiamo trovare il punto nel codice in cui vengono chiamate, cosa che il regmon non ci dice, ma APIspy si. Quindi
carichiamo apispy, carichiamo come processo il movgear e mettiamo da spiare l'API RegQueryValueExA. Eseguiamolo e avremo la lista di alcune linee di codice in cui viene chiamata quest'api. Se andiamo a fare il confronto con la lista nel regmon, vediamo che le regqueryvalue ai valori che ci interessano sono la pnultima e la terzultima. Così nell'apispy le corrispondenti saranno anche la penultima e la terzultima. Ricordate che in apispy una blocco di due api tipo:
RegQueryValueExA( )
RegQueryValueExA = 0
Va considerato come un'unica chiamata. Arriviamo quindi a trovare le linee di codice in cui vengono chiamate le due chiavi per ricontrollare il Nome e Serial. Il codice è il seguente:
:00428EA5 call esi
prima chiamata a RegName:00428EA7 test eax, eax
:00428EA9 jne 00428F42
:00428EAF lea ecx, dword ptr [esp+10]
:00428EB3 lea edx, dword ptr [esp+78]
:00428EB7 push ecx
:00428EB8 push edx
:00428EB9 push eax
:00428EBA push eax
:00428EBB mov eax, dword ptr [esp+1C]
:00428EBF push 004401D0
:00428EC4 push eax
:00428EC5 mov dword ptr [esp+28], edi
:00428EC9 call esi
chiamata a RegCode:00428ECB test eax, eax
controlla eax:00428ECD jne 00428F42
se eax=0 la chiave è stata letta:00428ECF lea ecx, dword ptr [esp+78]
questo è uguale al precedente:00428ED3 lea edx, dword ptr [esp+14]
frammento di codice::00428ED7 push ecx
salva i valori del nome e serial:00428ED8 push edx
e li passa alla call:00428ED9 call 00428D90
call a calcoli:00428EDE add esp, 00000008
:00428EE1 test eax, eax
:00428EE3 je 00428F42
salta se il codice era errato
Adesso basta noppare anche questo jump, ed il programma sarà registrato al 100%. Fortunatamente gli altri controlli sul serial finivano tutti qui, quindi non dobbiamo cercare altri punti di controllo. E questo è tutto per il craking. Vediamo ora come risolvere l'algoritmo di generazione del serial.
PUNTO SECONDO: TROVIAMO IL SERIAL
Crakkare non ci basta, vogliamo trovare il serial giusto (e magari scrivere anche un keygen), quindi ricominciamo. Rimettiamo un break su getwindowtexta. Ci ritroviamo nella prima parte di codice che ho scritto sopra. Arriviamo fino a:
00429019 call 00428D90
ed entriamo nella call.Arriviamo a:
:00428D90 push ebx
:00428D91 push ebp
:00428D92 mov ebp, dword ptr [esp+10]
:00428D96 push esi
:00428D97 push edi
:00428D98 cmp byte ptr [ebp+00], 6D
compare primo char del serial con 6D, cioè con "m":00428D9C jne 00428E44
se è diverso salta a Errore:00428DA2 cmp byte ptr [ebp+01], 76
compare secondo char con 76, cioè "v":00428DA6 jne 00428E44
se è diverso salta a Errore:00428DAC cmp byte ptr [ebp+02], 67
compare tezo char con 67, cioè "g":00428DB0 jne 00428E44
se è diverso salta a Errore:00428DB6 cmp byte ptr [ebp+03], 32
compare quarto char con 32, cioè "2":00428DBA jne 00428E44
se è diverso salta a Erroreda qui vediamo subito che i primi quattro char del serial devono essere "mvg2", indipendentemente dall'algo.
:00428DC0 mov ebx, 004401F0
...
un pò di controlli con la blacklist. Non inserite i numeri che vedete...
in memoria perchè non verranno accettati :00428DF3 call 0042FFA0 --> questa ci interessa. Entriamo nella call, entrate nelle eventuali sub-call che trovate fino ad arrivare al codice:
:0042FF55 cmp dword ptr [00440E5C], 00000001
:0042FF5C jle 0042FF6B
....
le righe qui in mezzo non vengono eseguite mai :0042FF6B mov edx, dword ptr [00440C50] muove in edx una tabella di valori:0042FF71 mov al, byte ptr [edx+2*esi]
mette in eax un valore della tabella corrispondente al valore edx+2*esi. Per i numeri ci mette sempre 84 Nota: il serial viene usato non tutto, ma solo la parte oltre la 7° cifra. Questo significa che il serial deve essere del tipo: "mvg2xxx" seguito dal numero, dove xxx è un valore qulasiasi.:0042FF74 and eax, 00000004
fa l'and di 84 con 04.:0042FF77 test eax, eax
se eax è 0:0042FF79 je 0042FF8B
salta alla fine:0042FF7B lea eax, dword ptr [ebx+4*ebx]
| questa è la parte importante:0042FF7E xor ecx, ecx
| abbiamo il cuore dell'algo:0042FF80 mov cl, byte ptr [edi]
| di generazione del serial:0042FF82 inc edi
| che se guardate bene:0042FF83 lea ebx, dword ptr [esi+2*eax-30]
| consiste nel convertire il numero decimale:0042FF87 mov esi, ecx
| messo dopo "mvg2xxx" in esadecimale:0042FF89 jmp 0042FF55
ricomincia il ciclo:0042FF8B cmp ebp, 0000002D
:0042FF8E mov eax, ebx
in eax ho il valore finale che verrà usato dopo:0042FF90 jne 0042FF94
:0042FF92 neg eax
:0042FF94 pop edi
:0042FF95 pop esi
:0042FF96 pop ebp
:0042FF97 pop ebx
:0042FF98 ret
Okkey, da qui uscirà un valore contenuto in eax. Teniamolo a mente, perchè ci servirà. Per comodità lo chiameremo Valore_Serial.
Questo Valore_Serial, se ci fate caso, non è altro che il corrispondente esadecimale del valore numerico immesso nel serial dopo la stringa "mvg2xxx". Se per serial avevate inserito il valore "mvg21234567", i primi sette char vengono scartati, e rimane 4567. Il suo corrispondente hex è 11D7, ed è quello che troveremo in eax.
Dopo il ret finiamo subito subito nella rotuine che fa dei calcoli sul nome. Eccola:
:00428DF8 mov edx, dword ptr [esp+18]
:00428DFC add esp, 00000004
:00428DFF mov edi, edx
edi anche contiene il puntatore al nome:00428E01 xor ecx, ecx
azzera ecx:00428E03 mov dl, byte ptr [edx]
mette in dl il char del nome:00428E05 mov esi, 000006FE
inizializza esi.:00428E0A test dl, dl
se il char è zero:00428E0C je 00428E36
salta vai alla fine:00428E0E inc ecx
incrementa ecx:00428E0F movsx edx, dl
mette dl in tutto edx:00428E12 mov ebx, ecx
copia ecx in ebx (ecx = contatore dei char):00428E14 imul ebx, edx
| moltiplica edx per ebx (edx = char attuale):00428E17 add esi, ebx
| aggiungi ad esi il risultato della moltiplicazione:00428E19 cmp esi, 00000DFD
| se esi è più piccolo di DFD:00428E1F jle 00428E27
| salta:00428E21 sub esi, 00000DFD
| se esi è più grande, allora sottrai DFD a esi:00428E27 cmp ecx, 0000000A
| se il contatore è minore di 0A:00428E2A jle 00428E2E
salta:00428E2C xor ecx, ecx
se è maggiore azzeralo:00428E2E mov dl, byte ptr [edi+01]
muovi in dl il prossimo char:00428E31 inc edi
incrementa edi:00428E32 test dl, dl
controlla dl:00428E34 jne 00428E0E
se è zero abbiamo finito:00428E36 cmp esi, eax
compare Valore_Serial con Valore_Nome:00428E38 jne 00428E44
se non sono uguali salta a errore.:00428E3A mov eax, 00000001
mette in eax 1, il che vuol dire che ci abbiamo azzeccato se arriviamo qui:00428E3F pop edi
:00428E40 pop esi
:00428E41 pop ebp
:00428E42 pop ebx
:00428E43 ret
Bene. Dalla riga 00428E14 a 00428E27 abbiamo il cuore della routine. Qui alla fine in esi viene sommato di volta in volta un valore ottenuto dalla moltiplicazione, e gli viene tolto il valore DFD se lo supera. Quindi vediamo alla riga 00428E26 il compare tra il valore ottenuto da esi, che chiamerò Valore_Nome con il Valore_Serial. Il Valore_Serial lo conosciamo già. E' ovvio che dobbiamo fare in modo che il Valore_Serial sia uguale a quello generato dal nome. Come si può fare? Semplice. Il Valore_Serial vi avevo detto che era il corrispondente hex del valore numerico inserito dopo "mvg2xxx". Quindi se deve essere uguale al Valore_Nome, non dobbiamo fare altro che prendere il Valore_Nome, trasformarlo in decimale e attaccarlo a mvg2xxx. Nel mio caso ho inserito il nome AndreaGeddon, ed il serial mvg2xxx4567. Il Valore_Nome che trovo è 50C, mentre il Valore_Serial è 11D7. Basta convertire 50C in decimale, e ottengo 1292. Adesso inserisco come serial mvg2xxx1292 et voilà, il programma è registrato.
Concludendo, se si vuole fare un keygen riassumiamo il lavoro nei seguenti passi:
- badate che n varia da 0 a B inclusi, poi ricomincia da 0.
- Abbiamo in partenza ESI = 6FE
- Prendiamo il valore hex della lettera di posto n nel nome (a partire dalla prima) e la moltiplichiamo per n.
Otterremo n_mod
- ESI = ESI + n_mod
- Se ESI > DFD, allora ESI = ESI - DFD
- Ripeti il ciclo per ogni lettera del Nome
- Alla fine otterremo in ESI il Valore_Nome, da convertire in decimale e attaccare al serial.
Con questo è tutto.
AndreaGeddon
Note Finali |
Saluto tutti gli amici della mailing list. Ciauuuz.
Disclaimer |
Home
Anonimato Assembly
CrackMe ContactMe Forum
Iscrizione Lezioni Links NewBies News Playstation
Tools Tutorial Search
UIC Faq