Reversing del daPope’s CrackMe #1

Data

by fUsHji

 

04/06/2005

UIC's Home Page

Published by Quequero

“Noi siamo i figli dei padri ammalati,

aquile al tempo di mutare le piume,…

 Grazie tante fushji, i tute sul java reversing tornano sempre utili!

 

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

 

www.crackmes.de

 

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).