【问题标题】:How to use Mono.Cecil to create HelloWorld.exe如何使用 Mono.Cecil 创建 HelloWorld.exe
【发布时间】:2017-01-14 23:18:39
【问题描述】:

你如何使用 Mono.Cecil 从头开始​​创建一个简单的程序?到目前为止,我能够找到的所有示例和教程都假设您正在使用现有的程序集、阅读或进行小的更改。

【问题讨论】:

    标签: .net mono.cecil


    【解决方案1】:

    我这里没有笔记本电脑(我正走在街上),所以我无法编写并向您展示完整的示例,但它就像您已经看到的其他示例一样简单。但是你需要创建一个并保存它。

    您需要创建一个 AssemblyDefinition、一个 ModuleDefinition、一个 Type 和 Method 并将其保存到磁盘。

    你需要记住它的 IL 和元数据编写器没有编译器。

    this 为例。

    【讨论】:

      【解决方案2】:

      请参阅以下代码以帮助您入门:

      var myHelloWorldApp = AssemblyDefinition.CreateAssembly(
          new AssemblyNameDefinition("HelloWorld", new Version(1, 0, 0, 0)), "HelloWorld", ModuleKind.Console);
      
      var module = myHelloWorldApp.MainModule;
      
      // create the program type and add it to the module
      var programType = new TypeDefinition("HelloWorld", "Program",
          Mono.Cecil.TypeAttributes.Class | Mono.Cecil.TypeAttributes.Public, module.TypeSystem.Object);
      
      module.Types.Add(programType);
      
      // add an empty constructor
      var ctor = new MethodDefinition(".ctor", Mono.Cecil.MethodAttributes.Public | Mono.Cecil.MethodAttributes.HideBySig
          | Mono.Cecil.MethodAttributes.SpecialName | Mono.Cecil.MethodAttributes.RTSpecialName, module.TypeSystem.Void);
      
      // create the constructor's method body
      var il = ctor.Body.GetILProcessor();
      
      il.Append(il.Create(OpCodes.Ldarg_0));
      
      // call the base constructor
      il.Append(il.Create(OpCodes.Call, module.Import(typeof(object).GetConstructor(Array.Empty<Type>()))));
      
      il.Append(il.Create(OpCodes.Nop));
      il.Append(il.Create(OpCodes.Ret));
      
      programType.Methods.Add(ctor);
      
      // define the 'Main' method and add it to 'Program'
      var mainMethod = new MethodDefinition("Main",
          Mono.Cecil.MethodAttributes.Public | Mono.Cecil.MethodAttributes.Static, module.TypeSystem.Void);
      
      programType.Methods.Add(mainMethod);
      
      // add the 'args' parameter
      var argsParameter = new ParameterDefinition("args",
          Mono.Cecil.ParameterAttributes.None, module.Import(typeof(string[])));
      
      mainMethod.Parameters.Add(argsParameter);
      
      // create the method body
      il = mainMethod.Body.GetILProcessor();
      
      il.Append(il.Create(OpCodes.Nop));
      il.Append(il.Create(OpCodes.Ldstr, "Hello World"));
      
      var writeLineMethod = il.Create(OpCodes.Call,
          module.Import(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) })));
      
      // call the method
      il.Append(writeLineMethod);
      
      il.Append(il.Create(OpCodes.Nop));
      il.Append(il.Create(OpCodes.Ret));
      
      // set the entry point and save the module
      myHelloWorldApp.EntryPoint = mainMethod;
      myHelloWorldApp.Write("HelloWorld.exe");
      

      【讨论】:

      • PDB 也会生成吗?
      • @AkshayBheda 不,但我认为没有必要生成 PDB。据我所知,PDB文件的工作是充当源代码和编译代码(dll)之间的桥梁,以便调试器知道哪一行代码对应于执行的代码。在这种情况下,没有源代码,因为程序是通过直接定义 IL 指令创建的。 Mono.Cecil 支持PDBs,但我认为这仅适用于修改 PDB 文件附带的现有 dll。
      猜你喜欢
      • 2011-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-22
      • 2023-04-01
      • 2014-01-10
      • 1970-01-01
      • 2012-05-01
      相关资源
      最近更新 更多