Jammer
Creazione di un KeyGenerator e di un Auto-KeyGenerator


23/10/2000

by "BlackDruiD"

 

 

UIC's Home Page

Published by Quequero

Hate breeds hate my eyes they have seen the decimation of all that is pure...

Creazione di un semplice KeyGen utilizzando la tecnica della Trasmigrazione attraverso Satori

Ha detto tutto lui, io non c'entro nulla :))))

...a system that feeds their machine with the blood and the money of the poor 
UIC's form   UIC's form

Difficoltà

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

 

In questo tutorial spiegherò come realizzare un generatore di codici seriali e come rendere lo stesso programma un auto-KeyGen.


Jammer
Creazione di un KeyGenerator e di un Auto-KeyGenerator 
Written by BlackDruiD


Introduzione


Ho fatto questo tutorial perchè... perchè.... non so perchè, sono cazzi miei.

Tools usati

SoftIce 4.05
WDasm 8.93

URL o FTP del programma

www.agnitum.com

Notizie sul programma 

Il programma fornisce un'ottima protezione contro attacchi Netbus e BackOrifice, controlla il vostro registro per vedere se c'è qualche chiave sospetta e fa altri controlli anti trojan.
Il prog è un trial di 30 gg con possibilità di registrazione.

Essay

Allora, dato che è stato già fatto un tutorial da Niutron su come crakkare questo programma (che trovate nella sito
della UIC) non analizzerò il programma ma mi limiterò a spiegare:
1 - il modo in cui il programma genera i numeri seriali per la registrazione.
2 - come trasformare il prog in un auto key-generator
 
Prima Parte

Come già saprete il nome inserito deve essere almeno di 8 caratteri, la prima parte
del codice deve avere come primo carattere un numeroe la seconda deve essere lunga 10 caratteri.
Il motivo per cui il primo carattere della prima parte del codice dev'essere un numero
è semplice: il prog infatti preleva tutti i caratteri finchè non ne trova uno diverso da un numero
o finchè non ne ha prelevati 7(è come se in C usaste la funzione atoi).
Quindi se inserite ad esempio:
A123456 -> errore
12a3456 -> il prog considera 12
456789A -> il prog considera 456789.
chiaro no?


La routine che genera il codice seriale inizia all'indirizzo 0041BE8A.

:0041BE8A mov eax, dword ptr [esi+64]                 ;sposta il nome in eax
:0041BE8D lea edi, dword ptr [ecx+01] 
:0041BE90 mov dl, byte ptr [eax+ecx]                     ;carica in dl le lettere del nome partendo dall' inizio
:0041BE93 sub eax, ecx
:0041BE95 mov byte ptr [ebp-0D], dl 
:0041BE98 mov edx, dword ptr [ebp-1C]                ;[EBP-1C] contiene la lunghezza del nome
:0041BE9B mov ecx, edi
:0041BE9D mov al, byte ptr [eax+edx-01]               ;carica in al le lettere del nome partendo dalla fine

; inizio del calcolo del seriale
:0041BEA1 imul ecx, edi 
:0041BEA4 movsx edx, al
:0041BEA7 add edx, dword ptr [ebp-20] 
:0041BEAA movsx eax, byte ptr [ebp-0D] 
:0041BEAE add edx, ecx
:0041BEB0 mov ecx, 000000FF
:0041BEB5 add eax, edx
:0041BEB7 xor edx, edx
:0041BEB9 div ecx
; fine del calcolo del seriale

:0041BEBB movzx eax, dl
:0041BEBE push eax
:0041BEBF lea eax, dword ptr [ebp-14]

:0041BEC2 push 00430B94
:0041BEC7 push eax

:0041BEC8 Call 00420AC6
:0041BECD add esp, 0000000C
:0041BED0 lea eax, dword ptr [ebp-14]
:0041BED3 mov ecx, ebx
:0041BED5 push eax

:0041BED6 Call 00420DCC
:0041BEDB mov ecx, edi
:0041BEDD cmp ecx, 00000005 
:0041BEE0 jl 0041BE8A                         ;esegue 5 volte il ciclo che inizia a 0041BE8A



Ora vi spiego in modo più dettagliato questa parte di codice.
Per l'esempio userò questi dati:
Nome: BlackDruiD
Prima parte del serial: 6663666;

la prima parte della routine 'prepara i valori' che saranno poi usati nella fase
di calcolo del seriale.

mov eax, dword ptr [esi+64]           ;sposta il nome in eax
lea edi, dword ptr [ecx+01] 
mov dl, byte ptr [eax+ecx]              ;carica in dl le lettere del nome
;partendo dall' inizio
sub eax, ecx
mov byte ptr [ebp-0D], dl 
mov edx, dword ptr [ebp-1C]         ;[EBP-1C] contiene la lunghezza del nome
mov ecx, edi
mov al, byte ptr [eax+edx-01]         ;carica in al le lettere del nome partendo dalla fine


Come vedete vengono utilizzati 2 contatori(EDI e ECX) che servono come indici dell'array che
contiene il nome.I due contatori vengono incrementati ad ogni ciclo.
La preparazione dei valori avviene in questo modo:
viene messo in eax un carattere del nome; il carattere da prelevare è indicato dall' istruzione

mov dl, byte ptr [eax+ecx]
EAX 'punta' al nome, ed ECX è il contatore di cui vi ho appena parlato
(ECX prima dell'inizio ciclo è inizializzato a 0)quindi il byte spostato in dl
sarà quello all'indirizzo (EAX+ECX).
Esempio:
Nome: B l a c k D r u i D 
0 1 2 3 4 5 6 7 8 9

EAX 'punta' al nome quindi, 'punta' alla prima lettera del nome.
ECX è il contatore inizialmente inizializzato 0 perciò al primo ciclo
in DL viene copiata la 'B' (EAX+0), poi la 'l' (EAX+1) e così via.


Il secondo valore utilizzato è prelevato allo stesso modo, ma partendo dalla
fine del nome:

sub eax, ecx
mov byte ptr [ebp-0D], dl 
mov edx, dword ptr [ebp-1C]             ;[EBP-1C] contiene la lunghezza del nome
mov ecx, edi
mov al, byte ptr [eax+edx-01]             ;carica in al le lettere del nome partendo dalla fine

per prelevare i caratteri partendo dalla fine, non fa altro che sommare 
l'indirizzo di partenza (EAX) alla lunghezza del nome e sottrarre 1 al risultato
Esempio:
Nome: B l a c k D r u i D
0 1 2 3 4 5 6 7 8 9

EAX 'punta' alla prima lettera del nome.
ECX = contatore.

sub eax,ecx
sottrae all'indirizzo di partenza il valore del contatore quindi:

primo ciclo 
B     0 <- eax - ecx (ecx = 0)
l     1
a     2
c     3
k     4
D     5
r     6
u     7
i     8
D     9

secondo ciclo 
.. -1 <- eax - ecx (ecx = 1)
B     0 
l     1
a    2
c    3
k    4
D   5
r    6
u    7
i     8
D  &nbsp9

e così via.

al valore di eax viene poi sommata la lunghezza del nome meno 1.
mov edx, dword ptr [ebp-1C]             ;[EBP-1C] contiene la lunghezza del nome

mov al, byte ptr [eax+edx-01]             ;carica in al le lettere del nome partendo dalla fine


in al verra quindi copiato:

primo ciclo 
B 0 <- eax
l 1
a 2
c 3
k 4
D 5
r 6
u 7
i 8
D 9 <- (eax + edx -1) (eax + 10 - 1)

AL = 'D'

secondo ciclo 
.. -1 <- eax
B 0 
l 1
a 2
c 3
k 4
D 5
r 6
u 7
i 8 <- (eax + edx -1) (eax + 10 - 1)
D 9 

AL = 'i'

ecc... ecc... ( ricordate che i cicli sono 5)


passiamo ora al calcolo del seriale.
A questo punto AL contiene uno dei caratteri presi partendo dalla fine del nome mentre
[ebp-0d] contiene un carattere preso partendo dall'inizio del nome.
(il char è stato spostato da dl a ebp-0d con questa istruzione: mov byte ptr [ebp-0D], dl)

; inizio del calcolo del seriale
imul ecx, edi                             ;vengono moltiplicati i due contatori
movsx edx, al                           ;edx = secondo valore prelevato in precedenza
add edx, dword ptr [ebp-20]   ;ebp-20 contiene la parte del serial che avete inserito
movsx eax, byte ptr [ebp-0D]  ;eax = primo valore prelevato in precedenza
add edx, ecx 
mov ecx, 000000FF
add eax, edx
xor edx, edx
div ecx
; fine del calcolo del seriale

come vedete l'algoritmo è molto semplice e funziona in questo modo:

imul ecx, edi
ECX = valore dei due contatori moltiplicati tra loro
movsx edx, al
EDX = valore ricavato in precedenza (una carattere prelevato dal nome)
add edx, dword ptr [ebp-20]
EDX = EDX + prima parte del serial (io ho inserito 6663666)
movsx eax, byte ptr [ebp-0D]
EAX = valore ricavato in precedenza (una carattere prelevato dal nome)
add edx, ecx
EDX = EDX + ECX
mov ecx, 000000FF
ECX = FF
add eax, edx
EAX = EAX + EDX
xor edx, edx
EDX = 0
div ecx
EAX = EAX / ECX

dopodichè il resto della divisione viene spostato in eax
movzx eax, dl

seguono due call che servono solo a copiare il valore dei 5 resti della divisione
in un buffer (i resti sono 5 poichè i cicli sono 5).
Ed è proprio in questo buffer che c'è il codice seriale corretto per il nostro nome!!!
Infatti il seriale non è altro che i 5 resti della divisione.
Esempio:
supponiamo che i resti siano stati: 20 35 FD 63 32
il vostro seriale è 2035FD6332
N.B. i valori sono assolutamente inventati.


Fine della prima parte, ora provate a scrivere un KeyGenerator.
Io l'ho fatto ma non vi allego il codice sorgente perchè sarebbe troppo semplice
e poco divertente per voi. Sbaglio? ;))

Seconda parte

Ora vi spiego come modificare il programma in modo da farlo diventare un auto-KeyGenerator.
inserite un nome di almeno 8 char, la prima parte del serial che abbia come prima cifra
un numero e la seconda parte di 10 caratteri.


:0041BEDD cmp ecx, 00000005
:0041BEE0 jl 0041BE8A

;una volta che i 5 cicli sono terminati, vi trovate qui

:0041BEE2 push [esi+68]                 <--- il serial che avete inserito
:0041BEE5 push dword ptr [ebx]     <--- il serial corretto

:0041BEE7 Call 0042117A             <--- verifica la correttezza del serial inserito
:0041BEEC pop ecx
:0041BEED test eax, eax
:0041BEEF pop ecx 
:0041BEF0 je 0041BEF9                 <--- serial ok
:0041BEF2 push 00000000
:0041BEF4 jmp 0041BFCA             <--- serial errato


arrivate qui
segue la messagebox che vi dirà che le informazioni inserite non sono corrette.
In particolare, la frase che appare si trova all'indirizzo 430B68( il secondo push).
Se in questo punto col softice date un'occhiata a EBX (d @ebx) trovate come per magia il 
seriale corretto.Tutto ciò che dovete fare è sostituire il push 00430B68 con
push DWORD PTR[ebx].
C'è un problema però: se attivate l'istruzione code on del softice noterete che
l'istruzione push 430b68 è 'lunga' 5 byte mentre push DWORD PTR[ebx] è lunga 2 byte.
Quindi dobbiamo noppare altri 3 byte altrimenti il prog va in crasha.
In softice posizioniamoci all'indirizzo 41bfcc, diamo il comando 'a' (senza le virgolette)
e inseriamo le istruzioni:
push DWORD PTR[ebx] -> invio
nop -> invio
nop -> invio
nop -> invio

:0041BFCA push 00000010
:0041BFCC push 00430B68 <--- Stringa di errore
:0041BFD1 Call 004207E4 <--- MessageBox di errore

riprovate a registrarvi inserendo info sbagliate e vedrete che il prog vi dirà gentilmente
il serial corretto per la registrazione.
Ora non vi resta che modificare l'eseguibile per rendere permanenti le modifiche.
Saprete sicuramente come fare, altrimenti andatevi a leggere un tutorial dove viene spiegato.
;) lo so, son pigro.
                                                                                                                 BlackDruiD



Note finali

Ho scritto questo tute senza voglia, quindi non vi lamentate se in alune parti son stato pigro.
Saluto tutti gli amici di ringzer0, della UIC e tutti quelli di #crack-it.

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.
Se proprio volete utilizzare i contenuti di questo tutorial ricordatevi di cancellare il programma dopo lo scadere del limite trial di 30 giorni!
Noi reversiamo al solo scopo informativo e di miglioramento del linguaggio Assembly.

(questo disclaimer l'ho copiato, lo ammetto)