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\TypeRenamerState.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\IChecksum.cs" />
|
||||
<Compile Include="SharpZipLib\Main.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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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