diff --git a/de4dot.code/de4dot.code.csproj b/de4dot.code/de4dot.code.csproj index ce7eb2d1..4e525b8f 100644 --- a/de4dot.code/de4dot.code.csproj +++ b/de4dot.code/de4dot.code.csproj @@ -338,16 +338,6 @@ - - - - - - - - - - diff --git a/de4dot.code/deobfuscators/CodeVeil/ResourceConverter.cs b/de4dot.code/deobfuscators/CodeVeil/ResourceConverter.cs index a5db07a5..e3e69fff 100644 --- a/de4dot.code/deobfuscators/CodeVeil/ResourceConverter.cs +++ b/de4dot.code/deobfuscators/CodeVeil/ResourceConverter.cs @@ -18,20 +18,33 @@ */ using System; +using System.Drawing; using System.IO; +using System.Runtime.Serialization; using dnlib.IO; using dnlib.DotNet; -using de4dot.code.resources; +using dnlib.DotNet.Resources; namespace de4dot.code.deobfuscators.CodeVeil { class ResourceConverter { ModuleDefMD module; ResourceInfo[] infos; - ResourceDataCreator dataCreator; + MyResourceDataCreator dataCreator; + + sealed class MyResourceDataCreator : ResourceDataCreator { + public MyResourceDataCreator(ModuleDef module) + : base(module) { + } + + protected override string GetAssemblyFullName(string simpleName) { + var asm = TheAssemblyResolver.Instance.Resolve(new AssemblyNameInfo(simpleName), Module); + return asm == null ? null : asm.FullName; + } + } public ResourceConverter(ModuleDefMD module, ResourceInfo[] infos) { this.module = module; - this.dataCreator = new ResourceDataCreator(module); + this.dataCreator = new MyResourceDataCreator(module); this.infos = infos; } @@ -65,7 +78,7 @@ namespace de4dot.code.deobfuscators.CodeVeil { break; case 4: // char[] - resourceData = dataCreator.Create(reader.ReadChars(info.length)); + resourceData = new CharArrayResourceData(dataCreator.CreateUserResourceType(CharArrayResourceData.ReflectionTypeName), reader.ReadChars(info.length)); break; case 5: // sbyte @@ -125,11 +138,11 @@ namespace de4dot.code.deobfuscators.CodeVeil { break; case 19: // Icon - resourceData = dataCreator.CreateIcon(reader.ReadBytes(info.length)); + resourceData = new IconResourceData(dataCreator.CreateUserResourceType(IconResourceData.ReflectionTypeName), reader.ReadBytes(info.length)); break; case 20: // Image - resourceData = dataCreator.CreateImage(reader.ReadBytes(info.length)); + resourceData = new ImageResourceData(dataCreator.CreateUserResourceType(ImageResourceData.ReflectionTypeName), reader.ReadBytes(info.length)); break; case 31: // binary @@ -147,4 +160,58 @@ namespace de4dot.code.deobfuscators.CodeVeil { }; } } + + class CharArrayResourceData : UserResourceData { + public static readonly string ReflectionTypeName = "System.Char[],mscorlib"; + char[] data; + + public CharArrayResourceData(UserResourceType type, char[] data) + : base(type) { + this.data = data; + } + + public override void WriteData(BinaryWriter writer, IFormatter formatter) { + formatter.Serialize(writer.BaseStream, data); + } + + public override string ToString() { + return string.Format("char[]: Length: {0}", data.Length); + } + } + + class IconResourceData : UserResourceData { + public static readonly string ReflectionTypeName = "System.Drawing.Icon,System.Drawing"; + Icon icon; + + public IconResourceData(UserResourceType type, byte[] data) + : base(type) { + icon = new Icon(new MemoryStream(data)); + } + + public override void WriteData(BinaryWriter writer, IFormatter formatter) { + formatter.Serialize(writer.BaseStream, icon); + } + + public override string ToString() { + return string.Format("Icon: {0}", icon); + } + } + + class ImageResourceData : UserResourceData { + public static readonly string ReflectionTypeName = "System.Drawing.Bitmap,System.Drawing"; + Bitmap bitmap; + + public ImageResourceData(UserResourceType type, byte[] data) + : base(type) { + bitmap = new Bitmap(Image.FromStream(new MemoryStream(data))); + } + + public override void WriteData(BinaryWriter writer, IFormatter formatter) { + formatter.Serialize(writer.BaseStream, bitmap); + } + + public override string ToString() { + return "Bitmap"; + } + } } diff --git a/de4dot.code/deobfuscators/CodeWall/AssemblyDecrypter.cs b/de4dot.code/deobfuscators/CodeWall/AssemblyDecrypter.cs index 72fac6c3..452cbb30 100644 --- a/de4dot.code/deobfuscators/CodeWall/AssemblyDecrypter.cs +++ b/de4dot.code/deobfuscators/CodeWall/AssemblyDecrypter.cs @@ -25,7 +25,7 @@ using System.Text; using dnlib.DotNet; using dnlib.DotNet.Emit; using de4dot.blocks; -using de4dot.code.resources; +using dnlib.DotNet.Resources; namespace de4dot.code.deobfuscators.CodeWall { class AssemblyDecrypter { diff --git a/de4dot.code/renamer/Renamer.cs b/de4dot.code/renamer/Renamer.cs index 0a72cb7c..07dc3503 100644 --- a/de4dot.code/renamer/Renamer.cs +++ b/de4dot.code/renamer/Renamer.cs @@ -23,7 +23,7 @@ using System.Text.RegularExpressions; using dnlib.DotNet; using dnlib.DotNet.Emit; using de4dot.code.renamer.asmmodules; -using de4dot.code.resources; +using dnlib.DotNet.Resources; using de4dot.blocks; namespace de4dot.code.renamer { diff --git a/de4dot.code/renamer/ResourceKeysRenamer.cs b/de4dot.code/renamer/ResourceKeysRenamer.cs index 75c95dc9..99bfde1a 100644 --- a/de4dot.code/renamer/ResourceKeysRenamer.cs +++ b/de4dot.code/renamer/ResourceKeysRenamer.cs @@ -26,7 +26,7 @@ using dnlib.DotNet; using dnlib.DotNet.Emit; using dnlib.IO; using de4dot.blocks; -using de4dot.code.resources; +using dnlib.DotNet.Resources; namespace de4dot.code.renamer { public class ResourceKeysRenamer { diff --git a/de4dot.code/resources/BuiltInResourceData.cs b/de4dot.code/resources/BuiltInResourceData.cs deleted file mode 100644 index 9ae41bbe..00000000 --- a/de4dot.code/resources/BuiltInResourceData.cs +++ /dev/null @@ -1,158 +0,0 @@ -/* - Copyright (C) 2011-2014 de4dot@gmail.com - - This file is part of de4dot. - - de4dot is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - de4dot is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with de4dot. If not, see . -*/ - -using System; -using System.IO; -using System.Runtime.Serialization; - -namespace de4dot.code.resources { - public class BuiltInResourceData : IResourceData { - readonly ResourceTypeCode code; - readonly object data; - - public object Data { - get { return data; } - } - - public ResourceTypeCode Code { - get { return code; } - } - - public BuiltInResourceData(ResourceTypeCode code, object data) { - this.code = code; - this.data = data; - } - - public void WriteData(BinaryWriter writer, IFormatter formatter) { - switch (code) { - case ResourceTypeCode.Null: - return; - - case ResourceTypeCode.String: - writer.Write((string)data); - break; - - case ResourceTypeCode.Boolean: - writer.Write((bool)data); - break; - - case ResourceTypeCode.Char: - writer.Write((ushort)(char)data); - break; - - case ResourceTypeCode.Byte: - writer.Write((byte)data); - break; - - case ResourceTypeCode.SByte: - writer.Write((sbyte)data); - break; - - case ResourceTypeCode.Int16: - writer.Write((short)data); - break; - - case ResourceTypeCode.UInt16: - writer.Write((ushort)data); - break; - - case ResourceTypeCode.Int32: - writer.Write((int)data); - break; - - case ResourceTypeCode.UInt32: - writer.Write((uint)data); - break; - - case ResourceTypeCode.Int64: - writer.Write((long)data); - break; - - case ResourceTypeCode.UInt64: - writer.Write((ulong)data); - break; - - case ResourceTypeCode.Single: - writer.Write((float)data); - break; - - case ResourceTypeCode.Double: - writer.Write((double)data); - break; - - case ResourceTypeCode.Decimal: - writer.Write((decimal)data); - break; - - case ResourceTypeCode.DateTime: - writer.Write(((DateTime)data).ToBinary()); - break; - - case ResourceTypeCode.TimeSpan: - writer.Write(((TimeSpan)data).Ticks); - break; - - case ResourceTypeCode.ByteArray: - case ResourceTypeCode.Stream: - var ary = (byte[])data; - writer.Write(ary.Length); - writer.Write(ary); - break; - - default: - throw new ApplicationException("Unknown resource type code"); - } - } - - public override string ToString() { - switch (code) { - case ResourceTypeCode.Null: - return "NULL"; - - case ResourceTypeCode.String: - case ResourceTypeCode.Boolean: - case ResourceTypeCode.Char: - case ResourceTypeCode.Byte: - case ResourceTypeCode.SByte: - case ResourceTypeCode.Int16: - case ResourceTypeCode.UInt16: - case ResourceTypeCode.Int32: - case ResourceTypeCode.UInt32: - case ResourceTypeCode.Int64: - case ResourceTypeCode.UInt64: - case ResourceTypeCode.Single: - case ResourceTypeCode.Double: - case ResourceTypeCode.Decimal: - case ResourceTypeCode.DateTime: - case ResourceTypeCode.TimeSpan: - return string.Format("{0}: '{1}'", code, data); - - case ResourceTypeCode.ByteArray: - case ResourceTypeCode.Stream: - var ary = data as byte[]; - if (ary != null) - return string.Format("{0}: Length: {1}", code, ary.Length); - return string.Format("{0}: '{1}'", code, data); - - default: - return string.Format("{0}: '{1}'", code, data); - } - } - } -} diff --git a/de4dot.code/resources/IResourceData.cs b/de4dot.code/resources/IResourceData.cs deleted file mode 100644 index 63374a2d..00000000 --- a/de4dot.code/resources/IResourceData.cs +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (C) 2011-2014 de4dot@gmail.com - - This file is part of de4dot. - - de4dot is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - de4dot is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with de4dot. If not, see . -*/ - -using System.IO; -using System.Runtime.Serialization; - -namespace de4dot.code.resources { - public interface IResourceData { - ResourceTypeCode Code { get; } - void WriteData(BinaryWriter writer, IFormatter formatter); - } -} diff --git a/de4dot.code/resources/ResourceDataCreator.cs b/de4dot.code/resources/ResourceDataCreator.cs deleted file mode 100644 index 53258145..00000000 --- a/de4dot.code/resources/ResourceDataCreator.cs +++ /dev/null @@ -1,235 +0,0 @@ -/* - Copyright (C) 2011-2014 de4dot@gmail.com - - This file is part of de4dot. - - de4dot is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - de4dot is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with de4dot. If not, see . -*/ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; -using dnlib.DotNet; - -namespace de4dot.code.resources { - public class ResourceDataCreator { - readonly ModuleDef module; - readonly ModuleDefMD moduleMD; - readonly Dictionary dict = new Dictionary(StringComparer.Ordinal); - readonly Dictionary asmNameToAsmFullName = new Dictionary(StringComparer.Ordinal); - - public ResourceDataCreator(ModuleDef module) { - this.module = module; - this.moduleMD = module as ModuleDefMD; - } - - public int Count { - get { return dict.Count; } - } - - public BuiltInResourceData CreateNull() { - return new BuiltInResourceData(ResourceTypeCode.Null, null); - } - - public BuiltInResourceData Create(string value) { - return new BuiltInResourceData(ResourceTypeCode.String, value); - } - - public BuiltInResourceData Create(bool value) { - return new BuiltInResourceData(ResourceTypeCode.Boolean, value); - } - - public BuiltInResourceData Create(char value) { - return new BuiltInResourceData(ResourceTypeCode.Char, value); - } - - public BuiltInResourceData Create(byte value) { - return new BuiltInResourceData(ResourceTypeCode.Byte, value); - } - - public BuiltInResourceData Create(sbyte value) { - return new BuiltInResourceData(ResourceTypeCode.SByte, value); - } - - public BuiltInResourceData Create(short value) { - return new BuiltInResourceData(ResourceTypeCode.Int16, value); - } - - public BuiltInResourceData Create(ushort value) { - return new BuiltInResourceData(ResourceTypeCode.UInt16, value); - } - - public BuiltInResourceData Create(int value) { - return new BuiltInResourceData(ResourceTypeCode.Int32, value); - } - - public BuiltInResourceData Create(uint value) { - return new BuiltInResourceData(ResourceTypeCode.UInt32, value); - } - - public BuiltInResourceData Create(long value) { - return new BuiltInResourceData(ResourceTypeCode.Int64, value); - } - - public BuiltInResourceData Create(ulong value) { - return new BuiltInResourceData(ResourceTypeCode.UInt64, value); - } - - public BuiltInResourceData Create(float value) { - return new BuiltInResourceData(ResourceTypeCode.Single, value); - } - - public BuiltInResourceData Create(double value) { - return new BuiltInResourceData(ResourceTypeCode.Double, value); - } - - public BuiltInResourceData Create(decimal value) { - return new BuiltInResourceData(ResourceTypeCode.Decimal, value); - } - - public BuiltInResourceData Create(DateTime value) { - return new BuiltInResourceData(ResourceTypeCode.DateTime, value); - } - - public BuiltInResourceData Create(TimeSpan value) { - return new BuiltInResourceData(ResourceTypeCode.TimeSpan, value); - } - - public BuiltInResourceData Create(byte[] value) { - return new BuiltInResourceData(ResourceTypeCode.ByteArray, value); - } - - public BuiltInResourceData CreateStream(byte[] value) { - return new BuiltInResourceData(ResourceTypeCode.Stream, value); - } - - public CharArrayResourceData Create(char[] value) { - return new CharArrayResourceData(CreateUserResourceType(CharArrayResourceData.ReflectionTypeName), value); - } - - public IconResourceData CreateIcon(byte[] value) { - return new IconResourceData(CreateUserResourceType(IconResourceData.ReflectionTypeName), value); - } - - public ImageResourceData CreateImage(byte[] value) { - return new ImageResourceData(CreateUserResourceType(ImageResourceData.ReflectionTypeName), value); - } - - public BinaryResourceData CreateSerialized(byte[] value) { - string assemblyName, typeName; - if (!GetSerializedTypeAndAssemblyName(value, out assemblyName, out typeName)) - throw new ApplicationException("Could not get serialized type name"); - string fullName = string.Format("{0},{1}", typeName, assemblyName); - return new BinaryResourceData(CreateUserResourceType(fullName), value); - } - - class MyBinder : SerializationBinder { - public class OkException : Exception { - public string AssemblyName { get; set; } - public string TypeName { get; set; } - } - - public override Type BindToType(string assemblyName, string typeName) { - throw new OkException { - AssemblyName = assemblyName, - TypeName = typeName, - }; - } - } - - bool GetSerializedTypeAndAssemblyName(byte[] value, out string assemblyName, out string typeName) { - try { - var formatter = new BinaryFormatter(); - formatter.Binder = new MyBinder(); - formatter.Deserialize(new MemoryStream(value)); - } - catch (MyBinder.OkException ex) { - assemblyName = ex.AssemblyName; - typeName = ex.TypeName; - return true; - } - catch { - } - - assemblyName = null; - typeName = null; - return false; - } - - public UserResourceType CreateUserResourceType(string fullName) { - UserResourceType type; - if (dict.TryGetValue(fullName, out type)) - return type; - - var newFullName = GetRealTypeFullName(fullName); - type = new UserResourceType(newFullName, ResourceTypeCode.UserTypes + dict.Count); - dict[fullName] = type; - dict[newFullName] = type; - return type; - } - - static void SplitTypeFullName(string fullName, out string typeName, out string assemblyName) { - int index = fullName.IndexOf(','); - if (index < 0) { - typeName = fullName; - assemblyName = null; - } - else { - typeName = fullName.Substring(0, index); - assemblyName = fullName.Substring(index + 1).Trim(); - } - } - - string GetRealTypeFullName(string fullName) { - var newFullName = fullName; - - string typeName, assemblyName; - SplitTypeFullName(fullName, out typeName, out assemblyName); - if (!string.IsNullOrEmpty(assemblyName)) - assemblyName = GetRealAssemblyName(assemblyName); - if (!string.IsNullOrEmpty(assemblyName)) - newFullName = string.Format("{0}, {1}", typeName, assemblyName); - - return newFullName; - } - - string GetRealAssemblyName(string assemblyName) { - string newAsmName; - if (!asmNameToAsmFullName.TryGetValue(assemblyName, out newAsmName)) - asmNameToAsmFullName[assemblyName] = newAsmName = TryGetRealAssemblyName(assemblyName); - return newAsmName; - } - - string TryGetRealAssemblyName(string assemblyName) { - var simpleName = Utils.GetAssemblySimpleName(assemblyName); - - if (moduleMD != null) { - var asmRef = moduleMD.GetAssemblyRef(simpleName); - if (asmRef != null) - return asmRef.FullName; - } - - var asm = TheAssemblyResolver.Instance.Resolve(new AssemblyNameInfo(simpleName), module); - return asm == null ? null : asm.FullName; - } - - public List GetSortedTypes() { - var list = new List(dict.Values); - list.Sort((a, b) => ((int)a.Code).CompareTo((int)b.Code)); - return list; - } - } -} diff --git a/de4dot.code/resources/ResourceElement.cs b/de4dot.code/resources/ResourceElement.cs deleted file mode 100644 index bb8c85eb..00000000 --- a/de4dot.code/resources/ResourceElement.cs +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 2011-2014 de4dot@gmail.com - - This file is part of de4dot. - - de4dot is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - de4dot is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with de4dot. If not, see . -*/ - -namespace de4dot.code.resources { - public class ResourceElement { - public string Name { get; set; } - public IResourceData ResourceData { get; set; } - - public override string ToString() { - return string.Format("N: {0}, V: {1}", Name, ResourceData); - } - } -} diff --git a/de4dot.code/resources/ResourceElementSet.cs b/de4dot.code/resources/ResourceElementSet.cs deleted file mode 100644 index 28c9649c..00000000 --- a/de4dot.code/resources/ResourceElementSet.cs +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2011-2014 de4dot@gmail.com - - This file is part of de4dot. - - de4dot is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - de4dot is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with de4dot. If not, see . -*/ - -using System; -using System.Collections.Generic; - -namespace de4dot.code.resources { - public class ResourceElementSet { - Dictionary dict = new Dictionary(StringComparer.Ordinal); - - public int Count { - get { return dict.Count; } - } - - public IEnumerable ResourceElements { - get { return dict.Values; } - } - - public void Add(ResourceElement elem) { - dict[elem.Name] = elem; - } - } -} diff --git a/de4dot.code/resources/ResourceReader.cs b/de4dot.code/resources/ResourceReader.cs deleted file mode 100644 index 7e545800..00000000 --- a/de4dot.code/resources/ResourceReader.cs +++ /dev/null @@ -1,180 +0,0 @@ -/* - Copyright (C) 2011-2014 de4dot@gmail.com - - This file is part of de4dot. - - de4dot is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - de4dot is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with de4dot. If not, see . -*/ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Text.RegularExpressions; -using dnlib.DotNet; -using dnlib.IO; - -namespace de4dot.code.resources { - [Serializable] - public class ResourceReaderException : Exception { - public ResourceReaderException(string msg) - : base(msg) { - } - } - - public struct ResourceReader { - IBinaryReader reader; - ResourceDataCreator resourceDataCreator; - - ResourceReader(ModuleDef module, IBinaryReader reader) { - this.reader = reader; - this.resourceDataCreator = new ResourceDataCreator(module); - } - - public static ResourceElementSet Read(ModuleDef module, IBinaryReader reader) { - return new ResourceReader(module, reader).Read(); - } - - ResourceElementSet Read() { - ResourceElementSet resources = new ResourceElementSet(); - - uint sig = reader.ReadUInt32(); - if (sig != 0xBEEFCACE) - throw new ResourceReaderException(string.Format("Invalid resource sig: {0:X8}", sig)); - if (!CheckReaders()) - throw new ResourceReaderException("Invalid resource reader"); - int version = reader.ReadInt32(); - if (version != 2) - throw new ResourceReaderException(string.Format("Invalid resource version: {0}", version)); - int numResources = reader.ReadInt32(); - if (numResources < 0) - throw new ResourceReaderException(string.Format("Invalid number of resources: {0}", numResources)); - int numUserTypes = reader.ReadInt32(); - if (numUserTypes < 0) - throw new ResourceReaderException(string.Format("Invalid number of user types: {0}", numUserTypes)); - - var userTypes = new List(); - for (int i = 0; i < numUserTypes; i++) - userTypes.Add(new UserResourceType(reader.ReadString(), ResourceTypeCode.UserTypes + i)); - reader.Position = (reader.Position + 7) & ~7; - - var hashes = new int[numResources]; - for (int i = 0; i < numResources; i++) - hashes[i] = reader.ReadInt32(); - var offsets = new int[numResources]; - for (int i = 0; i < numResources; i++) - offsets[i] = reader.ReadInt32(); - - long baseOffset = reader.Position; - long dataBaseOffset = reader.ReadInt32(); - long nameBaseOffset = reader.Position; - long end = reader.Length; - - var infos = new List(numResources); - - for (int i = 0; i < numResources; i++) { - reader.Position = nameBaseOffset + offsets[i]; - var name = reader.ReadString(Encoding.Unicode); - long offset = dataBaseOffset + reader.ReadInt32(); - infos.Add(new ResourceInfo(name, offset)); - } - - infos.Sort((a, b) => a.offset.CompareTo(b.offset)); - for (int i = 0; i < infos.Count; i++) { - var info = infos[i]; - var element = new ResourceElement(); - element.Name = info.name; - reader.Position = info.offset; - long nextDataOffset = i == infos.Count - 1 ? end : infos[i + 1].offset; - int size = (int)(nextDataOffset - info.offset); - element.ResourceData = ReadResourceData(userTypes, size); - - resources.Add(element); - } - - return resources; - } - - class ResourceInfo { - public string name; - public long offset; - public ResourceInfo(string name, long offset) { - this.name = name; - this.offset = offset; - } - public override string ToString() { - return string.Format("{0:X8} - {1}", offset, name); - } - } - - IResourceData ReadResourceData(List userTypes, int size) { - uint code = ReadUInt32(reader); - switch ((ResourceTypeCode)code) { - case ResourceTypeCode.Null: return resourceDataCreator.CreateNull(); - case ResourceTypeCode.String: return resourceDataCreator.Create(reader.ReadString()); - case ResourceTypeCode.Boolean: return resourceDataCreator.Create(reader.ReadBoolean()); - case ResourceTypeCode.Char: return resourceDataCreator.Create((char)reader.ReadUInt16()); - case ResourceTypeCode.Byte: return resourceDataCreator.Create(reader.ReadByte()); - case ResourceTypeCode.SByte: return resourceDataCreator.Create(reader.ReadSByte()); - case ResourceTypeCode.Int16: return resourceDataCreator.Create(reader.ReadInt16()); - case ResourceTypeCode.UInt16: return resourceDataCreator.Create(reader.ReadUInt16()); - case ResourceTypeCode.Int32: return resourceDataCreator.Create(reader.ReadInt32()); - case ResourceTypeCode.UInt32: return resourceDataCreator.Create(reader.ReadUInt32()); - case ResourceTypeCode.Int64: return resourceDataCreator.Create(reader.ReadInt64()); - case ResourceTypeCode.UInt64: return resourceDataCreator.Create(reader.ReadUInt64()); - case ResourceTypeCode.Single: return resourceDataCreator.Create(reader.ReadSingle()); - case ResourceTypeCode.Double: return resourceDataCreator.Create(reader.ReadDouble()); - case ResourceTypeCode.Decimal: return resourceDataCreator.Create(reader.ReadDecimal()); - case ResourceTypeCode.DateTime: return resourceDataCreator.Create(new DateTime(reader.ReadInt64())); - case ResourceTypeCode.TimeSpan: return resourceDataCreator.Create(new TimeSpan(reader.ReadInt64())); - case ResourceTypeCode.ByteArray: return resourceDataCreator.Create(reader.ReadBytes(reader.ReadInt32())); - case ResourceTypeCode.Stream: return resourceDataCreator.CreateStream(reader.ReadBytes(reader.ReadInt32())); - default: - int userTypeIndex = (int)(code - (uint)ResourceTypeCode.UserTypes); - if (userTypeIndex < 0 || userTypeIndex >= userTypes.Count) - throw new ResourceReaderException(string.Format("Invalid resource data code: {0}", code)); - return resourceDataCreator.CreateSerialized(reader.ReadBytes(size)); - } - } - - static uint ReadUInt32(IBinaryReader reader) { - try { - return reader.Read7BitEncodedUInt32(); - } - catch { - throw new ResourceReaderException("Invalid encoded int32"); - } - } - - bool CheckReaders() { - bool validReader = false; - - int numReaders = reader.ReadInt32(); - if (numReaders < 0) - throw new ResourceReaderException(string.Format("Invalid number of readers: {0}", numReaders)); - int readersSize = reader.ReadInt32(); - if (readersSize < 0) - throw new ResourceReaderException(string.Format("Invalid readers size: {0:X8}", readersSize)); - - for (int i = 0; i < numReaders; i++) { - var resourceReaderFullName = reader.ReadString(); - var resourceSetFullName = reader.ReadString(); - if (Regex.IsMatch(resourceReaderFullName, @"^System\.Resources\.ResourceReader,\s*mscorlib,")) - validReader = true; - } - - return validReader; - } - } -} diff --git a/de4dot.code/resources/ResourceTypeCode.cs b/de4dot.code/resources/ResourceTypeCode.cs deleted file mode 100644 index d1baf198..00000000 --- a/de4dot.code/resources/ResourceTypeCode.cs +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 2011-2014 de4dot@gmail.com - - This file is part of de4dot. - - de4dot is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - de4dot is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with de4dot. If not, see . -*/ - -namespace de4dot.code.resources { - public enum ResourceTypeCode { - Null, - String, - Boolean, - Char, - Byte, - SByte, - Int16, - UInt16, - Int32, - UInt32, - Int64, - UInt64, - Single, - Double, - Decimal, - DateTime, - TimeSpan, - ByteArray = 0x20, - Stream = 0x21, - UserTypes = 0x40, - } -} diff --git a/de4dot.code/resources/ResourceWriter.cs b/de4dot.code/resources/ResourceWriter.cs deleted file mode 100644 index 803158e9..00000000 --- a/de4dot.code/resources/ResourceWriter.cs +++ /dev/null @@ -1,148 +0,0 @@ -/* - Copyright (C) 2011-2014 de4dot@gmail.com - - This file is part of de4dot. - - de4dot is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - de4dot is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with de4dot. If not, see . -*/ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; -using System.Text; -using dnlib.DotNet; - -namespace de4dot.code.resources { - public class ResourceWriter { - ModuleDefMD module; - BinaryWriter writer; - ResourceElementSet resources; - ResourceDataCreator typeCreator; - Dictionary dataToNewType = new Dictionary(); - - ResourceWriter(ModuleDefMD module, Stream stream, ResourceElementSet resources) { - this.module = module; - this.typeCreator = new ResourceDataCreator(module); - this.writer = new BinaryWriter(stream); - this.resources = resources; - } - - public static void Write(ModuleDefMD module, Stream stream, ResourceElementSet resources) { - new ResourceWriter(module, stream, resources).Write(); - } - - void Write() { - InitializeUserTypes(); - - writer.Write(0xBEEFCACE); - writer.Write(1); - WriteReaderType(); - writer.Write(2); - writer.Write(resources.Count); - writer.Write(typeCreator.Count); - foreach (var userType in typeCreator.GetSortedTypes()) - writer.Write(userType.Name); - int extraBytes = 8 - ((int)writer.BaseStream.Position & 7); - if (extraBytes != 8) { - for (int i = 0; i < extraBytes; i++) - writer.Write((byte)'X'); - } - - var nameOffsetStream = new MemoryStream(); - var nameOffsetWriter = new BinaryWriter(nameOffsetStream, Encoding.Unicode); - var dataStream = new MemoryStream(); - var dataWriter = new BinaryWriter(dataStream); - var hashes = new int[resources.Count]; - var offsets = new int[resources.Count]; - var formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.File | StreamingContextStates.Persistence)); - int index = 0; - foreach (var info in resources.ResourceElements) { - offsets[index] = (int)nameOffsetWriter.BaseStream.Position; - hashes[index] = (int)Hash(info.Name); - index++; - nameOffsetWriter.Write(info.Name); - nameOffsetWriter.Write((int)dataWriter.BaseStream.Position); - WriteData(dataWriter, info, formatter); - } - - Array.Sort(hashes, offsets); - foreach (var hash in hashes) - writer.Write(hash); - foreach (var offset in offsets) - writer.Write(offset); - writer.Write((int)writer.BaseStream.Position + (int)nameOffsetStream.Length + 4); - writer.Write(nameOffsetStream.ToArray()); - writer.Write(dataStream.ToArray()); - } - - void WriteData(BinaryWriter writer, ResourceElement info, IFormatter formatter) { - var code = GetResourceType(info.ResourceData); - WriteUInt32(writer, (uint)code); - info.ResourceData.WriteData(writer, formatter); - } - - static void WriteUInt32(BinaryWriter writer, uint value) { - while (value >= 0x80) { - writer.Write((byte)(value | 0x80)); - value >>= 7; - } - writer.Write((byte)value); - } - - ResourceTypeCode GetResourceType(IResourceData data) { - if (data is BuiltInResourceData) - return data.Code; - - var userData = (UserResourceData)data; - return dataToNewType[userData].Code; - } - - static uint Hash(string key) { - uint val = 0x1505; - foreach (var c in key) - val = ((val << 5) + val) ^ (uint)c; - return val; - } - - void InitializeUserTypes() { - foreach (var resource in resources.ResourceElements) { - var data = resource.ResourceData as UserResourceData; - if (data == null) - continue; - var newType = typeCreator.CreateUserResourceType(data.TypeName); - dataToNewType[data] = newType; - } - } - - void WriteReaderType() { - var memStream = new MemoryStream(); - var headerWriter = new BinaryWriter(memStream); - var mscorlibFullName = GetMscorlibFullname(); - headerWriter.Write("System.Resources.ResourceReader, " + mscorlibFullName); - headerWriter.Write("System.Resources.RuntimeResourceSet"); - writer.Write((int)memStream.Position); - writer.Write(memStream.ToArray()); - } - - string GetMscorlibFullname() { - var mscorlibRef = module.GetAssemblyRef("mscorlib"); - if (mscorlibRef != null) - return mscorlibRef.FullName; - - return "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; - } - } -} diff --git a/de4dot.code/resources/UserResourceData.cs b/de4dot.code/resources/UserResourceData.cs deleted file mode 100644 index 8e303e02..00000000 --- a/de4dot.code/resources/UserResourceData.cs +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright (C) 2011-2014 de4dot@gmail.com - - This file is part of de4dot. - - de4dot is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - de4dot is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with de4dot. If not, see . -*/ - -using System.Drawing; -using System.IO; -using System.Runtime.Serialization; - -namespace de4dot.code.resources { - public abstract class UserResourceData : IResourceData { - readonly UserResourceType type; - - public string TypeName { - get { return type.Name; } - } - - public ResourceTypeCode Code { - get { return type.Code; } - } - - public UserResourceData(UserResourceType type) { - this.type = type; - } - - public abstract void WriteData(BinaryWriter writer, IFormatter formatter); - } - - public class CharArrayResourceData : UserResourceData { - public static readonly string ReflectionTypeName = "System.Char[],mscorlib"; - char[] data; - - public CharArrayResourceData(UserResourceType type, char[] data) - : base(type) { - this.data = data; - } - - public override void WriteData(BinaryWriter writer, IFormatter formatter) { - formatter.Serialize(writer.BaseStream, data); - } - - public override string ToString() { - return string.Format("char[]: Length: {0}", data.Length); - } - } - - public class IconResourceData : UserResourceData { - public static readonly string ReflectionTypeName = "System.Drawing.Icon,System.Drawing"; - Icon icon; - - public IconResourceData(UserResourceType type, byte[] data) - : base(type) { - icon = new Icon(new MemoryStream(data)); - } - - public override void WriteData(BinaryWriter writer, IFormatter formatter) { - formatter.Serialize(writer.BaseStream, icon); - } - - public override string ToString() { - return string.Format("Icon: {0}", icon); - } - } - - public class ImageResourceData : UserResourceData { - public static readonly string ReflectionTypeName = "System.Drawing.Bitmap,System.Drawing"; - Bitmap bitmap; - - public ImageResourceData(UserResourceType type, byte[] data) - : base(type) { - bitmap = new Bitmap(Image.FromStream(new MemoryStream(data))); - } - - public override void WriteData(BinaryWriter writer, IFormatter formatter) { - formatter.Serialize(writer.BaseStream, bitmap); - } - - public override string ToString() { - return "Bitmap"; - } - } - - public class BinaryResourceData : UserResourceData { - byte[] data; - - public BinaryResourceData(UserResourceType type, byte[] data) - : base(type) { - this.data = data; - } - - public override void WriteData(BinaryWriter writer, IFormatter formatter) { - writer.Write(data); - } - - public override string ToString() { - return string.Format("Binary: Length: {0}", data.Length); - } - } -} diff --git a/de4dot.code/resources/UserResourceType.cs b/de4dot.code/resources/UserResourceType.cs deleted file mode 100644 index 0bc69ccf..00000000 --- a/de4dot.code/resources/UserResourceType.cs +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (C) 2011-2014 de4dot@gmail.com - - This file is part of de4dot. - - de4dot is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - de4dot is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with de4dot. If not, see . -*/ - -namespace de4dot.code.resources { - public class UserResourceType { - readonly string name; - readonly ResourceTypeCode code; - - public string Name { - get { return name; } - } - - public ResourceTypeCode Code { - get { return code; } - } - - public UserResourceType(string name, ResourceTypeCode code) { - this.name = name; - this.code = code; - } - - public override string ToString() { - return string.Format("{0:X2} {1}", (int)code, name); - } - } -} diff --git a/dnlib b/dnlib index 8775c005..16f04746 160000 --- a/dnlib +++ b/dnlib @@ -1 +1 @@ -Subproject commit 8775c0055bccf44c2717c318e5c2358b06d5b989 +Subproject commit 16f047464e4c1649a0d16a745f8797f35ea7e6fe