Round-Tripping: didattica, utilità e fantasia
Il round-tripping,
nell'accezione .NET del termine, è una tecnica in base alla quale viene
modificato il contenuto di un modulo .NET tramite:
- disassembling con ILDASM
- modifica manuale del codice IL
- re-assembling con
ILASM
Esempio
didattico .
Abbiamo sviluppato il nostro
immancabile Hello World in C# (Console Application).
class Hello
{
public static void Main(String[] args)
{
System.Console.WriteLine("Hello, world !");
}
}
Compiliamo ed otteniamo
hello.exe, che, incredibilmente, una volta eseguito stampa a video:
Hello, World !
Disassembliamo con ildasm, generando in output il
file hello.il:
ildasm hello.exe
/out=hello.il
Modifichiamo il file il, cambiando la stringa
visualizzata (ovviamente le modifiche possono essere ben più radicali, ma è
giusto un esempio):
all'interno dell'implementazione del metodo Main, cambiamo
l'istruzione:
ldstr "Hello, World !"
in
ldstr "I've been hacked !"
Salviamo il file (hello2.il),
riassembliamo con ilasm:
ilasm
hello2.il /output=hello2.exe
e voila, il gioco è fatto e il nostro programma stampa a
video:
I've been
hacked !
Vista così,
questa tecnica può sembrare più una perdita di tempo (forse si faceva prima a
modificare i sorgenti C#
) o un esercizio senza utilità
pratica.
E per il nostro esempio è assolutamente vero.
Ma ci sono occasioni in cui il round-tripping
si rivela l'unica tecnica a disposizione, o almeno la più facilmente
percorribile.
Vi porto un esempio di vita vissuta.
Per un progetto che stavo seguendo alcuni mesi fa, era
stato sviluppato un componente COM che doveva "fare da ponte" fra una libreria
di basso livello scritta in C++/MFC e l'applicazione (.NET)
principale.
Nell'idl erano state definite ed esportate alcune
strutture, in modo tale che queste venissero incluse nella type library e
fossero, pertanto, fruibili da codice managed senza bisogno di ridefinizione
(quando le strutture dati sono molte e molto corpose evitare la ridefinizione
non è una brutta idea).
I problemi sorsero quando ci fu la necessità di passare
istanze di queste strutture per copia da un appdomain ad un altro.
tlbimp, infatti (che per inciso viene richiamato da VS
quando si aggiunge una reference ad un componente COM), aveva correttamente
inserito la definizione managed delle strutture nell'assembly di
interoperabilità, ma non le aveva marcate come serializzabili (perchè avrebbe
dovuto, in fin dei conti ?).
La tecnica del
roundtripping, in questa situazione, si è rivelata utile ed efficace: è bastato aggiungere lo
pseudo-attributo serializable ai tipi relativi.
In pratica la definizione passava da:
.class public sequential ansi sealed beforefieldinit XXXX extends [mscorlib]System.ValueType
a:
.class public serializable sequential ansi sealed beforefieldinit XXXX extends [mscorlib]System.ValueType
Ovviamente, dopo le prime, tediosissime patch a mano,
abbiamo sviluppato un tool che automatizzasse questa procedura, e tutto è filato
liscio (almeno da quel punto di vista).
E veniamo,
finalmente, al terzo punto menzionato nel titolo di questo post: la
fantasia .
Qui c'è un link ad un uso ... strano ed interessante
del round-tripping.
Mike Stall, l'autore del post (e del tool di cui parla), ha
utilizzato il round-tripping per iniettare codice IL in un assembly generato da
C# (o VB.NET, eccetera).
Le limitazioni, come lo stesso autore evidenzia, sono
diverse e rendono questo strumento molto più didattico che pratico e ...
vendibile.
Però l'idea, ed i workaround per risolvere alcune
situazioni, secondo me non sono niente male davvero !
powered by IMHO 1.2