UIC Lezione 2
(Creare un KeyMaker)

 

08/09/99

by "Int19"

 

 

UIC's Home Page

Published by Quequero



Ottimi questo tutorial, lo ritengo il migliore, leggetelo perchè è veramente chiaro ed esauriente

 

UIC's form

Per chi volesse contattarmi….

E-mail: [email protected]

Nick: Int19 aka Il.Socio, UIN: 4044843

UIC's form

Difficoltà

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

 

Scaricate qua l'allegato

 

Cerceremo di creare un KeyMaker per l’esercizio proposto.


 UIC Lezione 2
 Creare un KeyMaker

 
Written by Int19


Introduzione


Ciao a tutti, questo e’ il mio primo tute, quindi non siate troppo spietati nel giudicarlo, io cerchero’ di farmi capire il piu’ possibile, se vi restano dei dubbi siete liberi di contattarmi.

Tools usati

Il classico e indispensabile SoftICE 4.0, W32Dasm 8.93, e il Borland TurboC per il KeyMaker.


URL o FTP del programma

Beh, se state leggendo questo credo che tutti lo conosciate ormai : http://quequero.cjb.net


Notizie sul programma 

Il programma presenta due box nei quali inserire nome e numero di serie, ed un bottone per la registrazione, inserendo un

Serial errato compare un messagebox che riporta l’errore.

Essay

Eccoci qui….

Dunque, tanto per iniziare piazzo gli usuali breakpoint “BPX GetDlgItemTextA” e “BPX GetWindowTextA”,

inserisco un nome (Int19) e un serial (12345) pigio il bottone e Bang! ecco la finestrella di SoftICE che poppa sullo schermo.

Pigiando “F12” mi ritrovo al punto dal quale e’ stata chiamata la GetWindowTextA,

dando un’occhiata agli argomenti passati alla funzione scopro l’indirizzo dove e’ stato memorizzato

il nome che ho inserito piu’ precisamente alla locazione 40219F

 

:004011F2   push 00000019              

:004011F4   push 0040219F    ß--- Buffer dove viene salvato il nome

:004011F9   push dword ptr [004020D7]  

 

* Reference To: USER32.GetWindowTextA, Ord:0000h

                                  |

:004011FF   Call 004013B3

:00401204   xor ecx, ecx

:00401206   mov al, byte ptr [0040219F]        ß--- Preleva il primo char del nome

:0040120B   test al, al

:0040120D   je 00401371      ß--- Salta se il testo e’ vuoto

:00401213   xor eax, eax

 

 

  ED ORA VIENE IL BELLO, ANALIZZIAMO LA ROUTINE DI CRITTOGRAFIA DEL NOME

 

 

* Jump at Address:

|:00401277

|

:00401215   mov al, byte ptr [ecx+0040219F]    ß--- Preleva il prossimo char del nome

:0040121B   test eax, eax

:0040121D   je 00401279      ß--- Salta se siamo giunti alla fine del nome

                                   ed esce dal ciclo di crittografia

:0040121F   xor al, cl       ß--- xor tra il char e la sua posizione all’interno

                                   del nome…..  Nel mio caso sarà  “I” xor 0 al 1° passaggio

                                   poi “n” xor 1 al 2° passaggio ecc..

:00401221   mov edi, ecx     ß--- ora edi contiene la posizione del char corrente                  

:00401223   mul edi          ß--- il char viene moltiplicato per la posizione

:00401225   sub al, 25       ß--- ora il char viene decrementato di 25h

:00401227   add al, cl       ß--- e sommato con la sua posizione

:00401229   xor al, byte ptr [ecx+00402000]    ß--- xor tra il char e dei valori costanti

 

  La locazione 402000 contiene i seguenti valori: 12 45 D1 FF quindi verra’ effettuato

  l’xor con 12 al 1° passaggio con 45 al 2° passaggio ecc..

  Come vedremo alla fine del tute sono rilevanti solo i primi 4 bytes del nome quindi

  prendiamo in considerazione solo 4 bytes della locazione 402000.

  A questo punto vengono effettuati una serie di operazioni matematiche che coinvolgono

  Il registro ebx, la cosa importante da notare e’ che il valore finale di ebx

  NON viene in alcun modo salvato in memoria, NE’ modifica il valore di al (il nostro char)

  Inoltre il contenuto di ebx viene SOVRASCRITTO ad ogni ciclo dall’istruzione alla linea

  401234, quindi e’ molto probabile che tutte le operazioni che vengono effettuate su di

  esso siano li solo per confonderci, se cosi’ non fosse ebx assumerebbe un valore 

  significativo che dipenderebbe solo dal valore dell’ultimo char (a causa della linea 401234)

  Le istruzioni che ho marcato con *** sono molto probabilmente delle istruzioni inutili,

  utilizzate per confondere un po’ le idee e confesso che per quel che mi riguarda

  inizialmente ci e’ riuscito benissimo, ho iniziato ad avere dei sospetti quando ho incontrato

  l’istruzione 40125A:rol bl,08  che lascia praticamente invariato il registro.

 

* Possible StringData Ref from Data Obj ->"77103798325"

                                  |

:0040122F   mov edx, 00402193                   ***

:00401234   mov ebx, dword ptr [0040219F]       ***

:0040123A   xor ebx, edx                        ***

 

* Possible StringData Ref from Data Obj ->"34065479327"

                                  |

:0040123C   mov edx, 00402183                   ***

:00401241   xor ebx, edx                        ***

:00401243   add ebx, ecx                        ***

:00401245   add al, byte ptr [ecx+00402000]    ß-- Viene sommato un valore (12 45 D1)

:0040124B   xor bl, byte ptr [ecx+00402000]     ***

:00401251   shl al, 02        ß--- shift a sinistra di 2 bit

:00401254   ror al, 04        ß--- rotazione a destra di 4 bit

:00401257   shr bl, 03                          ***

:0040125A   rol bl, 08                          ***

:0040125D   xor bl, al                          ***

:0040125F   xor bl, byte ptr [00402002]         ***

:00401265   xor bl, cl                          ***

:00401267   rol bl, 08                          ***

:0040126A   add bl, al                          ***

:0040126C   sub al, 05        ß--- decrementa il char di 5

:0040126E   sub bl, al                          ***

:00401270   mov byte ptr [ecx+0040218F], al    ß--- salva il risultato a partire dalla  

                                                     locazione 40218F

:00401276   inc ecx           ß--- incrementa la posizione corrente per poter esaminare il

                                    prossimo char

:00401277   jmp 00401215

 

  Ora la crittografia del nome e’ stata compiuta ed il risultato salvato nella locazione  

  40218F, adesso viene eseguita un’ulteriore conversione.

 

* Jump at Address:

|:0040121D

|

:00401279   xor ecx, ecx

 

* Jump at Address:

|:004012A0

|

:0040127B    mov al, byte ptr [ecx+0040218F]  ß--- Carica in al un char dal nome crittografato

:00401281    test al, al

:00401283    je 00401331     ß--- Salta se siamo alla fine del nome crittografato

                                      ed esce dal ciclo di conversione

:00401289    cmp al, 66       

:0040128B    jg 0040131B     ß--- Salta se il char e’ > di 66 ‘f’

 

* Jump at Address:

|:00401321

|

:00401291    cmp al, 30      ß--- Salta se il char e’ < di 30 ‘0’

:00401293    jl 00401326

 

  A questo punto il nostro char crittografato sara’ compreso tra il set di caratteri che vanno

  Da ‘0’ a ‘f’

 

* Jump at Address:

|:0040132C

|

:00401299    inc ecx         ß-- incrementa la posizione per passare al prossimo char

:0040129A    mov byte ptr [ecx+004021A7], al   ß-- salva il risultato a partire dalla

                                                 locazione 004021A8

:004012A0    jmp 0040127B    ß-- continua la conversione

 

    |

    |

    |

 

* Jump at Addresses:

|:0040128B, :0040131F

|

:0040131B    sub al, 12      ß-- decrementa il char di 12

:0040131D    cmp al, 66      ß-- finche’ non e’ <= di 66  “f”

:0040131F    jg 0040131B          

:00401321    jmp 00401291

 

* Jump at Addresses:

|:00401293, :0040132A

|

:00401326    add al, 18      ß-- incrementa il char di 18

:00401328    cmp al, 30      ß-- finche’ non e’ >= di 30  “0”

:0040132A    jl 00401326

:0040132C    jmp 00401299

 

  Nella locazione 4021A8 ora c’e’ il nostro numero di serie tanto cercato (Int19/97EY)

  infatti se lo utilizziamo ci compare il tanto amato messaggino di successo.

 

  E ADESSO CREIAMO IL NOSTRO KEYMAKER.

  Dunque, Eliminando le istruzioni inutili che operavano sul registro ebx (quelle marcate con

  gli asterischi) rimane ben poco codice, ed e’ possibile tradurlo in C in questo modo:

 

 

 

#include <stdio.h>

 

void ror4(char *num)         ß-- Esegue la rotazione di 4 bits verso destra

{

  char tmp=(*num & 0x0F);

  tmp=tmp << 4;

  *num=(*num >> 4) & 0x0F;

  *num=*num | tmp;

}

 

int c;

const loc402000[4]={0x12, 0x45, 0xD1, 0xFF};

char serial[6]={"     "};

char name[6]={"     "};

 

void main(void)

{

  printf("Second Lesson KeyMaker by Int19\n");

  printf("Name : ");

  scanf("%s",name);

  c=0;

  while ((name[c]!='\0') && (c<4)) {         ß--- 40121D

    serial[c]=((name[c] ^ c)*c - 0x25 + c);  ß--- da 40121F a 401227

    serial[c]= (serial[c] ^ loc402000[c]) + loc402000[c];  ß--- istruzioni 401229 e 401245

    serial[c]= serial[c] << 2;               ß--- 401251

    ror4(&serial[c]);                        ß--- 401254

    serial[c]=serial[c] - 5;                 ß--- 40126C

    c++;

  };

  c=0;                         

  while ((name[c]!='\0') && (c<4)) {         ß--- 401283

    while (serial[c]>0x66)  serial[c] = serial[c] - 0x12;  ß--- da 40131B a 401321

    while (serial[c]<0x30)  serial[c] = serial[c] - 0x18;  ß--- da 401326 a 40132C

    c++;

  };

  printf("S/N  : %s\n", serial);

}

 

  Il confronto tra il seriale immesso e quello calcolato in base al nome viene effettuato  

  immediatamente dopo la seconda chiamata alla GetWindowTextA (legge il seriale immesso)

 

:004012C8   push 00000019

:004012CA   push 004021A3

:004012CF   push dword ptr [004020DB]

 

* Reference To: USER32.GetWindowTextA, Ord:0000h

                                  |

:004012D5   Call 004013B3

:004012DA   xor ecx, ecx

:004012DC   mov eax, dword ptr [ecx+004021A3]   ß-- Seriale immesso

:004012E2   mov ebx, dword ptr [ecx+004021A8]   ß-- Seriale calcolato

:004012E8   inc ecx

:004012E9   cmp eax, ebx     ß-- Confronta i 2 seriali

:004012EB   jne 004012A2     ß-- Serial errato

:004012ED   mov al, byte ptr [ecx+004021A3]

:004012F3   mov bl, byte ptr [ecx+004021A8]

:004012F9   test al, al      ß-- Serve solo a confondere le idee

:004012FB   je 00401303     

:004012FD   cmp al, bl       ß-- E’ un compare ridondante perche’ confronta il 2° char

                                  dei due seriali, ma l’intruzione 4012E9 ha gia’ effettuato

                                  il confronto dei primi 4 chars e se siamo qui significa che i

                                  primi 4 chars sono uguali.

:004012FF   jne 004012A2     ß-- Serial errato (non eseguira’ mai questo salto)

:00401301   jmp 00401303     ß-- Serial corretto

 

  Come potete notare il confronto tra i due seriali avviene facendo un compare dei primi

  quattro caratteri, alla linea 4012E9 tutto il codice che viene dopo la linea 4012EB

  e’ inutile perche’ in ogni caso si eseguira’ un jump alla locazione 401303

 

 

Note finali

Un saluto a tutti i compagni di classe, e’ da un pezzo che non faccio un salto in IRC, magari un giorno di questi rispolvero l’mirc e ci si incontra sul canale. Ed ora qualche ringraziamento a… Phobos, Catlike, Mojo, Mark, Machine Head, Kermit, Dyntro, Horse, Grave,  Joe, Pab Gamer, Emesis, Sherlox, Andy, Quake, Stood, Ozone, Plucky.                                    PDM, OGN, RZR, DOD, PWA, PC, UCF… nonche’ tutti quelli che hanno pubblicato tutorial riguardanti cracking/hacking, se non fosse per loro non sarei mai stato in grado di svolgere questo lavoro, un ringraziamento in particolare a tutti coloro che hanno reso possibile l’UIC, byez Il.Socio.

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 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 ;)))) 


 

 

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

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

UIC