Zoom Icon

Soluzione Crackme 12

From UIC Archive

Crackme n.12 : Una vera e propria applicazione!

Contents


Soluzione Crackme 12
Author: ValerioSoft
Email: ValerioSoft(AT)tin.it
Website:
Date: 20/02/2007 (dd/mm/yyyy)
Level: Luck and skills are required
Language: Italian Flag Italian.gif
Comments: Risolviamo questo crackme INFAME !!!



Introduzione

Ragazzi sto per iniziare a scrivere il mio primo tutorial e mi sa proprio di aver scelto il CrackMe più complicato per poterlo fare :-( ........ comunque non mi scoraggio e vado avanti.

Bene, cercherò di essere il più chiaro possibile in modo tale che i Newbies come me possano comprendere!
Devo ringraziare Zero_G per averci fornito l'ultima versione di Ollydbg già configurata con tutti plugin e con syntax highlightning più chiara (http://zerog.altervista.org/tools.htm). Io mi ero fermato a SoftIce ma devo dire che Ollydbg ci viene davvero incontro.

Bene è giunta l'ora di iniziare! :-) .......... che entrino le fanciulle!!!


Tools


Notizie sul CrackMe N.12

Questo è un crackme scritto da FLIPPER nel lontano 1997 ed è ottimo per passare da puro Newbie a SemiNewbie!!! :-D

..............o almeno spero di aver imparato qualcosa di più dopo averlo crackato!!! (dimmelo tu Que!!!! NdQue: hai fatto davvero un ottimo lavoro, completo in ogni parte, bravo!!!)


Essay

Bene Bene Bene...

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

  1. unregistered delay initiated ( le label sono molto importanti ).
  2. Se si attende che il timer arrivi a zero viene attivato il menù FILE che permette di salvare il documento. Proviamo a salvare e OPS compare una bella messageBox con su scritto: Shareware Notice e You must register to use this option. Annotiamo Annotiamo :-)
  3. Nella cartella del CrackMe ci sono altri 2 bei file, il primo si chiama APP1.DAT che se lo apriamo con il notepad contiene una serie di numeri, poi c'è APP1.CFG che viene creato quando si avvia l'applicazione per la prima volta e contiene CrcValue, Reg_Name, Reg_Num.

Penso possa bastare!!!! Ora possiamo avviare il nostro amato SoftIce noooooooooooooooooooooooooo scusate Ollydbg!!! Facciamolo 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.

C'è più roba di quanto sperassi, infatti compaiono : unregistered delay initialized, "Shareware Notice", "You must register to use this option" e poi ancora qualcosa che non vedevamo tipo Save Dialog, Enter a Filename e Notepad.txt, ecc ecc.Questo è un buon punto di partenza per patchare il programma e come si può notare Ollydbg ci ha dato una mano raggruppando per noi tutte le stringhe UNICODE.

Proviamo ad utilizzare come punto di partenza Shareware Notice eYou must register to use this option quindi clicchiamoci su con il tasto sinistro del mouse e poi premiamo Invio, ci porta dritti dritti alla locazione 00405565. Io solitamente disassemblo il programma da crackare anche con Wdasm il quale mi permette di vedere quale punto del programma ci porta ad una determinata locazione. Infatti guardate il listato seguente :

... Referenced by a CALL at Address: 00404030

00405512 55 push ebp 00405513 8BEC mov ebp, esp ... 0040555F 8945B0 mov dword ptr [ebp-50], eax 00405562 8945C0 mov dword ptr [ebp-40], eax 00405565 C74598A42D4000 mov [ebp-68], 00402DA4 // UNICODE "Shareware Notice" 0040556C 897590 mov dword ptr [ebp-70], esi

Reference To: MSVBVM50.__vbaVarDup, Ord:0000h

0040556F E81CBEFFFF Call 00401390 00405574 8D55A0 lea edx, dword ptr [ebp-60] 00405577 8D4DE0 lea ecx, dword ptr [ebp-20] 0040557A C745A83C2D4000 mov [ebp-58], 00402D3C // UNICODE "You must register to use this option." ... Reference To: MSVBVM50.rtcMsgBox, Ord:0253h

0040559B E8F6BDFFFF Call 00401396 // Richiama il box nel caso in cui si tenta di salvare


Bene come si può notare molto probabilmente si giunge a questa parte di codice dalla riga 00404030, andiamo a vedere cosa c'è li :

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 :

... 00403ECA 663D1B00 cmp ax, 001B 00403ECE 0F8E61010000 jle 00404035 00403ED4 663DFE00 cmp ax, 00FE // confronta i due valori e se sono uguali o il primo è minore
// del secondo salta all'errore di salvataggio.Se il nome cifrato
// e la password sono uguali alla locazione 408030 c'è 00FF
00403ED8 0F8E52010000 jle 00404030 // Se non salta come si può notare qualche rigo più sotto
// c'è il box per salvare il file 00403EDE 6A0A push 0000000A ... 00403F0D 8945A0 mov dword ptr [ebp-60], eax 00403F10 C78548FFFFFF4C2A4000 mov dword ptr [ebp+FFFFFF48], 00402A4C // UNICODE "NOTEPAD.TXT" 00403F1A 89BD40FFFFFF mov dword ptr [ebp+FFFFFF40], edi Reference To: MSVBVM50.__vbaVarDup, Ord:0000h | 00403F20 E86BD4FFFF Call 00401390 00403F25 8D9550FFFFFF lea edx, dword ptr [ebp+FFFFFF50] 00403F2B 8D4DC0 lea ecx, dword ptr [ebp-40] 00403F2E C78558FFFFFF302A4000 mov dword ptr [ebp+FFFFFF58], 00402A30 // UNICODE "Save Dialog" 00403F38 89BD50FFFFFF mov dword ptr [ebp+FFFFFF50], edi Reference To: MSVBVM50.__vbaVarDup, Ord:0000h | 00403F3E E84DD4FFFF Call 00401390 00403F43 8D9560FFFFFF lea edx, dword ptr [ebp+FFFFFF60] 00403F49 8D4DD0 lea ecx, dword ptr [ebp-30] 00403F4C C78568FFFFFF082A4000 mov dword ptr [ebp+FFFFFF68], 00402A08 //UNIC. "Enter a Filename"

Quindi abbiamo trovato il primo punto debole del programma, potremmo pensare di noppare tutta la riga 00403ED8 ovvero inserire al posto di 0F8E52010000 tante coppie di 90 (909090909090). Vediamo come si patcha un programma:

Facciamo una copia dell'eseguibile (APP1.EXE) in modo tale da avere sempre una copia funzionante del programma e poi apriamolo con HIEW32.Sicuramente compaiono una serie di simboli strani ora premiamo F4 e scegliamo DECODE.Adesso premiamo F5 che serve a saltare da una determinata riga del programma e scriviamo l'indirizzo 403ED8 preceduto da un punto (.).Hiew32 ci porta alla locazione desiderata e non ci resta che premere F3 per modificare l'Opcode 0F8E52010000 sostituendolo con 909090909090. Il 90 rappresenta il NOP ovvero No Operation, quindi che cosa stiamo facendo??? Stiamo eliminando il Jump in modo tale che il programma non avvia mai la messageBox di "Shareware Notice".Dopo aver sostituito i valori non ci resta che premere F9 (Update) e F10 (Exit).Non ci resta che mettere l'eseguibile modificato nella cartella del CrackMe provare ad eseguirlo.(Non cancellate il file creato perché ci servirà in seguito).

Con altri programmi questa mossa ci avrebbe permesso di salvare ugualmente il file senza essere registrati ma in questo programma il metodo non funziona dato che il programma al suo avvio controlla l'integrità di alcune righe di codice e in questo caso si accorge che è stata fatta qualche modifica.Ci conviene continuare la nostra ricerca, prendete nuovamente il file non modificato e riapritelo con Ollydbg, poi aprite la schermata per la ricerca delle stringhe e selezionate questa volta "unregistered delay initiated -->" e premete invio :

... 0040528E E9DF000000 jmp 00405372 Referenced by a (U)nconditional or (C)onditional Jump at Address: |0040523A(C) | 00405293 8B4508 mov eax, dword ptr [ebp+08] // mette in eax l'indirizzo che contiene il valore
// per attivare o meno il counter
00405296 66C70530804000FE00 mov word ptr [00408030], 00FE // mette il valore che ci porta
// all'errore nella locazione 408030
0040529F 66833801 cmp word ptr [eax], 0001 // confronta la costante 1 con il valore contenuto
// alla locazione puntata da eax
004052A3 0F85C9000000 jne 00405372 // se i valori sono uguali non salta e mostra il counter
// con la scritta "unregistered delay initialized"

... 004052C2 7514 jne 004052D8 004052C4 6810804000 push 00408010 004052C9 68A81F4000 push 00401FA8 Reference To: MSVBVM50.__vbaNew2, Ord:0000h | 004052CE E8DBC0FFFF Call 004013AE 004052D3 A110804000 mov eax, dword ptr [00408010] Referenced by a (U)nconditional or (C)onditional Jump at Address: |004052C2(C) | 004052D8 8B08 mov ecx, dword ptr [eax] ... | 004052E9 E8CCC0FFFF Call 004013BA 004052EE 8BD8 mov ebx, eax 004052F0 68D82C4000 push 00402CD8 // UNICODE "unregistered delay initiated -->"


Come si può notare qualche riga di codice più su rispetto a "unregistered delay initiated -->" c'è un riferimento ad un salto condizionato situato alla riga 004052C2 ma se controllate vi accorgete che è troppo vicino e poi se salta o non salta si arriva ugualmente alla scritta "unregistered delay initiated -->" quindi non è ciò che stiamo cercando!Diamo un'occhiata ancora più su e ci accorgiamo che c'è un'altro salto condizionato alla riga 0040523A ( una riga di codice lontana).È giunta l'ora di piazzare qualche breakpoint in modo tale da controllare cosa succede realmente a runtime, quindi andiamo qualche riga di codice precedente alla 0040523A ad esempio sulla Call vbaVarTstEq, la selezioniamo e poi clicchiamo con il tasto destro del mouse e scegliamo Breakpoint -> Hardware,on execution.

Ollydbg interromperà l'esecuzione del programma proprio nell'istante prima di eseguire questa funzione dando a noi il controllo totale sul programma, quindi clicchiamo sul triangolino del Play ed avviamo l'applicazione.Bene sembra aver funzionato, quindi ora premiamo 2 volte F8 (ovvero eseguiamo l'intera Call come se fosse un'unica istruzione e poi eseguiamo anche il Test su AX). Ora ci troviamo sul JE (ricordiamo che significa Jump if equal e che è uguale al JZ che significa Jump if zero) quindi salteremo alla locazione 405293 (e saremo vicini all'errore) dato che AX=0.Grazie ad Olly possiamo cambiare il flusso del programma settando lo Zero Flag a 0, guardate a destra c'è una piccola Z con al suo fianco un 1, bene clicchiamoci sull'1 due volte, ora il valore dovrebbe essere zero.Ora il salto non viene più eseguito e ce ne accorgiamo dal fatto che compare la scritta Jump is not taken al posto di Jump is taken.Ora steppiamo con F7 (che permette di eseguire un istruzione alla volta come F8 ma con la differenza che se si preme F7 su una Call allora la si esegue passo passo) e ci troveremo ad eseguire l'istruzione successiva al JE ovvero 0040523C.

Reference To: MSVBVM50.__vbaVarTstEq, Ord:0000h | 00405232 E807C2FFFF Call 0040143E // Qui controlla se il seriale UNICODE inserito è uguale
// al nome UNICODE cifrato restituisce eax=0 se sono diversi
00405237 6685C0 test ax, ax 0040523A 7457 je 00405293 // Se eax=0 allora salta ad attiva counter.
// Bisognerebbe nopparlo per patchare il programma
0040523C 393D10804000 cmp dword ptr [00408010], edi 00405242 66C70530804000FF00 mov word ptr [00408030], 00FF // altrimenti mette alla locazione
// 408030 il valore 00FF che ci permette
// di salvare il file. In questo caso non
// mostra neanche il counter


Ora premiamo il tasto play di Ollydbg e vediamo cosa accade!Perfetto il counter non compare più quindi questo è un altro punto vulnerabile anzi è il migliore in quanto se provate a salvare il file non ci mostra neanche la messagebox di errore.Prima di provare a patchare il programma secondo me conviene porsi una domanda!!! Che cosa succede con l'esecuzione della Call che si trova alla riga 00405232???? :-). Scopriamolo!!! Apriamo la schermata di registrazione del programma ed inseriamo un nome ed un serial, io metto ValerioSoft come nome e Quequero come serial ( sempre se nQue mi da il permesso :-D ). Ora riavviamo il programma cliccando (da Ollydbg) Debug->Restart (questo ricarica nuovamente il CrackMe).eseguiamo il programma premendo sul triangolo del Play e ci ritroviamo nuovamente alla riga 00405232 (infatti li abbiamo piazzato un bel Breakpoint).Ora eseguiamo la Call premendo questa volta F7 (qui le cose si ingarbugliano un po') eseguiamo anche il salto e poi ci appare questo :

7413B99E |. FF7424 08 PUSH DWORD PTR SS:[ESP+8] 7413B9A2 |. FF7424 08 PUSH DWORD PTR SS:[ESP+8] 7413B9A6 |. 6A 00 PUSH 0 7413B9A8 |. E8 E74AFFFF CALL 74130494 7413B9AD |. 8B0485 D4C51174 MOV EAX,DS:[EAX*4+7411C5D4] 7413B9B4 \. C2 0800 RETN 8


Come si può notare steppando con F8 (voi non lo fate) è che il valore di EAX (che a noi serve) viene modificato dalla Call che si trova in questo listato quindi dobbiamo entrarci con F7.Poi steppiamo numerose volte con F8 (il trucco è guardare attentamente qual'è l'ultima volta che viene modificato il valore di EAX prima di uscire dalla funzione).Dopo vari tentativi guardate cosa ho trovato :

74130632 . FF73 08 PUSH DWORD PTR DS:[EBX+8] 74130635 . FF72 08 PUSH DWORD PTR DS:[EDX+8] 74130638 . FF75 08 PUSH DWORD PTR SS:[EBP+8] 7413063B . E8 BC3FF0FF CALL 740345FC


Steppiamo e guardiamo in basso a destra quali parametri vengono passati alla funzione!Si proprio così passa alla funzione il nostro serial ed una stringa formata da lettere e numeri.Dopo l'esecuzione della Call il valore di EAX sarà 00000001 perché le due stringhe non sono uguali!Poi questo valore viene rielaborato da :

7413B9AD |. 8B0485 D4C51174 MOV EAX,DS:[EAX*4+7411C5D4]


Sembra un casino ma è semplice infatti il valore di EAX viene moltiplicato per 4 e sommato alla costante 7411C5D4 poi il valore risultante si trova tra parentesi quadre quindi indica una locazione, quindi sposta in EAX il valore contenuto a quella locazione ovvero 00000000. Se non siete convinti nella zona dei comandi di Ollydbg inserite d 7411C5D8 ovvero ((1*4)+7411C5D4) e vedete in basso a sinistra che a quella locazione ci sono tanti 00000000. Invece come si può intuire a noi serve in EAX il valore della locazione 7411C5D4 che invece contiene FFFFFFFF ovvero un valore negativo.Tornati infatti alla locazione 00405237 se in EAX c'è 00000000 allora il Jump ci porta al Counter mentre se in EAX c'è FFFFFFFF il programma funziona alla grande. Proviamo infatti a modificare il valore contenuto in EAX (in alto a destra) prima di eseguire il TEST alla riga 00405237 inserendo al posto degli 0 tante F.

Bene in questo modo il programma non avvia il Counter e ci permette di salvare anche i file!!!Proviamo quindi a patchare il programma ma ci dobbiamo aspettare il peggio dato che il CrackMe come ho detto in precedenza controlla alcuni byte del file exe all'avvio in modo tale da non farlo funzionare in caso di manomissione ovvero genera una cosiddetta eccezione.Facciamo una copia dell'eseguibile (APP1.EXE) in modo tale da avere sempre una copia funzionante del programma e poi apriamolo con HIEW32.Sicuramente compaiono una serie di simboli strani ora premiamo F4 e scegliamo DECODE.Adesso premiamo F5 che serve a saltare da una determinata riga del programma e scriviamo l'indirizzo 40523A preceduto da un punto (.).Hiew32 ci porta alla locazione desiderata e non ci resta che premere F3 per modificare l'Opcode 7457 sostituendolo con 9090. Il 90 rappresenta il NOP ovvero No Operation, quindi che cosa stiamo facendo??? Stiamo eliminando il Jump in modo tale che qualsiasi valore ci sia in EAX il programma non avvia mai il Counter.Dopo aver sostituito i valori non ci resta che premere F9 (Update) e F10 (Exit).Non ci resta che mettere l'eseguibile modificato nella cartella del CrackMe e provare ad eseguirlo.

Non possiamo credere ai nostri occhi!!!!!!!!!!!!!!!!!!! Il nostro caro e vecchio Flipper si è dimenticato di inserire un controllo anche su questi byte e quindi il programma funziona alla grandeeeeeeeeeeeeee. Io comunque non sono del tutto contento e voi?????????????????????? Siamo riusciti a patchare il programmillo solo per una dimenticanza del programmatore e questo ci fa rimanere su un livello di difficoltà 1 ....... secondo me ci conviene lo stesso indagare.

All'inizio del tutorial abbiamo parlato di APP1.DAT ed abbiamo detto che conteneva degli strani valori....state pensando ciò che sto pensando io???? Forse questi sono i valori che vengono confrontati con gli opcode del file APP1.EXE. È arrivato il momento di utilizzare il file patchato ma che non si avvia....vi avevo detto di non cancellarlo.........cosa avete fatto??? :-D beh ricreateloooooooooo

Apriamolo con Ollydbg, poi apriamo la schermata per le stringhe e tra queste c'è la stringa ".DAT" che guarda caso è l'estensione del file APP1.DAT, bene clicchiamoci su e premiamo invio, poi piazziamo un bel breakpoint on execution ed avviamo il programma con il Play. Il programma dovrebbe fermarsi proprio li e se continuate a steppare vi accorgete che il file viene letto riga per riga:

0040698E 50 push eax // UNICODE "APP1" 0040698F 6838334000 push 00403338 // UNICODE ".DAT" Reference To: MSVBVM50.__vbaStrCat, Ord:0000h | 00406994 E8F1A9FFFF Call 0040138A ... 004069AB 6A01 push 00000001 Reference To: MSVBVM50.__vbaFileOpen, Ord:0000h | 004069AD E8A2A9FFFF Call 00401354 // Apre il file APP1.DAT
Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |00406F3B(C), :0040700A(U) | 004069DB 6A07 push 00000007 Reference To: MSVBVM50.rtcEndOfFile, Ord:023Bh | 004069DD E844AAFFFF Call 00401426 // verifica se è la fine del file 004069E2 6685C0 test ax, ax 004069E5 6A07 push 00000007 004069E7 0F8522060000 jne 0040700F // se è la fine salta altrimenti..... 004069ED 8D45C0 lea eax, dword ptr [ebp-40] 004069F0 50 push eax Reference To: MSVBVM50.__vbaLineInputStr, Ord:0000h | 004069F1 E82AAAFFFF Call 00401420 // legge una riga del file APP1.DAT e la mette in memoria


Adesso se continuiamo ad eseguire il listato a runtime arriviamo alla riga 00406B26 che passa alla funzione la seconda parte della riga letta (riga che cambia ad ogni iterazione, nel primo caso sarà 6338FE068C).Piazziamo un bel breakpoint on execution proprio alla riga 00406B26 in modo tale da interrompere l'esecuzione del programma ad ogni iterazione dato che le righe da leggere sono 7.Dopo aver piazzato il breakpoint riavviamo tutto da Debug->Restart, ora andiamo in Debug->Hardware Breakpoint e cancelliamo tutti quei breakpoint che avevamo settato in precedenza e che non ci servono più, lasciamo solo quello settato alla riga 00406B26. Ora premiamo Play e Olly ci porterà dritti dritti a quella riga e se guardiamo il valore passato alla funzione è proprio 6338FE068C, premiamo ancora Play e guardiamo il valore passato alla funzione che è 0A886E04050563381E050A8B640405056338FB050A8B570405056F0F, premiamo ancora Play ma questa volta il programma si interrompe bruscamente quindi questo ci fa pensare che la parte del programma che abbiamo modificato ha qualche relazione con questa stringa!!!!!!!!!! :-D

La cosa più logica secondo me è capire cosa genera questa eccezione e quindi perché non viene letta la terza stringa. Scorriamo il listato verso l'alto utilizzando Wdasm partendo dalla locazione 00406B26 alla ricerca di qualche salto condizionato, scorrendo arriviamo alla locazione 004069DB :

Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |00406F3B(C), :0040700A(U) | 004069DB 6A07 push 00000007 Reference To: MSVBVM50.rtcEndOfFile, Ord:023Bh | 004069DD E844AAFFFF Call 00401426 // verifica se è la fine del file


Guardate ci sono ben 2 salti, bisogna procedere a tentativi in modo da individuare quello giusto, proviamo quindi ad inserire un breakpoint proprio alla riga 00406F3B, fatto questo riavviamo nuovamente il programma e premiamo Play (Come al solitooooooooooooo :-D ) ed il programma si ferma alla riga 00406B26, allora premiamo ancora Play e giungiamo alla riga 00406F3B, come potete notare il Jump è attivo in quanto nella prima riga del file errori non ce ne sono. Allora premiamo 2 volte Play e ritorniamo sul Jump ma questa volta non è settato dato che il problema è nella seconda riga. Allora scopriamo quali valori vengono passati alla funzione per far si che il Jump venga attivato o meno, quindi togliamo il breakpoint alla riga 00406F3B e lo piazziamo un po' più su ovvero alla riga 00406F2E. Riavviamo tutto e controlliamo, io vi mostro il pezzo di codice disassemblato con Wdasm :

Referenced by a (U)nconditional or (C)onditional Jump at Address: |00406E2B(C) | 00406F2E FF758C push [ebp-74] // passa alla funzione la locazione che contiene i byte del file 00406F31 FF75A4 push [ebp-5C] // passa alla funzione la locazione che contiene i byte giusti
Reference To: MSVBVM50.__vbaStrCmp, Ord:0000h | 00406F34 E827A4FFFF Call 00401360 // controlla le 2 stringhe 00406F39 85C0 test eax, eax 00406F3B 0F849AFAFFFF je 004069DB // se sono uguali salta per leggere la nuova riga
// altrimenti va verso la chiusura del programma.
00406F41 833DB083400000 cmp dword ptr [004083B0], 00000000


Quindi dobbiamo dedurre che sostituendo il JE 004069DB con un JMP 004069DB sicuramente il controllo anche se genera l'errore è costretto a continuare e non può generare l'eccezione. Quindi adesso dobbiamo utilizzare un altro bel programma ovvero il PHOG che ci aiuta a creare l'opcode che ci serve per passare dal JE al JMP. Apriamo il PHOG ed inseriamo la riga del JE ovvero 00406F3B dove c'è scritto INDIRIZZO e poi inseriamo je 004069DB dove c'è scritto MNEMONICO e premiamo invio, guardate un po' ci ha generato proprio l'Opcode corrispondente alla riga editata più l'indirizzo dell'istruzione successiva 00406F41 che coincide proprio con il listato qui sopra. Ora invece dobbiamo sostituire il JE con il JMP e mettere le altre cose come stavano prima e poi premere invio. Come opcode ci da E99BFAFFFF e come istruzione successiva ci da 00406F40, ALLLLLLLLTTTTTTTTTTTTTTTTTTTT!!!!!!!!

L'istruzione successiva è diversa quindi sostituendo 0F849AFAFFFF con E99BFAFFFF l'istruzione successiva si sballa di un byte quindi dobbiamo aggiungere anche un 90 finale e quindi l'opcode diventa E99BFAFFFF90. Salviamo le modifiche al codice con HIEW32, mettiamo il file nella cartella del CrackMe e avviamolo.......siiiiiiiiiiiiiiiiiiiiiiiiiii, prima il file non partiva mentre adesso si avvia, compare il Counter ma se proviamo a salvare il file ci permette di farlo.

Ora proviamo a capire se c'è una vera corrispondenza tra i numeri contenuti nel file APP1.DAT ed i numeri passati alla funzione alla locazione 00406F31. Utilizziamo il file APP1.EXE originale (non patchato) e apriamolo con Ollydbg, settiamo un breakpoint on execution alla locazione 00406F31 ed avviamolo con il Play. Ollydbg si fermerà proprio su alla riga indicata e quindi segnamoci su un foglio le sequenze di valori passate alla funzione per tutte e 7 le volte (Questa è già una indicazione in quanto le righe del file APP1.DAT sono proprio 7 ). Ora è arrivato il momento di utilizzare AXE che ci permette di trovare all'interno di un file delle corrispondenze in esadecimale. Provate infatti ad aprire il file APP1.EXE e scegliete dal menù Edit->Find, poi inserite per il tipo "rawbyte" e cercate 663DFB0389. Bene AXE vi segna in verde la corrispondenza trovata e vi da anche l'offset in cui si trova (segnatevi sul foglio anche l'offset in notazione decimale, se vi da la notazione esadecimale cliccate con il mouse sulla parola offset e lui cambierà notazione), se premete Edit->Find Forward vi trova anche le altre occorrenze successive nel caso in cui esistono! Per questo esempio ovviamente le corrispondenze sono 2.

Ricapitolando alla riga 00406F31 viene passata alla funzione una sequenza di byte che corrisponde proprio ad i byte esatti del file eseguibile che vengono confrontati dalla Call con la sequenza di byte passati alla riga 00406F2E che contiene invece la sequenza di byte presenti nel file eseguibile quindi se noi patchamo il file eseguibile le due sequenze di byte risultano diverse e quindi il programma genera l'eccezione.(Questo lo abbiamo visto anche in precedenza). Ora dobbiamo cercare di capire che corrispondenza c'è tra i numeri del file APP1.DAT e quelli della locazione 00406F31, ragionando l'unico posto dove qualcosa può accadere è dopo la lettura di una delle righe quindi il modo per scoprire questa corrispondenza è settare un breakpoint on execution 004069F1. Facciamolo, io vi propongo il listato disassemblato con i relativi commenti :

00406BA1 FF75B8 push [ebp-48] // passa alla funzione la seconda parte della stringa
Reference To: MSVBVM50.rtcMidCharBstr, Ord:0277h | 00406BA4 E837A9FFFF Call 004014E0 // mette in eax l'indirizzo del primo byte e così via 00406BA9 8BD0 mov edx, eax // copia il suo indirizzo in edx
00406BAB 8D8D78FFFFFF lea ecx, dword ptr [ebp+FFFFFF78] // mette in ECX l'indirizzo
Reference To: MSVBVM50.__vbaStrMove, Ord:0000h | 00406BB1 E8ECA7FFFF Call 004013A2 // salva a quell'indirizzo un'altro indirizzo
00406BB6 8D8D2CFFFFFF lea ecx, dword ptr [ebp+FFFFFF2C] // mette in ECX l'indirizzo
// generato dalla sottrazione
Reference To: MSVBVM50.__vbaFreeVar, Ord:0000h | 00406BBC E813A9FFFF Call 004014D4 // azzera la locazione di ECX 00406BC1 8D8578FFFFFF lea eax, dword ptr [ebp+FFFFFF78] // mette in eax l'indirizzo che contiene
// la locazione della lettera
00406BC7 50 push eax // passa l'indirizzo alla funzione 00406BC8 E8B0D8FFFF call 0040447D 00406BCD DD9D14FFFFFF fstp qword ptr [ebp+FFFFFF14] 00406BD3 C7850CFFFFFF05000000 mov dword ptr [ebp+FFFFFF0C], 00000005 00406BDD 8D950CFFFFFF lea edx, dword ptr [ebp+FFFFFF0C] 00406BE3 8D4DD0 lea ecx, dword ptr [ebp-30] Reference To: MSVBVM50.__vbaVarMove, Ord:0000h | 00406BE6 E8E3A8FFFF Call 004014CE 00406BEB C78514FFFFFF05000000 mov dword ptr [ebp+FFFFFF14], 00000005 00406BF5 89B50CFFFFFF mov dword ptr [ebp+FFFFFF0C], esi 00406BFB 8D45D0 lea eax, dword ptr [ebp-30] 00406BFE 50 push eax 00406BFF 8D850CFFFFFF lea eax, dword ptr [ebp+FFFFFF0C] 00406C05 50 push eax 00406C06 8D852CFFFFFF lea eax, dword ptr [ebp+FFFFFF2C] 00406C0C 50 push eax Reference To: MSVBVM50.__vbaVarXor, Ord:0000h | 00406C0D E8CCA7FFFF Call 004013DE // questa funzione xora il 5 con ogni byte della riga
// ed ottiene i valori esatti che il file eseguibile
// deve avere


C'è da dire che per comprendere cosa stava accadendo a runtime io ho inserito il breakpoint alla riga 004069F1 dove viene letta la riga del file APP1.DAT e poi steppando ho compreso che i valori della seconda parte della riga venivano xorati con il 5 alla riga 00406C0D. Provate infatti a xorare con la colcolatrice scientifica di WinZoz il valore esadecimale 63 con 5 ed otterrete 66 oppure 38 con 5 ed otterrete 3D e così via.

Prima vi ho fatto segnare su un foglio di carta le sequenze di valori passate alla funzione più il relativo offset decimale, confrontate tutto con ciò che è contenuto nel file APP1.DAT, bene sappiamo che ogni byte della seconda parte di ogni rigo viene xorato con il 5 e si ottiene quindi una corrispondenza perfetta mentre per gli offset basta effettuare una semplice sottrazione decimale, ovvero 14989 - 12941 = 2048 questo valore risulta essere lo scarto tra i due valori, quindi gli altri offset saranno 15044 - 2048 = 12966, 16040 - 2048 = 13992, ecc. ecc.

Tutte queste zone di codice che vengono controllate risultano essere quindi delle zone calde e quindi ottime per poter patchare l'applicazione anche se in realtà ve ne sono alcune a mio avviso totalmente inutili!!!

Il Serial Fishing

Siamo giunti alla sezione dedicata al Serial Fishing e non vi nascondo che qui ho qualche perplessità anch'io soprattutto con i floating point!!!

Per pescare l'algoritmo che genera il codice a partire dal nome io ho sicuramente utilizzato un metodo a mio avviso molto da newbie in quanto ho praticamente tenuto d'occhio delle particolari locazioni della memoria in modo tale da seguire il percorso all'indietro partendo dalla riga 00405232 che controlla se il seriale UNICODE inserito è uguale al nome UNICODE cifrato. Piazzate quindi un bel breakpoint alla riga 00405232 e quando Ollydbg prende il controllo entrate nella Call con F7 e steppate fino ad arrivare qui:

74130632 . FF73 08 PUSH DWORD PTR DS:[EBX+8] 74130635 . FF72 08 PUSH DWORD PTR DS:[EDX+8] 74130638 . FF75 08 PUSH DWORD PTR SS:[EBP+8] 7413063B . E8 BC3FF0FF CALL 740345FC


Steppiamo e guardiamo in basso a destra quali parametri vengono passati alla funzione!Si proprio così passa alla funzione il nostro serial ed una stringa formata da lettere e numeri. A questo punto cosa fare??? Beh la cosa più ovvia è quella di tener d'occhio la locazione che contiene la stringa formata da lettere e numeri che si trova alla locazione 14D75C, a questa locazione si trova la stringa UNICODE : 6.A.B.B.E.2.D.0

Ora il discorso si complica notevolmente in quanto bisogna rintracciare le istruzioni che vanno a modificare quella locazione prima della Call che si trova alla riga 00405232, io inizialmente ho agito in questa maniera : ho disassemblato il programma con W32dasm ( a mio avviso è molto comodo per rintracciare i vari salti del programma ) e sono andato alla riga 00405232, ora guardiamo verso l'alto in cerca di una istruzione che può essere raggiunta da un JUMP, la prima è 0040518F che può essere raggiunta mediante un salto condizionato dalla riga 00405188.Piazziamo un breakpoint alla riga 0040518F, riavviamo il programma da Ollydgb e quando prende il controllo scriviamo nella command line in basso a sinistra "d 14D75C" ovviamente senza gli apici. Controlliamo i valori contenuti a quella locazione e ci accorgiamo che non sono cambiati quindi ciò significa che tutte le istruzioni successive alla 0040518F non modificano il contenuto di quella locazione e quindi dobbiamo piazzare il breakpoint ancora più su. Guardiamo quindi il disassemblato di W32dasm partendo dalla locazione 0040518F saliamo ulteriormente alla ricerca di un altro JUMP, i nostri occhi cadono alla riga 004050DA che può essere raggiunta da un salto condizionato dalla riga 00405389, piazziamo il nostro breakpoint alla riga 004050DA e controlliamo poi con il solito metodo la locazione 14D75C e notiamo che i valori sono sempre li quindi dobbiamo salire ancora. Arriviamo alla riga 00404F97 che può essere raggiunta da un salto condizionato dalla riga 00404F34, piazziamo il nostro breakpoint e controlliamo la locazione 14D75C, bene questa volta i valori sono cambiati quindi questo significa che ci sarà una istruzione successiva alla 00404F97 che metterà alla locazione 14D75C la stringa UNICODE : 6.A.B.B.E.2.D.0, steppiamo quindi con F8 osservando la locazione 14D75C. La locazione viene riempita alla riga 00405061 dalla Call, eliminiamo i breakpoint precedenti e ne piazziamo un altro a questa riga e riavviamo, eseguiamo l'applicazione ed Ollydbg prende il controllo, entriamo nella Call con F7 alla ricerca dell'istruzione che modifica i valori della locazione 14D75C, il trucco è steppare con F8 in modo tale da non entrare nelle altre Call e poi nel caso incontriamo un'altra Call che modifica la locazione allora al nuovo riavvio ci entriamo con F7. Secondo quanto detto infatti la nostra locazione viene modificata dalla Call 7407300E che mette in EAX la nostra stringa in formato non UNICODE, quindi riavviamo ed entriamo con F7, steppando incontriamo prima del RET l'istruzione MOV EAX,SS:[EBP-8] che mette in EAX la nostra stringa in formato non UNICODE che si trova alla locazione 12F888, se nella command line scriviamo "d ebp-8" ( senza apici ) possiamo guardare il contenuto della locazione. Quindi adesso la locazione da controllare non è più la 14D75C ma la 12F888, riavviamo e notiamo che alla riga 00405061 la locazione 12F888 non è stata ancora riempita con il valore D0E2BB6A (da notare che viene messo in memoria al contrario ovvero in modalità Little Endian) quindi dobbiamo sicuramente entrare nella Call con F7, poi steppiamo con F8 e arriviamo nuovamente alla Call 7407300E e notiamo che la locazione 12F888 non è stata ancora modificata quindi ci entriamo con F7 e steppiamo con F8, bene la nostra locazione viene modificata dalla Call 7404B193 quindi riavviamo perché dobbiamo entrarci dentro con F7 per vedere cosa succede.Entrati nella Call 7404B193 steppiamo con F8 e ci accorgiamo che la CALL OLEAUT32.#147 modifica la nostra locazione quindi riavviamo ed entriamo con F7 e steppiamo con F8, arriviamo all'istruzione MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] che modifica la locazione 12F888 inserendo i valori contenuti alla locazione 12F7EC ovvero D0E2BB6A quindi adesso questa diventa la nuova locazione da tenere d'occhio. Riavviamo e alla riga 00405061 controlliamo il contenuto della locazione 12F7EC, bene contiene già i valori quindi ci sarà qualche altra istruzione precedente alla 00405061 che la inizializza con quei valori. Riapriamo il disassemblato di W32dasm e cerchiamo un JUMP precedente, io mi fermo qui anche perché il procedimento utilizzato è abbastanza lungo...............spero di essere stato chiaro!

L'algoritmo per la generazione del Serial inizia alla riga 00404CB7, io vi mostro il disassemblato con i relativi commenti inseriti da me medesimo :

00404CB7 50 push eax // passa la posizione della lettera ES: 00000001
00404CB8 FF3524804000 push dword ptr [00408024] // passa alla funzione il nome
// UNICODE ES: ValerioSoft
Reference To: MSVBVM50.rtcMidCharBstr, Ord:0277h | 00404CBE E81DC8FFFF Call 004014E0 // mette in eax la locazione che contiene
// la lettera 14D75C ES: 56000000 = V
00404CC3 8BD0 mov edx, eax // copia la locazione in edx
00404CC5 8D8D14FFFFFF lea ecx, dword ptr [ebp+FFFFFF14] Reference To: MSVBVM50.__vbaStrMove, Ord:0000h | 00404CCB E8D2C6FFFF Call 004013A2 00404CD0 50 push eax // passa alla funzione la locazione della lettera 14D75C
Reference To: MSVBVM50.rtcAnsiValueBstr, Ord:0204h | 00404CD1 E8BCC7FFFF Call 00401492 // mette in eax la lettera 00000056 = V 00404CD6 50 push eax // passa alla funzione la lettera
Reference To: MSVBVM50.__vbaStrI2, Ord:0000h | 00404CD7 E85AC6FFFF Call 00401336 // trasforma la lettera esadecimale in UNICODE
// e mette in eax la locazione in cui è contenuta
// 14D794 ES: 56000000 = 38003600 che corrisponde al
// numero decimale 86 ovvero la lettera V ( se non
// siete sicuri procuratevi una tabella ASCII )
00404CDC 8BD0 mov edx, eax // copia la locazione in edx
00404CDE 8D8D10FFFFFF lea ecx, dword ptr [ebp+FFFFFF10] Reference To: MSVBVM50.__vbaStrMove, Ord:0000h | 00404CE4 E8B9C6FFFF Call 004013A2 00404CE9 50 push eax // passa alla funzione la lettera UNICODE
Reference To: MSVBVM50.rtcR8ValFromBstr, Ord:0245h | 00404CEA E8D9C7FFFF Call 004014C8 // carica il suo valore ( 86 ) nel registro del coprocessore
00404CEF DD9DC4FEFFFF fstp qword ptr [ebp+FFFFFEC4] // memorizza il numero nella cima dello
// stack in memoria (12F988) e dopo averlo
// fatto lo estrae (o elimina) dallo stack
// ES: 12F988 = 00000000 00805540 ( NQUE
// qui c'è bisogno del tuo aiuto, che
// rappresentazione del numero è ???? )
00404CF5 8D95BCFEFFFF lea edx, dword ptr [ebp+FFFFFEBC] 00404CFB 8D8D48FFFFFF lea ecx, dword ptr [ebp+FFFFFF48] 00404D01 C785BCFEFFFF05000000 mov dword ptr [ebp+FFFFFEBC], 00000005 Reference To: MSVBVM50.__vbaVarMove, Ord:0000h | 00404D0B E8BEC7FFFF Call 004014CE // sposta il numero in un'altra locazione (12FA14)
00404D10 8D8510FFFFFF lea eax, dword ptr [ebp+FFFFFF10] 00404D16 50 push eax ...

Reference To: MSVBVM50.__vbaVarAdd, Ord:0000h | 00404D47 E85EC7FFFF Call 004014AA // Accede alla locazione 12FA14 (che conterrà la somma
// delle lettere ) e prende il suo valore e lo somma con
// il valore nel registro del coprocessore ( contiene il
// valore della lettera scandita ) e memorizza il
// risultato nel registro del coprocessore ed anche in
// 12F9C8
00404D4C 8BD0 mov edx, eax 00404D4E 8D8D18FFFFFF lea ecx, dword ptr [ebp+FFFFFF18] Reference To: MSVBVM50.__vbaVarMove, Ord:0000h | 00404D54 E875C7FFFF Call 004014CE // passa il valore delle somme in 12F9E4
00404D59 8D857CFEFFFF lea eax, dword ptr [ebp+FFFFFE7C] 00404D5F 50 push eax 00404D60 8D858CFEFFFF lea eax, dword ptr [ebp+FFFFFE8C] 00404D66 50 push eax 00404D67 8D45C0 lea eax, dword ptr [ebp-40] 00404D6A 50 push eax Reference To: MSVBVM50.__vbaVarForNext, Ord:0000h | 00404D6B E834C7FFFF Call 004014A4 00404D70 E91EFFFFFF jmp 00404C93 // salta per un'altra lettera


Penso sia chiaro!!! In questa parte dell'algoritmo viene effettuata la somma decimale di tutte le lettere del nome ValerioSoft e viene memorizzata alla locazione 12F9E4, quindi per il mio nome avremo 86+97+108+101+114+105+111+83+111+102+116 = 1134 ovvero 12F9E4 = 00000000 00B89140

Una volta che lettere del nome sono state tutte sommate viene attivato il JUMP che si trova alla riga 00404C95 e ci porta alla riga 00404D75 :

00404D8A E81BC7FFFF Call 004014AA // somma 1134 e 57001 e memorizza il risultato in
// 12F9C8 = 00000000 E062EC40 00404D8F 8BD0 mov edx, eax
00404D91 8D8D18FFFFFF lea ecx, dword ptr [ebp+FFFFFF18] Reference To: MSVBVM50.__vbaVarMove, Ord:0000h | 00404D97 E832C7FFFF Call 004014CE // mette il risultato nella locazione 12F9E4
00404D9C 8D85CCFEFFFF lea eax, dword ptr [ebp+FFFFFECC]


Quindi è stata effettuata una bella addizione tra il valore ricavato dalla somma delle lettere più 57001 di cui non sappiamo nulla o meglio conosciamo solo la locazione che lo contiene ovvero 12F9F4, anche in questo caso ci conviene tener d'occhio la locazione indicata e guardando il disassemblato di W32dasm la cosa più ovvia da fare è mettere un breakpoint alla riga 00404AA0, riavviare e steppare con F8. Bene vedete più giù cosa succede????

00404BBC C785D4FEFFFFA9DE0000 mov dword ptr [ebp+FFFFFED4], 0000DEA9 // salva in 12f998
// la costante 0000DEA9
00404BC6 899DCCFEFFFF mov dword ptr [ebp+FFFFFECC], ebx Reference To: MSVBVM50.__vbaVarMove, Ord:0000h | 00404BCC E8FDC8FFFF Call 004014CE // la mette alla locazione 12F9F4


È una costante e quindi il valore 57001 viene sempre sommato indipendentemente dal nome inserito.Continuiamo quindi ad osservare l'algoritmo del serial riprendendo da dove avevamo lasciato ovvero alla riga 00404D8A.Se vi siete segnati tutti gli spostamenti per la generazione del serial su un foglio (ricordate il ragionamento a ritroso???? ) adesso dovreste sapere che la prossima istruzione che ci modifica il valore alla locazione 12F9E4 è la riga 00404E63

00404E63 E848C6FFFF Call 004014B0 // moltiplica 58135 con 2033 e memorizza il risultato in
// 12F9C8 = 0000009C A62D9C41 00404E68 8BD0 mov edx, eax 00404E6A 8D8D18FFFFFF lea ecx, dword ptr [ebp+FFFFFF18] Reference To: MSVBVM50.__vbaVarMove, Ord:0000h | 00404E70 E859C6FFFF Call 004014CE // mette il risultato nella locazione 12F9E4


Adesso ci conviene controllare da cosa dipende il valore 2033 posto alla locazione 12FA04 e ci conviene ripiazzare un breakpoint alla riga 00404AA0 e riavviare, steppiamo con F8, la locazione 12FA04 viene modificata dalla riga 00404BED, guardate:

00404BDD C785D4FEFFFFF1070000 mov dword ptr [ebp+FFFFFED4], 000007F1 // salva in 12f998
// la costante 000007F1
00404BE7 89B5CCFEFFFF mov dword ptr [ebp+FFFFFECC], esi Reference To: MSVBVM50.__vbaVarMove, Ord:0000h | 00404BED E8DCC8FFFF Call 004014CE // la mette alla locazione 12F9F4


Questa è un'altra costante quindi vale il discorso fatto in precedenza!!!! Ora togliamo il breakpoint e torniamo ad analizzare l'algoritmo del serial :

00404E8A E8F1C5FFFF Call 00401480 // divide 118188455 con 6 e memorizza il risultato
// in 12F9C8 = 555555BD 19C97241
00404E8F 50 push eax 00404E90 8D85ECFEFFFF lea eax, dword ptr [ebp+FFFFFEEC] 00404E96 50 push eax Reference To: MSVBVM50.__vbaVarInt, Ord:0000h | 00404E97 E8EAC5FFFF Call 00401486 // tronca la parte decimale del risultato e lo rende
// un numero intero, poi lo memorizza alla locazione 12F9B8
00404E9C 8BD0 mov edx, eax 00404E9E 8D8D18FFFFFF lea ecx, dword ptr [ebp+FFFFFF18]

Reference To: MSVBVM50.__vbaVarMove, Ord:0000h | 00404EA4 E825C6FFFF Call 004014CE // mette i valori della locazione 12F9B8
// nella locazione 12F9E4 = 000000B0 19C97241


Anche in questo caso il 6 è una costante, vi fidate???? OK allora possiamo continuare...............alla riga 00404EBB c'è una somma :

00404EBB E8EAC5FFFF Call 004014AA // somma 19698075 con 1771000117 ( 698F5135 è una
// costante! ) e memorizza il risultato in 12F9C8
00404EC0 8BD0 mov edx, eax 00404EC2 8D8D18FFFFFF lea ecx, dword ptr [ebp+FFFFFF18] Reference To: MSVBVM50.__vbaVarMove, Ord:0000h | 00404EC8 E801C6FFFF Call 004014CE // mette il risultato nella locazione
// 12F9E4 = 000000B4 F8AEDA41


Questa è l'ultima operazione effettuata infatti il valore contenuto alla locazione 12F9E4 non viene più modificato fino all'istruzione 00405232 che controlla se il serial inserito è uguale a quello calcolato! Ricapitoliamo la situazione:

Io all'inizio ho inserito come nome ValerioSoft, come prima cosa viene effettuata la somma decimale tra tutte le lettere e quindi 86+97+108+101+114+105+111+83+111+102+116 = 1134 poi al risultato si somma 57001 e quindi 57001 + 1134 = 58135, questo risultato viene moltiplicato con 2033 e quindi 58135 x 2033 = 118188455, questo risultato va diviso per 6 e quindi 118188455 : 6 = 19698075.83, di questo risultato si prende solo la parte intera ovvero 19698075 e si somma con 1771000117 quindi 19698075 + 1771000117 = 1790698192 che convertito in esadecimale con la calcolatrice di WinZoZ diventa 6ABBE2D0, questo quindi è il serial che registra il programma se inseriamo come nome ValerioSoft.

Visto che abbiamo FINALMENTE finito, vorrei omaggiare QUEQUERO trovando il suo serial corrispondente, questa volta facciamo direttamente i calcoli :

81 + 85 + 69 + 81 + 85 + 69 + 82 + 79 = 631
631 + 57001 = 57632
57632 x 2033 = 117165856
117165856 : 6 = 19527642
19527642 + 1771000117 = 1790527759 che convertito in esadecimale fa 6AB9490F

Il KeyGen

In base ai calcoli effettuati per la generazione del serial è molto semplice creare un Keygen in linguaggio C. Bastano infatti una manciata di istruzioni, guardate il listato seguente :

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

#define DIM 8 // definisce la costante DIM

void esadecimale(); // converte il numero decimale in esadecimale void visualizza(); // visualizza il numero convertito nella base scelta

int vet[DIM]; // vettore per memorizzare le cifre del numero convertito long int serial; // numero decimale da convertire

int main() {

   char nome[20];                 // in C le stringhe sono vettori di char
   long int somma=0;              // variabile usata per i calcoli
   unsigned int i;
   printf("\n\n\nKeygen CrackMe N.12 coded by ValerioSoft\n\n");
   printf("Inserisci il nome: ");
   scanf("%s", nome);             // mette nella variabile il nome inserito
   for(i=0; i<=strlen(nome); i++) somma += nome[i]; // somma lettere
   for(i=0;i<DIM;i++)             // azzeramento elementi del vettore 
   {
       vet[i]=0;
   }
   somma += 57001;                  // somma = somma + 57001
   somma *= 2033;                   // somma = somma * 2033
   somma /= 6;                      // somma = somma / 6              
   somma += 1771000117;             // somma = somma + 1771000117
   serial = somma;                  // assegno il risultato a serial per la
                                    // conversione in esadecimale 
   esadecimale();                   // converte in esadecimale il valore
                                    // contenuto nella variabile serial
   printf("\nSeriale calcolato: ");
   visualizza();                    // visualizza il numero esadecimale
   scanf("%s", nome);               // serve a non far chiudere il programma
   return 0;

}

void esadecimale() {

   int i;	                     
   for (i = 0;i<DIM; i++)           // memorizzazione a partire dall'ultimo
   {	                             // elemento del vettore
       vet[DIM-1-i]=serial%16;	     // resto della divisione
       serial=serial/16;	     // quoziente della divisione
   } 

}

void visualizza() {

 int j;
 for(j=0;j<DIM;j++)
 {
   if(vet[j]>=10) printf("%c ",vet[j]+ 'A' - 10);	// controllo per la
   else printf("%c ",vet[j]+'0');           		// visualizzazione delle
 }                                           		// lettere esadecimali

}


Bene anche il keygen è funzionante, adesso posso ricoverarmi!!! :-D



Note Finali

Beh essendo nuovo non mi resta che salutare tutta UIC e soprattutto a chi ha scritto prima di me tutorial e mi ha permesso di imparare qualcosa!

Un saluto particolare va Quequero per la sua pazienza (Sei così pignola/o per l'estetica che credo tu sia realmente una donna!!!hai già un fidanzato??? ;-D). Un saluto doveroso va anche a Zero_G. Spero di poter scrivere qualche altro tutorial e spero di non aver commesso molti errori!!!! 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.