Reversing e cracking di una applicazione java |
||
Data |
by "epokh" |
� |
03/Oct/2004 |
Published by Quequero |
|
Wong Long il fondatore dello stile Tang Lang disse: |
Complimentissimi a epokh, un tutorial di questo tipo ci mancava davvero tanto, grazie tante, spero che il tute serva a incuriosire anche altri reverser. |
"Il fine di una tazza è nel suo essere vuota" |
.... |
|
.... |
Difficolt� |
( )NewBies (X)Intermedio ( )Avanzato ( )Master |
� |
Introduzione |
Tools usati |
URL o FTP del programma |
Notizie sul programma |
Essay |
I cracker suddetti però si sono trovati spiazzati non poco dalla nuova piattaforma sw della SUN che richiede un approccio radicalmente differente da quello delle applicazioni Win32, in quanto fare il debugging di un'applicazione java con il softice significa fare il debugging dell'interprete java e vi assicuro che non è una delle cose più divertenti al mondo?Perchè? .. L'interprete java (lo trovate in /bin/java.exe della vostra JRE) legge gli opcode del byte code dal file .class di cui sta effettuando il parsing, li traduce e a seconda dell'istruzione esegue interrupt (hw e sw),chiamate di sistema, operzioni aritmetiche ecc.
Attenzione: il debugging è difficile ma non impossibile, se ci saranno richieste a sufficienza si potrà approfondire l'argomento.
Comunque in questo tutorial effettueremo il reversing del crack me e non il debugging perciò state tranquilli. La conoscenza di Java è fondamentale, ma basterà conoscere a sufficienza i package java.awt ( platform undependent)e javax.swing (platform dependent).
Passiamo ora al crackme: l'applicazione è distribuita in formato jar, crack_me.jar , lanciamo il programma ( con java -jar crack_me.jar se non avete impostato l'interprete fra le variabili d'ambiente) e sul menu clickiamo Help->Registrati. E' richiesto il nome dell'utente e il seriale in una dialog box simile quelle di Windows.
Se il seriale non è corretto un messaggio di errore ce lo segnala, quindi ora sappiamo dove andare a cercare nel codice dell'applicazione decompilata.
Il primo passo è estrarre le risorse contenute nel file .jar in una cartella. Dico risorse perchè nel jar oltre ai file .class ed al manifesto ci possono essere immagini, eseguibili e tutto quello che può servire all'applicazione in fase di run-time.
Il contenuto del nostro jar può essere visualizzato con: jar tf crack_me.jar l'output è il seguente:
Per estrarre il contenuto possiamo procedere in due modi: con WinZip o con Dj Decompiler. Lanciamo Dj Decompiler ed apriamo il nostro jar dal dialogo open file, a questo punto possiamo vedere tutto il contenuto dell'archivio che estraiamo in una cartella a nostra scelta.
Bene nel mio caso l'estrazione fallisce il programma sembre avere un bug: Fatal Error in UnzDLL.DLL: abort exception. Fa niente lo estraiamo con il winzip. Le risorse sono divise in due cartelle: nella cartella META-INF troviamo il manifesto nell'altra crack_me troviamo i file .class e una immagine png.
Ricordiamo che le cartelle contenenti i file .class corrispondo ai package quindi le classi contenute in una stessa cartella hanno lo stesso scope.
Perchè tanti file per un applicazione tanto piccola? Ricordiamo che in Java il file deve avere lo stesso nomde della classe, quindi ogni classe corrisponde ad un file.Come troviamo la classe contente il punto d'ingresso per l'applicazione? Apriamo il manifesto con il notepad e leggiamo:
M anifest-Version: 1.0
Main-Class: crack_me.Applicazione
Quindi il file nella cartella crack_me, Applicazione.class contiene il metodo main. Decompiliamo con DJ e otteniamo
import java.awt.Dimension; //
Referenced classes of package crack_me: public class
Applicazione public Applicazione() public static
void main(String args[]) boolean packFrame; |
// Decompiler options:
packimports(3) // Source File Name: Main.java
package crack_me; import java.awt.*; // Referenced
classes of package crack_me: public class
Main extends JFrame public Main() //crezione
degli oggetti della GUI private
void jbInit() public void
jMenuHelpAbout_actionPerformed(ActionEvent e) void jMenuRegister_actionPerformed(ActionEvent
e) //PUBLIC oggetti della GUI JPanel contentPane; |
Ma dove sono gli oggetti che gestiscono gli eventi, cioè gli oggetti che implementano l'interfaccia ActionListener? Per l'oggetto jMenuRegister la classe che implementa l'action listener è Main_jMenuRegister_actionAdapter che il DJ ci segnala fra le classi referenziate.
Il metodo che gestisce l'evento di click sulla voce Register è come evidenziato
void jMenuRegister_actionPerformed(ActionEvent e)
{
Register dlg = new Register(this);
.....
dlg.show();
}
Il metodo non fa altro che generare una DialogBox corrispodente all'oggetto dlg di tipo Register. Il metodo dlg.show() serve per visualizzare la DialogBox.
La classe Register è presente nel package locale quindi la decompiliamo:
// Decompiler options: packimports(3) // Source File Name: Register.java
package crack_me; import java.awt.*; // Referenced classes
of package crack_me: public class Register
extends JDialog public Register(Frame
parent) private void jbInit() void BottoneReg_actionPerformed(ActionEvent
e) // il gestore dell'evento associato al bottone
JPanel panel1; |
La classe Register eredita da JDialog la classe che appunto modella un dialogo, infatti nella sezione pubblica della classe possiamo notare i componenti del dialogo:
LabelNome ->una label: quella del nome
TextUtente-> il campo per inserire il nome dell'utente
LabelSeriale-> una label: quella del seriale
TextSeriale ->il campo per inserire il seriale
BottoneReg -> un bottone per registrare il seriale
Il metodo che gestisce l'evento associato al bottone è: void BottoneReg_actionPerformed(ActionEvent e) che contiene finalmente la routine di controllo del seriale. Analizziamola:
for(int i = 0; i < bintserial.length; i++)
sum += bintserial[i]; -> sum contiene la somma dei valori dell'array di interi
if(sum >= 416 && sum <= 420) -> la somma è compresa tra 416 e 20?
check = true; -> se si controllo passato
else
check = false;
}
} else
{
check = false;
}
Un vantaggio del reversing in ambiente Java è che il bytecode generato dal compilatore essendo predisposto per un unico processore virtuale è fedele nella maggioranza dei casi al sorgente originale. Quindi possiamo anche: modificare la routine di controllo della classe Register, compilarla e reinserirla nel jar senza aver modificato le altre classi.
Quello che facciamo adesso è impenasabile nel mondo win32:
1.modidichiamo il codice sorgente di Register.java modo che il check sia sempre vero:
if(check=true){....
OK...} else
{.....
NO}
2.salviamo il sorgente modificato in un cartella con lo stesso package delle classi, nel mio caso G:\crack_me. Nella stessa cartella copiamo il jar originale crack_me.jar
3.ricompiliamo solo la classe Register usando le classi che stanno nel package, nella cartella crack_me creata :
G:\crack_me\> javac -classpath crack_me.jar Register.java
4.aggiungiamo la classe Register ricompilata nel jar dalla directory superiore, questo è importante altrimenti la classe non verrà aggiunta nel package corretto:
G:\>jar uf crack_me/crack_me.jar crack_me/Register.class
5.verifica
G:\crack_me\>javac -jar crack_me.jar
Incredibile funziona! Mi sono meravigliato anche io la prima volta, ma non bisogna stupirsi più di tanto perchè il Java non effettua un vero e proprio linking dei file .class.
������������������������� ������������������������������������������������������������������������������� ...::: EPOKH :::...
Note finali |
Spero di trovare altre occasioni per approfondire il cracking in Java. Chiedi e ti sarà dato.
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 che ogni sviluppatore ha dovuto portare avanti per fornire ai rispettivi consumatori i migliori prodotti possibili.
Reversiamo al solo scopo informativo e per migliorare la nostra conoscenza del linguaggio Assembly.�