如何使用dnlib从IL指令生成C#代码并解决指令操作数无效报错
问题原因
你收到Invalid instruction operand报错的核心原因是:dnlib 不支持直接将 .NET 原生反射的 ConstructorInfo、MethodInfo 对象作为 IL 指令的操作数,必须先将系统反射类型转换为 dnlib 定义的元数据引用类型后才可使用。
解决方法
调用当前目标模块 ModuleDef 实例提供的 Import 方法,将你反射获取的构造函数、方法信息转为 dnlib 可识别的 IMethod 引用,再传入指令的操作数位置即可。
修改后的完整示例代码
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,目标GetIp是实例方法,不需要静态可去掉该标识 MethodAttributes.Private | MethodAttributes.HideBySig) { Body = new CilBody() }; // 核心修改:导入反射成员为dnlib元数据引用 var webClientCtorRef = (IMethod)module.Import(constructor); var downloadStringMethodRef = (IMethod)module.Import(methodInfo); m.Body.Instructions.Add(new Instruction(OpCodes.Newobj, webClientCtorRef)); m.Body.Instructions.Add(new Instruction(OpCodes.Ldstr, "https://api.myip.com/")); m.Body.Instructions.Add(new Instruction(OpCodes.Callvirt, downloadStringMethodRef)); m.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
内容的提问来源于stack exchange,提问作者Milton Cardoso
相关产品推荐
相关产品推荐

