> CraCk Me n.1 Di Bad
Sector:SoLuTiOn < Realizzato da NoRpiUs
ToOLz
uTiLiZzATi: - Debugger ( Olly Dbg
)
SpiEgaZiOnE: Questo crack me e' stato scritto da Bad Sector e a me e'
piaciuto perche' ha una routine un po' diversa dal solito... ma andiamo ad
analizzarla. Scopo: creare un keygen. Apriamo ollydbg e mettiamo un bpx sulle 2
GetDlgItemTextA e runniamo. Mettiamo i soliti dati a caso e il debugger
poppa:
CALL <JMP.&USER32.GetDlgItemTextA> ; prende il nome CMP
EAX,0 ; confronta se e' 0 JE
Crackme1.004011EF ; se lo e' esce CMP
EAX,4 ; ora confronta se il nome e' lungo 4
char JB
Crackme1.004011EF ; e se lo e' esce ancora XOR
ECX,ECX ; azzera ecx XOR
EBX,EBX ; azzera ebx XOR
ESI,ESI ; azzera esi
Ok fin qua nulla di particolare, fa
solo una validazione del nome, quindi da qui capiamo che il nostro user deve
essere per forza maggiore di 4 char. Ora inizia la prima routine di
crittazione:
MOV DWORD PTR SS:[EBP-4],EAX ; mette in ss[ebp-4] la lunghezza del nome MOVSX EAX,BYTE PTR
DS:[ECX+4020F3] ; mette in eax la
ECXesima lettera del nome CMP
EAX,20 ; la confronta con 20h (uno spazio
vuoto) JE SHORT Crackme1.0040117B ; se e' uno spazio, esce IMUL
EAX,EAX,4 ; moltiplica eax per 4 ADD
EBX,EAX ; somma eax a ebx MOV
ESI,EBX ; mette ebx in esi INC
ECX ; passa alla lettera successiva del nome CMP
ECX,DWORD PTR SS:[EBP-4] ; confronta ecx con la lunghezza del nome JNZ SHORT
Crackme1.00401168 ;
se non sono uguali torna a inizio
ciclo
Qua il nostro bel crack me non fa
altro che fare dei piccoli calcoli con il nome. Non lasciatevi prendere dal
panico dal primo mov, non e' nulla di particolare, mette solo in ss alla
posizione [ebp-4] la lunghezza del nome che alla fine di ogni ciclo andra' a
confrontare con ecx (che e' un contatore) ... quindi quello che fa non e' altro
che fare i calcoli aumentando ad ogni ciclo ecx finche' non raggiunge la
lunghezza dell' user. Scriviamoci il keygen fino a questo punto:
#include <stdio.h> #include
<string.h>
main() {
int lun, i, eax, esi = 0; char
*nome;
printf("Scrivi un nome: "); scanf("%s",nome);
lun
= strlen(nome); for ( i = 0; i < lun; i++) { eax =
nome[i]; eax *= 4; esi += eax;
} }
Ecco, alla fine avremo il nostro
valore in ebx che sara' uguale al valore che ci sara' in esi (visto che a ogni
ciclo ce un mov esi, ebx quindi viene ad ogni ciclo riscritto il valore di esi,
ma a noi quello che interessa e' il valore alla fine di tutti i cicli
naturalmente). Passiamo al secondo ciclo:
CMP ESI,0 ; confronta esi con
0 JE SHORT Crackme1.004011EF ; se lo e' esce MOV
EBX,654789 ; mette 654789h in ebx Iniziociclo: MOVSX EAX,BYTE PTR
DS:[ECX+4020F2] ; mette in eax la
lettera ECXesima del nome DEC
EBX ; decrementa ebx IMUL
EAX,EBX,2 ; moltiplica ebx per 2 e il risultato va in
eax ADD EBX,EAX
; somma eax a ebx DEC
EBX ; decrementa ebx DEC
ECX ; decrementa ecx JNZ Iniziociclo
; se il flag Zero e' a 0 torna a
inizio ciclo
Secondo ciclo di crittazione, solo
che questa volta lo fa al "contrario": parte dall'ultima lettera del nome e fa
dei calcoli e dopo passa alla precedente, questo perche' ecx ha il valore del
ciclo di prima, ovvero e' uguale alla lunghezza del nome e a ogni ciclo viene
decrementato. Il keygen dovrebbe venire cosi' fino a questo punto:
#include <stdio.h> #include
<string.h>
main() {
int lun, i, eax, esi = 0;
unsigned long ebx = 6637449; char *nome;
printf("Scrivi un nome:
"); scanf("%s",nome);
lun = strlen(nome); for ( i = 0; i <
lun; i++) { eax = nome[i]; eax *= 4; esi +=
eax; }
for ( i = 0; i < lun; i++) {
ebx--; ebx += ebx * 2; ebx--; } }
In realta' il movsx subito dopo l'inizio del ciclo
non serve a nulla per il seriale, per cui a noi serve solo ebx. Come ultima
parte ce un piccolo passaggio:
PUSH ESI ; pusha esi
(primo for) PUSH EBX
; pusha ebx (secondo for) PUSH
Crackme1.004020C7 ; pusha
la stringa "BS-%lX-%lu" PUSH Crackme1.004021BB ; qua chissa' che cazzo
pushi CALL <JMP.&USER32.wsprintfA> ; e richiama lo sprintf
In questo passaggio viene data la forma finale al
serial, ovvero: BS-<EBX>-<ESI> , ebx in esadecimale (%lX) e esi
in decimale (%lu). Infatti lo sprintf (comando che e' usato anche in c) non
fa altro che prendere una stringa e sbattergli dentro dei valori in determinate
posizioni. Perfetto ora siamo arrivati alla fine, scriviamoci il keygen finale:
#include <stdio.h> // per lo scanf e
printf #include <string.h> // per l' strlen #include
<stdlib.h> // per l'exit(1)
main() {
int lun, i,
eax, esi = 0; unsigned long ebx = 6637449; char *nome;
printf("Scrivi un nome: "); scanf("%s",nome);
lun =
strlen(nome); if (lun < 4) { printf("Nome troppo corto,
minimo 4 caratteri"); exit(1); }
for ( i = 0; i <
lun; i++) { eax = nome[i]; eax *= 4; esi +=
eax; }
for ( i = 0; i < lun; i++) {
ebx--; ebx += ebx * 2; ebx--; }
printf("Il
seriale e': BS-"); printf("%X-",ebx); // %X stampa il numero
in esadecimale e maiuscolo printf("%d",esi); }
Complimenti a Bad per questo bel crack me, mi e'
davvero piaciuto. Ciao, alla prox.
|