Beispiel #1
0
        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");
        }