Tutorial lezione 2 UIC + key generator


16/09/1999

by "syscalo"

 

 

UIC's Home Page

Published by Quequero

- Windows 9x:
32 bit extensions and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company, that can't stand 1 bit of competition (original by Creeping).

Raga, la seconda migliore soluzione, bravo syscalo!!!! Strana formattazione ma comunque ottime spiegazioni

Non è che non apprezzo windows è che mi stanno più simpatici quelli che si tirano matti a inventare frasi del genere :)
UIC's form
E-mail: syscalo@tiscalinet.it
UIC's form

Difficoltà

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

 

 

Scaricate qua l'allegato

Ho pensato di impostare il tutorial nel seguente modo:

- spiegazione della generazione del seriale mantenendo solo le istruzioni necessarie.

- spiegazione del perchè sono state eliminate certe istruzioni..


Tutorial lezione 2 UIC
incluso key generator
Written by syscalo

Introduzione

Questo programma richiede nome e seriale: il seriale giusto viene generato dal nome e viene confrontato direttamente con il seriale inserito che non viene modificato in alcun modo (meno lavoro per noi ;) Ma allora siete dei lavativi???? :)

Tools usati

-Softice: è sufficiente questo.
-wdasm: solo per stampare parte del listato per avere qualcosa da leggere al ..... ;))

URL o FTP del programma

http://quequero.members.easyspace.com/prj/corsosecondo.html

Essay

Cominciamo: come anticipato ora spiegherò l'algoritmo di generazione del seriale.
Alcune osservazioni:
- quando scrivo "salta alla label loc_xxxxxx" il valore xxxxxx è lo stesso che viene visualizzato in softice come indirizzo dell'istruzione a cui salterà.
- le istruzioni jg e jl sono salti condizionati per numeri con segno. E' importante ricordarselo quando si eseguono i confronti.
- chr sta per carattere :)
Ecco il codice:
   push   00000019   # caratteri max da leggere: in questo caso il valore è esagerato (credo volontariamente) visto che il # max di chr inseribili nel campo nome del programma è 4
   push   0040219F   locazione in cui verrà salvato il nome inserito
   push   dword ptr [004020D7]  
   call   GetWindowTextA   chiamata alla funzione per acquisire il nome
   xor   ecx,ecx   azzera il registro ecx
loc_401215:   mov   al, byte ptr [ecx+0040219F]   carica in al il cod. ASCII dal 1° chr del nome
   test   eax, eax   |
   jz   short loc_401279   |se il nome è terminato salta alla label loc_401279
   xor   al, cl   xora al con cl (che mantiene il conteggio dei chr)
   mov   edi, ecx   copia ecx in edi
   mul   edi   moltiplicazione senza segno: esegue eax×edi e salva il risultato in eax (da qui si capisce perchè tutti i seriali generati iniziano per 9: infatti edi al primo ciclo è uguale a 0 quindi "annulla" l'effetto dell'acquisizione del 1° chr del nome azzerando eax)...quindi per Que e Due verrà generato lo stesso codice ;))
   sub   al, 25h   sottrae 25h ad al
   add   al, cl   somma cl ad al
   xor   al, byte ptr [ecx+00402000]   xora al con il byte all'indirizzo 00402000+ecx: in questo modo il valore con cui vengono xorati i chr varia per ognuno di essi. Per trovare i valori usati come maschera è sufficiente dare in softice il comando "d 00402000" e leggere i primi 4 byte visualizzati.(ovviamente in softice deve essere in esecuzione il file due.exe :)
   add   al, byte ptr [ecx+00402000]   somma ad al lo stesso valore con cui è stato xorato
   shl   al, 2   esegue 2 shift a sinistra su al
   ror   al, 4   esegue 4 rotazioni a destra su al (queste sono operazioni logiche  che servono a modificare un po' il valore di al, usate per variegare un po' le istruzioni invece di avere solo add e xor ;)
   sub   al, 5   sottrae 5h ad al
   mov   byte ptr [ecx+0040218F], al   salva al alla locazione 0040218F+ecx (serve per riprendere il codice per le modifiche successive) A
   inc   ecx   incrementa ecx di 1 (conteggio # chr)
   jmp   short loc_401215   salta alla label loc_401215 (in pratica riesegue le istruzioni precedenti fino alla terminazione del nome)
loc_401279:   xor   ecx, ecx   azzera ecx
loc_40127B:   mov   al, byte ptr [ecx+0040218F]   carica in al il valore modificato nel ciclo precedente (vedere A )
   test   al, al   |
   jz   loc_401331   |se il nome (modificato) è terminato salta alla label loc_401331. Alla label loc_401331 ci sono parte delle istruzioni inutili. Queste fanno delle elaborazioni sul codice ma salvano il risultato in locazioni di memoria che non vengono cagate per niente nel controllo finale: in sostanza il codice generato dal nome rimane invariato! Dopo queste istruzioni si passerà all'acquisizione del seriale da noi inserito e al controllo con il codice generato dal nome. ( vedere X )
   cmp   al, 66h   |
   jg   loc_40131B   |confronta al con 66h e se è maggiore salta alla label loc_40131B ( B )
loc_401291:   cmp   al, 30h   |
   jl   loc_401326   |confronta al con 30h e se è minore salta alla label loc_401326 ( C )
loc_401299:   inc   ecx   incrementa di 1 ecx (conteggio chr)
   mov   byte ptr [ecx+004021A7], al   salva al (eventualmente modificato) alla locazione 004021A7+ecx (avendo incrementato ecx prima di questa istruzione il codice generato dal nome avrà inizio dalla locazione 004021A8 che è quella che poi viene letta al momento del confronto con il seriale inserito)
   jmp   short loc_40127B   salta alla label loc_40217B (ripete le istruzioni precedenti fino alla fine del nome)
loc_40131B:   sub   al, 12h   sottrae 12h ad al
   cmp   al, 66h   |
   jg   short loc_40131B   |se al è maggiore di 66h salta alla label loc_40131B (in pratica continua a sottrarre 12h ad al fino a quando diventa minore di 66h)
   jmp   loc_401291   riprende l'esecuzione dall'istruzione successiva a quella che ha generato il salto a loc_40131B ( vedere B )
loc_401326:   add   al, 18h   somma 18h ad al
   cmp   al, 30h   |
   jl   short loc_401326   |se al è minore di 30h salta alla label loc_401326 (in pratica continua a sommare 18h ad al fino a quando diventa maggiore di 30h)
   jmp   loc_401299   riprende l'esecuzione dall'istruzione successiva a quella che ha generato il salto a loc_401326 ( vedere C )
Ok, la generazione del seriale è terminata. Ora spiegherò perchè certe istruzioni sono state eliminate. Dovete avere sott'occhio il listato completo.
Consideriamo il primo ciclo di istruzioni di elaborazione del seriale, cioè quello che inizia con la label loc_401215 e termina con l'istruzione jmp short loc_401215:
in questo ciclo ci sono diverse istruzioni che modificano il registro bl (o ebx); bhe queste sono tutte inutili perchè al termine del ciclo il risultato non viene salvato da nessuna parte (mentre il registro al si) ed inoltre nessuna di queste operazioni influenza il valore di al o condiziona in qualche modo il flusso del programma (per intenderci non ci sono istruzioni di controllo sul valore del registro bl che vadano ad esempio a condizionare dei salti).
Dimenticavo: appena dopo la chiamata a GetWindowTextA viene effettuato un controllo sul primo chr; se questo è nullo viene visualizzato il messaggio "Wè son mica scemo!!! :)" che Que ha simpaticamente inserito per scoraggiare chiunque pensasse che il programma funzionasse anche senza codici :) (in realtà serve anche ad evitare che venga elaborato il nome se premiamo il tasto register senza inserire alcun valore nel campo nome)
Per quanto riguarda il secondo ciclo (da loc_401279 a jmp short loc_40127B) questo è tutto da tenere, nessuna istruzione per confonderci ;)
Il terzo ciclo invece è proprio stato creato SOLO per premere un po' di F8 in softice! Infatti, come accennato durante la spiegazione della generazione del seriale, è vero che qui vengono effettuate delle elaborazioni sul nome modificato e che vengono salvati i risultati, ma è anche vero che le locazioni di memoria dove vengono salvati, oltre a sovrascriversi a vicenda, non vengono considerate per niente dal programma quando deve effettuare il controllo per decidere se il nostro codice è buono o se siamo solo dei fannulloni che inseriscono numeri a caso sperando che funzioni ;))
Siamo arrivati al momento della verità: il superprogramma verifica la bontà del nostro seriale.
loc_4012C8:   push   19h   | ( X )
   push   004021A3   |
   push   dword ptr  [004020DB] |
   call   GetWindowTextA   |acquisisce il seriale da noi inserito; per vederne il cod. ASCII in softice: d 004021A3
   xor   ecx, ecx   azzera ecx
   mov   eax, dword ptr [ecx+004021A3]  carica in eax il seriale da noi inserito
   mov   ebx, dword ptr [ecx+004021A8]  carica in ebx il seriale generato dal nostro nome (quindi se vi interessa solo trovare il vostro seriale arrivate fino qui e leggete il contenuto di ebx oppure usate il mio key generator :)
   inc   ecx   incrementa di 1 ecx
   cmp   eax, ebx   |confronta seriale inserito e seriale calcolato dal nome
   jnz   short loc_4012A2   |se sono diversi salta a loc_4012A2 (visualizza "Serial sbagliato :(" )
   mov   al, byte ptr [ecx+004021A3] altrimenti carica in al il 2° chr del seriale inserito
   mov   bl, byte ptr [ecx+004021A8] carica in bl il 2° chr del seriale calcolato dal nome
   test   al, al |
   jz   short loc_401303 |se al è uguale a 0 salta a loc_401303 (visualizza "Chiave indovinata...Complimenti!!!") (in realtà questa condizione si verifica solo se il nome inserito è di una sola lettera (qualsiasi) e se il seriale inserito è 9; se non capite perchè proprio 9 rileggete la descrizione della generazione del seriale)
   cmp   al, bl |altrimenti confronta al e bl
   jnz   short loc_4012A2   |e se sono diversi salta a loc_4012A2 (visualizza "Serial sbagliato :(" ) (questa condizione invece non si verificherà mai perchè se arriviamo ad eseguirla vuol dire che seriale inserito e seriale calcolato sono uguali quindi è impossibile che i secondi chr siano diversi; credo sia stata inserita per fare in modo di fregare il cracker poco attento (e un po' stantito...battutaccia :) che pensi di risolvere il tutto noppando i jump precedenti :)
   jmp   short loc_401303   salta all'istruzione successiva (visualizza "Chiave indovinata...Complimenti!!!")
loc_401303:   qui ci sono le istruzioni che visualizzano il messaggio "Chiave indovinata...Complimenti!!!"

Ci siamo! Potete rilassarvi, è tutto finito :)

««««Ciao a tutti»»»»

syscalo

Note finali

Spero che vada tutto bene e che sia comprensibile ciò che ho scritto.

Un saluto a tutta la UIC...

...e un fuck a Tiscali che nel momento in cui scrivo non mi permette di spedire la posta e di aggiornare i ng salutandomi con un messaggio di errore originale come "You have no permission to talk. Goodbye" (almeno più innovativo di quelli di windows )

Un ringraziamento va a Int19 che si è reso disponibile per un confronto su questa lezione! Poi ti spiegherò quale era il mio problema :-{

Disclaimer

Vorrei ricordare che il software va comprato (anche i tutorial della UIC? :) un disclaimer è come una mela, non fa mai male....o era una pera? Bhooo NdQue :) 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 immane che ogni singolo programmatore ha dovuto portare avanti per fornire ai rispettivi consumatori i migliori prodotti possibili (Quequero ci mette sempre tutto il suo impegno :). E dai che in fondo mi ci faccio il mazzo più io che voi :))) NdQue
Noi reversiamo al solo scopo informativo e di miglioramento del linguaggio Assembly.
Capitoooooooo????? Bhè credo di si ;)))) 

 

 

UIC's page of reverse engineering, scegli dove andare:

Home   Anonimato   Assembly    ContactMe  CrackMe   Links   
NewBies   News   Forum   Lezioni  
Tools   Tutorial 

UIC