PraetorianCm

Keyfile Protection

Data

by "Evilcry"

 

28/07/2002

UIC's Home Page

Published by Quequero


Qualche mio... eventuale commento sul tutorial :)))

 

....

Home page se presente: www.evilcry.cjb.net
E-mail: evilcry@virgilio.it
Nick, UIN, canale IRC/EFnet frequentato   irc.azzurra.it   #crack-it
 

....

Difficoltà

(x)NewBies ()Intermedio ( )Avanzato ( )Master

 

 

PraetorianCm
Keyfile protection
Written by Evilcry.

Introduzione

Il crackme che andremo a reversare utilizza uno sche di protezione molto semplice, basato su un keyfile

Tools usati

-SoftIce
-ApiSpy
-Non siate lameri non usate altro :P

URL o FTP del programma

www.evilcry.da.ru

www.crackmes.de

Notizie sul programma

Il crackme in questione è diviso in tre livelli di difficoltà crescente. Un livello superato abilita l' altro.

Essay

Livello 1

Dopo aver avviato il programma vi troverete davanti ad una messagebox che ci manda a quel paese :D. Con un ApiSpy controlliamo le eventuali Imports....mhhh ci sono tre API interessanti cioè:

CreatefileA=Apre o crea un file.

GetFileSize=Ci restituisce la grandezza del file.

ReadFile=Legge il file.

Se non l' avete già fatto vi consiglio di leggere il quarto corso della UIC in cui viene spiegato molto bene il funzionamento di queste API.Comunque per comodità vi riporto la reference della prima API che incontreremo in questo crackme, CreateFileA :

HANDLE CreateFile(

LPCTSTR lpFileName, // pointer to name of the file QUESTO E' IL PARAMETRO CHE CI INTERESSA

DWORDdwDesiredAccess, // 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 );

Senza approfondire molto, vi dico che il primo (ricordate la struttura LIFO dello stack no????) parametro è quello che ci interessa, cioè il puntatore al nome del file da aprire. Spesso dopo la CALL troverete un

cmp EAX,FFFFFFFF

je Errore_Apertura_File

che controlla se il file sia stato aperto correttamente, in caso di errore (ad esempio il file non esiste) la call torna -1 cioè FFFFFFFF....semplice no? :-}

Adesso caricate il programmillo dal symbol loader del Sice , per evitare di steppare fino alla morte :-} e settate un BPX CreateFileA. Premete F12 UNA volta e poi con F10 steppate su un RET, e :vi troverete nel processo del nostro programma...diamoci un occhiata:

004010A8 push 00000000 ---|Parametri per CreateFileA

004010AA push 00000080 ---|

004010AF push 00000003 ---|

004010B1 push 00000000 ---|

004010B3 push 00000001 ---|

004010B5 push 80000000 ---|

Possible StringData Ref from Data Obj ->"sdrs-sws"

004010BA push 0040303B ---| Puntata alla locazione che contiene il nome del file

Reference To: KERNEL32.CreateFileA, Ord:0032h

004010BF Call 00401160

004010C4 cmp eax, FFFFFFFF-----controlla se ci sono stati errori

004010C7 ret

Dovrebbe esservi tutto chiaro, basta fare d 0040303B e vedrete il nome del file cioè test.txt, quando vi trovate davanti al nome di un file senza il percorso significa che questo si trova nella stessa directory del programma. Non ci resta che creare un file con il Notepad ad esempio , chiamarlo test.txt, disabilitare il Breakpoint ed avviare il crackme che vi darà accesso al secondo livello :)).

Livello 2

Abilitate un breakpoint a GetFileSize, il codice è cosi intuitivo che non c' è bisogno neanche delle references :-). Come nel primo livello premete UNA volta F12 e poi con F10 steppate un' altra volta su un ret, e vi ritroverete nel codice. Analizziamolo:

004010C8 push 00000000 ----Parametro di GetFileSize

004010CA push dword ptr [00403044] -----Handle del nostro file

Reference To: KERNEL32.GetFileSize, Ord:00FEh

004010D0 Call 0040116C

004010D5 cmp eax, 0000000A Controlla che il file sia grande 10 bytes (A in esadecimale)

004010D8 ret

La routine è semplicissima, in EAX abbiamo la grandezza del file in esadecimale, il programma controlla che il nostro file sia grande A bytes cioè 10 in decimale. Disabilitate tutti i breakpoint ed andate a inserire nel file dieci caratteri a caso (MI RACCOMANDO 10 :P).Se tutto è andato bene dovrebbe comparirvi la messagebox d' errore del terzo livello, quindi si intuisce che il secondo è superato ihihhihi.

Livello 3

Per questo livello ci serve conoscere ReadFile, perciò vi riporto le sue references:

BOOL ReadFile(

HANDLE hFile, // handle of file to read

LPVOID lpBuffer, // indirizzo del buffer che riceverà i dati

DWORD nNumberOfBytesToRead, // Numero bytes da leggere

LPDWORD lpNumberOfBytesRead, // Numero di bytes letti

POVERLAPPED lpOverlapped // address of structure for data ); NON CI INTERESSA

la traduzione è stata presa dal quarto corso della UIC

Mettete un breakpoint a ReadFile steppate nella maniera che avete precedentemente visto, ora vediamo il codice:

004010D9 push 00000000 ---Parametro della Read

004010DB push 00403088 ---Byte letti

004010E0 push 00000004 ----Byte da leggere

004010E2 push 0040307E --Indirizzo dove troveremo i bytes letti

004010E7 push dword ptr [00403044] ----HANDLE

Reference To: KERNEL32.ReadFile, Ord:01FDh

004010ED Call 00401178

004010F2 cmp byte ptr [0040307E], 2D Confronta il primo carattere letto con 2D

004010F9 je 004010FF Se è uguale salta a 0010FF, sennò ci manda alla messge box d' errore

004010FB xor eax, eax

004010FD jmp 00401112

Referenced by a (U)nconditional or (C)onditional Jump at Address:

004010FF cmp byte ptr [0040307F], 30 Confronta il secondo char letto con 30

00401106 je 0040110C Se è uguale va alla congratulation box

00401108 xor eax, eax

0040110A jmp 00401112

Referenced by a (U)nconditional or (C)onditional Jump at Address:

:0040110C B801000000 mov eax, 00000001

:00401111 C3 ret

Qui vediamo che vengon letti i primi 4 chars che si trovano nel nostro file, poi il programma controlla

che il primo carattere sia 2D cioè il trattino, se è cosi passa a leggere il secondo char.Il secondo char deve essere uguale a 30 cioè 0 in ASCII, se è giusto salta alla congratulation box.Capite che i caratteri

da cambiare sono i primi due, sostisuiteli con - e 0 , occhio a non dimenticarvi di cancellare il char sostituito, perchè sennò la lunghezza del file non sarà più di 10 (Ricordate :))

 

Spero di essere stato chiaro, se avete qualche dubbio no esitate a mailarmi.

 

Note finali

In fine colgo l' occasione per salutare:Quequero, AndreaGeddon, [Evil], e4m, Slash, Quake2^AM, Albe,BIGAlex, Ntoskrnl, CityHunter, CyberPK.

Disclaimer

Noi reversiamo al solo scopo informativo e di miglioramento del linguaggio Assembly (Sisi!ci credo :P).

Capitoooooooo????? Bhè credo di si ;))))