Il nostro primo Crack - Update al 10/2003
(Se non avete mai messo mano a un debugger... Questo e' il momento)

Data

by "Quequero"

 

02/Oct/2003

UIC's Home Page

Published by Quequero

Accadono cose che sono come domade.
Passa un minuto, oppure anni, e poi la vita risponde.
(Ale Baricco)

Questo tutorial e' stato scritto con lo scopo di essere lo starting point per tutti quelli che volessero avvicinarsi al reversing, buona fortuna ragazzi!

Non c’è al mondo nulla di così difficile per l’uomo come percorrere la strada che lo conduce a se stesso. (Herman Hesse)

....

Home page: http://quequero.org
E-mail: quequero(at)bitchx(dot)it
Nick: Quequero, #crack-it irc.azzurra.org

....

Difficoltà

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

 
Video

Introduzione

La prima volta che lessi un tutorial fu quello di Ed!son, c'era SoftIce 2.0, c'era l'assembly a 16-bit e c'era il dos... Il tutorial stava dentro un file .bat ed era a sfondo blu con testo in giallo... Poche righe, una paginetta circa che rappresento' per me l'inizio di tutto. Fu una vera a propria illuminazione, da li' comincio' la mia avventura nel mondo del reversing, avventura che va avanti ancora oggi dopo anni e che ha preso vie inaspettate e divertenti che mi hanno dato l'occasione di far avvicinare altre persone a questo affascinante mondo.
Questo tutorial viene scritto con lo stesso intento, se dopo averlo letto si e' accesa in voi la lampadina... Beh probabilmente siete sulla strada giusta, buona fortuna.

Tools usati

Windows XP/2k/2k3
OllyDbg qualunque versione andra' bene (il tutorial e' stato fatto con la 1.08), se il link non andasse, cercate su google o nell'archivio UIC, per questo tutorial ho scelto Olly perche' e' di dimensioni ridotte (poco piu' di un megabyte) e perche' e' free... Oltretutto la sua interfaccia e' estremamente userfriendly e tutto sommato e' un ottimo debugger... Percio' ragazzi, niente SoftICE stavolta :)

Command Line Plugin nell'archivio troverete una dll, dovete solo metterla nella directory dove si trova ollydbg.exe ed avrete anche la commandline di cui si parla sotto.

URL o FTP del programma

RogerWilco v1.4.1.6 e' una versione rippata piccolissima, funziona solo il sistema di registrazione, ovvero l'unica cosa di cui abbiamo bisogno.

Notizie sul programma

RogerWilco e' un programma che viene utilizzato da coloro che giocano online in team, serve a chiacchierare via microfono con gli altri membri della squadra o semplicemente a fare voice-chat. Lo schema di protezione e' assolutamente banale e si tratta di un name/serial che analizzeremo a fondo tra poco. Non e' necessaria alcuna conoscenza specifica dal momento che imparerete le basi tra qualche riga.

Essay

Per prima cosa unzippate e avviate RogerWilco (mi raccomando, se vi appare la schermata di configurazione, configuratelo prima altrimenti ad ogni avvio ve lo chiedera', in questo modo vi risparmiate un sacco di problemi, tanto la configurazione prende appena una ventina di secondi), il pacchetto originale e' quasi 1Mb ma per risparmiare banda ho levato tutto quello che non serviva e in fatti questo e' grande 174kb, se avete bisogno del programma completo potete trovarlo sulla sua home page.
Avviate RogerWilco e clickate su "about", in alto a sinistra c'e' scritto: "Registered To: (Unregisterd)", ok il programma non e' registrato ma a destra abbiamo un pulsante "Enter registration info", clickateci e vi verra' chiesto di inserire un nome, una mail e una key, il nostro obiettivo sara' quello di trovare la chiave giusta per il nostro nome.
Fate una prova, mettete un nome, una mail e un numero fittizzi:
Name: Quequero
E-Mail: [email protected]
Key: 666111666

Clickate su Register e... Beh appare un box con scritto "The registration key you entered is invalid". Perfetto, tutto cio' di cui abbiamo bisogno e' esaminare il codice del programma per vedere come viene manipolato il nostro nome per ottenere un numero valido, il problema e' che non abbiamo il codice sorgente del programma ma questo non e' poi un ostacolo insormontabile, in fondo se il programma si esegue sulla nosta macchina vuol dire che in qualche linguaggio sara' pur scritto.. E se lo capisce la macchina, lo possiamo capire anche noi. Tutto cio' che dobbiamo fare e' entrare all'interno del programma e seguirlo passo-passo, step-by-step per trovare il numero che ci interessa. Ma come si fa tutto questo?
Per prima cosa unzippate OllyDbg in una directory a piacere, avviate il file OllyDbg.exe e se all'inizio appare un box "Old Dll" rispondete di si, il debugger e' pronto, questo sara' lo strumento che useremo per entrare nel codice del programma.
Premete F3, oppure clickate sull'icona apri, e selezionate il file roger.exe, appena il debugger ha caricato il programma in memoria, clickate sul pulsantino "Play" in alto a sinistra, attendete qualche attimo e in secondo piano apparira' la finestra del RogerWilco, tutto quello che vedete all'interno della finestra principale di Olly e' proprio il codice assembly che noi andremo ad analizzare.
Ci si presenta subito un problema, il programma e' fatto di svariate migliaia di righe di codice, come facciamo a sapere quali sono quelle che ci interessano? Questa volta utilizzeremo un tipo di attacco classico, ricordate la messagebox che appariva dopo aver clickato su "Register"? Partiremo da li e torneremo un pochetto indietro.
Dovete sapere che una messagebox viene generata dall'API (Application Program Interface) MessageBox, se avete un'Api Reference (win32.hlp) oppure un MSDN o se siete semplicemente curiosi, andate su msdn.microsoft.com e inserite nel campo di ricerca: MessageBox, vi verra' restituita la struttura di MessageBox che e' la seguente:

int MessageBox(
  HWND hWnd,
  LPCTSTR lpText,
  LPCTSTR lpCaption,
  UINT uType
);

hWnd serve a dire all'API a quale finestra appartiene la messagebox che sta per esser generata.
lpText e' il testo della messagebox.
lpCaption e' la caption, ovvero il titolo della messagebox.
uType serve a specificare i bottoni e le icone presenti nella messagebox.
La messagebox del RogerWilco sara' probabilmente generata usando una chiamata simile a:

MessageBox(NULL, "The registration key you entered is invalid", "Roger Wilco", MB_OK | MB_ICONWARNING);

Adesso sappiamo come viene creato questo box, di conseguenza sappiamo anche in quale punto del codice dobbiamo entrare.
Vi lascio riflettere un secondo su una cosa, anche se non conoscete alcun linguaggio di programmazione concettualmente quello che succede quando premiamo il pulsante di registrazione e' questo:

1. Il programma preleva il nome, la mail e la key inserite nelle tre editbox
2. Il nome viene manipolato in modo da ottenere un numero
3. Il numero ottenuto viene controllato con quello che ha inserito l'utente
3.1 Se il numero e' uguale crea una messagebox con scritto "Registrazione completata" o "Grazie" etc...
3.2 Se il numero e' diverso crea una messagebox con scritto "The registration key you entered is invalid"

Cio' che stiamo per fare e' proprio andare a ritroso dal punto 3.2 fino al punto 2, questo si chiama backtracing, ovvero tracciamo il codice all'indietro per trovare il punto in cui viene effettuato il controllo tra il nostro numero e quello creato dal programma.
A questo punto torniamo nella finestra di Olly e premiamo Alt+F1, dovrebbe apparirvi una command line, badando bene alle maiuscole e alle minuscole, scrivete li dentro:
bpx MessageBoxA
e premete invio, ingrandite la finestra principale ma tenete a portata di mano la command line.
Tutto cio' che abbiamo fatto e' stato dire a Olly che deve fermare l'esecuzione del programma non appena viene richiamata l'API MessageBox, bpx vuol dire: breakpoint on execution e MessageBoxA e' la chiamata sulla quale deve fermarsi, la 'A' finale indica che vogliamo mettere un breakpoint sulla versione a 32-bit di MessageBox, se non avessimo messo quella 'A' il debugger si sarebbe fermato solo se fosse stata invocata la versione a 16-bit di MessageBox (quindi mai!).
State molto attenti alle maiuscole perche' se non sono giuste OllyDbg non piazza il breakpoint!!
A questo punto dentro il RogerWilco inserite il vostro nome, la vostra mail e un numero fittizio, io utilizzero' i dati di sopra... Quindi premete "Register"... E zap! Siamo di nuovo dentro Olly, analizziamo la prima riga:

004074BA   FF155C124100   CALL DWORD PTR DS:[<&USER32.MessageBoxA>]   ; MessageBoxA

004074BA Questo e' l'indirizzo di memoria nel quale si trova questa riga di codice, proprio come l'indirizzo di un'abitazione.

FF15 5C124100 Questo invece e' il codice macchina (opcode), in numerazione esadecimale, ed e' quello che viene eseguito dalla macchina.

CALL DWORD PTR DS:[<&USER32.MessageBoxA>] Questa e' la versione assembly del codice macchina, in pratica il debugger traduce da codice macchina a codice assembly... Sarebbe altrimenti un pochetto scomodo leggere il codice esadecimale non credete? :)... Ma del resto e' esattamente questa la parte che ci interessa, quella riga infatti vuol dire "Chiama MessageBoxA che si trova dentro la dll di sistema User32", l'istruzione CALL non fa null'altro che eseguire una sotto routine del programma.

; MessageBoxA Questo e' semplicemente il commento del debugger.

E' piu' ragionevole che siate un pochetto spaventati da tutte queste informazioni, ma con un po' di pratica ben presto diventera' tutto normale. Torniamo pero' ai nostri passi, ora l'esecuzione del programma e' bloccata e infatti se provate a clickare sul RogerWilco vedrete che la finestra non viene mostrata, questo perche' la chiamata a MessageBox ancora non viene eseguita, dunque non vediamo nulla.
Dentro OllyDbg provate a salire qualche riga con il mouse, vedrete il testo della Messagebox che sta per essere creata...

004074AD  PUSH 30             ; Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
004074AF  PUSH roger.004130D8 ; Title = "Roger Wilco"
004074B4  PUSH roger.004156E8 ; Text = "The registration key you entered is invalid"
004074B9  PUSH EAX            ; hOwner = NULL
004074BA  CALL DWORD PTR [<&USER32.MessageBoxA>>  ; MessageBoxA


Ma qualche riga sopra (all'indirizzo 00407481) guardate cosa c'e': "Thank you for registering RogerWilco", e due righe sotto ancora una chiamata a MessageBoxA, accidenti a quanto pare siamo vicini al punto 3. dove il seriale inserito viene confrontato con quello generato e quindi viene scelta la strada da prendere.
Quello che abbiamo fatto e' un po' di backtracing del codice... Infatti siamo risaliti, ma fino a che punto dobbiamo fare la strada del salmone? Beh ragione vuole che probabilmente il programma fara' qualcosa tipo: "Se il seriale e' giusto vai di li, altrimenti vai di la", questo immagino fosse intuibile vero? Bene, come dovreste sapere i programmi vengono eseguiti riga dopo riga, dall'alto in basso e l'unico modo per far tornare indietro un programma e' usare un salto, in inglese salto si dice jump e guarda caso l'istruzione di salto in assembly e' proprio: JMP, ce ne sono un'altra trentina ma i piu' importanti oltre questo sono JNE/JNZ (Jump if Not Equal/Jump if Not Zero) e JE/JZ (Jump if Equal/Jump if Zero) le due forme sono equivalenti. JMP e' un salto incondizionato perche' quando l'esecuzione del programma arriva li, si salta e basta, gli altri tipi di salto sono tutti condizionati perche' vengono effettuati in base a determinate condizioni. Queste condizioni vengono generate principalmente da due istruzioni, CMP e TEST, la prima sta per "Compare" (confronta) e la seconda per test :p.
Prima di proseguire nella spiegazione di queste istruzioni e' necessario aprire una parentesi: all'interno dei processori Intel/AMD/Cyrix sono presenti alcuni registri hardware, questi non sono nulla piu' che dei contenitori dentro al quale possiamo mettere dei numeri. Ce ne sono svariati ma per il momento ne consideriamo 4, detti anche General Purpose Registers che sono: EAX, EBX, ECX, EDX. Un'altro registro che ci interessa e' quello dei flags, un flag e' semplicemente un bit che puo' assumere due valori: 0 (non settato) oppure 1 (settato), il flag register e' grande 1byte, cioe' 8-bit dunque... 8 flags, uno di questi bit si chiama Zero Flag ed e' molto importante, vedremo ora perche'.
Torniamo dunque a noi, come si utilizzano le istruzioni TEST e CMP? Cosi (ci sono altre forme che non analizzeremo ora):

test eax, eax // lo ZeroFlag viene settato a 1 se EAX = 0
cmp ebx, ecx  // lo ZeroFlag viene settato a 1 se EAX = EBX
cmp ecx, 1
   // lo ZeroFlag viene settato a 1 se ECX = 1

Le istruzioni JNZ/JNE e JZ/JE rispettivamente eseguiranno il salto se lo Zero Flag non e' settato (JNZ/JNE) e se lo Zero Flag e' settato (JZ/JNE), quindi lo Zero Flag viene settato/unsettato almeno dopo ogni TEST e dopo ogni CMP. Abbiamo quindi imparato molte istruzioni, diciamo le piu' importanti: 5 tipi di salto, due di confronto e l'istruzione CALL, conosciamo anche i nomi di alcuni registri. A questo punto esaminiamo un po' di codice tanto per imparare le altre due/tre istruzioni fondamentali :).
Scorriamo il codice all'insu' in cerca di qualche TEST o CMP, siamo vicini ai messaggi ed e' dunque probabile che la decisione sulla validita' del serial venga fatta qui vicino... Ed infatti guardando all'indirizzo 0040742E troviamo:

0040742E    TEST EAX,EAX             // Se EAX e' 0 setta lo ZeroFlag a 1...
00407430    POP EBX
00407431    JNZ SHORT roger.004074A6 // ...E salta all'indirizzo 004074A6

Esaminiamo cosa c'e' all'indirizzo 004074A6:

004074A6 MOV EAX,DWORD PTR SS:[ESP+318]
004074AD PUSH 30
004074AF PUSH roger.004130D8 // Title = "Roger Wilco"
004074B4 PUSH roger.004156E8 // Text = "The registration key you entered is invalid"
004074B9 PUSH EAX
004074BA CALL DWORD PTR DS:[<&USER32.MessageBoxA>>

Nulla di buono a quanto pare... E' proprio il pezzo di programma che fa comparire la messagebox di registrazione fallita (che in gergo viene chiamato: Beggar Off), ma proviamo a fare una cosa... Facciamo in modo che il programma NON effettui quel salto e vediamo cosa succede.
Per prima cosa portatevi col mouse all'indirizzo 00407431, premete F2, se la riga si fa rossa allora abbiamo piazzato un nuovo breakpoint, ma quello vecchio non ci serve piu' percio' premete Alt+B e cancellate con DEL (o CANC) tutte le righe dove sta scritto "MessageBoxA", deve restare solo il breakpoint che abbiamo appena piazzato... Tornate in RogerWilco (se la finestra non appare allora vi siete scordati che il debugger ha congelato il programma, premete un paio di volte sull'icona Play poi tornate in Roger :)) e clickate su register... Zack, il debugger si ferma dove volevamo noi, guardate ora nella finestra a destra dove stanno i nomi dei registri (EAX, ECX, EBX, EDX...), se guardate poco piu' in basso c'e': CPAZSTD... Ecco questo e' il flag register e Z e' proprio lo zero flag e come potete vedere e' a 0 (unsettato), infatti Ollydbg appena sotto la finestra del codice ci dice "Jump is taken", facciamo in modo che questo jump non avvenga, clickate sullo 0 di fianco alla Z e premete invio (oppure clickate col destro sullo 0 e scegliete "Set"), lo 0 e' diventato 1? Se si perfetto! Guardate sotto la finestra del codice: "Jump is NOT taken", ottimo! Premete play e guardate, il programma risulta registrato :))).
Ma se provate a chiudere il programma e a riaprilo... Allora noterete che torna ad essere non registrato... Il motivo e' chiaro, all'avvio il programma prende il seriale fittizio e vede che e' falso, cosa possiamo fare? Cerchiamo il seriale a questo punto!
Vedrete che sara' semplice, ora sapete anche come invertire i salti! Quindi facciamo ancora un po' di backtrace e vediamo dove viene generato questo bel numerello, usiamo un po di zen... Trasformare il nome in un numero puo' essere un'operazione che richiede molte istruzioni quindi magari avranno messo questa conversione in una subroutine richiamata da una call, avviamo di nuovo RogerWilco dentro Olly... Premiamo play e inseriamo il seriale, i breakpoint sono stati salvati, ottimo, guardiamo in alto e all'indirizzo 004073F0 troviamo una call... Mettiamo un breakpoint con F2 su quella CALL, magari siamo fortunati, premiamo play, reinseriamo il seriale e zack... Siamo sulla call, premete F8 una solta volta, in questo modo eseguite la subroutine SENZA entrarci dentro, F8 viene anche detto single-step perche' fa eseguire una riga di codice alla volta.
Guardate la finestra dei registri a destra... EAX, ECX ed EDX sono in rosso, vuol dire che la sub-routine sulla quale siamo passati li ha modificati. Vediamo se dentro questi registri c'e' qualcosa, scrivete nella commandline: d eax, vuol dire: dump eax, cioe': fammi vedere cosa c'e' dentro eax. Ed ora guardate nella finestra in basso a sinistra:

00416A10   52 64 47 44 2D 35 45 52 72 2D 32 72 32 51 2D 36   RdGD-5ERr-2r2Q-6
00416A20   62 67 45 00 00 00 00 00 00 00 00 00 00 00 00 00   bgE.............

Quel numero: RdGD-5ERr-2r2Q-6bgE (ovviamente diverso se avete inserito un nome diverso dal mio) non potrebbe essere il nostro seriale appena generato dalla call??? Boh, proviamo! Premete play, mettetelo e clickate register, se il debugger si ferma premete play di nuovo.
Wow! ce l'abbiamo fatta il seriale e' proprio questo!!! Come avevamo ipotizzato la CALL ha generato il numero per il confronto col nostro seriale e noi l'abbiamo pescato con le mani nel sacco :), terminiamo qui? Naaaa cerchiamo adesso di capire COSA e' successo dalla call in poi.

Appena dopo la call, come potete vedere con Olly, EAX non contiene il seriale bensi un numero: 00416A10, questo numero indica l'indirizzo in memoria nel quale si trova il seriale, per verificarlo digitate appena dopo la call: "d 00416A10" nella commandline, nella finestra in basso troverete esattamente il nostro seriale. Il seriale e' numero lungo 19 caratteri che ovviamente non entrerebbe dentro EAX che e' grande soltanto 32bit (cioe' 4 byte), e' piu' convienente allora dire al programma dove si trova in memoria, in questo modo ne possiamo prendere un pezzetto alla volta per esaminarlo, ed e' quello che succede esattamente nel nostro caso. Quando un registro contiente un indirizzo di memoria, si dice che quel registro punta ad una locazione, nel nostro caso eax PUNTA al seriale.
Prima di continuare spieghiamo l'ultima istruzione della serata: MOV, come potete immaginare significa MOVE, cioe' muovi e si usa in questa maniera:

mov eax, ebx // Copia il valore che sta in ebx dentro eax
mov ebx, 12 // Copia il numero 12 dentro ebx
mov eax, [ebx]
   // Copia in eax il valore puntato da ebx

Spieghiamo l'ultimo caso: immaginate che ebx punti al seriale, quindi ebx = 00416A10, se io facessi:
mov eax, ebx
allora copierei in eax il valore che sta in ebx, percio' eax = ebx = 00416A10, ma se invece che copiarne il valore volessi mettere dentro eax il seriale? Beh dovrei dire al programma di copiare in eax quello che si trova all'indirizzo di memoria contenuto da ebx, e si fa cosi:
mov eax, [ebx]
che sarebbe equivalente a scrivere:
mov eax, [00416A10]
non dovrebbe essere troppo complicato... Ma c'e' una cosa, con le due istruzioni qui sopra muoviamo in eax 4byte dalla locazione 00416A10, e se volessimo avere nel registro un byte alla volta? Non sarebbe difficile, tutti e 4 i general purpose registers possono essere suddivisi in registrini piu' piccoli, ecco come:
eax - 32bit cioe' 4 byte
ax - 16 byte cioe' 2 byte
ah, al - 8 bit ciascuno, cioe' un byte

Ecco quindi che copiare 2 byte puntati da ebx a eax diventa:
mov ax, [ebx] // Copia in ax i primi due byte puntati da ebx (ax e' grande 16bit percio' piu' di due byte non ci entrano)
spostarne uno:
mov al, [ebx] // Copia in al il primo byte puntato da ebx (al e' grande 8bit percio' piu' di un byte non ci entra)
Lo stesso vale per gli altri, avremo quindi "ebx, bx, bh, bl", "ecx, cx, ch, cl", "edx, dx, dh dl", la H sta per "High", la L per "Low", vi faccio un disegnino per chiarirvi le idee:

                        |---AH---|---AL---|
                        |-------AX--------|
bit 31 |---------------EAX----------------| bit 0

NB: Questa suddivisione vale sono per i 4 general purpose registers, gli altri: ESI, EDI, EBP, ESP, possono essere suddivisi soltanto in parti da 16bit l'una: ESI, SI; EDI, DI; EBP, BP; ESP, SP e cosi via.
Un esempio pratico: dentro OllyDbg prendete un registro qualunque nella finestra di destra, ad esempio in questo istante EAX contiene 00416A10 percio': eax = 00416A10, ax = 6A10, ah = 6A, al = 10.
Come vedete e' semplicissimo. Ora che conoscete piu' nel dettaglio i registri e sapete cosa vuol dire che un registro "punta a", possedete tutti gli strumenti necessari per studiare la call qui sotto e crackare il vostro primo programma:

004073F0   CALL roger.00407120 ; Questa e' la call che crea il seriale, dopo di essa EAX punta al vero seriale
004073F5   ADD ESP,4
004073F8   MOV ESI,EAX ; Copia in ESI l'indirizzo di memoria contenuto in EAX (quindi ora anche ESI punta al seriale)
004073FA   LEA ECX,DWORD PTR SS:[ESP+110] ; ECX punta al nostro seriale (fate "d ecx" nella commandline dopo questa riga)
00407401   
MOV DL,BYTE PTR DS:[ECX] ; Copia un byte del valore puntato da ECX (il nostro seriale) in DL
00407403   MOV BL,BYTE PTR DS:[ESI] ; Copia un byte del valore puntato da ESI (il vero seriale) in BL
00407405   MOV AL,DL ; Copia in AL un byte del vero seriale
00407407   CMP DL,BL ; Confronta quindi un byte del seriale vero con una cifra del nostro
00407409   JNZ SHORT roger.00407429 ; Se sono diversi vai verso la Beggar Off
0040740B   TEST AL,AL ; AL = 0? (Il seriale e' finito)
0040740D   JE SHORT roger.00407425 ; Se si allora il seriale e' finito
0040740F   MOV DL,BYTE PTR DS:[ECX+1] ; Copia in DL il byte successivo del nostro seriale
00407412   MOV BL,BYTE PTR DS:[ESI+1] ; Copia in BL il byte successivo del nostro seriale

00407415   MOV AL,DL
; Copia in AL un byte del vero seriale
00407417   CMP DL,BL ; Anche questa cifra e' uguale?
00407419   JNZ SHORT roger.00407429 ; No? Vai verso la beggar off
0040741B   ADD ECX,2 ; Altrimenti aumenta ECX di 2
0040741E   ADD ESI,2 ; E ESI di 2
00407421   TEST AL,AL ; Il seriale e' terminato?
00407423   JNZ SHORT roger.00407401 ; No? Allora continua ad esaminarlo

La routine e' molto semplice (e poco ottimizzata ;p), tutto quello che succede e' questo: viene caricata in un registro una cifra del vero seriale, e in un altro una cifra del seriale da noi inserito, vengono confrontate, se sono uguali si passa ad esaminare la prossima altrimenti si salta alla beggar off. Come vedete ECX ed ESI vengono usati come contatori (ECX e' detto anche counter register) e vengono incrementati di due ad ogni giro (add ecx, 2 significa: aggiungi 2 a ecx).
Perche'? Se 00416A10 e' l'indirizzo al quale si trova la PRIMA cifra del seriale, allora 00416A11 sara' l'indirizzo al quale si trova la seconda cifra, 00416A12 la terza e cosi via... Percio' ECX ed ESI punteranno alla prima cifra durante il primo giro, alla terza durante il secondo e cosi via fino alla fine... Quando AL = 0 vuol dire che il seriale e' finito. Il jump all'indirizzo 00407423 e' quello che fa eseguire questo loop, se non ci fosse allora verebbero esaminati solo i primi due caratteri e non tutto il seriale :).
Questa introduzione al reversing per oggi e' terminata, il titolo mentiva, non abbiamo assolutamente crackato il programma ma abbiamo fatto in modo di scoprire quale fosse il seriale (questa pratica e' detta: reverse engineering sebbene non abbiamo studiato la maniera in cui viene generato questo numero a partire dal nome), abbiamo dunque studiato la routine di protezione invece di modificare fisicamente la struttura del programma ed e' questo che si dovrebbe fare sempre, non e' mai buona norma cambiare un programma tenetelo sempre a mente.
Prima di buttarvi a crackare chissa' cosa dovreste leggere il secondo tutorial perche' chiarira' molti dei dubbi che dovreste avere in questo momento :)
-=Quequero=-

Note finali

Saluto e ringrazio AndreaGay, tutti gli amici di #crack-it, #ahccc, #fogna, #asm, i fratellini Spp e quelle 7 tipe che ieri al pub si sono tanto divertite con me ihihihih :)))

Disclaimer

Vorrei ricordare che il software va comprato e  non rubato, dovete registrare il vostro prodotto dopo il periodo di valutazione. Non mi ritengo responsabile per eventuali danni causati al vostro computer determinati dall'uso improprio di questo tutorial. Questo documento è stato scritto per invogliare il consumatore a registrare legalmente i propri programmi, e non a fargli fare uso dei tantissimi file crack presenti in rete, infatti tale documento aiuta a comprendere lo sforzo che ogni sviluppatore ha dovuto portare avanti per fornire ai rispettivi consumatori i migliori prodotti possibili.

Reversiamo al solo scopo informativo e per migliorare la nostra conoscenza del linguaggio Assembly.