Zoom Icon

Soluzione Crackme 16

From UIC Archive

Crackme n.16 : Nome e serial con pulsante di registr. disabilitato ;)))

Contents


Soluzione Crackme 16
Author: ValerioSoft
Email: ValerioSoft(AT)tin.it
Website:
Date: 01/03/2007 (dd/mm/yyyy)
Level: Luck and skills are required
Language: Italian Flag Italian.gif
Comments: Proverbio Cinese : Il baco da seta tesse il suo bozzolo e vi rimane dentro, imprigionato; il ragno tesse la sua tela e ne rimane fuori, libero.



Introduzione

ANCORA TU???
Certo!!! Benvenuti al mio terzo Tutorial o almeno spero :-)


Tools


Notizie sul CrackMe N.16

Questo è un crackme scritto da Magenta [GD] ed ha diverse differenze con i CrackMe trattati nei precedenti Tute.


Essay

Bene Bene Bene...

...come prima cosa avviamo il CrackMe in modo tale da individuare qualche punto debole :

  1. Come prima cosa notiamo quella bella scritta a scorrimento, io la sostituirei subito con ValerioSoft :-D
  2. AZZZZZZ come seconda cosa notiamo che il pulsante OK è disabilitato!!!

Penso non ci sia nient'altro di rilevante!!!! Avviamo Ollydbg e poi mediante File->Apri carichiamo l'eseguibile del CrackMe. La prima cosa da fare è controllare se c'è qualche riferimento alle stringhe di testo che ci siamo segnati in precedenza.Quindi clicchiamo con il tasto destro del mouse sulla parte relativa al codice e poi scegliamo Search for -> All Referenced Text String.

Ciò che risalta ai nostri occhi sono le stringhe : UNICODE "Congratulations", UNICODE "Info", UNICODE "Crackme#3 was written by Magenta [GD]" e UNICODE "Magenta [GD]".

Proviamo ad utilizzare come punto di partenza UNICODE "Magenta [GD]" quindi clicchiamoci su con il tasto sinistro del mouse e poi premiamo Invio, ci porta dritti dritti alla locazione 00402B25. Osservate l'istruzione MOV EDX,00401E6C, cosa significa? Significa che alla locazione 00401E6C c'è la scritta UNICODE Magenta [GD], quindi adesso scriviamo nella Command line d 401E6C e premiamo INVIO. Quante lettere formano la stringa Magenta [GD] ???? 12 ( compreso lo spazio :-D ) quindi quanti byte occuperà in memoria la stringa essendo UNICODE????? 12 x 2 = 24 byte. Mentre ValerioSoft in UNICODE ne occupa solo 22 byte (11 x 2) quindi dovremo aggiungere altri 2 byte del tipo 00 Clicchiamo con il pulsante sinistro del mouse sul primo byte visualizzato ovvero 4D e tenendo il pulsante premuto selezioniamo tutti i byte che compongono la stringa Magenta [GD] compreso il punto finale, poi clicchiamo il tasto destro e scegliamo Binary->Edit oppure con la tastiera facciamo Ctrl+E. Adesso compare una nuova finestra, entriamo nella zona UNICODE e sostituiamo alle lettere di Magenta [GD] le lettere di ValerioSoft o qualsiasi altra cosa volete :-) purchè non superi il numero di caratteri consentito ovvero 12. Se avete inserito ValerioSoft vi è rimasta una lettera in più del vecchio nome, quindi cancellatela ed inserite nella parte HEX (alla fine) due coppie di zeri ovvero 0000.
Segnamoci i valori HEX vecchi (li vedete ancora in basso a sinistra) e quelli generati perchè ci serviranno più tardi.
Io mi segno : 4D 00 61 00 67 00 65 00 6E 00 74 00 61 00 20 00 5B 00 47 00 44 00 5D 00 e 56 00 61 00 6C 00 65 00 72 00 69 00 6F 00 53 00 6F 00 66 00 74 00 00 00 Quando avete finito premete il pulsante OK e poi avviate il pulsante dal Play. Bellissimo!!!! Ora compare il mio nome scorrevole!!!! :-D
Cosa abbiamo fatto???? Abbiamo modificato una locazione di memoria a RunTime quindi ciò significa che al prossimo riavvio tornerà tutto come prima. Per rendere infatti permanente la modifica dobbiamo patchare il programma. Lo facciamo??? Certo!!!
Avviamo AXE e poi apriamo l'eseguibile da modificare (prima di modificare fatevi una copia del file in modo da avere una copia integra in caso di errori) e cerchiamo una parte della stringa (4D006100670065) con il solito modo, ci porta dritti dritti alla stringa UNICODE Magenta [GD], attenzione perchè ce ne sono due e quella che ci interessa è la seconda!!!Possiamo sostituirla con quella nuova e salvare il file. Avviamo il l'applicazione patchata e vaiiiiiiiiiiiiiiii, è semplicemente uno spettacolo!!!! :-D :-) :-P

Le regole per questo CrackMe ci impongono di non patchare il programma ma noi ce ne strafreghiamo e lo facciamo lo stesso!!! Come punto di partenza dobbiamo individuare la Call che crea il Form con il pulsante disabilitato, per questo motivo avviamo Ollydbg steppiamo due volte con F8 e come per magia compare il Form di registrazione, riavviamo l'applicazione e questa volta entriamo nella Call <JMP.&MSVBVM50.#100> con F7 e poi continuiamo a steppare con F8 .....
Senza portarla alla lunga vi riporto qui di seguito tutte le Call in cui dovete entrare per trovare la funzione che inizializza il form inquisito

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

00404030 E8DD140000 call 00405512 // richiama il form di errore nel caso
// in cui si tenta di salvare


La Call che richiama il form di errore viene a sua volta richiamata dalla riga 00403ED8, andiamo a vedere :

Call 7403A294 Call 7403A4C7 Call 7403FF16 Call 74042053 Call 7408B42F Call EBX+1C Call 740599B7 Call 74059A3D Call 74059A82 Call 74059FC7 Call 74058E4B Call 74058EFE Call 74056DB8

L'ultima di queste Call contiene la funzione CreateWindowExA che viene richiamata più volte, una per ogni parte costituente il Form di registrazione, quindi piazziamo un Breakpoint on Execution alla riga 74056F84 in modo da controllarla più da vicino!!! Ciò che ci interessa viene passato alla funzione al terzo giro, guardiamo il listato:

74056F84 PUSH EAX // |hMenu = 00000002 74056F85 PUSH DWORD PTR SS:[EBP-30] // |hParent = 00130472 ('Form1',

                                                   // class='ThunderRT5Form')

74056F88 PUSH DWORD PTR SS:[EBP-1C] // |Height = 29 (41.) 74056F8B PUSH DWORD PTR SS:[EBP-18] // |Width = 81 (129.) 74056F8E PUSH EDI // |Y = 60 (96.) 74056F8F PUSH DWORD PTR SS:[EBP-C] // |X = 0 74056F92 PUSH DWORD PTR SS:[EBP-4] // |Style = WS_CHILD|WS_TABSTOP|

                                                   // WS_CLIPSIBLINGS|WS_DISABLED|2000

74056F95 PUSH DWORD PTR DS:[ESI+7C] // |WindowName = "OK" 74056F98 PUSH EBX // |Class = C226 74056F99 PUSH DWORD PTR SS:[EBP-14] // |ExtStyle = WS_EX_NOPARENTNOTIFY 74056F9C CALL DS:[<&USER32.CreateWindowExA>] // \CreateWindowExA


Ciò che a noi interessa è il parametro Style che contiene WS_DISABLED, quindi steppiamo con F8 fino alla riga '74056F92 e vediamo qual'è la locazione che contiene i valore del parametro Style, la locazione è la 12FB90e in questo caso contiene il valore 4C012000,se lo modifichiamo prima di passarlo alla funzione vediamo che Style cambia ed è proprio questo il nostro intento!!!

Vi mostro qui di seguito una tabella con i relativi valori:

00 00 00 00 WS_OVERLAPPED 01 00 00 00 WS_OVERLAPPED|1 02 00 00 00 WS_OVERLAPPED|2 03 00 00 00 WS_OVERLAPPED|3 ...... FF FF 00 00 WS_OVERLAPPED|FFFF 00 00 01 00 WS_OVERLAPPED|WS_MAXIMIZEBOX 00 00 02 00 WS_OVERLAPPED|WS_MINIMIZEBOX 00 00 03 00 WS_OVERLAPPED|WS_MINIMIZEBOX|WS_MAXIMIZEBOX 00 00 04 00 WS_OVERLAPPED|WS_THICKFRAME 00 00 05 00 WS_OVERLAPPED|WS_MAXIMIZEBOX|WS_THICKFRAME 00 00 06 00 WS_OVERLAPPED|WS_MINIMIZEBOX|WS_THICKFRAME 00 00 07 00 WS_OVERLAPPED|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_THICKFRAME 00 00 08 00 WS_OVERLAPPED|WS_SYSMENU 00 00 09 00 WS_OVERLAPPED|WS_MAXIMIZEBOX|WS_SYSMENU 00 00 0A 00 WS_OVERLAPPED|WS_MINIMIZEBOX|WS_SYSMENU 00 00 0B 00 WS_OVERLAPPED|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU 00 00 0C 00 WS_OVERLAPPED|WS_SYSMENU|WS_THICKFRAME 00 00 0D 00 WS_OVERLAPPED|WS_MAXIMIZEBOX|WS_SYSMENU|WS_THICKFRAME 00 00 0E 00 WS_OVERLAPPED|WS_MINIMIZEBOX|WS_SYSMENU|WS_THICKFRAME 00 00 0F 00 WS_OVERLAPPED|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU|WS_THICKFRAME 00 00 10 00 WS_OVERLAPPED|WS_HSCROLL ........ 00 00 20 00 WS_OVERLAPPED|WS_VSCROLL ........ 00 00 40 00 WS_OVERLAPPED|WS_DLGFRAME 00 00 70 00 WS_OVERLAPPED|WS_BORDER 00 00 C0 00 WS_OVERLAPPED|WS_CAPTION 00 00 00 02 WS_OVERLAPPED|WS_CLIPCHILDREN 00 00 00 04 WS_OVERLAPPED|WS_CLIPSIBLINGS 00 00 00 08 WS_OVERLAPPED|WS_DISABLED 00 00 00 10 WS_OVERLAPPED|WS_VISIBLE 00 00 00 20 WS_OVERLAPPED|WS_MINIMIZE

Da qua non c'è più WS_OVERLAPPED:

00 00 00 40 WS_CHILD 00 00 01 40 WS_CHILD|WS_TABSTOP 00 00 02 40 WS_CHILD|WS_GROUP 00 00 03 40 WS_CHILD|WS_GROUP|WS_TABSTOP 00 00 04 40 WS_CHILD|WS_THICKFRAME 00 00 05 40 WS_CHILD|WS_TABSTOP|WS_THICKFRAME 00 00 06 40 WS_CHILD|WS_GROUP|WS_THICKFRAME 00 00 07 40 WS_CHILD|WS_GROUP|WS_TABSTOP|WS_THICKFRAME 00 00 08 40 WS_CHILD|WS_SYSMENU ........ 00 00 10 40 WS_CHILD|WS_HSCROLL ........ 00 00 20 40 WS_CHILD|WS_VSCROLL ........ 00 00 40 40 WS_CHILD|WS_DLGFRAME 00 00 80 40 WS_CHILD|WS_BORDER 00 00 C0 40 WS_CHILD|WS_CAPTION ........ 00 00 00 42 WS_CHILD|WS_CLIPCHILDREN 00 00 00 44 WS_CHILD|WS_CLIPSIBLINGS 00 00 00 48 WS_CHILD|WS_DISABLED 00 00 00 50 WS_CHILD|WS_VISIBLE 00 00 00 60 WS_CHILD|WS_MINIMIZE ........ 00 00 00 80 WS_POPUP 00 00 01 80 WS_POPUP|WS_MAXIMIZEBOX 00 00 02 80 WS_POPUP|WS_MINIMIZEBOX 00 00 03 80 WS_POPUP|WS_MINIMIZEBOX|WS_MAXIMIZEBOX 00 00 04 80 WS_POPUP|WS_THICKFRAME 00 00 05 80 WS_POPUP|WS_MAXIMIZEBOX|WS_THICKFRAME 00 00 06 80 WS_POPUP|WS_MINIMIZEBOX|WS_THICKFRAME 00 00 07 80 WS_POPUP|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_THICKFRAME 00 00 08 80 WS_POPUP|WS_SYSMENU 00 00 09 80 WS_POPUP|WS_MAXIMIZEBOX|WS_SYSMENU 00 00 0A 80 WS_POPUP|WS_MINIMIZEBOX|WS_SYSMENU 00 00 0B 80 WS_POPUP|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU 00 00 0C 80 WS_POPUP|WS_SYSMENU|WS_THICKFRAME 00 00 0D 80 WS_POPUP|WS_MAXIMIZEBOX|WS_SYSMENU|WS_THICKFRAME 00 00 0E 80 WS_POPUP|WS_MINIMIZEBOX|WS_SYSMENU|WS_THICKFRAME 00 00 0F 80 WS_POPUP|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU|WS_THICKFRAME 00 00 10 80 WS_POPUP|WS_HSCROLL ........ 00 00 20 80 WS_POPUP|WS_VSCROLL ........ 00 00 40 80 WS_POPUP|WS_DLGFRAME 00 00 80 80 WS_POPUP|WS_BORDER 00 00 C0 80 WS_POPUP|WS_CAPTION 00 00 00 82 WS_POPUP|WS_CLIPCHILDREN 00 00 00 84 WS_POPUP|WS_CLIPSIBLINGS 00 00 00 88 WS_POPUP|WS_DISABLED 00 00 00 90 WS_POPUP|WS_VISIBLE 00 00 00 A0 WS_POPUP|WS_MINIMIZE

00 00 00 C0 C0000000


Guardate WS_CHILD|WS_DISABLED inizia da 00 00 00 48 quindi dato WS_ENABLED non esiste per eliminarlo dobbiamo salire di un gradino ovvero a 00 00 00 44 Su WS_CHILD|WS_CLIPSIBLINGS, poi gli aggiungiamo 00 00 01 che è il valore di WS_TABSTOP ed otteniamo 00 00 01 44 che corrisponde a WS_CHILD|WS_TABSTOP|WS_CLIPSIBLINGS, ora ci manca il 2000 finale quindi aggiungiamo anche 00 20 ed otteniamo 00 20 01 44 che corrisponde a WS_CHILD|WS_TABSTOP|WS_CLIPSIBLINGS:2000

Inseriamo questo valore alla locazione 12FB90 e passiamolo alla funzione steppando con F8, poi avviamo il programma e come per magia il pulsante adesso è abilitato, ricordate che questa è una modifica a runtime e quindi al prossimo riavvio tornerà tutto come prima. Ma adesso premiamolo questo benedetto pulsanteeeeeeeeeeeeeeeeeeeeeeee

Congratulation
Well done!! Please send your code to: [email protected]

Ecco il motivo per cui non è ammessa la patch, perchè il pulsante di OK viene sicuramente reso cliccabile a runtime nel caso in cui Il Nome coincide in qualche modo con il Serial.

Solitamente per patchare questo tipo di programmi si utilizza Resource Hacker il quale ci permette di cambiare le impostazioni ai form ma in questo caso non funziona e per questo motivo io onestamente sono andato a tentativi! Ho aperto il programma con AXE e sono andato nella zona in cui ci sono i nomi di tutti gli oggetti che fanno parte del form di registrazione. All'offset 6D0 c'è la stringa OK, io ho cominciato ad incrementare ad uno ad uno i valori esadecimali che si trovano dopo l'OK ed ho notato che questi modificavano in qualche modo il pulsante OK, ad esempio il valore 05 trasformato in 06 influenza la posizione y del pulsante mentre 07 trasformato in 08 influenza Width ovvero la posizione della stringa OK nel pulsante, ecc. ecc.
All'offset 6E0 troviamo 67 02 08 00, beh quest'ultimo 00 trasformato in 01 elimina proprio il WS _DISABLED dallo Style. Salviamo quest'ultima modifica ed avviamo il programma patchato, ora il pulsante viene sempre abilitato ad ogni riavvio.
Lo so è un metodo un pò alla cieca ma sulla strutturazione del file non so darvi spiegazioni :-(

Il Serial Fishing

Come vi dicevo questo programma è un pò diverso dagli altri visto che non funziona la tecnica che utilizziamo sempre ovvero trovare la stringa che ci fa i complimenti e poi vedere qual'è il JUMP che ci porta li.Infatti andiamo a vedere cosa c'è alla riga che utilizza la stringa UNICODE Congratulation utilizzando il solito metodo.

0040221C C74584C01D4000 mov [ebp-7C], 00401DC0 // UNICODE "Congratulations"

...

0040223B FFD7 call edi

Reference To: MSVBVM50.rtcMsgBox, Ord:0253h

0040223D 8B1D70414000 mov ebx, dword ptr [00404170] // mostra la messagebox

Adesso guardiamo più su, cerchiamo ilm JUMP che ci porta a questa parte di codice :

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

00402190 55 push ebp

C'è un salto incondizionato che si trova alla riga 00401B0C.Cosa significa incondizionato? Significa che qualsiasi cosa succede il salto viene effettuato comunque, quindi non si verifica nessun tipo di evento.

Questa cosa ci spiazza un pò perchè non possiamo effettuare il Back Trace, ma non ci perdiamo d'animo, avviamo Ollydbg ed apriamo il programma, poi clicchiamo con il tasto destro del mouse su un punto qualsiasi del codice e scegliamo Search for ->All Intermodular calls. Bene qui ci sono tutte le funzioni utilizzate dal programma, sulla base dei vecchi Tute quale può essere secondo voi una funzione interessante??? Sicuramente _vbaVarTstEq!!! Clicchiamo allora con il tasto destro del mouse su una di queste occorrenze e scegliamo l'opzione Set breakpoint on every call to _vbaVarTstEq, chiudiamo la finestra ed avviamo il programma, inseriamo come nome ValerioSoft e poi come Serial una lettera o un numero qualsiasi e come per magia Ollydbg prenderà il controllo del programma.

Reference To: MSVBVM50.__vbaVarTstEq, Ord:0000h

                                 |

0040257A FF15A0414000 Call dword ptr [004041A0] // Confronta il numero di byte del // nome (ValerioSoft = 22d = 16h)

                                                               // con lo 0

00402580 6685C0 test ax, ax 00402583 0F857E040000 jne 00402A07 // se il numero di byte è 0 salta

                                                               // altrimenti vuol dire che è
                                                               // stato inserito un nome
                                                               // e quindi continua


Per capire cosa fa dovete entrare nella Call con F7. Dato che abbiamo inserite il nome ValerioSoft sicuramente non salterà e continuerà ed eseguire le altre istruzioni, noi premiamo nuovamente il pulsante Play e Ollydbg prenderà nuovamente il controllo del programma.

Reference To: MSVBVM50.__vbaVarTstEq, Ord:0000h

                                 |

004026C5 FF15A0414000 Call dword ptr [004041A0] // Controlla se stiamo

                                                                       // alla fine del nome

004026CB 6685C0 test ax, ax 004026CE 743D je 0040270D // se non è la fine

                                                                       // del nome allora salta

004026D0 8D8D30FFFFFF lea ecx, dword ptr [ebp+FFFFFF30] 004026D6 8D55BC lea edx, dword ptr [ebp-44]


Essendo al primo giro sicuramente non ci troviamo alla fine del nome dato che deve elaborare tutte le lettere che compongono la parola ValerioSoft, per questo motivo salta.

Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004026CE(C) | 0040270D 8D4DDC lea ecx, dword ptr [ebp-24] // ---- salta qui ---- 00402710 8D9548FFFFFF lea edx, dword ptr [ebp+FFFFFF48] 00402716 51 push ecx 00402717 52 push edx

Reference To: MSVBVM50.__vbaStrVarVal, Ord:0000h

                                 |

00402718 FF15C8414000 Call dword ptr [004041C8] // al primo giro prende

                                                                       // l'indirizzo della
                                                                       // prima lettera ( V ) del
                                                                       // nome e lo mette in EAX

0040271E 50 push eax // passa alla funzione

                                                                       // l'indirizzo della
                                                                       // lettera

Reference To: MSVBVM50.rtcAnsiValueBstr, Ord:0204h

                                 |

0040271F FF1554414000 Call dword ptr [00404154] // mette il valore della

                                                                       // lettera (V) in EAX

00402725 8D9500FFFFFF lea edx, dword ptr [ebp+FFFFFF00] 0040272B 8D8D6CFFFFFF lea ecx, dword ptr [ebp+FFFFFF6C] 00402731 66898508FFFFFF mov word ptr [ebp+FFFFFF08], ax // salva la lettera in

                                                                       // memoria

00402738 89BD00FFFFFF mov dword ptr [ebp+FFFFFF00], edi 0040273E FFD6 call esi // MSVBVM50.__vbaVarMove

00402740 8D8D48FFFFFF lea ecx, dword ptr [ebp+FFFFFF48] // mette in ECX l'indirizzo

                                                                     // che contiene il carattere
                                                                     // da leggere (n.2)

...

Reference To: MSVBVM50.__vbaStrVarVal, Ord:0000h

                                 |

00402757 FF15C8414000 Call dword ptr [004041C8] // mette in EAX l'indirizzo

                                                                     // che contiene la seconda
                                                                     // lettera del nome ( a )

0040275D 50 push eax // passa l'indirizzo alla

                                                                       // funzione

Reference To: MSVBVM50.rtcAnsiValueBstr, Ord:0204h

                                 |

0040275E FF1554414000 Call dword ptr [00404154] // mette in EAX il valore

                                                               // della seconda lettera (61)

00402764 8D9500FFFFFF lea edx, dword ptr [ebp+FFFFFF00] 0040276A 8D8D5CFFFFFF lea ecx, dword ptr [ebp+FFFFFF5C] 00402770 66898508FFFFFF mov word ptr [ebp+FFFFFF08], ax // mette il valore in

                                                                       // memoria

00402777 89BD00FFFFFF mov dword ptr [ebp+FFFFFF00], edi 0040277D FFD6 call esi // MSVBVM50.__vbaVarMove

...

Reference To: MSVBVM50.__vbaVarTstGt, Ord:0000h

                                 |

00402799 FF152C414000 Call dword ptr [0040412C] // confronta i valori

                                                                       // delle due lettere
                                                                       // ES: (V = 56) < (a = 61)

0040279F 6685C0 test ax, ax 004027A2 89BD08FFFFFF mov dword ptr [ebp+FFFFFF08], edi 004027A8 89BD00FFFFFF mov dword ptr [ebp+FFFFFF00], edi 004027AE 743C je 004027EC // se la condizione è vera

                                                                       // salta altrimenti
                                                                       // continua...


Quello che si comprende è che al primo giro vengono prese in considerazione le prime due lettere del nome ovvero la V = 56h e a = 61, alla riga 00402799 viene effettuato un confronto : 56h è minore di 61h???? Si allora salta alla riga 004027EC

Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004027AE(C) | 004027EC 8D855CFFFFFF lea eax, dword ptr [ebp+FFFFFF5C] // primo e secondo giro

                                                                       // salta qui

...

Reference To: MSVBVM50.__vbaVarMul, Ord:0000h

                                 |

00402801 FF15B4414000 Call dword ptr [004041B4] // (a = 61) x 2 = C2 00402807 50 push eax

...

Reference To: MSVBVM50.__vbaVarAdd, Ord:0000h

                                 |

00402816 FF15FC414000 Call dword ptr [004041FC] // (V = 56) + C2 = 118 0040281C 8BD0 mov edx, eax

...

Reference To: MSVBVM50.rtcVarStrFromVar, Ord:0265h

                                 |

0040282E FF1504424000 Call dword ptr [00404204] // 118 viene trasformato in UNICODE

                                                              // 280 attraverso divisioni
                                                              // successive con il valore A e
                                                              // viene preso il resto della
                                                              // divisione

L'unica cosa rilevante è rappresentata dalle divisioni successive per Ah = 10 decimale, vediamo:

118 / A = 1C resto 0

1C / A =  2 resto 8
 2 / A =  0 resto 2                                      

Prendendo in considerazione solo i resti delle divisioni in ordine inverso otteniamo 280. Allo stesso modo al secondo giro vengono prese in considerazione la l = 6C e la a = 61. Alla fine dei calcoli otterremo il numero 313. Al terzo giro invece le lettere prese in considerazione sono la l = 6C e la e = 65 ma sappiamo che 6c non è minore di 65 quindi il salto non viene effettuato, guardate il listato seguente :

Reference To: MSVBVM50.__vbaVarMul, Ord:0000h

                                 |

004027C5 FF15B4414000 Call dword ptr [004041B4] // (l = 6C) * 2 = D8

                                                                       // (non serve)

004027CB 8D8D5CFFFFFF lea ecx, dword ptr [ebp+FFFFFF5C] 004027D1 50 push eax 004027D2 8D9520FFFFFF lea edx, dword ptr [ebp+FFFFFF20] 004027D8 51 push ecx 004027D9 52 push edx

Reference To: MSVBVM50.__vbaVarSub, Ord:0000h

                                 |

004027DA FF1530414000 Call dword ptr [00404130] // D8 - (e = 65) = 73

                                                                       // (non serve)

004027E0 8BD0 mov edx, eax 004027E2 8D4D8C lea ecx, dword ptr [ebp-74] 004027E5 FFD6 call esi 004027E7 E999000000 jmp 00402885


Ho scritto a fianco che no serve dato che i valori ottenuti non vengono utilizzati per la generazione del Serial!!!

Alla fine continuando con lo stesso procedimento e saltando le coppie di lettere dove la prima è maggiore o uguale della seconda otterremo il Serial: 280313329327305334

-D ...purtroppo dobbiamo trovare il Serial corrispondente al nome Quequero altrimenti si offende :

Q = 51 u = 75 e = 65 q = 71 u = 75 e = 65 r = 72 o = 6F

51 < 75 // yes 75 x 2 = EA + 51 = 13B = 315 13B / A = 1F resto 5

1F / A = 3  resto 1
 3 / A = 0  resto 3       

75 < 65 // no

65 < 71 // yes 71 x 2 = E2 + 65 = 147 = 327 147 / A = 20 resto 7

20 / A = 3  resto 2
 3 / A = 0  resto 3

71 < 75 // yes 75 x 2 = EA + 71 = 15B = 347 15B / A = 22 resto 7

22 / A = 3  resto 4
 3 / A = 0  resto 3

75 < 65 // no

65 < 72 // yes 72 x 2 = E4 + 65 = 149 = 329 149 / A = 20 resto 9

20 / A = 3  resto 2
 3 / A = 0  resto 3

72 < 6F // no

Name: Quequero e Serial: 315327347329

Il pranzo è servito!!!

Il KeyGen

Il Keygen in linguaggio C.

#include <stdio.h> #include <string.h> #include <stdlib.h>

int main() {

   char nome[20];
   long int somma = 0, molt = 0, quoziente = 0, resto = 0;
   char * serial;        
   unsigned int i,j,n,lunghezza = 0;
   

printf("\n\n\nKeygen CrackMe N.16 coded by ValerioSoft\n\n"); printf("Inserisci il nome: "); scanf("%s", nome);

   printf("\nnumero lettere: %d ",strlen(nome));
   

// conta le coppie di lettere prese in considerazione

   for(i=0; i<strlen(nome); i++) {
             if ( nome[i] < nome[i+1] ) {
                  lunghezza++;
             }
   }
    
   printf("\n\nnumero di coppie da valutare: %d\n",lunghezza);
   

// alloca dinamicamente la memoria per la stringa del serial

   serial = (char *) malloc((lunghezza*3) * sizeof(char));
   if (!serial) {
           printf("\nErrore di allocazione della memoria/n");
           exit(1);
   }
   
   n = 2;   // contatore usato per memorizzare i resti a tre a tre
            // in ordine inverso
for(i=0; i<strlen(nome); i++) { // n. iterazioni = lunghezza nome if ( nome[i] < nome[i+1] ) { molt = nome[i+1] * 2; // ES: (a=61) x 2 = 118 somma = nome[i] + molt; // ES: (V=56) + 118 quoziente = somma; for(j=0; j<3; j++) { resto = quoziente % 10; // ES: 118 modulo (10=A) quoziente = quoziente / 10; // ES: 118 / (10=A) *(serial + n) = resto; // memorizza il resto in // terza posizione n=2 n--; // decrementa n }

n = n + 6; // dopo il for, n = -1, quindi somma 6 per // ottenere n=5 ovvero la sesta posizione

              }
   }
   // mostra il serial

printf("\n\nSeriale calcolato: "); for(i=0;i < (lunghezza*3); i++) printf("%d",*(serial+i));

   // attende un carattere qualsiasi in ingresso

scanf("%s", nome);

   // libera la memoria allocata	

free(serial); return 0; }


Anche questa fatica è fatta!!! :-D



Note Finali

Un saluto a tutti quelli che mi conoscono!!! Ciaoooooooooooooooooo alla proximaaaaaaaaa

ValerioSoft


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 malevole 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.