Reversing e cracking di una applicazione java |
||
Data |
by "epokh" |
� |
22/10/2004 |
Published by Quequero |
|
Wong Long il fondatore dello stile Tang Lang disse: |
Grazie
epokh questi tute torneranno davvero utili! |
"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 |
Ho deciso di scrivere questo nuovo tutorial quando mi sono imbattuto in alcune protezioni "strane" che ho trovato in alcune applicazioni Java. Java infatti sfrutta le possibilità offerte dalla programmazione ad oggetti per nascondere le funzioni di controllo per la registrazione.
In questa lezione esporremo il concetto di base di questa protezione tramite un semplice programma, in modo da chiarire l'approccio che si deve usare in questi frangenti.
L'applicazione è distribuita in un file jar come l'altra volta: lanciamo il programma, java -jar crack_me.jar e proviamo a registrarci.La routine di controllo del seriale è cambiata quindi bisogna reversare il programma. Listiamo il contenuto del file jar con jar tf crack_me.jar, i file sono:
Come possiamo notare ci sono due nuove classi ControlloF e ControlloP, il cui nome è abbastanza eloquente, ricordiamo però che in una applicazione vera i nomi possono essere meno sospettosi tipo ImageHandler e FigureHandler in modo da disorientare il reverser.
Estraiamo il contenuto del file jar con WinZip nella cartella crack_me ed apriamo il manifesto nella cartella META-INF. Il manifesto è il seguente:
Manifest-Version: 1.0
Main-Class: crack_me.Applicazione
Decompiliamo la classe Applicazione nella cartella crack_me, per scoprire che instanzia un oggetto di tipo Main che eredita da JFrame, la classe che manipola le finestre di Windows
package crack_me;
import java.awt.Dimension; // Referenced classes of package crack_me: public Applicazione() <-costruttore di Applicazione public static void main(String args[]) |
package crack_me;
import java.awt.*; // Referenced classes of package crack_me: public class Main extends JFrame { private void jbInit() throws Exception } |
Il gestore degli eventi per l'item del menu che si chiama "Registrati" è l'oggetto instanza della classe Main_jMenuRegister_actionAdapter. Nella lezione 1 non ho spiegato bene questa cosa: la classe Main_jMenuRegister_actionAdapter implementa l'interfaccia ActionListener in modo da gestire gli eventi dell'oggetto Main, infatti se la decompiliamo otteniamo:
package crack_me;
import java.awt.event.ActionEvent; // Referenced classes of package crack_me: class Main_jMenuRegister_actionAdapter implements ActionListener Main_jMenuRegister_actionAdapter(Main adaptee) public void actionPerformed(ActionEvent e) <- implementa il metodo ActionPerformed Main adaptee;
|
Come possiamo vedere dal codice la classe Main_jMenuRegister_actionAdapter implementa il metodo actionPerformed dell'interfaccia ActionListener dicendo che il gestore del click sull'item "Registrati" è il metodo jMenuRegister_actionPerformed(e) della classe Main.
Il metodo jMenuRegister_actionPerformed(e) è il seguente:
void jMenuRegister_actionPerformed(ActionEvent e)
{
Register dlg = new Register(this);
.....
dlg.show();
}
Il metodo non fa altro che instanziare un oggetto di tipo Register che eredita a sua volta da JDialog, la classe che gestisce i dialoghi. In modo analogo individuiamo il metodo che gestisce il click sul bottone Registra che si chiama
La classe Register è presente nel package locale quindi la decompiliamo:
void BottoneReg_actionPerformed(ActionEvent e) { String user = TextUtente.getText(); String serial = TextSeriale.getText(); ControlloF ctrl = new ControlloF(user, serial); boolean check = ctrl.check(); if(check) { JOptionPane.showMessageDialog(null, "OK", "Applicazione registrata", 1); main.MainInfo.setText("Applicazione registrata"); main.jMenuRegister.disable(); } else { JOptionPane.showMessageDialog(null, "No", "Il seriale non \350 corretto", 0); } dispose(); } |
Questa volta il controllo viene effettuato da un oggetto apposito, come richiedeuna buona progettazione ad oggetti, ctrl instanza della classe ControlloF. Il costruttore di ControlloF ha come parametri formali due oggetti di tipo stringa che corrispondono al nome dell'utente e al seriale. Il metodo check di ControlloF ritorna un valore booleano che indica se il seriale è corretto oppure no.
A questo punto decompiliamo la classe ControlloF
package crack_me; // Referenced classes of package crack_me: public class ControlloF extends ControlloP ControlloF(String utente, String serial) |
Ma come è possibile? Il metodo check non è presente in ControlloF mentre il costruttore si. Il trucco è semplice: i programmatori hannno nascosto il metodo di controllo sfruttando l'ereditarietà. La classe ControlloF eredita da ControlloP, quindi il metodo sarà nella superclasse che andremo a decompilare.
// Source File Name: ControlloP.java
package crack_me; public class ControlloP public ControlloP(String utente, String seriale) public boolean check() <- ecco il metodo nascosto private String utente; |
Bingo, abbiamo trovato il metodo nascosto check. Il controllo è banale: si sommano le lunghezze delle stringhe di nome utente e seriale e si controlla se la somma è compresa tra 10 e 15, estremi esclusi. Un esempio di seriale corretto è:
Utente: Paolo (6 caratteri) Seriale: Diprox
Modifichiamo allora la classe ControlloP in modo che restituisca sempre TRUE:
public boolean check() <- ecco il metodo nascosto
{
int len1 = utente.length();
int len2 = seriale.length();
return TRUE;
}
2.salviamo il sorgente modificato in un cartella con lo stesso package delle classi, nel mio caso F:\ToCrack\crack_me. Nella stessa cartella copiamo il jar originale crack_me.jar
3.ricompiliamo solo la classe ControlloP usando le classi che stanno nel package, nella cartella crack_me creata :
F:\ToCrack\crack_me\> javac -classpath crack_me.jar ControlloP.java
4.aggiungiamo la classe ControlloP ricompilata nel jar dalla directory superiore, questo è importante altrimenti la classe non verrà aggiunta nel package corretto:
G:\ToCrack>jar uf crack_me/crack_me.jar crack_me/ControlloP.class
5.verifica
G:\ToCrack\crack_me\>java -jar crack_me.jar
Nella lezione 1 ho scritto javac invece che java, chiedo perdono :->, molti avranno bestemmiato!
L'applicazione viene registrata con qualsiasi nome e seriale.
������������������������� ������������������������������������������������������������������������������� ...::: EPOKH :::...
Note finali |
Nelle prossime lezioni ci divertiremo alla grande visto che inizieremo a reversare delle applicazioni "vere".
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.�