sigsys|dk


Blog om udvikling

Mono.Cecil

udgivet 1/25/2015 4:30:13 PM

Mono.Cecil er smart. Det er et bibliotek som kan bruges til manipulere managed dll filer efter de er kompileret. Det er et godt stykke værktøj hvis du fx står med en dll, som du ikke kan debugge, da du ikke source filen, eller måske ikke kan installere windbg på serveren. Her kan man hente dll’en ned, og fx smide trace information ind de steder som skal kigges efter i sømmene. Jeg har altid kigget lidt på code injection, da jeg synes det er sjovt. Man får styrket IL gymnastikken lidt, og får rørt lidt ved aspekt orienteret programmering (det er ihvertfald min indgangsvinkel til at lege med Mono.Cecil).

Jeg har fx lavet en lille WriterLibrary, som jeg gerne vil bruge i en anden dll, kaldet WebApplication.dll. Mit lille tankespil går ud på at WebApplication.dll er min, ikke source kode defineret, ikke windbg-able, applikation, som jeg gerne vil trace. WriterLibrary er min “store” debug og trace bibliotek som jeg gerne vil bruge til at kigge WebApplication efter i sømmene. Der er ikke meget dokumentation omkring Mono.Cecil på nettet, dog er det meget simpelt at komme igang med. For at komme igang vil jeg springe lige ud i det. Jeg har lavet et konsol program som ser sådan her ud

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace CecilTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Mono.Cecil.AssemblyDefinition source =
                Mono.Cecil.AssemblyDefinition.ReadAssembly(@"C:sti\til\\WebApplication.dll");
 
            Mono.Cecil.AssemblyDefinition lib =
                Mono.Cecil.AssemblyDefinition.ReadAssembly(@"C:\sti\til\WriterLibrary.dll");
 
            source.MainModule.Import(lib.MainModule.Types[1]);
            source.MainModule.Write("WebApplicationModified.dll");
        }
    }
}

For at alt dette virker skal vi også have fat i Mono.Cecil, men dette er let. Man henter Mono.Cecil med NuGet. Åbn Package Manager Console og kør “Install-Package Mono.Cecil”. Kommandoen henter de dll’er der skal til for man kan gøre brug af Mono.Cecil. Min WriterLibrary er her blot en simpel class library som ser sådan her ud

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace WriterLibrary
{
    public class Writer
    {
        public void WriteLine(string s)
        {
            Console.WriteLine("wrote:" + s);
        }
    }
}

Når man laver en Import på en hvilken som helst type fra WriterLibrary til WebApplication dll’en, så sørger Mono.Cecil også for at lave en reference til WriterLibrary dll’en. Du kan selv tjekke efter ved at inspicere WebApplication dll’en før konsol applikationen er kørt, og efter. Da man skal betale for Reflector, vil jeg råde alle til at bruge IlSpy. Google den, og hent programmet. Den kan ikke alt det som Reflector kan, men den er gratis, og man kan kigge på dll’er. Meget praktisk Smiley

Ved at inspicere WebApplication dll’en efter konsol applikationen er kørt, kan man se at referencen er tilføjet. Meget smart. Man kan nu bruge WriterLibrary til at lave trace på WebApplication. Jeg har endnu ikke lavet noget injection, men det er noget jeg vil skrive om efterfølgende, da jeg selv lige skal lære at bruge Mono.Cecil. Min vision med dette eksempel er at jeg vil prøve at injecte WriteLine funktionskaldet ind i WebApplication.dll’ens Global.Application_Error, da jeg ved at WebApplication gør brug af en Global.asax.

Håber at der er nogen der kan bruge mit lille eksempel til noget.