如何从 IL 指令生成 C# 代码
How to generate C# code from IL Instructions
我正在尝试使用 dnlib 库从 IL 指令生成 c# 代码。
我要生成的代码是这个:
private string GetIp()
{
return new WebClient().DownloadString("https://api.myip.com/");
}
我的代码:
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));
尝试将模块保存到磁盘时出现错误(无效指令操作数)。
现在我的代码正在生成这些指令:
newobj - Void .ctor()
ldstr - https://api.myip.com/
callvirt - System.String DownloadString(System.String)
ret -
他们应该是这样的:
newobj - System.Void System.Net.WebClient::.ctor()
ldstr - https://api.myip.com/
callvirt - System.String System.Net.WebClient::DownloadString(System.String)
ret -
我尝试用 constructor
替换 webclientType
变量,但没有成功,也没有成功地在网上找到任何信息。
在尝试一些东西时,我发现我需要使用加载了 .NET 模块的主要对象(来自 dnlib)(ModuleDefMD
)。
所以我是这样做的:
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
是我加载 .NET 文件的主要对象:
ModuleDefMD module = ModuleDefMD.Load(TxtFilepath.Text);
现在生成此 C# 代码:
static string GetIp()
{
return new WebClient().DownloadString("https://api.myip.com/");
}
我正在尝试使用 dnlib 库从 IL 指令生成 c# 代码。
我要生成的代码是这个:
private string GetIp()
{
return new WebClient().DownloadString("https://api.myip.com/");
}
我的代码:
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));
尝试将模块保存到磁盘时出现错误(无效指令操作数)。
现在我的代码正在生成这些指令:
newobj - Void .ctor()
ldstr - https://api.myip.com/
callvirt - System.String DownloadString(System.String)
ret -
他们应该是这样的:
newobj - System.Void System.Net.WebClient::.ctor()
ldstr - https://api.myip.com/
callvirt - System.String System.Net.WebClient::DownloadString(System.String)
ret -
我尝试用 constructor
替换 webclientType
变量,但没有成功,也没有成功地在网上找到任何信息。
在尝试一些东西时,我发现我需要使用加载了 .NET 模块的主要对象(来自 dnlib)(ModuleDefMD
)。
所以我是这样做的:
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
是我加载 .NET 文件的主要对象:
ModuleDefMD module = ModuleDefMD.Load(TxtFilepath.Text);
现在生成此 C# 代码:
static string GetIp()
{
return new WebClient().DownloadString("https://api.myip.com/");
}