sinceramente da un crackme cosi' facile mi aspettavo qualcosa di piu' da voi
riprendo da dove eravamo rimasti
00401342 CALL <JMP.&USER32.GetDlgItemTextA>
'La call che abbiamo brekkato che legge la stringa dalla TextBox
00401347 SUB ESP, 10
'siamo qui
0040134A MOV [LOCAL.6], EAX
0040134D CMP BYTE PTR SS:[EBP-A], 0
00401351 JNS SHORT KeygenMe.0040135C
00401353 MOV DL, 0
00401355 LEA EAX, DWORD PTR SS:[EBP-A]
00401358 ADD BYTE PTR DS:[EAX], DL
0040135A JMP SHORT KeygenMe.0040134D
0040135C CMP [LOCAL.6], 0C
; 'Verfica che il seriale sia minore di 13 caratteri altrimenti avvisa con li messaggio qui sotto.
00401360 JLE SHORT KeygenMe.00401382
; se è vero allora salta a 00401382 altrimenti entra
00401362 MOV DWORD PTR SS:[ESP+8], KeygenMe.00403000 ; |ASCII "The name must have less than 12 letters !"
0040136A MOV DWORD PTR SS:[ESP+4], 3F3 ; |
00401372 MOV EAX, [ARG.1] ; |
00401375 MOV DWORD PTR SS:[ESP], EAX ; |
00401378 CALL <JMP.&USER32.SetDlgItemTextA>
; 'Scrive nel TextBox he name must have less than 12 letters !
0040137D SUB ESP, 0C
00401380 JMP SHORT KeygenMe.004013F1
00401382 MOVSX EAX, BYTE PTR SS:[EBP-A]
'se il nick inserito è minore di 13 caratteri allora siamo qui
Ora inizia il cuore dell'algoritmo di generazione del Codice:
00401382 MOVSX EAX, BYTE PTR SS:[EBP-A]
'mette la prima lettera del nick in EAX,
00401386 LEA EDX, DWORD PTR DS:[EAX+3B9ACA00]
'EDX = EAX + 3B9ACA00 Somma al valore di EAX il valore 3B9ACA00 e lo mette in EDX, in pratica EDX=Nome(0)+3B9ACA00
0040138C MOVSX EAX, BYTE PTR SS:[EBP-A]
'come sopra prende il primo carattere del nick e lo mette in EAX
00401390 IMUL EAX, [LOCAL.6]
'moltiplica EAX per la lunghezza del nick (contenuta in LOCAL.6) e lo mette in EAX cioè EAX = EAX x 8, lunghezza del nick Predator è 8 caratteri
00401394 IMUL EAX, EDX
'anche qui una moltiplicazione EAX = EAX x EDX
Riassumendo in dettaglio accade questo:
per comoditàdefinisco il primo carattere del nick abbreviandolo cosi nome(0)
EAX = (nome(0) + 3B9ACA00) x (nome(0) x lunghezza del nick)
Considerato che il primo carattere del nick Predator è la lettera P e che P in ASCII è il valore 80 (alt+80) e che 80 in esadecimale corrisponde a 80, è equivalente dire:
EAX = (HEX(P) + 3B9ACA00)x(HEX(P) x 8) cioè:
EAX = (50 + 3B9ACA00) x (50 x 8)
e dato che
50 + 3B9ACA00 = 3B9ACA50
50 X 8 = 280
EAX = 3B9ACA50 x 280
EAX = 2F9C800
che in decimale è 49924096
Mi sembra chiarissimo spiegato cosi, perciò proseguiamo
NOTA segno e senza segno: il valore massimo di un DWORD è di FFFFFFFF il valore minimo è 7FFFFFF, quando parlero' di segno intendo valori maggiori o superiori a questi ^^
00401397 MOV [LOCAL.7], EAX
' mette il valore di EAX in LOCAL.7, ricordo che EAX ora è 2F9C800
0040139A CMP [LOCAL.7], 0 <----------------+
' confronta il valore di LOCAL.7 con zero
0040139E JNS SHORT KeygenMe.004013AB |
' JNS esegue un salto se l'operazione precedente ritorna un numero con segno
004013A0 LEA EAX, [LOCAL.7] |
' se non viene eseguito il salto sopra allora mette LOCAL.7 in EAX
004013A3 ADD DWORD PTR DS:[EAX], 3B9ACA00 |
' aggiunge il valore 3B9ACA00 ad EAX
004013A9 JMP SHORT KeygenMe.0040139A ------+
' salta per ripetere l'operazione fino a che LOCAL.7 ha un valore senza segno
Percio' alle operazione matematiche di prima aggiungiamo queste appena viste e concludiamo la prima parte dell'algoritmo in questo modo:
fai (nome(0) + 3B9ACA00) x (nome(0) x lunghezza di nome)
e se ha segno continua ad aggiungere il valore 3B9ACA00.
vediamo che viene questa parte, tutto questo codice serve a mettere il valore di EAX calcolato sopra cioè 2F9C800 che in decimale è 49924096, cioè il valore del campo Code del crackme (ovviamente inserendo il nick Predator).
004013AB MOV DWORD PTR SS:[ESP+C], 1
004013B3 MOV EAX, [LOCAL.7] ; |
004013B6 MOV DWORD PTR SS:[ESP+8], EAX
004013BA MOV DWORD PTR SS:[ESP+4], 3F3
004013C2 MOV EAX, [ARG.1]
004013C5 MOV DWORD PTR SS:[ESP], EAX
004013C8 CALL <JMP.&USER32.SetDlgItemInt>
'mostra il codice nel TextBox
bene ora vediamo la parte che genera il seriale di verifica
prima di tutto facciamo pulizia dei break point precedenti, se ho riavviato il crackme, reinserisco il nick Predator, premo [OK] e mi appare il code
49924096 e come fa a calcolarlo lo abbiamo capito appena qui sopra.
Mettiamo ancora il break poit bpx GetDlgItemTextA
inserisco un seriale a caso tipo 111222333 e premo [Verify], Olly brekka nella user32, togliamo il break point premendo F2 e ritorniamo al codice premendo Alt+F9 e usciamo qui:
00401440 SUB ESP, 10
di seguito ci sono una serie di istruzioni che accompagnate da un GetDlgItemTextA, che in pratica sono quelle che vanno a leggere le stringhe inserite nei TextBox, scendiamo con F8 fino a portare la nostra attenzione dopo....
ovvero qui:
(spiego)
in questo pezzo di codice risiede la generazione del seriale che noi dobbiamo inserire!!!
004014EC CALL <JMP.&USER32.GetDlgItemInt>
; 'qui è l'ultima istruzione del tipo GET che incontriamo, in pratica qui il programma smette di leggere dati.
004014F1 SUB ESP, 10
'esegue una sottrazione ma non ci importa, ESP non lo incotriamo piu'
004014F4 MOV [LOCAL.7], EAX
'(Mettiamo un Breack point QUI) mette in LOCAL.7 il valore di EAX nel mio caso 02F9C800 (il CODE)
004014F7 MOV EAX, [LOCAL.7]
'mette in EAX il valore di LOCAL.7, ok lo ammetto non serviva ma lo fa
004014FA IMUL EAX, [LOCAL.6]
'moltiplica EAX x LOCAL.6 (la lunghezza del nick) da me: 02F9C800 x 8 = 17CE4000
004014FE IMUL EAX, EAX, 3E7
'esegue una moltiplicazione EAX = EAX x 3E7 --> EAX = 17CE4000 x 3E7 = E5DBC000
00401504 MOV [LOCAL.10], EAX
'mette in LOCAL.10 il valore di EAX
00401507 CMP [LOCAL.10], 0
'come prima verifica se ha segno, se non ha segno esegue il jump altrimenti...
0040150B JNS SHORT KeygenMe.00401518
0040150D LEA EAX, [LOCAL.10]
00401510 ADD DWORD PTR DS:[EAX], 3B9ACA00
'altrimenti aggiunge il valore 3B9ACA00 fino a quando EAX diventa senza segno
00401516 JMP SHORT KeygenMe.00401507
'riprende il ciclo
Nel mio caso entra una volta nel ciclo e fa E5DBC000 + 3B9ACA00 = 21768A00 che in decimale è 561416704
Riepilogando l'algoritmo è:
EAX = il valore calcolato precedentemente (il CODE)
EAX = EAX x 3E7
poi controlla se EAX ha segno, se ha segno aggiunge 3B9ACA00 fino a quando diventa senza segno
in pratica ecco i fatti a valori:
EAX = 2F9C800 'che corrisponde al valore decimale 49924096
EAX = 2F9C800 x 8 = 17CE4000 '8 sono i caratteri del nick 'Predator'[/b]
EAX = 17CE4000 x 3E7 = E5DBC000 ' 3E7 è un valore fisso inserito nel codice (in decimale è 999)
E5DBC000 è con segno in quanto maggiore di 7FFFFFFF, percio' aggiungo 3B9ACA00
EAX = E5DBC000 + 3B9ACA00
EAX = 21768A00 'adesso è senza segno in quanto minore di 7FFFFFFF
21768A00 in decimale ha valore 561416704, lo inserisco nel seriale, premo verify e... Good Job!
tutto chiaro?
riepilogando li nostro key-generator avràquesto schema logico
SERIALE = (primo carattere del nick + 3B9ACA00) x (primo carattere nick x lunghezza del nick)
e se ha segno continua ad aggiungere il valore 3B9ACA00.
SERIALE = SERIALE x lunghezza del nick
SERIALE = SERIALE x 3E7
se ha segno aggiungo 3B9ACA00 fino a quando diventa senza segno
chiapponi scansafatiche!!!!!!
Predator