Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate C# code from IL Instructions

Tags:

c#

cil

dnlib

I'm trying to generate c# code from IL instructions using the dnlib library.

The code I'm trying to generate is this one:

private string GetIp()
{
    return new WebClient().DownloadString("https://api.myip.com/");
}

My code:

Type webclientType = typeof(System.Net.WebClient);

ConstructorInfo constructor = webclientType.GetConstructors()[0];

MethodInfo methodInfo = webclientType.GetMethod("DownloadString", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance, null, System.Reflection.CallingConventions.Any, new Type[] { typeof(string) }, null);

MethodDefUser m = new MethodDefUser("GetIp", MethodSig.CreateInstance(module.CorLibTypes.String), MethodImplAttributes.IL, MethodAttributes.Static | MethodAttributes.HideBySig)
{
    Body = new CilBody()
};

m.Body.Instructions.Add(new Instruction(OpCodes.Newobj, constructor));
m.Body.Instructions.Add(new Instruction(OpCodes.Ldstr, "https://api.myip.com/"));
m.Body.Instructions.Add(new Instruction(OpCodes.Callvirt, methodInfo));
m.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));

I get an error (Invalid instruction operand) when trying to save the module to disk.

Right now my code is generating these instructions:

newobj - Void .ctor()
ldstr - https://api.myip.com/
callvirt - System.String DownloadString(System.String)
ret - 

When they should be this:

newobj - System.Void System.Net.WebClient::.ctor()
ldstr - https://api.myip.com/
callvirt - System.String System.Net.WebClient::DownloadString(System.String)
ret -

I've tried to replace the constructor for the webclientType variable but with no luck, also no luck finding any information online.

like image 417
Milton Cardoso Avatar asked May 12 '26 02:05

Milton Cardoso


1 Answers

while trying some stuff, I saw that I needed to be using the main object (from dnlib) that has the .NET module loaded (ModuleDefMD).

So I did it this way:

m.Body.Instructions.Add(new Instruction(OpCodes.Newobj, module.Import(typeof(System.Net.WebClient).GetConstructors()[0])));
m.Body.Instructions.Add(new Instruction(OpCodes.Ldstr, "https://api.myip.com/"));
m.Body.Instructions.Add(new Instruction(OpCodes.Callvirt, module.Import(typeof(System.Net.WebClient).GetMethod("DownloadString", new Type[] { typeof(string) }))));
m.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));

module being the main object where I load the .NET File:

ModuleDefMD module = ModuleDefMD.Load(TxtFilepath.Text);

This now generates this C# code:

static string GetIp()
{
    return new WebClient().DownloadString("https://api.myip.com/");
}
like image 118
Milton Cardoso Avatar answered May 14 '26 16:05

Milton Cardoso