예제 #1
0
 public MDEditorPatcher(RawModuleBytes moduleData, MetadataEditor mdEditor, IAssembly tempAssembly, TypeDef nonNestedEditedTypeOrNull)
 {
     this.moduleData   = moduleData;
     peFile            = (byte *)moduleData.Pointer;
     this.tempAssembly = tempAssembly;
     this.nonNestedEditedTypeOrNull = nonNestedEditedTypeOrNull;
     remappedTypeTokens             = new Dictionary <uint, uint>();
     sigBuilder         = new List <byte>();
     this.mdEditor      = mdEditor;
     tempAssemblyRefRid = 0;
 }
예제 #2
0
 public MDEditorPatcher(RawModuleBytes moduleData, MetadataEditor mdEditor, IAssembly tempAssembly, TypeDef?nonNestedEditedType, MDEditorPatcherOptions options)
 {
     this.moduleData          = moduleData;
     peFile                   = (byte *)moduleData.Pointer;
     this.tempAssembly        = tempAssembly;
     this.nonNestedEditedType = nonNestedEditedType;
     remappedTypeTokens       = new RemappedTypeTokens(nonNestedEditedType);
     sigBuilder               = new List <byte>();
     this.mdEditor            = mdEditor;
     this.options             = options;
     tempAssemblyRefRid       = 0;
 }
예제 #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 = nonNestedEditedTypeOrNull != null &&
                                  MDPatcherUtils.ExistsInMetadata(nonNestedEditedTypeOrNull) &&
                                  MDPatcherUtils.ReferencesModule(module, nonNestedEditedTypeOrNull?.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)) {
                    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, nonNestedEditedTypeOrNull, 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);
        }
예제 #4
0
        /// <summary>
        /// Converts 'AudioInfo' object to 'Track' object.
        /// </summary>
        /// <param name="audioInfo">'AudioInfo' object which is to be converted.</param>
        /// <returns>Created 'Track' object.</returns>
        private Track MediaInfoToTrack(AudioInfo audioInfo)
        {
            MetadataEditor metadataEditor = new MetadataEditor(audioInfo.Path);
            int            pictureCount   = metadataEditor.PictureCount;

            byte[] art = null;
            if (pictureCount > 0)
            {
                Artwork artwork = metadataEditor.GetPicture(0);
                art = artwork.Data;
            }

            return(new Track(audioInfo.Title, audioInfo.Artist, audioInfo.Album, art, audioInfo.Path, audioInfo.Duration));
        }
예제 #5
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);
        }
예제 #6
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);
            }
        }
        //------------------------------------------------------------------------------
        // Name: AddAttrib()
        // Desc: Add an attribute with the specifed language index.
        //------------------------------------------------------------------------------
        bool AddAttrib(string pwszFileName, ushort wStreamNum, string pwszAttribName,
                       ushort wAttribType, string pwszAttribValue, ushort wLangIndex)
        {
            try
            {
                IWMMetadataEditor MetadataEditor;
                IWMHeaderInfo3    HeaderInfo3;
                byte[]            pbAttribValue;
                int nAttribValueLen;
                WMT_ATTR_DATATYPE AttribDataType = ( WMT_ATTR_DATATYPE )wAttribType;
                ushort            wAttribIndex   = 0;

                if (!TranslateAttrib(AttribDataType, pwszAttribValue, out pbAttribValue, out nAttribValueLen))
                {
                    return(false);
                }

                WMFSDKFunctions.WMCreateEditor(out MetadataEditor);

                MetadataEditor.Open(pwszFileName);

                HeaderInfo3 = ( IWMHeaderInfo3 )MetadataEditor;

                HeaderInfo3.AddAttribute(wStreamNum,
                                         pwszAttribName,
                                         out wAttribIndex,
                                         AttribDataType,
                                         wLangIndex,
                                         pbAttribValue,
                                         (uint)nAttribValueLen);

                MetadataEditor.Flush();

                MetadataEditor.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return(false);
            }

            return(true);
        }
예제 #8
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);
        }
        /// <summary>
        /// Passes data from all tracks to View
        /// </summary>
        private void createTracksView()
        {
            TitleViewModel.Tracks.Clear();

            foreach (Track track in TracksManager.db_GetAllTracks())
            {
                TrackMetadata md = new TrackMetadata();
                if (track.title == null)
                {
                    md.Title = "unkown";
                    MetadataEditor.AddTitle(track.audio, "unknown");
                }
                else
                {
                    md.Title = track.title;
                    MetadataEditor.AddTitle(track.audio, track.title);
                }
                if (MetadataEditor.GetGenres(track.audio) == null || MetadataEditor.GetGenres(track.audio).Count() == 0)
                {
                    md.Genre = "unkown";
                    MetadataEditor.AddGenre(track.audio, new String[] { "unknown" });
                }
                else
                {
                    md.Genre = MetadataEditor.GetGenres(track.audio)[0];
                }
                if (MetadataEditor.GetArtists(track.audio) == null || MetadataEditor.GetArtists(track.audio).Count() == 0)
                {
                    md.Artist = "unknown";
                    MetadataEditor.AddArtist(track.audio, new String[] { "unknown" });
                }
                else
                {
                    md.Artist = MetadataEditor.GetArtists(track.audio)[0];
                }
                if (MetadataEditor.GetYear(track.audio) == 0)
                {
                    md.Year = "unknown";
                }
                else
                {
                    md.Year = MetadataEditor.GetYear(track.audio).ToString();
                }
                if (MetadataEditor.GetAlbum(track.audio) == null)
                {
                    md.Album = "unknown";
                    MetadataEditor.AddAlbum(track.audio, "unknown");
                }
                else
                {
                    md.Album = MetadataEditor.GetAlbum(track.audio);
                }
                if (MetadataEditor.GetDuration(track.audio).ToString(@"hh\:mm\:ss") == "00:00:00")
                {
                    md.Length = "unknown";
                }
                else
                {
                    md.Length = MetadataEditor.GetDuration(track.audio).ToString(@"hh\:mm\:ss");
                }
                TitleViewModel.Tracks.Add(md);
            }

            SelectAllTracks = true;
            CurrentFrame    = "TitleView.xaml";
        }
예제 #10
0
        /// <summary>Splices together all of the spans.</summary>
        /// <returns></returns>
        protected override object DoWork()
        {
            IStreamBufferRecComp recComp = null;
            Timer timer = null;

            try
            {
                // Timer used for updating progress
                timer = new Timer(new TimerCallback(HandleProgressUpdate), null, PollFrequency, PollFrequency);

                // Create the RecComp and initialize it
                recComp = (IStreamBufferRecComp)ClassId.CoCreateInstance(ClassId.RecComp);
                if (File.Exists(_target.FullName))
                {
                    File.Delete(_target.FullName);
                }
                recComp.Initialize(_target.FullName, _spans[0].File.FullName);
                _recComp = recComp;                 // only valid during this call

                // Add each span to the output file
                FileInfo dvrTarget = _target;
                for (int i = 0; i < _spans.Count; i++)
                {
                    // If the user has requested cancellation, stop processing
                    if (CancellationPending)
                    {
                        break;
                    }

                    // Do the append
                    VideoSpan span  = _spans[i];
                    ulong     start = VideoSpan.SecondsToHundredNanoseconds(span.StartPosition);
                    ulong     stop  = VideoSpan.SecondsToHundredNanoseconds(span.StopPosition);
                    recComp.AppendEx(span.File.FullName, start, stop);
                }
            }
            finally
            {
                // Clean up after the RecComp object and the timer
                if (timer != null)
                {
                    timer.Dispose();
                }
                if (recComp != null)
                {
                    recComp.Close();
                }
                while (Marshal.ReleaseComObject(recComp) > 0)
                {
                    ;
                }
            }

            // Copy the metadata if requested... use that from the first span.
            if (_copyMetadata)
            {
                using (MetadataEditor sourceEditor = new DvrmsMetadataEditor(_spans[0].File.FullName))
                {
                    using (MetadataEditor destEditor = new AsfMetadataEditor(_target.FullName))
                    {
                        MetadataEditor.MigrateMetadata(sourceEditor, destEditor);
                    }
                }
            }

            // Notify that we're done
            OnProgressChanged(100);
            return(null);
        }