public void ComputeMaxStackTestCall()
        {
            var methodBody = CreateDummyMethodBody();
            var importer   = new ReferenceImporter(methodBody.Method.Image);

            var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }));

            var instructions = methodBody.Instructions;

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldstr, "Lorem Ipsum"),
                CilInstruction.Create(CilOpCodes.Call, writeLine),
                CilInstruction.Create(CilOpCodes.Ret)
            });

            Assert.Equal(1, methodBody.ComputeMaxStack());
        }
        public void CreateAttributeWithEnumArgument()
        {
            // set up temp assembly.
            var assembly       = Utilities.CreateTempNetAssembly();
            var tableStream    = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>();
            var assemblyTable  = tableStream.GetTable <AssemblyDefinition>();
            var attributeTable = tableStream.GetTable <CustomAttribute>();
            var importer       = new ReferenceImporter(tableStream);

            var assemblyDef = assemblyTable[0];

            // create custom attribute.
            var signature = new CustomAttributeSignature();

            signature.FixedArguments.Add(
                new CustomAttributeArgument(importer.ImportTypeSignature(typeof(DebuggableAttribute.DebuggingModes)),
                                            new ElementSignature((int)DebuggableAttribute.DebuggingModes.Default)));

            var attribute = new CustomAttribute(importer.ImportMethod(typeof(DebuggableAttribute).GetConstructor(new Type[]
            {
                typeof(DebuggableAttribute.DebuggingModes)
            })), signature);

            assemblyDef.CustomAttributes.Add(attribute);
            attributeTable.Add(attribute);

            // build and validate.
            assembly       = Utilities.RebuildNetAssembly(assembly);
            tableStream    = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>();
            assemblyTable  = tableStream.GetTable <AssemblyDefinition>();
            assemblyDef    = assemblyTable[0];
            attributeTable = tableStream.GetTable <CustomAttribute>();
            var newAttribute = attributeTable[0];

            Assert.IsTrue(assemblyDef.CustomAttributes.Contains(newAttribute));
            Assert.AreEqual(attribute.Constructor.FullName, newAttribute.Constructor.FullName);
            Assert.AreEqual(attribute.Signature.FixedArguments.Count, newAttribute.Signature.FixedArguments.Count);

            for (int i = 0; i < attribute.Signature.FixedArguments.Count; i++)
            {
                Utilities.ValidateArgument(attribute.Signature.FixedArguments[i], newAttribute.Signature.FixedArguments[i]);
            }
        }
        public void ImportInternalMethodDefinition()
        {
            var assembly = NetAssemblyFactory.CreateAssembly(DummyAssemblyName, true);
            var image    = assembly.NetDirectory.MetadataHeader.LockMetadata();
            var importer = new ReferenceImporter(image);

            var type = new TypeDefinition("SomeNamespace", "SomeType");

            image.Assembly.Modules[0].TopLevelTypes.Add(type);

            var method = new MethodDefinition("SomeMethod", MethodAttributes.Public | MethodAttributes.Static,
                                              new MethodSignature(new[] { image.TypeSystem.String }, image.TypeSystem.Void));

            type.Methods.Add(method);

            var newReference = importer.ImportMethod(method);

            Assert.Same(method, newReference);
        }
        public void StackInsufficientValues()
        {
            var methodBody = CreateDummyMethodBody();
            var importer   = new ReferenceImporter(methodBody.Method.Image);

            var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(int) }));

            var instructions = methodBody.Instructions;

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldc_I4, -1),
                CilInstruction.Create(CilOpCodes.And),
                CilInstruction.Create(CilOpCodes.Ldc_I4, -1),
                CilInstruction.Create(CilOpCodes.Call, writeLine),
                CilInstruction.Create(CilOpCodes.Ret),
            });

            Assert.Throws <StackInbalanceException>(() => methodBody.ComputeMaxStack());
        }
        public void ComputeMaxStackBranch()
        {
            var methodBody = CreateDummyMethodBody();
            var importer   = new ReferenceImporter(methodBody.Method.Image);

            var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(int) }));

            var instructions = methodBody.Instructions;
            var target       = CilInstruction.Create(CilOpCodes.Call, writeLine);

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldc_I4_1),
                CilInstruction.Create(CilOpCodes.Br, target),
                CilInstruction.Create(CilOpCodes.Ldc_I4_2),
                target,
                CilInstruction.Create(CilOpCodes.Ret),
            });
            Assert.Equal(1, methodBody.ComputeMaxStack());
        }
        public void PreserveTypeRefsWithExtraImportShouldAtLeastHaveOriginalTypeRefs()
        {
            var module           = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld_NetCore);
            var originalTypeRefs = GetMembers <TypeReference>(module, TableIndex.TypeRef);

            var importer = new ReferenceImporter(module);
            var readKey  = importer.ImportMethod(typeof(Console).GetMethod("ReadKey", Type.EmptyTypes));

            var instructions = module.ManagedEntrypointMethod.CilMethodBody.Instructions;

            instructions.RemoveAt(instructions.Count - 1);
            instructions.Add(CilOpCodes.Call, readKey);
            instructions.Add(CilOpCodes.Pop);
            instructions.Add(CilOpCodes.Ret);

            var newModule   = RebuildAndReloadModule(module, MetadataBuilderFlags.PreserveTypeReferenceIndices);
            var newTypeRefs = GetMembers <TypeReference>(newModule, TableIndex.TypeRef);

            Assert.Equal(originalTypeRefs, newTypeRefs.Take(originalTypeRefs.Count), Comparer);
        }
        public void PreserveAssemblyRefsWithExtraImportShouldAtLeastHaveOriginalAssemblyRefs()
        {
            var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld_NetCore);
            var originalAssemblyRefs = GetMembers <AssemblyReference>(module, TableIndex.AssemblyRef);

            var importer = new ReferenceImporter(module);
            var exists   = importer.ImportMethod(typeof(File).GetMethod("Exists", new[] { typeof(string) }));

            var instructions = module.ManagedEntrypointMethod.CilMethodBody.Instructions;

            instructions.RemoveAt(instructions.Count - 1);
            instructions.Add(CilOpCodes.Ldstr, "file.txt");
            instructions.Add(CilOpCodes.Call, exists);
            instructions.Add(CilOpCodes.Pop);
            instructions.Add(CilOpCodes.Ret);

            var newModule       = RebuildAndReloadModule(module, MetadataBuilderFlags.PreserveAssemblyReferenceIndices);
            var newAssemblyRefs = GetMembers <AssemblyReference>(newModule, TableIndex.AssemblyRef);

            Assert.Equal(originalAssemblyRefs, newAssemblyRefs.Take(originalAssemblyRefs.Count), Comparer);
        }
        public void PersistentNullArgument()
        {
            var assembly = NetAssemblyFactory.CreateAssembly(DummyAssemblyName, true);
            var header   = assembly.NetDirectory.MetadataHeader;
            var image    = header.LockMetadata();
            var importer = new ReferenceImporter(image);

            var customAttribute = new CustomAttribute(
                (ICustomAttributeType)importer.ImportMethod(
                    typeof(DisplayNameAttribute).GetConstructor(new[] { typeof(string) })),
                new CustomAttributeSignature(new[]
                                             { new CustomAttributeArgument(image.TypeSystem.String, new ElementSignature(null)) }));

            image.Assembly.CustomAttributes.Add(customAttribute);

            header.UnlockMetadata();

            image = header.LockMetadata();
            Assert.Single(image.Assembly.CustomAttributes);
            Assert.Null(image.Assembly.CustomAttributes[0].Signature.FixedArguments[0].Elements[0].Value);
        }
        public void PersistentConstructor()
        {
            var assembly = NetAssemblyFactory.CreateAssembly(DummyAssemblyName, true);
            var header   = assembly.NetDirectory.MetadataHeader;
            var image    = header.LockMetadata();
            var importer = new ReferenceImporter(image);

            var customAttribute = new CustomAttribute(
                (ICustomAttributeType)importer.ImportMethod(
                    typeof(AssemblyTitleAttribute).GetConstructor(new[] { typeof(string) })),
                new CustomAttributeSignature(new[]
                                             { new CustomAttributeArgument(image.TypeSystem.String, new ElementSignature("SomeArgument")) }));

            image.Assembly.CustomAttributes.Add(customAttribute);

            header.UnlockMetadata();

            image = header.LockMetadata();
            Assert.Single(image.Assembly.CustomAttributes);
            Assert.Equal(customAttribute.Constructor, image.Assembly.CustomAttributes[0].Constructor, _comparer);
        }
        public void ComputeMaxStackExceptionHandlers()
        {
            var methodBody = CreateDummyMethodBody();
            var importer   = new ReferenceImporter(methodBody.Method.Image);

            var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(int) }));

            var instructions = methodBody.Instructions;

            var tryStart     = CilInstruction.Create(CilOpCodes.Nop);
            var handlerStart = CilInstruction.Create(CilOpCodes.Pop);
            var handlerEnd   = CilInstruction.Create(CilOpCodes.Nop);

            instructions.AddRange(new[]
            {
                tryStart,
                CilInstruction.Create(CilOpCodes.Ldc_I4_0),
                CilInstruction.Create(CilOpCodes.Call, writeLine),
                CilInstruction.Create(CilOpCodes.Leave, handlerEnd),
                handlerStart,
                CilInstruction.Create(CilOpCodes.Ldc_I4_1),
                CilInstruction.Create(CilOpCodes.Ldc_I4_2),
                CilInstruction.Create(CilOpCodes.Add),
                CilInstruction.Create(CilOpCodes.Call, writeLine),
                CilInstruction.Create(CilOpCodes.Leave, handlerEnd),
                handlerEnd,
                CilInstruction.Create(CilOpCodes.Ret),
            });

            methodBody.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Exception)
            {
                TryStart     = tryStart,
                TryEnd       = handlerStart,
                HandlerStart = handlerStart,
                HandlerEnd   = handlerEnd,
                CatchType    = importer.ImportType(typeof(Exception))
            });

            Assert.Equal(2, methodBody.ComputeMaxStack());
        }
        public void ImportGenericInstanceMethod()
        {
            var assembly = NetAssemblyFactory.CreateAssembly(DummyAssemblyName, true);
            var image    = assembly.NetDirectory.MetadataHeader.LockMetadata();
            var importer = new ReferenceImporter(image);

            var specification = new MethodSpecification(
                new MemberReference(
                    CreateTypeReference(typeof(Activator)),
                    "CreateInstance",
                    new MethodSignature(new GenericParameterSignature(GenericParameterType.Method, 0))
            {
                GenericParameterCount = 1
            }),
                new GenericInstanceMethodSignature(CreateTypeDefOrRef(typeof(Stream))));

            var newSpecification = importer.ImportMethod(specification);

            Assert.NotSame(specification, newSpecification);
            Assert.Equal(specification, newSpecification, _comparer);
            Assert.Equal(image, newSpecification.Image);
        }
        public void CustomBlobs()
        {
            var assembly  = NetAssemblyFactory.CreateAssembly("SomeAssembly", false);
            var header    = assembly.NetDirectory.MetadataHeader;
            var image     = header.LockMetadata();
            var importer  = new ReferenceImporter(image);
            var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }));

            var main = new MethodDefinition("Main", MethodAttributes.Public | MethodAttributes.Static,
                                            new MethodSignature(image.TypeSystem.Void));

            main.CilMethodBody = new CilMethodBody(main);
            main.CilMethodBody.Instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldstr, "Hello, world!"),
                CilInstruction.Create(CilOpCodes.Call, writeLine),
                CilInstruction.Create(CilOpCodes.Ret)
            });

            image.Assembly.Modules[0].TopLevelTypes[0].Methods.Add(main);

            image.ManagedEntrypoint = main;

            var extraBlobs = new BlobSignature[]
            {
                new DataBlobSignature(new byte[] { 1, 2, 3 }),
                new DataBlobSignature(new byte[] { 4, 5, 6 })
            };

            // Commit changes to assembly
            var builder = new CustomBuilder(extraBlobs);

            image.Header.UnlockMetadata(builder);

            var blobStream = header.GetStream <BlobStream>();

            Assert.Equal(new byte[] { 1, 2, 3 }, blobStream.GetBlobByOffset(builder.GetBlobOffset(extraBlobs[0])));
            Assert.Equal(new byte[] { 4, 5, 6 }, blobStream.GetBlobByOffset(builder.GetBlobOffset(extraBlobs[1])));
        }
        public void PersistentManagedSmallMethod()
        {
            const string expectedOutput = "Hello, world!";

            var assembly   = CreateTempAssembly();
            var image      = assembly.NetDirectory.MetadataHeader.Image;
            var importer   = new ReferenceImporter(image);
            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, expectedOutput),
                CilInstruction.Create(CilOpCodes.Call,
                                      importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }))),
                CilInstruction.Create(CilOpCodes.Ret)
            });

            assembly.NetDirectory.MetadataHeader.UnlockMetadata();
            _context.VerifyOutput(assembly, expectedOutput);
        }
        public void PersistentExtraData()
        {
            var assembly = NetAssemblyFactory.CreateAssembly(DummyAssemblyName, true);
            var header   = assembly.NetDirectory.MetadataHeader;
            var image    = header.LockMetadata();
            var importer = new ReferenceImporter(image);

            var extraData = new byte[] { 1, 2, 3, 4 };

            var customAttribute = new CustomAttribute(
                (ICustomAttributeType)importer.ImportMethod(
                    typeof(ObfuscationAttribute).GetConstructor(Type.EmptyTypes)),
                new CustomAttributeSignature {
                ExtraData = extraData
            });

            image.Assembly.CustomAttributes.Add(customAttribute);

            header.UnlockMetadata();

            image = header.LockMetadata();
            Assert.Equal(extraData, image.Assembly.CustomAttributes[0].Signature.ExtraData);
        }
Exemple #15
0
        public void ImportInternalMethodDefinition()
        {
            var assembly       = Utilities.CreateTempNetAssembly();
            var metadataHeader = assembly.NetDirectory.MetadataHeader;
            var tableStream    = metadataHeader.GetStream <TableStream>();

            var importer = new ReferenceImporter(tableStream);

            var type = new TypeDefinition("SomeNamespace", "SomeType");

            tableStream.GetTable <TypeDefinition>().Add(type);

            var method = new MethodDefinition("SomeMethod", MethodAttributes.Public | MethodAttributes.Static,
                                              new MethodSignature(new[] { metadataHeader.TypeSystem.String }, metadataHeader.TypeSystem.Void));

            type.Methods.Add(method);
            tableStream.GetTable <MethodDefinition>().Add(method);

            var newReference = importer.ImportMethod(method);

            Assert.AreSame(method, newReference,
                           "Imported method definition is not the same object as the original.");
        }
        public void CloneNestedClasses()
        {
            var sourceAssembly = WindowsAssembly.FromFile(typeof(SimpleClass).Assembly.Location);
            var sourceImage    = sourceAssembly.NetDirectory.MetadataHeader.LockMetadata();

            var assembly = NetAssemblyFactory.CreateAssembly("SomeAssembly", false);
            var header   = assembly.NetDirectory.MetadataHeader;
            var image    = header.LockMetadata();
            var importer = new ReferenceImporter(image);
            var cloner   = new MemberCloner(image);

            var simpleClass = cloner.CloneType(sourceImage.Assembly.Modules[0].TopLevelTypes.First(x => x.Name == "ClassWithNestedClasses"));

            image.Assembly.Modules[0].TopLevelTypes.Add(simpleClass);

            var main = new MethodDefinition("Main", MethodAttributes.Public | MethodAttributes.Static,
                                            new MethodSignature(image.TypeSystem.Void));

            main.CilMethodBody = new CilMethodBody(main);

            main.CilMethodBody.Instructions.Add(CilInstruction.Create(CilOpCodes.Newobj,
                                                                      simpleClass.Methods.First(x => x.Name == ".ctor")));
            main.CilMethodBody.Instructions.Add(CilInstruction.Create(CilOpCodes.Ldc_I4, 12));
            main.CilMethodBody.Instructions.Add(CilInstruction.Create(CilOpCodes.Call,
                                                                      simpleClass.Methods.First(x => x.Name == "SomeMethod")));
            main.CilMethodBody.Instructions.Add(CilInstruction.Create(CilOpCodes.Call,
                                                                      importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }))));
            main.CilMethodBody.Instructions.Add(CilInstruction.Create(CilOpCodes.Ret));

            image.Assembly.Modules[0].TopLevelTypes[0].Methods.Add(main);
            image.ManagedEntrypoint = main;

            header.UnlockMetadata();

            _context.VerifyOutput(assembly, "abc" + 12);
        }
        public void ComputeMaxStackLoop()
        {
            var methodBody = CreateDummyMethodBody();
            var importer   = new ReferenceImporter(methodBody.Method.Image);

            var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(int) }));

            var instructions = methodBody.Instructions;
            var loopHead     = CilInstruction.Create(CilOpCodes.Nop);

            instructions.AddRange(new[]
            {
                loopHead,
                CilInstruction.Create(CilOpCodes.Ldc_I4_1),
                CilInstruction.Create(CilOpCodes.Ldc_I4_2),
                CilInstruction.Create(CilOpCodes.Add),
                CilInstruction.Create(CilOpCodes.Call, writeLine),
                CilInstruction.Create(CilOpCodes.Ldc_I4_0),
                CilInstruction.Create(CilOpCodes.Brtrue, loopHead),
                CilInstruction.Create(CilOpCodes.Ret),
            });

            Assert.Equal(2, methodBody.ComputeMaxStack());
        }
        public void CreateAttributeWithNamedArgument()
        {
            const string fieldName     = "MyField";
            const string argumentValue = "MyXmlAttribute";
            const string propertyName  = "IsNullable";
            const bool   propertyValue = true;

            // set up temp assembly.
            var assembly       = Utilities.CreateTempNetAssembly();
            var typeSystem     = assembly.NetDirectory.MetadataHeader.TypeSystem;
            var tableStream    = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>();
            var fieldTable     = tableStream.GetTable <FieldDefinition>();
            var attributeTable = tableStream.GetTable <CustomAttribute>();
            var importer       = new ReferenceImporter(tableStream);

            // create temp field.
            var field = new FieldDefinition(fieldName, FieldAttributes.Static, new FieldSignature(typeSystem.String));

            fieldTable.Add(field);

            // create custom attribute.
            var signature = new CustomAttributeSignature();

            signature.FixedArguments.Add(
                new CustomAttributeArgument(typeSystem.String,
                                            new ElementSignature(argumentValue)));
            signature.NamedArguments.Add(
                new CustomAttributeNamedArgument()
            {
                ArgumentMemberType = CustomAttributeArgumentMemberType.Property,
                ArgumentType       = typeSystem.Boolean,
                MemberName         = propertyName,
                Argument           = new CustomAttributeArgument(typeSystem.Boolean, new ElementSignature(propertyValue))
            });

            var attribute = new CustomAttribute(importer.ImportMethod(typeof(XmlAttributeAttribute).GetConstructor(new Type[]
            {
                typeof(string)
            })), signature);

            field.CustomAttributes.Add(attribute);
            attributeTable.Add(attribute);

            // build and validate.
            assembly       = Utilities.RebuildNetAssembly(assembly);
            fieldTable     = tableStream.GetTable <FieldDefinition>();
            field          = fieldTable.First(x => x.Name == fieldName);
            attributeTable = tableStream.GetTable <CustomAttribute>();
            var newAttribute = attributeTable[0];

            Assert.IsTrue(field.CustomAttributes.Contains(newAttribute));
            Assert.AreEqual(attribute.Constructor.FullName, newAttribute.Constructor.FullName);

            Assert.AreEqual(attribute.Signature.FixedArguments.Count, newAttribute.Signature.FixedArguments.Count);
            for (int i = 0; i < attribute.Signature.FixedArguments.Count; i++)
            {
                Utilities.ValidateArgument(attribute.Signature.FixedArguments[i],
                                           newAttribute.Signature.FixedArguments[i]);
            }

            Assert.AreEqual(attribute.Signature.NamedArguments.Count, newAttribute.Signature.NamedArguments.Count);
            for (int i = 0; i < attribute.Signature.NamedArguments.Count; i++)
            {
                Utilities.ValidateNamedArgument(attribute.Signature.NamedArguments[i],
                                                newAttribute.Signature.NamedArguments[i]);
            }
        }
        /// <inheritdoc />
        public override object ResolveMember(MetadataToken token)
        {
            switch (token.Table)
            {
            case TableIndex.TypeDef:
                var type = _tokens[(int)token.Rid];
                if (type is RuntimeTypeHandle runtimeTypeHandle)
                {
                    return(_importer.ImportType(Type.GetTypeFromHandle(runtimeTypeHandle)));
                }
                break;

            case TableIndex.Field:
                var field = _tokens[(int)token.Rid];

                if (field is null)
                {
                    return(null);
                }

                if (field is RuntimeFieldHandle runtimeFieldHandle)
                {
                    return(_importer.ImportField(FieldInfo.GetFieldFromHandle(runtimeFieldHandle)));
                }

                if (field.GetType().FullName == "System.Reflection.Emit.GenericFieldInfo")
                {
                    bool result = FieldReader.TryReadField <RuntimeFieldHandle>(field, "m_field", out var mField);
                    var  ctx    = FieldReader.ReadField <RuntimeTypeHandle>(field, "m_context");
                    return(_importer.ImportField(FieldInfo.GetFieldFromHandle(result
                            ? mField
                            : FieldReader.ReadField <RuntimeFieldHandle>(field, "m_fieldHandle"), ctx)));
                }

                break;

            case TableIndex.Method:
            case TableIndex.MemberRef:
                var obj = _tokens[(int)token.Rid];

                if (obj is RuntimeMethodHandle methodHandle)
                {
                    return(_importer.ImportMethod(MethodBase.GetMethodFromHandle(methodHandle)));
                }

                if (obj.GetType().FullName == "System.Reflection.Emit.GenericMethodInfo")
                {
                    var  context   = FieldReader.ReadField <RuntimeTypeHandle>(obj, "m_context");
                    bool hasHandle = FieldReader.TryReadField <RuntimeMethodHandle>(obj, "m_method", out var mMethod);
                    var  mHandle   = FieldReader.ReadField <RuntimeMethodHandle>(obj, "m_methodHandle");
                    var  method    = MethodBase.GetMethodFromHandle(
                        hasHandle ? mMethod : mHandle,
                        context);

                    return(_importer.ImportMethod(method));
                }

                if (obj.GetType().FullName == "System.Reflection.Emit.VarArgMethod")
                {
                    return(_importer.ImportMethod(FieldReader.ReadField <MethodInfo>(obj, "m_method")));
                }

                break;

            case TableIndex.StandAloneSig:
                var reader = ByteArrayDataSource.CreateReader((byte[])_tokens[(int)token.Rid]);
                return(CallingConventionSignature.FromReader(new BlobReadContext(_readerContext), ref reader));
            }

            return(token);
        }
Exemple #20
0
        public void NonExistentStreams()
        {
            var assembly = NetAssemblyFactory.CreateAssembly("SomeAssembly", true);
            var header   = assembly.NetDirectory.MetadataHeader;

            // Remove #US Stream.
            var usHeader = header.StreamHeaders.FirstOrDefault(x => x.Name == "#US");

            if (usHeader != null)
            {
                header.StreamHeaders.Remove(usHeader);
            }

            // Lock metadata.
            var image    = header.LockMetadata();
            var importer = new ReferenceImporter(image);

            // Create new method with a string.
            var method = new MethodDefinition("Test",
                                              MethodAttributes.Public | MethodAttributes.Static,
                                              new MethodSignature(image.TypeSystem.Void));

            method.CilMethodBody = new CilMethodBody(method)
            {
                Instructions =
                {
                    CilInstruction.Create(CilOpCodes.Ldstr,                                                       "Hello, world!"),
                    CilInstruction.Create(CilOpCodes.Call,                                                        importer.ImportMethod(
                                              typeof(Console).GetMethod("WriteLine",                              new[] { typeof(string) }))),
                    CilInstruction.Create(CilOpCodes.Ret)
                }
            };
            image.Assembly.Modules[0].TopLevelTypes[0].Methods.Add(method);

            // Commit changes.
            header.UnlockMetadata();

            // Check if #US stream is added again.
            var usStream = header.GetStream <UserStringStream>();

            Assert.NotNull(usStream);
        }