C# compila a una máquina virtual, llamada CLR (Common Language Runtime), en código ensamblador llamado originalmente MSIL.
El proyecto Mono nació como un versión multiplataforma de C#. En 2016 la empresa creadora, Ximian, fue comprada por Microsoft, y en 2024 Microsoft cedió el proyecto al proyecto Wine.
Así, aunque Mono parece obsoleto hoy en día, el subproyecto CECIL de Mono se mantiene al día, conformándose como una excelente herramienta para analizar IL.
Así, si queremos crear un decompilador, solo tenemos que preparar un proyecto que incluya el paquete NuGET Mono.Cecil.
$ mkdir disasm
$ cd disasm
$ dotnet new console
$ dotnet package new Mono.Cecil
Solo necesitamos una clase muy sencilla para decompilar.
class Disasm {
public static Instruction[] GetMethodInstructions(string assemblyPath, string typeName, string methodName)
{
var toret = Array.Empty<Instruction>();
using (var assembly = AssemblyDefinition.ReadAssembly( assemblyPath ))
{
var type = assembly.MainModule.Types.FirstOrDefault( t => t.Name == typeName );
var method = type?.Methods.FirstOrDefault( m => m.Name == methodName );
if ( method?.HasBody == true ) {
toret = [ .. method.Body.Instructions ];
}
}
return toret;
}
public static string StrFromInstructions(Instruction[] instructions)
{
return string.Join(
"\n",
instructions.Select(
i => $"{i.Offset:X4}: {i.OpCode} {i.Operand}" ) );
}
}
Ya solo necesitamos llamar a los métodos de la case con un nombre de ensamblado, otro de clase y finalmente, un nombre de método.
class App {
static void Decompile(string dllName, string clsName, string mthName)
{
var instructions = Disasm.GetMethodInstructions(
dllName, clsName, mthName );
Console.WriteLine( "DisAsm\n" );
Console.WriteLine( Disasm.StrFromInstructions( instructions ) );
}
static void Main(string[] args)
{
if ( args.Length < 4 ) {
Console.WriteLine( "Please provide: file_name class_name mth_name" );
} else {
Decompile( args[ 1 ], args[ 2 ], args[ 3 ] );
}
}
Y ahora podemos ejecutarlo, por ejemplo, utilizando el propio ejecutable, y dirigirlo al método Disasm.StrFromInstructions().
$ dotnet run bin/Debug/net11.0/disasm.dll Disasm StrFromInstructions
DisAsm
0000: nop
0001: ldstr
0006: ldarg.0
0007: ldsfld System.Func`2<Mono.Cecil.Cil.Instruction,System.String> Disasm/<>c::<>9__1_0
000C: dup
000D: brtrue.s IL_0026: call System.Collections.Generic.IEnumerable`1<!!1> System.Linq.Enumerable::Select<Mono.Cecil.Cil.Instruction,System.String>(System.Collections.Generic.IEnumerable`1<!!0>,System.Func`2<!!0,!!1>)
000F: pop
0010: ldsfld Disasm/<>c Disasm/<>c::<>9
0015: ldftn System.String Disasm/<>c::<StrFromInstructions>b__1_0(Mono.Cecil.Cil.Instruction)
001B: newobj System.Void System.Func`2<Mono.Cecil.Cil.Instruction,System.String>::.ctor(System.Object,System.IntPtr)
0020: dup
0021: stsfld System.Func`2<Mono.Cecil.Cil.Instruction,System.String> Disasm/<>c::<>9__1_0
0026: call System.Collections.Generic.IEnumerable`1<!!1> System.Linq.Enumerable::Select<Mono.Cecil.Cil.Instruction,System.String>(System.Collections.Generic.IEnumerable`1<!!0>,System.Func`2<!!0,!!1>)
002B: call System.String System.String::Join(System.String,System.Collections.Generic.IEnumerable`1<System.String>)
0030: stloc.0
0031: br.s IL_0033: ldloc.0
0033: ldloc.0
0034: ret
Con Mono.Cecil, podremos incluso generar nuestros propios ensamblados, modificando el ensamblado original. ¿Te apuntas?
Top comments (2)
Thank you for sharing such an excellent post. I really enjoyed reading it.
I’m a Python Full-Stack Engineer with over 10 years of experience designing and building scalable software solutions for clients across a variety of industries. Along the way, I’ve learned that successful projects depend not only on strong technical execution but also on creating real business value.
With my recent contract completed, I’m exploring new opportunities to collaborate with professionals who value innovation, practical problem-solving, and long-term partnerships. I enjoy discussing ideas that combine technical excellence with sound business strategy, creating outcomes that benefit everyone involved.
I believe every connection has the potential to become something meaningful. If you're interested in exchanging ideas, exploring opportunities, or simply connecting with someone who enjoys building impactful technology, I'd be happy to hear from you.
Wishing you success in your future endeavors, and I look forward to connecting.
If you allow me, I wanna discuss further about collaboration and income...
Let's become rich together with my ideas...How about you?