Move .NET resources read/writer code to dnlib
This commit is contained in:
parent
7a282f0962
commit
9e2a9016d2
|
@ -338,16 +338,6 @@
|
||||||
<Compile Include="renamer\TypeNames.cs" />
|
<Compile Include="renamer\TypeNames.cs" />
|
||||||
<Compile Include="renamer\TypeRenamerState.cs" />
|
<Compile Include="renamer\TypeRenamerState.cs" />
|
||||||
<Compile Include="renamer\VariableNameState.cs" />
|
<Compile Include="renamer\VariableNameState.cs" />
|
||||||
<Compile Include="resources\BuiltInResourceData.cs" />
|
|
||||||
<Compile Include="resources\IResourceData.cs" />
|
|
||||||
<Compile Include="resources\ResourceDataCreator.cs" />
|
|
||||||
<Compile Include="resources\ResourceElement.cs" />
|
|
||||||
<Compile Include="resources\ResourceElementSet.cs" />
|
|
||||||
<Compile Include="resources\ResourceReader.cs" />
|
|
||||||
<Compile Include="resources\ResourceTypeCode.cs" />
|
|
||||||
<Compile Include="resources\ResourceWriter.cs" />
|
|
||||||
<Compile Include="resources\UserResourceData.cs" />
|
|
||||||
<Compile Include="resources\UserResourceType.cs" />
|
|
||||||
<Compile Include="SharpZipLib\Checksums\Adler32.cs" />
|
<Compile Include="SharpZipLib\Checksums\Adler32.cs" />
|
||||||
<Compile Include="SharpZipLib\Checksums\IChecksum.cs" />
|
<Compile Include="SharpZipLib\Checksums\IChecksum.cs" />
|
||||||
<Compile Include="SharpZipLib\Main.cs" />
|
<Compile Include="SharpZipLib\Main.cs" />
|
||||||
|
|
|
@ -18,20 +18,33 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
using dnlib.IO;
|
using dnlib.IO;
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using de4dot.code.resources;
|
using dnlib.DotNet.Resources;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CodeVeil {
|
namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
class ResourceConverter {
|
class ResourceConverter {
|
||||||
ModuleDefMD module;
|
ModuleDefMD module;
|
||||||
ResourceInfo[] infos;
|
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) {
|
public ResourceConverter(ModuleDefMD module, ResourceInfo[] infos) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.dataCreator = new ResourceDataCreator(module);
|
this.dataCreator = new MyResourceDataCreator(module);
|
||||||
this.infos = infos;
|
this.infos = infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +78,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: // char[]
|
case 4: // char[]
|
||||||
resourceData = dataCreator.Create(reader.ReadChars(info.length));
|
resourceData = new CharArrayResourceData(dataCreator.CreateUserResourceType(CharArrayResourceData.ReflectionTypeName), reader.ReadChars(info.length));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5: // sbyte
|
case 5: // sbyte
|
||||||
|
@ -125,11 +138,11 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 19: // Icon
|
case 19: // Icon
|
||||||
resourceData = dataCreator.CreateIcon(reader.ReadBytes(info.length));
|
resourceData = new IconResourceData(dataCreator.CreateUserResourceType(IconResourceData.ReflectionTypeName), reader.ReadBytes(info.length));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 20: // Image
|
case 20: // Image
|
||||||
resourceData = dataCreator.CreateImage(reader.ReadBytes(info.length));
|
resourceData = new ImageResourceData(dataCreator.CreateUserResourceType(ImageResourceData.ReflectionTypeName), reader.ReadBytes(info.length));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 31: // binary
|
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";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ using System.Text;
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.code.resources;
|
using dnlib.DotNet.Resources;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.CodeWall {
|
namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
class AssemblyDecrypter {
|
class AssemblyDecrypter {
|
||||||
|
|
|
@ -23,7 +23,7 @@ using System.Text.RegularExpressions;
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using de4dot.code.renamer.asmmodules;
|
using de4dot.code.renamer.asmmodules;
|
||||||
using de4dot.code.resources;
|
using dnlib.DotNet.Resources;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.renamer {
|
namespace de4dot.code.renamer {
|
||||||
|
|
|
@ -26,7 +26,7 @@ using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
using dnlib.IO;
|
using dnlib.IO;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.code.resources;
|
using dnlib.DotNet.Resources;
|
||||||
|
|
||||||
namespace de4dot.code.renamer {
|
namespace de4dot.code.renamer {
|
||||||
public class ResourceKeysRenamer {
|
public class ResourceKeysRenamer {
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
|
|
||||||
namespace de4dot.code.resources {
|
|
||||||
public interface IResourceData {
|
|
||||||
ResourceTypeCode Code { get; }
|
|
||||||
void WriteData(BinaryWriter writer, IFormatter formatter);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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<string, UserResourceType> dict = new Dictionary<string, UserResourceType>(StringComparer.Ordinal);
|
|
||||||
readonly Dictionary<string, string> asmNameToAsmFullName = new Dictionary<string, string>(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<UserResourceType> GetSortedTypes() {
|
|
||||||
var list = new List<UserResourceType>(dict.Values);
|
|
||||||
list.Sort((a, b) => ((int)a.Code).CompareTo((int)b.Code));
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace de4dot.code.resources {
|
|
||||||
public class ResourceElementSet {
|
|
||||||
Dictionary<string, ResourceElement> dict = new Dictionary<string, ResourceElement>(StringComparer.Ordinal);
|
|
||||||
|
|
||||||
public int Count {
|
|
||||||
get { return dict.Count; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<ResourceElement> ResourceElements {
|
|
||||||
get { return dict.Values; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(ResourceElement elem) {
|
|
||||||
dict[elem.Name] = elem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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<UserResourceType>();
|
|
||||||
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<ResourceInfo>(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<UserResourceType> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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<UserResourceData, UserResourceType> dataToNewType = new Dictionary<UserResourceData, UserResourceType>();
|
|
||||||
|
|
||||||
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";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
2
dnlib
2
dnlib
|
@ -1 +1 @@
|
||||||
Subproject commit 8775c0055bccf44c2717c318e5c2358b06d5b989
|
Subproject commit 16f047464e4c1649a0d16a745f8797f35ea7e6fe
|
Loading…
Reference in New Issue
Block a user