Claudio Brotto

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

Posted: feb 22 2005, 04:16 by devlizard
Filed under: