private static MethodDefinition CreateNativeMethod(MetadataImage image) { var nativeMethod = new MethodDefinition("MyNativeMethod", MethodAttributes.Assembly | MethodAttributes.Static | MethodAttributes.PInvokeImpl, new MethodSignature(image.TypeSystem.Int32)); nativeMethod.ImplAttributes = MethodImplAttributes.Native | MethodImplAttributes.Unmanaged | MethodImplAttributes.PreserveSig; var nativeBody = new X86MethodBody(); nativeBody.Instructions.Add(new X86Instruction { Mnemonic = X86Mnemonic.Mov, OpCode = X86OpCodes.Mov_Eax_Imm1632, Operand1 = new X86Operand(X86Register.Eax), Operand2 = new X86Operand(1337), }); nativeBody.Instructions.Add(new X86Instruction { Mnemonic = X86Mnemonic.Retn, OpCode = X86OpCodes.Retn, }); nativeMethod.MethodBody = nativeBody; return(nativeMethod); }
public void PersistentNativeMethod() { var assembly = CreateTempAssembly(); assembly.NetDirectory.Flags &= ~ImageNetDirectoryFlags.IlOnly; var image = assembly.NetDirectory.MetadataHeader.Image; var importer = new ReferenceImporter(image); var nativeMethod = new MethodDefinition("MyNativeMethod", MethodAttributes.Assembly | MethodAttributes.Static | MethodAttributes.PInvokeImpl, new MethodSignature(image.TypeSystem.Int32)); nativeMethod.ImplAttributes = MethodImplAttributes.Native | MethodImplAttributes.Unmanaged | MethodImplAttributes.PreserveSig; var nativeBody = new X86MethodBody(); nativeBody.Instructions.Add(new X86Instruction { Mnemonic = X86Mnemonic.Mov, OpCode = X86OpCodes.Mov_Eax_Imm1632, Operand1 = new X86Operand(X86Register.Eax), Operand2 = new X86Operand(1337), }); nativeBody.Instructions.Add(new X86Instruction { Mnemonic = X86Mnemonic.Retn, OpCode = X86OpCodes.Retn, }); nativeMethod.MethodBody = nativeBody; image.Assembly.Modules[0].TopLevelTypes[0].Methods.Add(nativeMethod); var mainMethod = image.Assembly.Modules[0].TopLevelTypes.First(x => x.Name == TypeName).Methods.First(x => x.Name == MainMethodName); var instructions = mainMethod.CilMethodBody.Instructions; instructions.AddRange(new[] { CilInstruction.Create(CilOpCodes.Ldstr, "The secret number is: {0}"), CilInstruction.Create(CilOpCodes.Call, nativeMethod), CilInstruction.Create(CilOpCodes.Box, importer.ImportType(typeof(int))), CilInstruction.Create(CilOpCodes.Call, importer.ImportMethod( typeof(Console).GetMethod("WriteLine", new[] { typeof(string), typeof(object) }))), CilInstruction.Create(CilOpCodes.Ret) }); assembly.NetDirectory.MetadataHeader.UnlockMetadata(); _context.VerifyOutput(assembly, "The secret number is: 1337"); }