From f9ab0e16c54b1d86ce2c2d06738115174707666e Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sat, 2 Sep 2023 14:21:42 +0200 Subject: [PATCH 1/5] Update to dnlib 4.1.0 --- DnSpyCommon.props | 2 +- Extensions/dnSpy.AsmEditor/Resources/ResourceCommands.cs | 2 +- Extensions/dnSpy.AsmEditor/Resources/ResourceElementVM.cs | 2 +- .../Documents/TreeView/Resources/SerializationUtilities.cs | 2 +- .../TreeView/Resources/SerializedImageListStreamerUtilities.cs | 2 +- .../Documents/TreeView/Resources/SerializedImageUtilities.cs | 2 +- .../Documents/TreeView/Resources/ResourceElementSetNodeImpl.cs | 2 +- dnSpy/dnSpy/app.config | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/DnSpyCommon.props b/DnSpyCommon.props index 6b7a8c6dba..ddc935493e 100644 --- a/DnSpyCommon.props +++ b/DnSpyCommon.props @@ -43,7 +43,7 @@ 1.7.0 - 3.6.0 + 4.1.0 1.20.0 17.1.0 1.1.142101 diff --git a/Extensions/dnSpy.AsmEditor/Resources/ResourceCommands.cs b/Extensions/dnSpy.AsmEditor/Resources/ResourceCommands.cs index 8dffff5754..8bc9bf5ee4 100644 --- a/Extensions/dnSpy.AsmEditor/Resources/ResourceCommands.cs +++ b/Extensions/dnSpy.AsmEditor/Resources/ResourceCommands.cs @@ -766,7 +766,7 @@ static void Execute(Lazy undoCommandService, IAppService ap return; var outStream = new MemoryStream(); - ResourceWriter.Write(module, outStream, new ResourceElementSet()); + ResourceWriter.Write(module, outStream, ResourceElementSet.CreateForResourceReader(module)); var er = new EmbeddedResource(data.Name, outStream.ToArray(), data.Attributes); var treeView = appService.DocumentTreeView.TreeView; var treeNodeGroup = appService.DocumentTreeView.DocumentTreeNodeGroups.GetGroup(DocumentTreeNodeGroupType.ResourceTreeNodeGroup); diff --git a/Extensions/dnSpy.AsmEditor/Resources/ResourceElementVM.cs b/Extensions/dnSpy.AsmEditor/Resources/ResourceElementVM.cs index 1c916de69e..8f9fd38118 100644 --- a/Extensions/dnSpy.AsmEditor/Resources/ResourceElementVM.cs +++ b/Extensions/dnSpy.AsmEditor/Resources/ResourceElementVM.cs @@ -292,7 +292,7 @@ IResourceData CreateResourceData() { case ResourceElementType.TimeSpan: return new BuiltInResourceData((ResourceTypeCode)code, TimeSpanVM.Value); case ResourceElementType.ByteArray: return new BuiltInResourceData((ResourceTypeCode)code, Data ?? Array.Empty()); case ResourceElementType.Stream: return new BuiltInResourceData((ResourceTypeCode)code, Data ?? Array.Empty()); - case ResourceElementType.SerializedType: return new BinaryResourceData(new UserResourceType(UserTypeVM.TypeFullName, ResourceTypeCode.UserTypes), UserTypeVM.GetSerializedData()); + case ResourceElementType.SerializedType: return new BinaryResourceData(new UserResourceType(UserTypeVM.TypeFullName, ResourceTypeCode.UserTypes), UserTypeVM.GetSerializedData(), SerializationFormat.BinaryFormatter); default: throw new InvalidOperationException(); } } diff --git a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializationUtilities.cs b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializationUtilities.cs index a7e7269c51..e9dfbae570 100644 --- a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializationUtilities.cs +++ b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializationUtilities.cs @@ -56,7 +56,7 @@ static ResourceElement CreateSerializedImage(Stream stream, string filename) { var userType = new UserResourceType(typeName, ResourceTypeCode.UserTypes); var rsrcElem = new ResourceElement { Name = Path.GetFileName(filename), - ResourceData = new BinaryResourceData(userType, serializedData), + ResourceData = new BinaryResourceData(userType, serializedData, SerializationFormat.BinaryFormatter), }; return rsrcElem; diff --git a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageListStreamerUtilities.cs b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageListStreamerUtilities.cs index 020d38944e..d7641656d6 100644 --- a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageListStreamerUtilities.cs +++ b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageListStreamerUtilities.cs @@ -93,7 +93,7 @@ public static ResourceElement Serialize(ImageListOptions opts) { var typeName = SystemWindowsFormsImageListStreamer.AssemblyQualifiedName; return new ResourceElement { Name = opts.Name, - ResourceData = new BinaryResourceData(new UserResourceType(typeName, ResourceTypeCode.UserTypes), SerializationUtilities.Serialize(obj)), + ResourceData = new BinaryResourceData(new UserResourceType(typeName, ResourceTypeCode.UserTypes), SerializationUtilities.Serialize(obj), SerializationFormat.BinaryFormatter), }; } diff --git a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs index f9bcf38ee9..de4d0add50 100644 --- a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs +++ b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs @@ -116,7 +116,7 @@ public static ResourceElement Serialize(ResourceElement resElem) { return new ResourceElement { Name = resElem.Name, - ResourceData = new BinaryResourceData(new UserResourceType(typeName, ResourceTypeCode.UserTypes), SerializationUtilities.Serialize(obj)), + ResourceData = new BinaryResourceData(new UserResourceType(typeName, ResourceTypeCode.UserTypes), SerializationUtilities.Serialize(obj), SerializationFormat.BinaryFormatter), }; } } diff --git a/dnSpy/dnSpy/Documents/TreeView/Resources/ResourceElementSetNodeImpl.cs b/dnSpy/dnSpy/Documents/TreeView/Resources/ResourceElementSetNodeImpl.cs index 0db9a99c2c..0fe368892a 100644 --- a/dnSpy/dnSpy/Documents/TreeView/Resources/ResourceElementSetNodeImpl.cs +++ b/dnSpy/dnSpy/Documents/TreeView/Resources/ResourceElementSetNodeImpl.cs @@ -99,7 +99,7 @@ public override void RegenerateEmbeddedResource() { void RegenerateEmbeddedResource(ModuleDef module) { TreeNode.EnsureChildrenLoaded(); var outStream = new MemoryStream(); - var resources = new ResourceElementSet(); + var resources = resourceElementSet.Clone(); foreach (DocumentTreeNodeData child in TreeNode.DataChildren) { var resourceElement = ResourceElementNode.GetResourceElement(child); if (resourceElement is null) diff --git a/dnSpy/dnSpy/app.config b/dnSpy/dnSpy/app.config index cdb732c52e..16f54a9c01 100644 --- a/dnSpy/dnSpy/app.config +++ b/dnSpy/dnSpy/app.config @@ -45,7 +45,7 @@ - + From ebd6935bbed29d34b6793694f991bb245440c4c3 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sun, 3 Sep 2023 21:39:15 +0200 Subject: [PATCH 2/5] Add RESX support for additional resource element serialization formats --- .../MSBuild/ResXResourceFileWriter.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/dnSpy/dnSpy.Decompiler/MSBuild/ResXResourceFileWriter.cs b/dnSpy/dnSpy.Decompiler/MSBuild/ResXResourceFileWriter.cs index 717cc87765..94fd9187e3 100644 --- a/dnSpy/dnSpy.Decompiler/MSBuild/ResXResourceFileWriter.cs +++ b/dnSpy/dnSpy.Decompiler/MSBuild/ResXResourceFileWriter.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2023 ElektroKill This file is part of dnSpy @@ -182,8 +182,19 @@ ResXResourceInfo GetNodeInfo(IResourceData resourceData) { throw new ArgumentOutOfRangeException(); } } - if (resourceData is BinaryResourceData binaryResourceData) - return new ResXResourceInfo(ToBase64WrappedString(binaryResourceData.Data), binaryResourceData.TypeName, ResXResourceWriter.BinSerializedObjectMimeType); + if (resourceData is BinaryResourceData binaryResourceData) { + switch (binaryResourceData.Format) { + case SerializationFormat.BinaryFormatter: + return new ResXResourceInfo(ToBase64WrappedString(binaryResourceData.Data), binaryResourceData.TypeName, ResXResourceWriter.BinSerializedObjectMimeType); + case SerializationFormat.TypeConverterByteArray: + case SerializationFormat.ActivatorStream: + // RESX does not have a way to represent creation of an object using Activator.CreateInstance, + // so we fallback to the same representation as data passed into TypeConverter. + return new ResXResourceInfo(ToBase64WrappedString(binaryResourceData.Data), binaryResourceData.TypeName, ResXResourceWriter.ByteArraySerializedObjectMimeType); + case SerializationFormat.TypeConverterString: + return new ResXResourceInfo(Encoding.UTF8.GetString(binaryResourceData.Data), binaryResourceData.TypeName); + } + } throw new ArgumentOutOfRangeException(); } From 4be7b3e1c541ebafb1b7822b40dbb81526a38d4d Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Sun, 3 Sep 2023 21:55:15 +0200 Subject: [PATCH 3/5] Add support for deserializing images stored in newer formats --- .../Resources/SerializedImageUtilities.cs | 83 +++++++++++++++---- .../SerializedImageResourceElementNode.cs | 6 +- 2 files changed, 70 insertions(+), 19 deletions(-) diff --git a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs index de4d0add50..a1675056b2 100644 --- a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs +++ b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs @@ -20,6 +20,7 @@ You should have received a copy of the GNU General Public License using System; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Text; using dnlib.DotNet; using dnlib.DotNet.Resources; @@ -36,34 +37,84 @@ public static class SerializedImageUtilities { /// Serialized data /// Updated with the image data /// - public static bool GetImageData(ModuleDef? module, string typeName, byte[] serializedData, [NotNullWhen(true)] out byte[]? imageData) { + public static bool GetImageData(ModuleDef? module, string typeName, byte[] serializedData, [NotNullWhen(true)] out byte[]? imageData) => + GetImageData(module, typeName, serializedData, SerializationFormat.BinaryFormatter, out imageData); + + /// + /// Gets the image data + /// + /// Module + /// Name of type + /// Serialized data + /// Format of serialized data + /// Updated with the image data + /// + public static bool GetImageData(ModuleDef? module, string typeName, byte[] serializedData, SerializationFormat format, [NotNullWhen(true)] out byte[]? imageData) { imageData = null; + if (CouldBeBitmap(module, typeName)) { - var dict = Deserializer.Deserialize(SystemDrawingBitmap.DefinitionAssembly.FullName, SystemDrawingBitmap.ReflectionFullName, serializedData); - // Bitmap loops over every item looking for "Data" (case insensitive) - foreach (var v in dict.Values) { - var d = v.Value as byte[]; - if (d is null) - continue; - if ("Data".Equals(v.Name, StringComparison.OrdinalIgnoreCase)) { - imageData = d; - return true; + if (format == SerializationFormat.BinaryFormatter) { + var dict = Deserializer.Deserialize(SystemDrawingBitmap.DefinitionAssembly.FullName, SystemDrawingBitmap.ReflectionFullName, serializedData); + // Bitmap loops over every item looking for "Data" (case insensitive) + foreach (var v in dict.Values) { + var d = v.Value as byte[]; + if (d is null) + continue; + if ("Data".Equals(v.Name, StringComparison.OrdinalIgnoreCase)) { + imageData = d; + return true; + } } + return false; + } + if (format == SerializationFormat.ActivatorStream) { + imageData = serializedData; + return true; + } + if (format == SerializationFormat.TypeConverterByteArray) { + imageData = GetBitmapData(serializedData) ?? serializedData; + return true; } - return false; } if (CouldBeIcon(module, typeName)) { - var dict = Deserializer.Deserialize(SystemDrawingIcon.DefinitionAssembly.FullName, SystemDrawingIcon.ReflectionFullName, serializedData); - if (!dict.TryGetValue("IconData", out var info)) - return false; - imageData = info.Value as byte[]; - return imageData is not null; + if (format == SerializationFormat.BinaryFormatter) { + var dict = Deserializer.Deserialize(SystemDrawingIcon.DefinitionAssembly.FullName, SystemDrawingIcon.ReflectionFullName, serializedData); + if (!dict.TryGetValue("IconData", out var info)) + return false; + imageData = info.Value as byte[]; + return imageData is not null; + } + if (format == SerializationFormat.ActivatorStream || format == SerializationFormat.TypeConverterByteArray) { + imageData = serializedData; + return true; + } } return false; } + static byte[]? GetBitmapData(byte[] rawData) { + // Based on ImageConverter.GetBitmapStream + // See https://github.com/dotnet/winforms/blob/main/src/System.Drawing.Common/src/System/Drawing/ImageConverter.cs + if (rawData.Length <= 18) + return null; + + short sig = (short)(rawData[0] | rawData[1] << 8); + if (sig != 0x1C15) + return null; + + short headerSize = (short)(rawData[2] | rawData[3] << 8); + if (rawData.Length <= headerSize + 18) + return null; + if (Encoding.ASCII.GetString(rawData, headerSize + 12, 6) != "PBrush") + return null; + + var newData = new byte[rawData.Length - 78]; + Buffer.BlockCopy(rawData, 78, newData, 0, newData.Length); + return newData; + } + static bool CouldBeBitmap(ModuleDef? module, string name) => CheckType(module, name, SystemDrawingBitmap); static bool CouldBeIcon(ModuleDef? module, string name) => CheckType(module, name, SystemDrawingIcon); diff --git a/dnSpy/dnSpy/Documents/TreeView/Resources/SerializedImageResourceElementNode.cs b/dnSpy/dnSpy/Documents/TreeView/Resources/SerializedImageResourceElementNode.cs index d17a7ef783..045ad294e8 100644 --- a/dnSpy/dnSpy/Documents/TreeView/Resources/SerializedImageResourceElementNode.cs +++ b/dnSpy/dnSpy/Documents/TreeView/Resources/SerializedImageResourceElementNode.cs @@ -42,7 +42,7 @@ sealed class SerializedImageResourceElementNodeProvider : IResourceNodeProvider if (serializedData is null) return null; - if (SerializedImageUtilities.GetImageData(module, serializedData.TypeName, serializedData.Data, out var imageData)) + if (SerializedImageUtilities.GetImageData(module, serializedData.TypeName, serializedData.Data, serializedData.Format, out var imageData)) return new SerializedImageResourceElementNodeImpl(treeNodeGroup, resourceElement, imageData); return null; @@ -94,7 +94,7 @@ protected override IEnumerable GetDeserializedData() { return res; var binData = (BinaryResourceData)newResElem.ResourceData; - if (!SerializedImageUtilities.GetImageData(this.GetModule(), binData.TypeName, binData.Data, out var imageData)) + if (!SerializedImageUtilities.GetImageData(this.GetModule(), binData.TypeName, binData.Data, binData.Format, out var imageData)) return dnSpy_Resources.NewDataIsNotAnImage; try { @@ -111,7 +111,7 @@ public override void UpdateData(ResourceElement newResElem) { base.UpdateData(newResElem); var binData = (BinaryResourceData)newResElem.ResourceData; - SerializedImageUtilities.GetImageData(this.GetModule(), binData.TypeName, binData.Data, out var imageData); + SerializedImageUtilities.GetImageData(this.GetModule(), binData.TypeName, binData.Data, binData.Format, out var imageData); Debug2.Assert(imageData is not null); InitializeImageData(imageData); } From efe9817fc156ca7aac540f176fc54f5858dbb781 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Tue, 5 Sep 2023 20:31:17 +0200 Subject: [PATCH 4/5] Extend support for new serialization formats --- .../Resources/ResourceCommands.cs | 3 +- .../Resources/SerializedImageUtilities.cs | 33 ++++++++++- .../SerializedResourceElementNode.cs | 58 +++++++++++++++++-- 3 files changed, 85 insertions(+), 9 deletions(-) diff --git a/Extensions/dnSpy.AsmEditor/Resources/ResourceCommands.cs b/Extensions/dnSpy.AsmEditor/Resources/ResourceCommands.cs index 8bc9bf5ee4..430cd24bb6 100644 --- a/Extensions/dnSpy.AsmEditor/Resources/ResourceCommands.cs +++ b/Extensions/dnSpy.AsmEditor/Resources/ResourceCommands.cs @@ -2038,7 +2038,8 @@ static void Execute(Lazy undoCommandService, IAppService ap var opts = data.CreateResourceElementOptions(); string? error; try { - opts = new ResourceElementOptions(SerializedImageUtilities.Serialize(opts.Create())); + var format = ((BinaryResourceData)imgRsrcElNode.ResourceElement.ResourceData).Format; + opts = new ResourceElementOptions(SerializedImageUtilities.Serialize(opts.Create(), format)); error = imgRsrcElNode.CheckCanUpdateData(opts.Create()); } catch (Exception ex) { diff --git a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs index a1675056b2..ef778c4e7f 100644 --- a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs +++ b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs @@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License */ using System; +using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; @@ -150,7 +151,15 @@ public static bool CheckType(ModuleDef? module, string name, TypeRef expectedTyp /// /// Resource element /// - public static ResourceElement Serialize(ResourceElement resElem) { + public static ResourceElement Serialize(ResourceElement resElem) => Serialize(resElem, SerializationFormat.BinaryFormatter); + + /// + /// Serializes the image + /// + /// Resource element + /// Serialization format to use + /// + public static ResourceElement Serialize(ResourceElement resElem, SerializationFormat format) { var data = (byte[])((BuiltInResourceData)resElem.ResourceData).Data; bool isIcon = BitConverter.ToUInt32(data, 0) == 0x00010000; @@ -165,9 +174,29 @@ public static ResourceElement Serialize(ResourceElement resElem) { typeName = SystemDrawingBitmap.AssemblyQualifiedName; } + byte[] serializedData; + if (format == SerializationFormat.BinaryFormatter) { + serializedData = SerializationUtilities.Serialize(obj); + } + else if (format == SerializationFormat.TypeConverterByteArray) { + var converter = TypeDescriptor.GetConverter(obj.GetType()); + serializedData = (byte[])converter.ConvertTo(obj, typeof(byte[])); + } + else if (format == SerializationFormat.ActivatorStream) { + using (var stream = new MemoryStream()) { + if (obj is System.Drawing.Bitmap bitmap) + bitmap.Save(stream, bitmap.RawFormat); + else + ((System.Drawing.Icon)obj).Save(stream); + serializedData = stream.ToArray(); + } + } + else + throw new ArgumentOutOfRangeException(); + return new ResourceElement { Name = resElem.Name, - ResourceData = new BinaryResourceData(new UserResourceType(typeName, ResourceTypeCode.UserTypes), SerializationUtilities.Serialize(obj), SerializationFormat.BinaryFormatter), + ResourceData = new BinaryResourceData(new UserResourceType(typeName, ResourceTypeCode.UserTypes), serializedData, format), }; } } diff --git a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedResourceElementNode.cs b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedResourceElementNode.cs index 8560f692fb..50acb6a645 100644 --- a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedResourceElementNode.cs +++ b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedResourceElementNode.cs @@ -17,10 +17,13 @@ You should have received a copy of the GNU General Public License along with dnSpy. If not, see . */ +using System; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Runtime.Serialization.Formatters.Binary; +using System.Text; using System.Threading; using dnlib.DotNet.Resources; using dnSpy.Contracts.Images; @@ -91,16 +94,59 @@ public void Deserialize() { if (!CanDeserialize) return; - var serializedData = ((BinaryResourceData)ResourceElement.ResourceData).Data; - var formatter = new BinaryFormatter(); - try { + var binaryResourceData = ((BinaryResourceData)ResourceElement.ResourceData); + var serializedData = binaryResourceData.Data; + if (binaryResourceData.Format == SerializationFormat.BinaryFormatter) { + var formatter = new BinaryFormatter(); + try { #pragma warning disable SYSLIB0011 - deserializedData = formatter.Deserialize(new MemoryStream(serializedData)); + deserializedData = formatter.Deserialize(new MemoryStream(serializedData)); #pragma warning restore SYSLIB0011 + } + catch { + return; + } } - catch { - return; + else if (binaryResourceData.Format == SerializationFormat.TypeConverterByteArray) { + try { + var type = Type.GetType(binaryResourceData.TypeName); + if (type is null) + return; + var converter = TypeDescriptor.GetConverter(type); + if (converter is null) + return; + deserializedData = converter.ConvertFrom(serializedData); + } + catch { + return; + } } + else if (binaryResourceData.Format == SerializationFormat.TypeConverterString) { + try { + var type = Type.GetType(binaryResourceData.TypeName); + if (type is null) + return; + var converter = TypeDescriptor.GetConverter(type); + if (converter is null) + return; + deserializedData = converter.ConvertFromInvariantString(Encoding.UTF8.GetString(serializedData)); + } + catch { + return; + } + } + else if (binaryResourceData.Format == SerializationFormat.ActivatorStream) { + try { + var type = Type.GetType(binaryResourceData.TypeName); + if (type is null) + return; + deserializedData = Activator.CreateInstance(type, new MemoryStream(serializedData)); + } + catch { + return; + } + } + if (deserializedData is null) return; From 03b586d8ab008807417565a2468b728406a37f58 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Wed, 6 Sep 2023 21:14:17 +0200 Subject: [PATCH 5/5] Fixed nullability warnings --- .../TreeView/Resources/SerializedImageUtilities.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs index ef778c4e7f..a7ef3939c8 100644 --- a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs +++ b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/Resources/SerializedImageUtilities.cs @@ -180,7 +180,10 @@ public static ResourceElement Serialize(ResourceElement resElem, SerializationFo } else if (format == SerializationFormat.TypeConverterByteArray) { var converter = TypeDescriptor.GetConverter(obj.GetType()); - serializedData = (byte[])converter.ConvertTo(obj, typeof(byte[])); + var byteArr = converter.ConvertTo(obj, typeof(byte[])); + if (byteArr is not byte[] d) + throw new InvalidOperationException("Failed to serialize image"); + serializedData = d; } else if (format == SerializationFormat.ActivatorStream) { using (var stream = new MemoryStream()) { @@ -192,7 +195,7 @@ public static ResourceElement Serialize(ResourceElement resElem, SerializationFo } } else - throw new ArgumentOutOfRangeException(); + throw new ArgumentOutOfRangeException(nameof(format)); return new ResourceElement { Name = resElem.Name,