Engenius 4.0.1 Professional & Enterprise Edition ...e non solo =)
VB5 e VB6 reversing & Keygenning =)
W Smartcheck

Data

by " Pincopall "

 

26/04/2002

UIC's Home Page

Published by Quequero


Ma il prodotto "Microsoft Works" ...

Oh pincuzzo...Cavolo complimenti :) ma davvero tanti complimenti hai fatto proprio un bel tute :)

...non ha un nome contraddittorio? =PP

http://pincopall.cjb.net
E-mail: [email protected]
Pincopall on #crack-it #hackmaniaci #tcc ecc..

Difficoltà

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

 

Andremo a reversare Engenius 4, un programma scritto in VB6 ma che per verificare il codice che immettiamo per registrarlo si appoggia ad un file , regwzrd.ocx , scritto in VB5.
Il programma richiede un seriale per essere registrato come Professional Edition ed un altro per passare al successivo livello di Enterprise Edition ( ovviamente più ricco di opzioni ), ovviamente nella versione Trial ha alcune limitazioni, la più fastidiosa delle quali è senza dubbio il fatto che dopo 20 utilizzi pretende di essere registrato, bhè..e noi lo registreremo, no?


Engenius 4.0.1 Professional & Enterprise edition
VB5 e VB6 parliamone e reversiamoli
W Smartcheck

Written by Pincopall

 

KeyGen

Allegato

Introduzione


Allora, siccome un tutorial sul visual basic mancava a quelli scritti da me, eccomi quà a rimediare =)
Come detto sopra il programma in questione è si scritto in Visual Basic 6, ma fà, come tutti i programmi scritti in VB un grandissimo uso di .dll e .ocx, l'ocx in questione è regwzrd.ocx, quindi Engenius userà anche questo file oltrechè msvbvm60.dll ( la .dll tipica di ogni programma scritta in VB6 ) e msvbvm50.dll, file che è in realtà utilizzato da regwzrd.ocx scritto appunto in VB5.
Il tutorial è ovviamente per newbies in quanto la scarsità delle protezioni scritte in Visual Basic è nota, ma c'è una cosa da notare, ci sono molte "tecniche" quasi universali per trovare il seriale nei programmi scritti in VB6, prima fra tutte quella del bpx __vbastrcat, o l'ottimo metodo illustrato da Sator SSH nel tutorial su FF Contascatti 99, ma queste funzionano, da mia esperienza, solo se il programma utilizza l'msvbvm60.dll e non si appoggia su altri file quali il nostro .ocx che è si scritto in VB5 ma che, non dovendo egli essere registrato, ci fà tranquillamente accantonare tutte le nostre tecniche d reversing della msvbvm50.dll imparate leggendo ad esempio la mitica Enciclopedia Italiana sul Cracking by Alor =) .
Ovviamente ci calcoleremo il seriale, la routine non sarà niente di speciale, solo qualche Xor, ma vedremo come non ci sarà neppure necessario starci a studiare la routine ( cosa che faremo al solo scopo di assembly exercise =) ) poichè penserà a tutto il nostro amato Smartcheck.
Ergo se siete proprio alle prime armi leggetevi questo tut anche solo per imparare un po' ad usare Smartcheck =)
Piccola curiosità prima di buttarsi a capofitto nell'essay : msvbvm significa MicroSoft Visual Basic Virtual Machine =)..e ora viaaaaaaa

Tools usati


SoftIce 4.05 -- Come vedrete servirà solo per studiarci la routine e quindi solo per uno sfizio da reverser =)

WinDasm 8.93 o IDA -- Il disassemblatore ci serve sempre per la nostra curiosità

SmartCheck 6.2 -- Debugger per programmi scritti in VB, ci serve praticamente solo lui

URL o FTP del programma


http://www.pegasoweb.com , io l'ho trovato su una rivista con untilizzo ristretto a 20 avvii, cmq su l'url che vi ho dato si può tranquillamente trovare demo e/o ordinare
 

Notizie sul programma


Dicono di lui : " Engenius 4 permette di ottimizzare le pagine web e di inserirle nei principali motori di ricerca con semplicità ; Engenius 4 : il miglior strumento di promozione sul web che il denaro possa comprare "
Minchia...me lo devo proprio comprare hihihihihi :-P

Essay

Ok, abbiamo detto che il nostro programma è in Visual Basic 6, per cui, per chi non lo avesse fatto in precedenza, bisogna modificare il winice.dat in quanto poi il SoftIce ci servirà, anche se solo per curiosità, ergo togliamoci subito il pensiero, e poi il Sice ci servirà per il metodo del bpx __vbastrcat che vi andrò ad illustrare tra poco.
Dunque aggiungiamo, aò fine di esportare le funzioni di questa dll che verranno usate dai programmi in vb6 la stringa


EXP=C:\Windows\System\msvbvm60.dll

Per aver però molto meno da fare per i nostri scopi, questa frase la capirete dopo modifichiamo anche la stringa :

F5="^x;"
facendola diventare F5="^x;^dd eax;"

Questa aggiunta fa sì che ogni volta che noi premiamo F5 per uscire da SoftIce lui ci mostri il contenuto di eax, la troverete molto utile nel metodo del __vbastrcat dato che lì sarà necessario premere più e più volte F5 uscendo da SoftIce che ripopperà dopo pochi millisecondi e dove sarà necessario avere sempre sott'occhio il contenuto di eax.
Bene effettuate le modifiche salviamo winice.dat e riavviamo il sistema per renderle operative.

Siamo finalmente pronti per procedere con la nostra opera di VB reversing.
Ovvero il reversing di Engenius 4.0.1 Professional e EnterPrise Edition.
Dunque installiamolo e facciamolo partire, un avviso ci fà sapere che potremo usare questo programma per 20 volte, e vabbè andiamo a registrarci allora, andiamo nella edit box di registrazione, e mettiamo il nostro nome e il nostro codice...bhè ovviamente il prog ci dice che stiamo sbagliando codice bhè...ce l'aspettavamo =)
Piazziamo quache breakpoint sulle API usate solitamente in questi casi, quindi bpx MessageBoxA , bpx GetDlgItemTextA, bpx GetWindowsTextA ....rimettiamo nome e dummy serial eeeee..nada il Sice non poppa, un lieve sospetto comincia a insinuarsi nella nostra mente; sospetto che diventa certezza quando facciamo una di queste due cose : o togliamo tutti i bpx ( bc* ) e mettiamo un bpx hmemcpy prima di inserire un carattere del nome o del serial, oppure disassembliamo il file engeniusita.exe col nostro disassemblatore, IDA o WDasm o quel che vorrete.
Nel primo caso, dopo aver premuto un tasto vi ritroverete a dover premere un kasino di volte F5, ma ad un certo punto vedrete nella barra verde in basso apparire il nome msvbvm60.dll che appunto ci schiarisce le idee svelandoci che il programma è in VB6 ; nel secondo caso dopo aver disassemblato non potrete non notare i riferimenti a tutte quelle call che cominciano con Msvbvm60!__vbaxxxxxx bhè...=)
Ooooh ora che abbiamo capito perchè i nostri fedeli breakpoint sopra citati non funzionavano, non ci resta che fare quello che facciamo ogni volta che ci troviamo di fronte al reversing di un programma scritto in Visual Basic, ovvero tirare fuori il nostro fido SmartCheck e vedere che si puàò fare =). Dunque, se proprio siete alle prime armi come dicevo sopra, allora è meglio che vi parli del settaggio di SmartCheck, non lo farò però troppo dettagliatamente eh, per quello ci son un bel po' di tutorial, il migliore dei quali, secondo il mio modesto parere, è quello di Kill3xx ( ciao Killo! ) che dovete leggervi absolutely.
Per quanto riguarda le impostazioni di SmartCheck vi dirò semplicemente questo: una volta entrati nel menù Program - Settings, dovrete attivare tutto tranne, nella sezione Error Reporting, la voce "Report Errors Immediately" e nella sezione Reporting, la voce "Report MouseMove events from OCX control".
Dunque carichiamo il nostro Engenius in SmartCheck e facciamolo partire; bene, ora facciamo la normale procedura di inserimento name ( Pincopall Lockless ) & serial ( 23456988 ) e premiamo Register e ovviamente avremo la nostra beggar off in risposta. Vedremo apparire in SmartCheck, durante la esecuzione di Engenius i nomi di tutte le .dll e gli .ocx che il programma utilizza, quindi chiudiamo Engenius e vediamo aprirsi in SmartCheck una finestra con due sezioni "Results" e "Events" , bene, quella che ci interessa particolatmente è la "Events" che come vedete è divisa in due parti, già ma..c'è una infinità di events da esaminare, come facciamo a vedere dove avviene il calcolo del serial adatto al nostro nome? bhè...innanzitutto cerchiamo il momento in cui vediamo apparire la chiamata alla msgbox di errore e poi cerchiamo di capire il perchè questa viene chiamata, ovvero perchè il nostro serial è sbagliato.
Bene, mettiamo "msgbox" nel nostro box di ricerca e, nonostante di messagebox ce ne siano più di una noi siamo in grado di riconoscere quella che ci interessa, basta infatti guardare il contenuto della finestra di destra della sezione "Events", ed eccoci quindi giunti alla fine della nostra ricerca:

 MsgBox(VARIANT:String:"The Regi...", Integer:48, VARIANT:ByRef String:"Engenius...", 
VARIANT:Missing, VARIANT:Missing) returns Integer:1 Arguments -------------------- prompt (variant) String .bstrVal = 004D7B90 = "The Registration Code That You Have Entered Is Not Correct For P" Long buttons = 48 0x00000030 title (variant) unsigned short * * .pbstrVal = 004C6DA0 String = 004D5D50 = "Engenius 4" helpfile (variant) Long .scode = -2147352572 0x80020004 context (variant) Long .scode = -2147352572 0x80020004

Bhè mi sembra che queste righe parlino da sole no? =) la messageBox da noi cercata è questa =).
Nella finestra di destra vediamo inoltre una altra cosa interessante: siamo all'interno di Regwzrd.ocx =).
Dunque una volta trovata la nostra messageBox cominciamo a risalire nel codice per vedere che cosa ci porta quà e soprattutto perchè lo fà, risalendo notiamo tutta una serie di istruzioni che si ripetono periodicamente, cambiano solo i numeri da manipolare da loro presi, non perdete mai d'occhio la finestra di destra eh.
Bhè risalendo risalendo arriveremo alla fine alla chiamata di questa funzione: RegWizardPro.PropertyChanged e quì è meglio fermarci, anche perchè guardate 2 righe sotto cosa c'è: Len Returns LONG: 18 , andateci sopra, dovreste già esserci passati, e nella finestra di destra vedrete che cosa è lungo 18 caratteri ( in decimale ), già, c'è scritto, la stringa "Pincopall Lockless", very very good! =)
Vediamo cosa fà nelle righe seguenti :


Mid$
Asc returns Integer : 80
Chr$
Mid$
Asc returns Integer : 105
Chr$
Mid$
Asc returns Integer : 110
Chr$
....
Bhè così magari si capisce poco, ma come vi ho detto prima guardate sempre nella finestra di destra per capire cosa succede: se andate sul primo Mid$ noterete che lui prende la stringa "Pincopall Lockless" e ne coglie solo il carattere posto alla posizione 1, guardate il secondo, bhè ovviamente questo coglierà il carattere posto alla posizione 2 e così via; I due eventi successivi ci dicono esservi delle istruzioni che analizzano invece il carattere preso dal Mid$ che li precede definendone il valore in decimale e in esadecimale, così ad esempio se guardate il primo "Asc return Integer" ( che già dal nome si dovrebbe capire cosa fà ) vedrete che definisce il valore decimale del carattere ascii "P",prima lettera del nostro nome, il cui valore dec. è appunto 80, che in esadecimale, lo possiamo vedere se andiamo sulla riga Chr$, vale 50.
Questo procedimento avverrà ovviamente fino alla fine del nostro nome, inizierà così una nuova serie di istruzioni atte a portare il valore decimale di ogni lettera del nostro nome da numero intero a stringa, ed eccole quà:

Mid$
Asc returns Integer : 80
Integer (80) --> String ("80")
Mid$
Asc returns Integer : 105
Integer (105) --> String ("105")
....
E quà mi pare non ci sia niente da dire, come prima Mid$ prende l'nesimo valore del nostro nome, il secondo evento definisce il suo valore in decimale e il terzo evento ci dice che ci sono una serie di istruzioni che trasformano il valore decimale di cui sopra in una stringa.
Alla fine tutte queste stringhe verranno messe una dietro l'altra ottenendo così : "801051109911111297108108327611199107108101115115"
Ma vediamo cosa fà dopo aver ottenuto questa stringona:

Len returns LONG: 21
Long (21) --> Integer: 21
...
Come vedete prende in esame una altra stringa di 21 caratteri, e che stringa sarà? bhè, uno sguardo alla stringa nella finestra di destra e vediamo che si tratta di
"FabioHaCreatoEngenius"
Dunque, vediamo un po' che cosa fà subito dopo :

Mid$
Asc returns Integer : 56
Len returns LONG: 48
Mid$
Asc returns Integer : 70
Chr$
Mid$
Asc returns Integer : 48
Len returns LONG: 48
Mid$
Asc returns Integer : 97
Chr$
....

Una nuova serie periodica di eventi che cominciano con quel Mid$ e finiscono col Chr$, ma vediamo cosa fà nella finestra di destra, dunque il primo Mid$ prende il 1° carattere della stringona ottenuta prima, quindi "8", carattere il cui valore decimale è 56, Len returns LONG non ci nteressa, cmq definisce la lunghezza della stringona da cui è stato preso l'8; il secondo Mid$ prende il primo carattere della stringa "Fabio..." ovvero la "F", che ha valore decimale 70, quindi quel Chr$ ci notifica che c'è stato un insieme di istruzioni che ci ha restituito come risultato il numero 126 (7Eh) ovvero "~"; e qui si chiude il primo ciclo di eventi.
Si avrà quindi il secondo che si svolgerà nello stesso modo solo che userà i secondi caratteri di entrambe le stringhe e che alla fine ci restituirà nel Chr$ il valore 81 (51h) ovvero "Q". Questo andrà avanti fino alla fine dei caratteri di "FabioHaCreatoEngenius", ed il programma avrà ottenuto la stringa:
"~QSYZyPsK\PE^t_U\YXEK"
Prima di vedere in che modo verrà utilizzata questa stringa però c'è da notare che noi non sappiamo come vengano ottenuti i valori 125 o 81 e così via, ma in definitiva erm...non ce ne frega niente, però dai, noi siamo curiosi, e quindi ci andremo a vedere come vengono ottenuti questi risultati utilizzando SoftIce, infatti come vedete da SmartCheck non si vede =). Bhè se non avete voglia di andarvelo a vedere ve lo dico io, il programma xora semplicemente i 2 valori, così 70 xor 56 darà 126 , 48 xor 97 darà 81 e così via, ricordatevi che siamo sempre in base dieci eh.
C'è da notare però una cosa interessante, se la stringa ottenuta affiancando i valori decimali delle lettere del mio nome, non ha sufficienti cifre da xorare con ogni carattere della stringa "FabioHaCreatoEngenius", il programma comincia ad affiancarle di nuovo i valori decimali dei caratteri del nome, partendo ovviamente da quello del primo. (Alla fine del tutorial trovate un esempio di questo).
Sappiate inoltre che SIce ci tornerà molto utile in avanti, se non per trovare il seriale, per farci capire come il programma reagisca quando si trova di fronte a determinate situazioni, più avanti capirete che intendo ; poichè inoltre sono mmolto buono =) vi darò anche una buona imbeccata per non dovervi consumare il dito a steppare ed a cercare la API giusta su cui piazzare il bp, mettete, prima di premere su Register, un bpx __vbaStrToAnsi, una volta poppato Sice cominciate ad andare avanteè con F10, è qui che comincerà il calcolo del serial e vedrete tutte le istruzioni che nella finestra dello smartcheck vengono raggruppate in eventi, dove arriverete? bhè arriverete ad una call __vbastrCmp prima della quale verranno pushati 2 valori, il serial giusto e quello da noi immesso, a dirla così sembra facile, ma c'è voluto un po' per trovare la giusta API su cui brekkare, è sempre questo il problema del VB6 =) , e siccome questo è un tutorial scritto per essere interattivo =) provate voi a cercare altre buone API su cui puntare, ah...il bpx __vbastrcmp non funziona =) e come potrete notare ogni chiamata a qualche funzione vi porterà in msvbvm50.dll perchè il regwzrd.ocx è in Vb5 ricordate?.
Ma vediamo di andare avanti alla scoperta del serial :

Len returns LONG:21
Long (21) --> Integer (21)
Mid
....
Mid
Len returns LONG:21
Long (21) --> Integer (21)
Mid$
Asc returns Integer : 75
Str$
Trim$
Mid$
Asc returns Integer : 69
Str$
Trim$
...
Dunque, dopo aver stabilito la lunghezza della stringa ottenuta vediamo tutta una serie di Mid, alla fine dei quali otteniamo la stringa di partenza capovolta, abbiamo quindi: "KEXY\U_t^EP\KsPyZYSQ~" quindi abbiamo di nuovo una serie di cicli di eventi in cui, il primo Mid$ prende l'nesimo carattere della stringa, il secondo evento ne restituisce il valore decimale, e Str$ e Trim$ fanno diventarequesto valore decimale una stringa, alla fine della serie otterremo una nuova stringona data dall'insieme di tutte queste stringhe e che sarà nel mio caso :
"756988899285951169469809275118012190898381126"
Eccoci finalmente alla parte un po' più interessante: subito dopo l'ultimo ciclo di quelli sopra:

Len returns LONG:21
Long (21) --> Integer (21)
Mid$
Asc returns Integer : 69
Mid$
Mid$
Asc returns Integer : 78
Mid$
Mid$
Asc returns Integer : 71
Mid$
Mid$
Asc returns Integer : 45
Mid$

Dunque fermiamoci un attimo quà per identificare quella che chiameremo prima serie. Vediamo innanzitutto cosa fà all'inizio, introduce una nuova stringa, e guardate CHE string : "ENG-#####-^^^^&-^&#^&" stringa che ha tutta l'aria di essere la stringa di un seriale le cui prime tre lettere devono essere ENG, non fatevi però ingannare dai sei #, questi non sono lo stesso carattere, ma bensì caratteri con le stesse proprietà, cosiccome i sei ^ ed i 3 &.
Ma continuiamo ad analizzare questa prima serie di eventi, che puà essere sudduvusa in cicli del tipo "Mid$- Asc returns Integer -Mid$" quì il primo Mid$ prende il primo carattere della stringa "ENG...", il secondo evento stabilisce che è una E e che il suo valore decimale è 69 ed il 2° Mid$ decreta di sostituire a questo char il primo char della stessa stringa, quindi la E viene sostituita con la E, ovvero non cambia niente, ergo i primi 4 char del serial giusto devono rimanere come sono nella stringa-scheletro : ENG- .
Vediamo la seconda serie:

Mid$
Asc returns Integer :35
Mid$
Len returns LONG:46
Mid$
Asc returns Integer :35
Mid$
Len returns LONG:46
Mid$
Asc returns Integer :35
Mid$
Len returns LONG:46
....
Mid$
Asc returns Integer : 45
Mid$

In questa serie vedete che l'ultimo ciclo è uguale ai primi 4, ed è quello che definisce che il decimo carattere sia un "-" , mentre vediamo i precedenti 5 cicli : "Mid$- Asc returns Integer:XX - Mid$ - Len returns LONG:46" , in questi cicli avviene tutto come nei primi quattro, solo che, come potete vedere nella finestra di destra, il secondo Mid$ di ogni ciclo decreta che la sostituzione deve avvenire con l'nesimo carattere della stringa "756988..." quindi il primo carattere del gruppo ##### ovvero il quinto della stringa "ENG-#####-^^^^&-^&#^&" sarà sostituito dal primo carattere della stringa ottenuta prima, ovvero da un "7", il secondo # sarà sostituito dal 5 e così via, ed alla fine avremo anche la seconda parte del nostro serial che ora sarà : "ENG-75698-ancora da scoprire" =)
Bhè finita la seconda serie ci sarà la terza no?

Mid$
Asc returns Integer : 94
Mid$
Len returns LONG:2
Long (2) --> Integer (2)
Mid
Mid
Val returns double:88 (displayed as single-precision floating point)
Val returns double:88 (displayed as single-precision floating point)
Double (88) --> Long (88)
Chr
UCase$
Len returns LONG:46
Mid$
Asc returns Integer : 94
Mid$
Len returns LONG:2
Long (2) --> Integer (2)
Mid
Mid
Val returns double:99 (displayed as single-precision floating point)
Val returns double:99 (displayed as single-precision floating point)
Double (99) --> Long (99)
Chr
UCase$
Len returns LONG:46
Mid$
Asc returns Integer : 94
Mid$
Len returns LONG:2
Long (2) --> Integer (2)
Mid
Mid
Val returns double:82 (displayed as single-precision floating point)
Val returns double:82 (displayed as single-precision floating point)
Double (82) --> Long (82)
Chr
UCase$
Len returns LONG:46
....
Mid$
Asc returns Integer : 38
Mid$
Len returns LONG:2
Long (2) --> Integer (2)
Mid
Mid
Val returns double:15 (displayed as single-precision floating point)
Val returns double:15 (displayed as single-precision floating point)
Double (115) --> Long (115)
Chr
Len returns LONG:46
Mid$
Asc returns Integer : 45
Mid$

Ovviamente anche la terza serie finisce con l'assegnazione ad un carattere del seriale, il 16esimo, il valore d "-", in questa serie possiamo notare i primi 4 cicli di assegnazione che sono uguali tra loro con l'unica differenza dei valori assegnati, mentre il quinto ciclo è differente per la mancanza della istruzione UCase$, infatti il quinto ciclo assegna il valore al & e tutti i caratteri che vanno a sostituire questi & devono essere nella loro forma diciamo "originale", mentre quelli che vanno a sostituire i ^ devono essere maiuscoli, ecco perchè se anche stando sopra la istruzione UCase$ nella finestra a destra leggiamo un carattere minuscolo, nel seriale lo dovremo riportare come maiuscolo, e i # ?, bhè ormai lo avrete capito, tutti i caratteri che li vanno a sostituire devono essere cifre.
Ma vediamo più nel dettaglio come avviene la sostituzione in questi cicli, come vedete il programma prende sesto e settimo carattere della stringa "756988..", li ribalta, si nota nel terzo ciclo, e poi trova il carattere a cui corrisponde questo nuovo valore esadecimale; c'è da notare che se il numero ribaltato non corrisponde a nessun carattere alfabetico in quanto è troppo piccolo, come nel caso do 51 che ribaltato da 15, il programma gli mette davanti un 1, facendo così ad esempio diventare il 15 un 115 ovvero una "s", sempre però che il numero a cui mettere davanti l'1 non sia maggiore di 22, altrimenti si otterrebbe di nuovo un carattere non alfabetico, se invece lo è allora il prog utilizzerà un'altra via di fuga,ovvero sommerà a 100 la differenza fra il numero ottenuto e 48, che è il valore decimale del primo carattere numerico, lo vedrete ad esempio nel quarto ciclo dove da 49 si ottiene 101, ovvero 100+(49-48) , questo però sempre se il numero non è maggiore di 64, se lo è, fila tutto liscio e può essere preso il char ascii corrispondente a quel numero decimale; se poi il numero ribaltato è compreso tra 91 e 96 inclusi, se avete a disposizione una tavola di codici ASCII capite il perchè, il programma gli sottrae 6 renendolo così sempre minore o uguale a 90.
E se è maggiore di 96? bhè, tutto ok, prende o 97 o 98 o 99 come valori decimali, in ascci infatti risultano "a","b" e "c".
Come so tutte queste cose? Ricordate quando prima vi parlavo dell'utilizzo di SoftIce vero? =)

Ricapitolando :

il numero ribaltato è minore di 22?
Si --- metti davanti al numero un 1,cioè sommagli 100, e prendi il char ascii corrispondente a quel valore dec.
No --- è maggiore di 22 ma minore di 64?

Si --- utilizza la formula 100+("numero maggiore di 22"-48) e prendi il risultato come corr. decimale del char
No --- è maggiore di 64 ma minore di 91?

Si --- prendi il numero come corrispondenete decimale del char
No --- è compreso fra 91 e 96 compresi?

Si --- Sottrai al numero il valore 6 e prendi il risultato come corrispondente decimale del char
No --- Bhè non può che essere 97,98 o 99 e va bene, prendi quelli come corr. decimali=)

Quindi ora abbiamo anche la terza parte del nostro serial che in tutto ora risulata essere "ENG-75698-XCRYs-ancora da scoprire ma ormai è facile" =)
Eccoci infine giunti alla quarta ed ultima parte, esaminiamo la ultima parte di questa, dove vengono assegnati i valori degli ultimi #^& :
Mid$
Asc returns Integer : 35
Mid$
Len returns LONG:46
Mid$
Asc returns Integer : 94
Mid$
Len returns LONG:2
Long (2) --> Integer (2)
Mid
Mid
Val returns double:82 (displayed as single-precision floating point)
Val returns double:82 (displayed as single-precision floating point)
Double (82) --> Long (82)
Chr
UCase$
Len returns LONG:46
Mid$
Asc returns Integer : 38
Mid$
Len returns LONG:2
Long (2) --> Integer (2)
Mid
Mid
Val returns double:15 (displayed as single-precision floating point)
Val returns double:15 (displayed as single-precision floating point)
Double (115) --> Long (115)
Chr
Len returns LONG:46

Bhè ormai non c'è più bisogno di spiegare, no? guardate questi ultimi 3 cicli, il primo conferisce il valore ad # ed il secondo mid$ di questo ciclo decreta che il valore da sostituirvi si il 20esimo della stringa "7569...", nel secondo ciclo viene affibbiato al ^ il valore 89h ovvero "Y" e nell'ultimo si ha l'assegnazione a & del valore 90h ( 09 ribaltato ) ovvero "Z".
E poi?...e poi bhè Abbiamo finalmente ottenuto il nostro serial ovvero : "ENG-75698-XCRYs-Qe6YZ", inseriamolo e TADAA..professional version registrata..alèèè! Già la pofessional, e la Enterprise? Bhè...vi dirò credo di avervi annoiato abbastanza con la trattazione della prima routine per cui vi lascio divertire dicendovi che NON CAMBIA assolutamente nulla tranne il fatto che la stringa con cui Xorare carattere a carattere non è più "FabioHaCreatoEngenius" ma "EnterpriseEngeniusEdition" , esempio : per "Uic Rulez" il serial per la Enterprise Edition sarà "ENG-91879-GPXSG-BM8CU".


Dunque, dovendo fare un keygenerator è meglio riassumerci i passaggi con cui il programma ricava il seriale giusto dal nome da noi imesso:

Il nome deve essere di almeno una lettera =)
"Prima cifra del valore decimale della prima lettera del nome" XOR "F"
"Seconda cifra del valore decimale della prima lettera del nome" XOR "a"
....
Se la stringa ottenuta affiancando i valori decimali delle lettere del nome non ha abbastanza cifre per finire di essere xorata con "FabioHaCreatoEngenius", alla stringa sopra ottenuta ne viene affiancata una uguale e così via finchè la stringa ottenuta non ha cifre sufficienti.
Ad esempio, inserendo il nome "Ebe" la stringa che si otterrebbe sarebbe 6998101 , che non ha abbastanza cifre per il nostro scopo, ergo il programma riprende ad affiancargli i valori decimali delle lettere del nome finchè non si avrà una stringa con un numero sufficiente di cifre , ovvero 21, così la stringa finale che il prog andrà a considerare sarà 699810169981016998101.
La stringa ottenuta dai vari xor viene ribaltata e viene alla luce una stringa formata dalla sequenza dei valori decimali dei caratteri ottenuto con gli xor appena fatti solo che l'ordine sarà invertito rispetto a quello degli xor.
Il seriale che dobbiamo ottenere comincia per ENG-
I seguenti 5 caratteri sono i primi 5 caratteri della stringa sopra ottenuta;
Il decimo carattere è "-" ;
Dall'undicesimo al 15esimo i caratteri sono ottenuti prendendo il carattere ASCII che in esadecimale è dato dall'accoppiamento del sesto e settimo (per l'undicesimo) carattere della stringa sopra, ribaltato.
Se il numero decimale così ottenuto è maggiore di 64 e minore di 91, ok, può essere preso il char ascii corrispondente a quel numero decimale.
Se il numero decimale così ottenuto è minore di 22, gli viene posto davanti un 1 (ovvero viene sommato 100 al numero) , e questo sarà il valore decimale del carattere da prendere.
Se il numero decimale ottenuto è maggiore di 22 e minore di 64, il carattere ASCII da prendere avrà come numero decimale la somma data da 100+("numero maggiore di 22" - 48 ) ;
Se il numero decimale ottenuto dal ribaltamento compreso fra 91 e 96 inclusi, il carattere ASCII da prendere avrà il corrisp. valore decimale dato da ("Valore ottenuto dal ribalt." - 6) .
Se il numero decimale ottenuto è 97, 98 o 99 , questi sono i valori decimali dei char da prendere.
Dall'11esimo al 14esimo i caratteri devono essere maiuscoli ;
Il 16esimo carattere deve essere "-" ;
Il 17esimo carattere deve essere ottenuto come quelli dall'11esimo al 15esimo ovviamente accoppiando 16esimo e 17esimo carattere della stringa sopra ottenuta unendo i valori degli xor e deve essere maiuscolo ; allo stesso modo deve essere ottenuto il 18esimo ovviamente compiendo le operazioni sul 18esimo e 19 char , solo che questo può non essere maiuscolo.
Il 19esimo carattere deve essere il 20esimo della stringa ottenuta con gli xor ed è un numero.
Il 20esimo ed il 21esimo sono ottenuti allo stesso modo e devono avere le stesse proprietà rispettivamente del 17esimo e 18esimo carattere

Bhè abbiamo fatto un keygen a parole,vediamo d tradurlo adesso in un linguaggio più consono ai nostri scopi :-)
I sorgenti? Bhè i sorgenti li ho messi in una pagina separata visto che son più lunghi del tutorial stesso =), il keygen è infatti codato interamente in assembler...già è un po' da pazzi , ma spero serva anche a voi per imparare un po' di asm, visto che ci sono parecchie routine a mio avviso molto utili anche per altri scopi ( Vedi quella per trasformare un numero da Esadecimale in Decimale e viceversa ), routine che speravo di trovare in Internet...speranza ovviamente inutile =(
Bhè i src del keygen,pure commentati, li trovate quì, forse, anzi certamente, il codice non è molto ottimizzato, ma parte di questa "non ottimizzazione" è stata voluta in modo da rendere più facile la comprensione dei suddetti src anche a quelli che l'assembler non lo masticano proprio bene =) e poi bhè cercate di ottimizzarlo voi al meglio una volta che avete capito come funziona.

Well, That's all Folks,
See you the next time,

Pincopall

Note finali

Bhè è vero la parte di codice non è molto commentata, ma che c'era da commentare? ho scritto tutto nella parte di testo =), è vero che il tut così risulta un po' grigio ma prendetevela con chi ha creato il form :-P

Bhè i ringraziamenti sono proprio tanti, soprattutto per la parte che concerne il keygen, ringrazio infatti tutti quelli che mi han saputo dare consigli giusti ( pochi ma buoni ) e consigli sbajati ( molti ma buoni uguali, altrimenti nn li avrei potuti escludere =)
Un Grazie Grosso Così ad Andreageddon che spesso risolve i miei casini mentali =) , e pure a Quequero per il demon =)

I saluti son pure tanti :
Tutti i frequentanti #crack-it #hackmaniaci e #asm
Tutta la ML
Tutti i membri della rinata TCC e dei rinati Lockless con la speranza che sia la volta buona =)
GiPoco, Pk|Ra1n, Beb0s e Darko ovvero quelli che insieme a me gestiscono il neonato server dotdot.mine.nu
Ded, che anche questo semestre ha joinato insieme a me il Marc =)
Uno StraBacione alla Lilith^ che è troppo simpatica e che mi ha fatto entrare e mangiare gratis al FuturShow
:-****
Ciauzzzzzz


Disclaimer

Vorrei ricordare che questo software vaà comprato e non rubato e o crakkato capito?
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 immane che ogni singolo programmatore ha dovuto portare avanti per fornire ai rispettivi consumatori i migliori prodotti possibili.

Noi reversiamo al solo scopo informativo e di miglioramento del linguaggio Assembly.

Capitoooooooo????? Bhè credo di si ;))))