Reversing
del daPope’s CrackMe #1 |
||
Data |
by “fUsHji” |
|
04/06/2005 |
Published by Quequero |
|
“Noi siamo i figli dei padri
ammalati, aquile al tempo di mutare le piume,… |
|
…svolazziam
muti, attoniti, affamati, sull’agonia di un nume.” Proludio, Emilio Praga
(1864) |
.... |
Home
page: http://fushji.altervista.org E-mail: [email protected] |
.... |
Difficoltà |
( )NewBies (x)Intermedio ()Avanzato ( )Master |
|
Introduzione |
Si tratta
di un crack-me, scritto in java compilato con Microsoft Visual J++…
Tools usati |
J++ Extract
Jad
J2SDK
(qualsiasi versione è ok)
URL o FTP del programma |
Essay |
Dunque apriamo il crack-me e ci viene
chiesto un Name e un Serial, quindi fushji 458996, click su Register
e… “Invalid Serial. Try Again”. Ora prima di
procedere devo fare una piccola precisazione: a molti di voi potrebbe capitare
di aprire il crackme e trovarsi davanti il messaggio
"A Certain Program Is Detected. Unload", si tratta
di una piccola protezione Anti-SoftIce che vedremmo
subito come aggirare.
Apriamo J++ Extract, un tool che premette di estrarre dagli .exe
creati con MS VJ++ i file .class, e tiriamo fuori i files .class. tra tutti i files
estratti uno in particolare interessa la nostro scopo ‘CrackMe.java’,
apriamolo con un editor di testi e vediamo un po’ di codice Java:
import java.io.*; import java.lang.Character; public class Crackme
extends java.awt.Frame { /** Creates
new form Crackme */ public Crackme(String[] args) { initComponents (); pack (); setTitle("daPope's CrackMe #1 - Take a look att
http://surf.to/daPopesTutorial"); if(!checkForWinIce()){ . . . . . . private boolean checkForWinIce(){ try{ return parseAutoexec(new BufferedReader(new
FileReader("C:/Autoexec.bat"))); } catch(FileNotFoundException e){ return
false; } } private boolean parseAutoexec(BufferedReader br){ String
temp;
while(true){ try{ temp =
br.readLine(); if(temp!=null){ for(int i=0;i<temp.length();i++)
if(temp.regionMatches(true,i,"winice.exe",0,10))
return true; } else
return false; } catch(IOException e){ return
false; } }
} |
Per chi ha un po’ di dimestichezza con il
java, il codice è facile da leggere, comunque il crack-me cerca nel file autoexec.bat se è installato winice.exe, se lo trova il
messaggio che ritorna è che blocca il crack-me, lo avete già letto :). (apro
una piccola parentesi, personalmente io non avuto nessun problema per due
motivi 1. non
ho installato il softice; 2. In Windows XP in file autoexec.bat non c’è.). Comunque
per coloro i quali hanno avuto questo problema le strade da seguire sono due:
1.
Modificate
‘winice.exe’ con qualcosa come ‘asdasdasd.exe’;
2.
Cosa
molto più semplice fate in modo che winice.exe non
venga trovato in autoexec.bat, modificando
momentaneamente il file.
Fatte queste piccole modifiche, rilanciate il crack-me e
vedete se tutto va per il meglio… continuando con la lettura del codice, la
prima cosa che verrebbe da fare è andare a controllare la routine di gestione
dell’evento click sul bottone Register
private void button1ActionPerformed (java.awt.event.ActionEvent evt)
{ calculateSerial();
} . . . . . . private void calculateSerial(){ boolean fakeSuccess=false; String
name = textField1.getText(); String
serial = textField2.getText(); if(name.length()==0 || serial.length()==0)
label3.setText(
new Character('Y').toString() +
new Character('o').toString() +
new Character('u').toString() +
new Character(' ').toString()
+
new Character('M').toString() +
new Character('u').toString() +
new Character('s').toString() +
new Character('t').toString() + new Character(' ').toString() +
new Character('E').toString() +
new Character('n').toString() +
new Character('t').toString() +
new Character('e').toString() +
new Character('r').toString() +
new Character(' ').toString()
+
new Character('A').toString() +
new Character(' ').toString()
+
new Character('N').toString() +
new Character('a').toString() +
new Character('m').toString() +
new Character('e').toString() +
new Character(' ').toString()
+ new Character('A').toString() +
new Character('n').toString() +
new Character('d').toString() +
new Character(' ').toString()
+
new Character('A').toString() +
new Character(' ').toString()
+
new Character('S').toString() +
new Character('e').toString() +
new Character('r').toString() +
new Character('i').toString()
+
new Character('a').toString() +
new Character('l').toString() ); else{ char[] charName = name.toCharArray(); char[] charSerial = serial.toCharArray(); Character[]
chName=new Character[charName.length];
Character[] chSerial = new Character[charSerial.length]; if(name.length()>6 && serial.length()==9){ for(int i=0;i<charName.length;i++) chName[i]=new Character(charName[i]); for(int i=0;i<charSerial.length;i++) chSerial[i]=new Character(charSerial[i]); if(chName[0].compareTo(chSerial[4]) == 0){ if(chSerial[0].compareTo(chSerial[8]) == 0){ int tmp = (int)
((Character.getNumericValue(charName[1])+ Character.getNumericValue(charName[2])+ Character.getNumericValue(charName[3]))/3);
if( Character.getNumericValue(charSerial[2]) == tmp){ int tmp1 = (int) ((Character.getNumericValue(charName[charName.length-3])+ Character.getNumericValue(charName[charName.length-2])+ Character.getNumericValue(charName[charName.length-1]))/3);
if( Character.getNumericValue(charSerial[6] )== tmp1){
fakeSuccess=true;
}
} } } } if(fakeSuccess)
label3.setText(
new Character('T').toString() + new Character('r').toString() +
new Character('y').toString() +
new Character(' ').toString()
+
new Character('A').toString() +
new Character('n').toString() +
new Character('o').toString() +
new Character('t').toString() +
new Character('h').toString() +
new Character('e').toString() +
new Character('r').toString() +
new Character(' ').toString()
+
new Character('A').toString() +
new Character('p').toString() +
new Character('p').toString() +
new Character('r').toString() +
new Character('o').toString() +
new Character('a').toString() +
new Character('c').toString() +
new Character('h').toString() +
new Character('.').toString()
+
new Character(' ').toString()
+
new Character('R').toString() +
new Character('e').toString() +
new Character('g').toString() +
new Character('i').toString()
+
new Character('s').toString() +
new Character('t').toString() +
new Character('r').toString() +
new Character('a').toString() +
new Character('t').toString() +
new Character('i').toString()
+
new Character('o').toString() +
new Character('n').toString() + new Character(' ').toString() +
new Character('F').toString() +
new Character('A').toString() +
new Character('I').toString() +
new Character('L').toString() +
new Character('E').toString() +
new Character('D').toString() ); else
label3.setText(
new Character('I').toString() +
new Character('n').toString() +
new Character('v').toString() +
new Character('a').toString() +
new Character('l').toString() +
new Character('i').toString()
+
new Character('d').toString() +
new Character(' ').toString()
+
new Character('S').toString() +
new Character('e').toString() +
new Character('r').toString() + new Character('i').toString() +
new Character('a').toString() +
new Character('l').toString() +
new Character('.').toString()
+
new Character(' ').toString()
+
new Character('T').toString() +
new Character('r').toString() +
new Character('y').toString() +
new Character(' ').toString()
+
new Character('A').toString() +
new Character('g').toString() +
new Character('a').toString() +
new Character('i').toString()
+
new Character('n').toString() ); }
textField1.setText(""); textField2.setText(""); } |
Questo metodo è una
falsa routine di gestione, infatti prende user e il serial dalle textbox,
verifica la lunghezza e poi fa una serie di calcoli per calcolarsi il serial. Se i due serials coincidono,
abbiamo fatto esattamente il gioco del crack-me e ci vedremo stampato un bel
messaggio: “Try Another Approach Registration FAILED“.
Andiamo quindi a cercare la giusta procedure di calcolo del serial, e la troviamo
all’inizio del codice:
button1.setEnabled(false);
String name=args[0];
String serial = args[1]; StringBuffer correct = new StringBuffer(); for(int i=0;i<name.length();i++){ char a = name.charAt(i); //carattere alla posizione i di name <--+ int b = Character.getNumericValue(a);
//valore
numeri di a -----+ int c = b % 10; //modulo di b per 10 Integer d = new Integer(c); correct.append(d.toString()); //correct += d } if(serial.equals(correct.toString())){
registered = true;
try{ FileWriter theFile=new FileWriter("C:/Windows/systen.ini"); theFile.write("Well done
"+name+"\n\n"); theFile.write("
You've cracked daPope's CrackMe
#1"); theFile.write("using "+serial+" as serialnumber\n\n"); theFile.flush(); }
catch(Exception e){}; |
Come possiamo notare a name viene assegnato args[0] e a serial args[1], correct conterrà poi il serial giusto; se andiamo verso la
fine del codice ci accorgeremo che nel metodo main
vengono passati come parametri al costruttore della classe Crackme
gli argomenti acquisito da linea di comando, quindi l’user
e il serial per registrare il crackme non devono
essere inseriti nelle textbox, ma passati da linea di
comando:
C:\>
CrkMe.exe fushji 508798
Il
generazione
del serial avviene nel seguente modo:
for(int i=0;i<name.length();i++){
char a = name.charAt(i);
int b = Character.getNumericValue(a);
int c = b % 10;
Integer d = new Integer(c);
correct.append(d.toString());
}
infine se il serial inserito è giusto
viene creato un file C:\Windows\Systen.ini, che verrà controllato ogni volta
che il crack-me verrà lanciato nuovamente, per fare altri tentativi bisogna
cancellare il file.
IL KEYGENERATOR
Vediamo quindi come realizzare il keygen
per questo crackme:
/* * +---[KeyGenerator
for daPope's CrackMe #1 * * c0der: fUsHji
<[email protected]> * homepage:
http://fushji.altervista.org * */ import java.io.*; class keygen { public static void
main(String args[]){ System.out.println("+----[KeyGenerator for daPope's CrackMe #1"); System.out.println("+------[c0de
by fUshji
<http://fushji.altervista.org>"); if (args.length != 1) { System.out.println("Usage:
java keygen user"); System.exit(0); } String user = args[0]; StringBuffer
correct = new StringBuffer(); for(int i=0;i<user.length();i++){ char a = user.charAt(i); int
b = Character.getNumericValue(a); int
c = b % 10; Integer d = new
Integer(c); correct.append(d.toString()); } System.out.println("The
serial is: " + correct); } } |
Non mi sono preoccupato di riportare la
routine di generazione del fakeserial, tanto la sua
utilità è pari a zero.
.fUsHji
Note finali |
Un saluto e un
ringraziamento a daPope per il
crack-me, lo staff di crackmes.de
per gli innumerevoli crack-me con i quali giocarci, a Quequero
(che spero mi pubblicherà :P), a BlackDemon, Lord_dex e basta!
Disclaimer |
Vorrei ricordare che il crack-me va comprato e non rubato, ma…prrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
Reversiamo al solo scopo informativo e per migliorare la nostra conoscenza del linguaggio Java (‘sta volta).