如何使用 Mono.Cecil 创建 HelloWorld.exe

How to use Mono.Cecil to create HelloWorld.exe

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

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

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

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

例如检查this

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

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");