Exemple #1
0
        void AddInternalsVisibleToAttribute()
        {
            bool b = GetCorLibToken(out var corlibToken);

            Debug.Assert(b, "No corlib assembly found");
            if (!b)
            {
                return;
            }
            b = CodedToken.ResolutionScope.Encode(corlibToken, out uint corlibEncodedToken);
            Debug.Assert(b);
            if (!b)
            {
                return;
            }

            uint ivtTypeRefRid = mdEditor.TablesHeap.TypeRefTable.Create();
            var  ivtTypeRefRow = new RawTypeRefRow(corlibEncodedToken, mdEditor.StringsHeap.Create("InternalsVisibleToAttribute"), mdEditor.StringsHeap.Create("System.Runtime.CompilerServices"));

            mdEditor.TablesHeap.TypeRefTable.Set(ivtTypeRefRid, ref ivtTypeRefRow);

            uint ivtCtorRid = mdEditor.TablesHeap.MemberRefTable.Create();
            var  ivtCtorRow = new RawMemberRefRow(CodedToken.MemberRefParent.Encode(new MDToken(Table.TypeRef, ivtTypeRefRid)),
                                                  mdEditor.StringsHeap.Create(".ctor"), mdEditor.BlobHeap.Create(ivtCtorSigBlob));

            mdEditor.TablesHeap.MemberRefTable.Set(ivtCtorRid, ref ivtCtorRow);

            uint ivtCARid = mdEditor.TablesHeap.CustomAttributeTable.Create();
            var  ivtCARow = new RawCustomAttributeRow(CodedToken.HasCustomAttribute.Encode(new MDToken(Table.Assembly, 1)),
                                                      CodedToken.CustomAttributeType.Encode(new MDToken(Table.MemberRef, ivtCtorRid)),
                                                      mdEditor.BlobHeap.Create(MDPatcherUtils.CreateIVTBlob(tempAssembly)));

            mdEditor.TablesHeap.CustomAttributeTable.Set(ivtCARid, ref ivtCARow);
        }
Exemple #2
0
        void ReadTypeDefOrRef()
        {
            var  start         = currPos;
            uint codedToken    = ReadCompressedUInt32();
            uint compressedLen = (uint)(currPos - start);

            if (!CodedToken.TypeDefOrRef.Decode(codedToken, out MDToken token))
            {
                ThrowInvalidSignatureException();
            }
            if (!remappedTypeTokens.TryGetValue(token.Raw, out uint newToken))
            {
                return;
            }
            uint newCodedToken    = CodedToken.TypeDefOrRef.Encode(newToken);
            uint newCodedTokenLen = (uint)MDPatcherUtils.GetCompressedUInt32Length(newCodedToken);

            if (usingBuilder || newCodedTokenLen != compressedLen)
            {
                SwitchToBuilder(compressedLen);
                WriteCompressedUInt32(newCodedToken);
            }
            else
            {
                currPos = start;
                WriteCompressedUInt32(newCodedToken);
            }
        }
Exemple #3
0
        public unsafe bool Patch(ModuleDef module, out RawModuleBytes newModuleData)
        {
            var moduleData = this.moduleData;

            // NOTE: We can't remove the type from the corlib (eg. mscorlib) because the compiler
            // (Roslyn) won't recognize it as the corlib if it has any AssemblyRefs.
            // A possible fix is to add a new netmodule to the corlib assembly.
            bool fixTypeDefRefs = !(nonNestedEditedType is null) &&
                                  MDPatcherUtils.ExistsInMetadata(nonNestedEditedType) &&
                                  MDPatcherUtils.ReferencesModule(module, nonNestedEditedType?.Module) &&
                                  !module.Assembly.IsCorLib();
            bool addIVT = module == editedModule || MDPatcherUtils.HasModuleInternalAccess(module, editedModule);

            if (fixTypeDefRefs || addIVT)
            {
                DnSpyEventSource.Log.EditCodePatchModuleStart(module.Location);
                using (var md = MDPatcherUtils.TryCreateMetadata(moduleData, isFileLayout)) {
                    if (md is null)
                    {
                        throw new InvalidOperationException("Couldn't create metadata");
                    }
                    var mdEditor = new MetadataEditor(moduleData, md);
                    var options  = MDEditorPatcherOptions.None;
                    if (fixTypeDefRefs)
                    {
                        options |= MDEditorPatcherOptions.UpdateTypeReferences;
                    }
                    if (addIVT)
                    {
                        options |= MDEditorPatcherOptions.AllowInternalAccess;
                    }
                    var patcher = new MDEditorPatcher(moduleData, mdEditor, tempAssembly, nonNestedEditedType, options);
                    patcher.Patch(module);
                    if (mdEditor.MustRewriteMetadata())
                    {
                        var stream = new MDWriterMemoryStream();
                        new MDWriter(moduleData, mdEditor, stream).Write();
                        NativeMemoryRawModuleBytes?newRawData = null;
                        try {
                            newRawData = new NativeMemoryRawModuleBytes((int)stream.Length, isFileLayout: true);
                            stream.CopyTo((IntPtr)newRawData.Pointer, newRawData.Size);
                            moduleData = newRawData;
                        }
                        catch {
                            newRawData?.Dispose();
                            throw;
                        }
                    }
                }
                DnSpyEventSource.Log.EditCodePatchModuleStop(module.Location);
            }

            newModuleData = moduleData;
            return(true);
        }
Exemple #4
0
        MDSigPatcher(List <byte> sigBuilder, RemappedTypeTokens remappedTypeTokens, RawModuleBytes moduleData, uint blobOffset, uint sigOffset)
        {
            this.sigBuilder         = sigBuilder;
            this.remappedTypeTokens = remappedTypeTokens;
            currPos = (byte *)moduleData.Pointer + blobOffset + sigOffset;
            uint size = MDPatcherUtils.ReadCompressedUInt32(ref currPos, (byte *)moduleData.Pointer + moduleData.Size);

            startPos         = currPos;
            endPos           = currPos + size;
            usingBuilder     = false;
            recursionCounter = 0;
        }
Exemple #5
0
        MDSigPatcher(List <byte> sigBuilder, Dictionary <uint, uint> remappedTypeTokens, byte[] moduleData, uint blobOffset, uint sigOffset)
        {
            this.sigBuilder         = sigBuilder;
            this.remappedTypeTokens = remappedTypeTokens;
            this.moduleData         = moduleData;
            startOffset             = blobOffset + sigOffset;
            uint size = MDPatcherUtils.ReadCompressedUInt32(moduleData, ref startOffset);

            endOffset        = startOffset + size;
            currOffset       = startOffset;
            usingBuilder     = false;
            recursionCounter = 0;
        }
Exemple #6
0
        public unsafe bool Patch(ModuleDef module, out RawModuleBytes newModuleData)
        {
            var moduleData = this.moduleData;

            // NOTE: We can't remove the type from the corlib (eg. mscorlib) because the compiler
            // (Roslyn) won't recognize it as the corlib if it has any AssemblyRefs.
            // A possible fix is to add a new netmodule to the corlib assembly.
            bool fixTypeDefRefs = nonNestedEditedTypeOrNull != null &&
                                  MDPatcherUtils.ExistsInMetadata(nonNestedEditedTypeOrNull) &&
                                  MDPatcherUtils.ReferencesModule(module, nonNestedEditedTypeOrNull?.Module) &&
                                  !module.Assembly.IsCorLib();

            if (makeEverythingPublic || fixTypeDefRefs)
            {
                using (var md = MDPatcherUtils.TryCreateMetadata(moduleData, isFileLayout)) {
                    if (makeEverythingPublic)
                    {
                        new MetadataFixer(moduleData, md).MakePublic();
                    }
                    if (fixTypeDefRefs)
                    {
                        var mdEditor = new MetadataEditor(moduleData, md);
                        var patcher  = new MDEditorPatcher(moduleData, mdEditor, tempAssembly, nonNestedEditedTypeOrNull);
                        patcher.Patch(module);
                        if (mdEditor.MustRewriteMetadata())
                        {
                            var stream = new MDWriterMemoryStream();
                            new MDWriter(moduleData, mdEditor, stream).Write();
                            NativeMemoryRawModuleBytes newRawData = null;
                            try {
                                newRawData = new NativeMemoryRawModuleBytes((int)stream.Length);
                                stream.CopyTo((IntPtr)newRawData.Pointer, newRawData.Size);
                                moduleData = newRawData;
                            }
                            catch {
                                newRawData?.Dispose();
                                throw;
                            }
                        }
                    }
                }
            }

            newModuleData = moduleData;
            return(true);
        }
Exemple #7
0
        void DeleteTypeDef(MetadataEditor mdEditor, TypeDef nonNestedTypeDef)
        {
            Debug.Assert(nonNestedTypeDef.DeclaringType == null);

            var dict = new Dictionary <TypeDef, (TypeDef Type, uint TypeRefRid, RawTypeRefRow TypeRefRow)>();

            foreach (var type in MDPatcherUtils.GetMetadataTypes(nonNestedTypeDef))
            {
                var typeRefRid = mdEditor.TablesHeap.TypeRefTable.Create();
                remappedTypeTokens.Add(type.MDToken.Raw, new MDToken(Table.TypeRef, typeRefRid).Raw);

                // Remove the type by renaming it and making it private/internal
                var tdRow = mdEditor.TablesHeap.TypeDefTable.Get(type.Rid);
                var flags = tdRow.Flags;
                if ((flags & 7) <= 1)
                {
                    flags = flags & ~7U;                                // NotPublic
                }
                else
                {
                    flags = (flags & ~7U) | 3;                      // NestedPrivate
                }
                var deletedType = (Type : type, TypeRefRid : typeRefRid, TypeRefRow : new RawTypeRefRow(0, tdRow.Name, tdRow.Namespace));
                tdRow = new RawTypeDefRow(flags, mdEditor.StringsHeap.Create(Guid.NewGuid().ToString()), mdEditor.StringsHeap.Create(string.Empty), tdRow.Extends, tdRow.FieldList, tdRow.MethodList);
                mdEditor.TablesHeap.TypeDefTable.Set(type.Rid, ref tdRow);
                dict.Add(type, deletedType);
            }
            remappedTypeTokens.SetReadOnly();

            foreach (var kv in dict)
            {
                var  deletedType = kv.Value;
                uint resolutionScope;
                if (deletedType.Type.DeclaringType != null)
                {
                    var declType = dict[deletedType.Type.DeclaringType];
                    resolutionScope = CodedToken.ResolutionScope.Encode(new MDToken(Table.TypeRef, declType.TypeRefRid));
                }
                else
                {
                    resolutionScope = CodedToken.ResolutionScope.Encode(new MDToken(Table.AssemblyRef, GetOrCreateTempAssemblyRid()));
                }
                deletedType.TypeRefRow = new RawTypeRefRow(resolutionScope, deletedType.TypeRefRow.Name, deletedType.TypeRefRow.Namespace);
                mdEditor.TablesHeap.TypeRefTable.Set(deletedType.TypeRefRid, ref deletedType.TypeRefRow);
            }
        }
Exemple #8
0
        static bool HasInternalsVisibleToAttribute(ModuleDef targetModule, ModuleDef sourceModule)
        {
            var targetAssembly = targetModule.Assembly;

            if (targetAssembly == null)
            {
                return(false);
            }
            var sourceAssembly = sourceModule.Assembly;

            if (sourceAssembly == null)
            {
                return(false);
            }
            foreach (var ca in targetAssembly.CustomAttributes)
            {
                if (ca.ConstructorArguments.Count != 1)
                {
                    continue;
                }
                if (!MDPatcherUtils.CheckTypeDefOrTypeRefName(ca.Constructor?.DeclaringType, nameSystem_Runtime_CompilerServices, nameInternalsVisibleToAttribute))
                {
                    continue;
                }
                var asmName = (ca.ConstructorArguments[0].Value as UTF8String)?.String;
                if (asmName == null)
                {
                    continue;
                }
                int index = asmName.IndexOf(',');
                if (index >= 0)
                {
                    asmName = asmName.Substring(0, index);
                }
                asmName = asmName.Trim();
                if (!StringComparer.OrdinalIgnoreCase.Equals(sourceAssembly.Name.String, asmName))
                {
                    continue;
                }

                return(true);
            }
            return(false);
        }
Exemple #9
0
        public bool Patch(ModuleDef module, out byte[] newModuleData)
        {
            var moduleData = this.moduleData;

            // NOTE: We can't remove the type from the corlib (eg. mscorlib) because the compiler
            // (Roslyn) won't recognize it as the corlib if it has any AssemblyRefs.
            // A possible fix is to add a new netmodule to the corlib assembly.
            bool fixTypeDefRefs = nonNestedEditedTypeOrNull != null &&
                                  MDPatcherUtils.ExistsInMetadata(nonNestedEditedTypeOrNull) &&
                                  MDPatcherUtils.ReferencesModule(module, nonNestedEditedTypeOrNull?.Module) &&
                                  !module.Assembly.IsCorLib();

            if (makeEverythingPublic || fixTypeDefRefs)
            {
                using (var md = MDPatcherUtils.TryCreateMetadata(moduleData)) {
                    if (makeEverythingPublic)
                    {
                        bool success = new MetadataFixer(moduleData, md).MakePublic();
                        if (!success)
                        {
                            newModuleData = null;
                            return(false);
                        }
                    }
                    if (fixTypeDefRefs)
                    {
                        var mdEditor = new MetadataEditor(moduleData, md);
                        var patcher  = new MDEditorPatcher(moduleData, mdEditor, tempAssembly, nonNestedEditedTypeOrNull);
                        patcher.Patch(module);
                        if (mdEditor.MustRewriteMetadata())
                        {
                            var stream = new MDWriterMemoryStream();
                            new MDWriter(moduleData, mdEditor, stream).Write();
                            moduleData = stream.ToArray();
                        }
                    }
                }
            }

            newModuleData = moduleData;
            return(true);
        }
Exemple #10
0
        MDSigPatcher(List <byte> sigBuilder, RemappedTypeTokens remappedTypeTokens, RawModuleBytes moduleData, uint blobOffset, uint sigOffset)
        {
            if ((ulong)blobOffset + sigOffset > (ulong)moduleData.Size)
            {
                ThrowInvalidSignatureException();
            }
            this.sigBuilder         = sigBuilder;
            this.remappedTypeTokens = remappedTypeTokens;
            currPos = (byte *)moduleData.Pointer + blobOffset + sigOffset;
            uint size = MDPatcherUtils.ReadCompressedUInt32(ref currPos, (byte *)moduleData.Pointer + moduleData.Size);

            startPos = currPos;
            endPos   = currPos + size;
            if ((ulong)(endPos - (byte *)moduleData.Pointer) > (ulong)moduleData.Size)
            {
                ThrowInvalidSignatureException();
            }
            usingBuilder     = false;
            recursionCounter = 0;
        }