Reversing del corso 4 |
|
|
18/11/1999 |
by "BlackDruiD" |
|
|
Published by Quequero |
|
No escape the end is near, too late, die in fear |
Sto tutorial � 'na figata!!! |
Give respect, 'cos the rule is blood for blood |
UIC's form |
|
UIC's form |
Difficolt� |
(X )NewBies ( )Intermedio ( )Avanzato ( )Master |
Il programma che mi appresto a reversare richiede la creazione di un keyfile per la registrazione
Introduzione |
Tools usati |
URL o FTP del programma |
Essay |
Allora raga, partiamo subito col reversing!!!
Eseguite il programma, entrate in softice e settate un bpx sulla funzione CreateFile.
Dal Menu Help selezionate il menu Register e vi troverete in sice. Premete F11 per uscire
dalla funzione e scorrete verso l'alto la code window per dare un'occhiata ai parametri
passati alla funzione CreateFile.
Come vedete sotto, la funzione CreateFile ha come primo parametro il nome del file da
aprire
HANDLE CreateFile(
LPCTSTR lpFileName, <-'Nome del file da aprire'
// pointer to name of the file
DWORD dwDesiredAccess,
// access (read-write) mode
DWORD dwShareMode,
// share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
// pointer to security attributes
DWORD dwCreationDistribution,
// how to create
DWORD dwFlagsAndAttributes,
// file attributes
HANDLE hTemplateFile
// handle to file with attributes to copy
);
perci�, dato che i parametri sono passati da destra verso sinistra, l'ultimo push
prima della call CreateFile sar� il nome del keyfile.
.004194AE push ecx
;nome del file
.004194AF call CreateFileA
Settate un bpx 4194AE, uscite da softice e ripetete la procedura di registrazione; se
avete fatto tutto correttamente vi trovate all'indirizzo 4194AE.
Digitate 'd ecx' e vedrete il nome del keyfile (tin.key). Ora cancellate tutti i
breackpoint (bc*), uscite dal sice, create un file di nome 'tin.key' nella stessa
directory del programma 'quattro.exe' e scriveteci il vostro nick.
Rientrate in sice e settate un bpx ReadFile. Ripetete la procedura di registrazione e vi
troverete di nuovo in sice.
F11 per uscire dalla funzione e date ancora una volta un'occhiata ai parametri passati
BOOL ReadFile(
HANDLE hFile,
// handle del file da leggere
LPVOID lpBuffer,
// indirizzo del buffer che riceve i dati
DWORD nNumberOfBytesToRead,
// numero dei byte da leggere
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped
);
Ricordando che i parametri sono passati da destra verso sinistra, scoprirete che viene
letto un carattere alla volta e viene copiato all'indirizzo :57F8AD.
Ora disabilitate il breakpoint e steppate(F10) fino all'indirizzo :0040130B.
.0040130B xor ebx,ebx
;azzera
il contatore dei byte letti (max 30)
.0040130D jmp 00401340 ;salta all'indirizzo :401340
......
......
......
.00401340 movsx eax,bl
.00401343 cmp eax,1E ;controlla che non vengano letti pi� di 30 char
.00401346 jl 0040130F ;salta all'inizio della routine di lettura
Se siete stati attenti vi sarete accorti che il primo carattere letto non viene salvato da
nessuna parte, perci�, se ad esempio nel vostro keyfile avete inserito il nick
'BlackDruiD', il prog considerer� soltanto 'lackDruiD'.
Quindi, a meno che non volete farvi amputare il nome, editate il keyfile e come primo
carattere inseritene uno a caso diverso da NULL(0x00) (io ho usato '~') in questo modo:
~BlackDruiD.
Ora analizziamo la routine di lettura del keyfile:
.0040130F push 001
.00401311 push edi
.00401312 push dword ptr,[esi]
.00401314 call 00419048
;call ReadFile
.00401319 add esp,0C
.0040131C movsx eax,bl
.0040131F mov dl,[edi]
.00401321 mov [eax+ebp-00A0],dl ;salva il byte letto in un buffer
.00401328 cmp byte ptr[edi],00
;confronta il char letto con '00'(NULL)
.0040132B jne 00401332
;salta se il char letto � diverso da NULL
.0040132D inc byte ptr[ebp-002E]
;incrementa il contatore
dei caratteri NULL
.00401330 jmp 00401336
.00401332 mov byte ptr[ebp-002E],00
;azzera il
contatore dei caratteri NULL
.00401336 movsx ecx,byte ptr[ebp-002E] ;sposta in ecx il valore del contatore dei NULL
.0040133A cmp ecx,002
.0040133D jg 00401348
;se ecx > 2 salta a 401348
.0040133F inc ebx
;incrementa il contatore dei caratteri letti
.00401340 movsx eax,bl
.00401343 cmp eax,1E
.00401346 jl 0040130F
;salta se sono stati letti meno di 30 char
.00401348 mov byte ptr[ebp-002E],00
.0040134C xor ebx,ebx
.0040134E jmp 00401381
Analizziamo in profondit� la routine:
la procedura si comporta in questo modo:
-Legge un byte alla volta
.0040130F push 001
.00401311 push edi
.00401312 push dword ptr,[esi]
.00401314 call 00419048 ;call
ReadFile
-salva i caratteri in un buffer
.00401321 mov [eax+ebp-00A0],dl
se digitate '? eax+ebp-A0' scoprirete che l'indirizzo del buffer � 57F88C
-controlla se il carattere letto � NULL; in caso affermativo, incrementa un contatore che
si trova in [ebp-002E] altrimenti azzera il contatore.
.00401328 cmp byte ptr[edi],00
.0040132B jne 00401332
.0040132D inc byte ptr[ebp-002E]
.00401330 jmp 00401336
.00401332 mov byte ptr[ebp-002E],00
-controlla il numero di NULL letti e se � uguale a tre termina la procedura
.00401336 movsx ecx,byte ptr[ebp-002E]
.0040133A cmp ecx,002
.0040133D jg 00401348
se riguardate il passo precedente, vi renderete conto che i tre NULL devono essere
consecutivi, altrimenti la routine continuer� finch� non sono stati letti 30 caratteri e
il buffer conterr� (nel mio caso) 'BlackDruiDDDDDDDDDDDDDDDDDDDDD' anzich� 'BlackDruiD'
-controlla che il nick non sia pi� lungo di 30 caratteri
.0040133F inc ebx
.00401340 movsx eax,bl
.00401343 cmp eax,1E
.00401346 jl 0040130F
-salta alla seconda routine di lettura
.0040134C xor ebx,ebx
.0040134E jmp 00401381
Tutto chiaro no? avrete capito che per avere un nick valido dovete inserire tre caratteri
NULL subito dopo il nick stesso, nel vostro keyfile(fatelo con un hex editor).
Ora dovreste trovarvi all'indirizzo :00401381,steppate fino a :401350, all'inizio della
seconda routine di lettura del keyfile; Questa procedura si comporta esattamete come la
prima,(tranne per il fatto che salva i byte letti in un buffer all'indirizzo 57F86C) e
perci� non la commento.
Questa routine legge il keyfile a partire dal byte successivo ai tre NULL, dove cio� si
trova il nick crittato.
Editate quindi il vostro keyfile ed inserite un numero di caratteri pari al vostro
nick(per ora inserite valori casuali, poi vi spiegher� come calcolare quelli giusti),
seguiti da tre NULL finali.
.00401350 push 001
.00401352 push edi
.00401353 push dwort ptr,[esi]
.00401355 call 00419048
.0040135A add esp,0C
.0040135D movsx eax,bl
.00401360 mov dl,[edi]
.00401362 mov [eax+ebp-00C0],dl
.00401369 cmp byte ptr[edi],00
.0040136C jne 00401373
.0040136E inc byte ptr,[ebp-002E]
.00401371 jmp 00401377
.00401373 mov byte ptr[ebp-002E],00
.00401377 movsx ecx,byte ptr[ebp-002E]
.0040137B cmp ecx,002
.0040137E jg 00401389
.00401380 inc ebx
.00401381 movsx eax,bl
.00401384 cmp eax,1E
.00401387 jl 00401350
Finita la seconda routine vi trovate qui:
Come potete vedere c'� una funzione alla quale viene passato l'indirizzo del buffer
contenente il nick.
Se osservate il valore di ritorno noterete che restituisce la lunghezza del vostro
nickname
.00401389 lea edx,[ebp-00A0]
.0040138F push edx
.00401390 call 004146D4
Ora vi trovate all'inizio della routine di verifica del keyfile
.00401395 pop ecx
.00401396 mov edx,eax ;edx = lunghezza del nick
.00401398 xor ebx,ebx ;azzera il contatore
.0040139A cmp dl,bl
.0040139C jle 004013C9 ;salta �
stata raggiunta la fine del nick
.0040139E mov eax,ebx
.004013A0 inc eax
;incrementa il contatore
.004013A1 movsx ecx,al
.004013A4 mov al,[ecx+ebp-00A0] ;mette in al un carattere del nick
.004013AB movsx ecx,bl
.004013AE xor al,[ecx+ebp-00A0] ;XORa al col carattere del nick precedente
.004013B5 movsx ecx,bl
.004013B8 cmp al,[ecx+ebp-00C0] ;confronta al col carattere del nick crittato
.004013BF jne 004013C4
; salta se sono diversi
.004013C1 inc byte ptr,[ebp-002D] ;incrementa il contatore dei 'confronti con successo'
.004013C4 inc ebx
;incrmenta ebx
.004013C5 cmp dl,bl
.004013C7 jg 0040139E
;salta all'inizio della routine
.004013C9 cmp dl,[ebp-002D]
;verifica il numero di 'successi'
.004013CC jne 004013FE
;salta se sono diversi
.004013CE xor eax,eax
.004013D0 mov [000420140],eax
.004013D5 mov eax,000000001
-Analisi approfondita
- La routine di verifica del keyfile svolge le seguenti funzioni:
-Prende un carattere alla volta dal buffer del nick a partire dal secondo carattere
.004013A4 mov al,[ecx+ebp-00A0]
-esegue uno XOR tra il carattere del nick e il suo precedente
.004013AE xor al,[ecx+ebp-00A0]
-confronta il risultato dello XOR col byte del nick crittato
.004013B8 cmp al,[ecx+ebp-00C0]
se scrivete '? al' vedrete il valore del nick-crittato corretto
-incrementa un contatore se il carattere del nick crittato � corretto
.004013C1 inc byte ptr,[ebp-002D]
-esegue la routine finch� non � stata raggiunta la fine del nick
.004013C5 cmp dl,bl
.004013C7 jg 0040139E
-verifica che tutti i caratteri del nick crittato siano corretti
.004013C9 cmp dl,[ebp-002D]
-salta se il nick non � valido
.004013CC jne 004013FE
ok, 'sniffate' ogni carattere del nick-crittato facendo come vi ho detto sopra e poi
editate il keyfile inserendo i valori del nick-crittato corretti;(usate un hex editor per
editare il keyfile).
N.B. Notate che l'ultimo byte del nick-crittato corrisponde all'ultimo byte del nick non
crittato il keyfile ha la seguente struttura:
[1 char a piacere][nickname][3 NULL][nick-crittato][3 NULL]
Ora che avete il vostro keyfile, lanciate nuovamente il programma, registratevi, clikkate
sul menu 'about' e vi comparir� una messagebox che vi dir� che il prog � registrato.
A questo punto voi direte: Evvivaaaaa ce l'ho fattaaaaaa sono un master crakker!!!!!
Premete il tasto ok e troverete una brutta sorpresa..... Un'altra messagebox appare
dicendo 'chiave pirata'... ma non � tutto, il peggio deve ancora venire...clikkate su ok
e il pc esploder� in mille pezzi....oppure si spegner� semplicemente.
Ma cosa no ha funzionato? probabilmente, anzi, sicuramente ci deve essere un'altra routine
di verifica del keyfile che viene eseguita dopo la prima messagebox. Quindi entrate in
sice, disabilitate tutti i bpx e settatene uno su messageboxa Registratevi e andate a
vedere nel menu about;
Ora siete in sice, premete F11 e vi comparir� la messagebox 'registrato';
premete ok e sarete di nuovo in sice, subito dopo la 'call 'MessageBoxExA' all'indirizzo
:40B294.
Ora, dato che la routine che ci aspettiamo deve controllare di nuovo il keyfile, settiamo
un bel bpx su 'ReadFile' e premiamo F5.
Premete F11 per uscire dalla funzione ReadFile, cancellate il bpx readfile e iniziate a
steppare fino all'indirizzo :401830.
Notate niente di strano? Ebbene si, il programma rilegge tutto il keyfile eseguendo 2
routine pressoch� identiche alle prime che vi ho spiegato(differiscono nell'indirizzo in
cui salvano i byte letti dal file: 57F888 per la prima routine e 57F868 per la seconda).
Ora dovreste essere all'indirizzo :401879.
.00401879 push 001
.0040187B lea edx,[ebp-007F] ;buffer
per ReadFile
.0040187E push edx
.0040187F push dword ptr[edi]
.00401881 call 00419048
;call ReadFile
.00401886 add esp,0C
.00401889 mov al,[ebp-007F] ;carica
in al il byte letto da ReadFile
.0040188C mov dl,[ebp-000A0] ;carica in
dl il primo byte del nick
.00401892 xor dl,[ebp-000C0] ;primo byte del nick XOR primo byte del nick-crypted
.00401898 cmp dl,al
.0040189A je 004018AE
;salta se sono uguali
.0040189C push dword ptr,[ebp+00008]
.0040189F call 004018D9
;call
MessageBox 'chiave pirata'
.004018A4 pop ecx
.004018A5 push 000
.004018A7 push 005
.004018A9 call ExitWindowsEx ;esce da
windows
Analisi del codice:
il codice svolge le seguenti funzioni:
-legge l'ultimo carattere del keyfile e lo salva in [ebp-007F]
.00401879 push 001
.0040187B lea edx,[ebp-007F]
.0040187E push edx
.0040187F push dword ptr[edi]
.00401881 call 00419048
-carica in al il byte letto da ReadFile
.00401889 mov al,[ebp-007F]
-carica in dl il primo byte del nick
.0040188C mov dl,[ebp-000A0]
-esegue uno XOR tra il primo byte del nick e il primo byte del nick crittato e mette il
risultato in dl
.00401892 xor dl,[ebp-000C0]
-verifica l'esattezza del byte calcolato col byte del keyfile
.00401898 cmp dl,al
-visualizza la messagebox di errore se il byte non � esatto ed esce da windows
.0040189C push dword ptr,[ebp+00008]
.0040189F call 004018D9
.004018A5 push 000
.004018A7 push 005
.004018A9 call ExitWindowsEx
Avete capito bene cosa fa? Verifica che l'ultimo byte del keyfile sia uguale a:
primo-byte-nick XOR primo-byte-crypted_nick
es:
nel mio caso sar�:
primo byte del nick: B (42 hex)
primo byte del nick-crittato: '.' (2E
hex)
42 XOR 2E = 6C ('l') -> 2� carattere del
nick
il byte calcolato sar� sempre il secondo carattere del nick(o meglio,il terzo del
keyfile) dato che:
primo_crypted_nick = primo_nick XOR
secondo_nick
quindi facendo l'operazione inversa:
secondo_nick = primo_nick XOR
primo_crypted_nick
esempio:
Nick = BlackDruiD
Crypted_nick = 2E 0D 02 08 2F 36 07 1C 2D 44
('B' XOR 'l') 42 xor 6C = 2E
quindi
2E xor 42 = 6C
facile no?
Ora andate a completare il vostro keyfile con l'ultimo byte calcolato e provate a
registrarvi
FUNZIONAAAAA!!!! W il Druido Nero!!!!
Ora vi spiegher� come realizzare un semplice keymaker in c
Per i pochi sfortunati che non avessero un compilatore c, allego il file eseguibile.
____________________________________CUT HERE___________________________________________
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void main(void){
FILE *pFile;
char nick[31], key[31];
char nul[3] = {'\0','\0','\0'};
char length,i;
printf("Inserisci il nome\n");
gets(nick);
length=strlen(nick);
//calcolo sul nick
for(i=0; i<=length; i++){
key[i] = nick[i] ^ nick[i+1];
}
//creazione del file
if((pFile =
fopen("tin.key","w+b"))== NULL) {
printf("File error\n");
exit(1);
}
//scrittura del primo carattere
fputc('~', pFile);
//scrittura del nick
fputs(nick, pFile);
//scrittura dei 3 null
fwrite(&nul, sizeof(nul), 1, pFile);
//scrittura dela key
for(i=0; i<length; i++){
fputc(key[i],pFile);
}
//scrittura dei 3 null
fwrite(&nul, sizeof(nul), 1, pFile);
//scrittura del carattere di controllo
fputc(nick[1],pFile);
//chiusura del file
fclose(pFile);
printf("\nFile creato dal Druido
Nero!!!\n");
}
Finalmente ho finito questo tutorial!!!!!
BlackDruiD
|
Saluto prima di tutto TiN_MaN che ha realizzato questo crackme,
Quequero(e Gozzzilla), Ritz(che prima o poi dovr� pagarmi per tutte le magie che gli
faccio), attila_hk, d4emon, sPEZIO, xOANNON(gran bel sito), [aLT255], [SandMan],
baron_sam, Baneold, Nobody88, neural_noise, Insanity, AzaZ3l, Furb3t, ZeroByte, war_lock,
Kill3xx, Brigante(il mio avvocato ;)), Yado, Xinner, Alor, along3x, away,
BlackArrow(l'unico che � venuto a trovarmi allo smau), [H3ll], Anub|s, il mio cane, il
figlio della madre di mia sorella(sei un grande), mio padre mia madre e tutti quelli che
mi conoscono ;)
tutti gli amici di #crack-it e #uic
tutti i membri della UIC e della sua mailing list
tutti i membri di ringzer0
cazzo, quasi quasi i saluti son pi� lunghi del tutorial...
Disclaimer |
Home Assembly ContactMe CrackMe Links
NewBies News Forum Lezioni
Tools Tutorial