C# Framework.NET Reversing
(I.L. Craking)

Data

by "Pbdz"

 

14/aprile/2004

UIC's Home Page

Published by Quequero

Niente da dire...

Grandissimo Pbdz, finfalmente qualcuno che reversa un prog scritto in .net, complimenti, speriamo che questo serva da input per tutti gli altri :)

Niente da pensare...

....

Home page: http://pbdz.cjb.net
E-mail: [email protected]

....

Difficoltà

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

 

Avete mai provato a disassemblare un programma scritto in C#?


C# Framework.NET Reversing
I.L. Cracking
Written by Pbdz

Introduzione

Salve a tutti! E' parecchio che non mi faccio vivo da queste parti! Ho scritto questa specie di tutorial perchè fin'ora non ho trovato niente su internet riguardo questo argomento. Siccome programmo da quasi un anno col C# volevo vedere com'era "dall'altra parte"! :-)

Tools usati

Per disassemblare consiglierei IDA, altrimenti basta scrivere sulla nel prompt dei comandi: ildasm.
Per modificare il file basta un qualsiasi Hex Editor.

URL o FTP del programma

Ecco il link al mio programma. Per scaricare il framework andate sul sito di zio Bill! ;-)

Notizie sul programma

Cos'è il Framework.NET?
Questo oscuro oggetto (di casa microsoft) non è altro che una piattaforma
su cui possono girare determinati programmi, piattaforma anche chiamata CLR (Common Language Runtime).
Per farvi un esempio basta pensare alle varie dll che servono per far girare un programma in VB.
Il concetto è lo stesso, se fate un programma in C# VB.Net ecc...e non avete il framework installato, il programma non vi funzionerà mai. Il programma non funzionerà perchè conterrà istruzioni differenti dalle solite... Supponiamo che faccia un programma in c#, compilando il codice sorgente ottengo un tipo di file chiamato Assembly, ha l'estensione .exe, ma non contiene al suo interno del codice macchina, bensì I.L.
(intermediate language). Questo I.L. sarà tradotto dal CLR in linguaggio macchina vero e proprio, e quindi
sarà adatto per l'esecuzione. Il vantaggio di questo meccanismo sta nel fatto che il CLR compila solo il
codice che serve, perciò si risparmia tempo, in più una volta che ha compilato il codice questo viene salvato
e non sarà più necessario ricompilarlo al momento di una futura esecuzione.
Inutile dire che il framework lo trovate sul sito di ZiA Bill! :-) Potete scaricare quello "normale" che pesa una 20ina di Mb o, se volete divertirvi potete scaricare l'SDK, ma pesa molto di più! (sconsigliato se avete ancora un 56K come me! Consigliato se avete un amico con l'adsl! ;-))
Spero di essere stato abbastanza esaustivo!

Essay

Per analizzare un file assembly io consiglierei IDA, ho la versione 4.3 e mi riconosce il framework.
Per modificare il file ci serviremo di un classico editor esadecimale, va bene qualunque marca!
Iniziamo!
Siccome per parecchi di voi è la prima volta che avete a che fare con questo I.L. vi posto prima il codice sorgente in modo da raffrontare le varie istruzioni!

/*Programma di esempio*/
using System;
using System.Windows.Forms;

class crackme
{
public static void Main()
{
int num;
num = 13;
if(num == 23)
{
MessageBox.Show("Registrato!","Crackme");
}
else
{
MessageBox.Show("Devi registrarmi! :-(","Crackme");
}

}
}
/*Programma di esempio*/

Credo che sia chiaro quello che il programma fa! No? Vabè ve lo spiego:
Dichiaro una variabile, le assegno il valore 13. La variabile è uguale a 23?
Se si mostra la MsgBox "Registrato" altrimenti mostra la MsgBox d'errore!
Naturalmente il programma mostrerà sempre il messaggio d'errore a meno che
qualche birbantello non lo modifichi a dovere! ;-) Provate ad avviare il programma e vedrete!

Andiamo ora a disassemblare il file con IDA, ecco la parte principale:

.class private auto ansi crackme extends [mscorlib]System.Object
{


.method public static hidebysig void Main()
{
.entrypoint
.locals init (int32 V0)
ldc.i4.s 13
stloc.0
ldloc.0
ldc.i4.s 23

loc_16:
bne.un.s loc_2A
ldstr "Registrato!"
ldstr "Crackme"
call value class [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(class System.String, class System.String)
pop
br.s loc_3A

loc_2A: // CODE XREF: Main+6j
ldstr "Devi registrarmi :-("
ldstr "Crackme"
call value class [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(class System.String, class System.String)
pop

loc_3A: // CODE XREF: Main+18j
ret
}

Non spaventatevi! La prima volta che ho visto una cosa del genere ho detto "E mo che è sta roba?"
Questo è il famigerato I.L.! :-) E' una specie d'assembler, un pò contorta come cosa, ma che ci
possiamo fare? Almeno abbiamo qualcosa di nuovo da imparare! :-)


Quello che ci interessa sono le istruzioni presenti in Main():
-------------------------------------------
.locals init (int32 V0) --> Dichiaro una variabile di tipo int32 --> int num;
ldc.i4.s 13 --> questa funzione è composta da ldc che pusha un valore numerico nello stack,
id4 significa che il numero è di tipo int32, la s sta per short, serve per immagazzinare variabili
piccole, per risparmiare memoria in questo vengono usati solo 4 byte, senza la s vengono usati 8 byte.
In sintesi carichiamo nello stack il numero 13.
stloc.0 --> Inserisce il valore contenuto nello stack (13) nella nostra variabile...lo zero sta a significare il numero della posizione della nostra variabile, se per esempio avevo dichiarato 4 variabili e io dovevo mettere il valore 13 nella 3a variabile avrei dovuto scrivere stloc.2 (funziona come l'indice di un vettore o un array).
ldloc.0 --> Carica il valore della nostra variabile nello stack (sintassi analoga a stloc)
ldc.i4.s 23 --> Carica il valore 23 nello stack (serve per fare il confronto con 13!)
bne.un.s loc_2A --> Questa è la funzione chiave, in pratica possiamo equipararla ad un "jne loc_2A"
in pratica se i 2 valori pushati nello stack non sono uguali, il programma salta
alla locazione loc_2A! E guarda caso alla proprio li c'è la nostra MessageBox d'errore!
Letteralmente significa Branch on equal. Questa istruzione
non salta, ma si "ramifica" :-)
-------------------------------------------
Come crackare questo programma? Ci sono 2 modi, o cambiamo il secondo valore pushato con 13 in modo da avere 2 valori uguali e quindi non far verificare la condizione di disuguaglianza o cambiare il salto da "jne" a "je" :-) Io opto per la seconda, almeno modifichiamo un pò di codice! :-)
Se dovessimo modificare il codice sorgente dovremmo fare solo questa modifica:
da if(num == 23) a if(num != 23)
L'istruzione che fa tutto al contrario della nostra si chiama "beq.s addr" che significa Branch on equal...il programma salterà solo quando si verificherà una condizione di uguaglianza...quindi..è come se mettessimo un nop! :-)
AGIRE:
Ci siamo! Il momento clou è arrivato...ci appresteremo a modificare il nostro bel eseguibile! (!?!?!?)
Sapete che ogni istruzione ha un OpCode, queste istruzioni hanno opcode differenti da quelli che siamo abituati a vedere di solito!
L'istruzione bne.un.s ha come opcode 33, se non usavamo la s aveva come opcode 40. Per "crackare" il programma dobbiamo inserire il l'opcode 2E che equivale a beq.s e il gioco è fatto!
Apriamo l'hex editor, portiamoci all'offset della nostra istruzione (0000262h), modifichiamo, salviamo e riavviamo...TADAAAAAAAAA!!! Il programma è "Registrato"! :-)
Questo è tutto! Byez!

 

Note finali

Ringrazio in primis me stesso. Un saluto a tutti gli amici di #asm...anche se faccio il "vegetale"! Un saluto ai Metallica, Megadeth, Ac/Dc, Testament, Pantera...

Disclaimer

Qui inserirete con questo carattere il vostro piccolo disclaimer, non è obbligatorio però è meglio per voi se c'è. Dovete scrivere qualcosa di simile a: 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 immane che ogni singolo programmatore ha dovuto portare avanti per fornire ai rispettivi consumatori i migliori prodotti possibili.

Noi reversiamo al solo scopo informativo e di miglioramento del linguaggio Assembly.