Port more code, including renamer

This commit is contained in:
de4dot 2012-11-04 00:50:24 +01:00
parent db6875859a
commit 7ba4905cc7
23 changed files with 367 additions and 353 deletions

View File

@ -19,16 +19,9 @@
using System;
using System.Collections.Generic;
#if PORT
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
#endif
//TODO: Remove these
using DN = dot10.DotNet;
using DNE = dot10.DotNet.Emit;
using DNM = dot10.DotNet.MD;
using dot10.DotNet;
using dot10.DotNet.Emit;
using dot10.DotNet.MD;
namespace de4dot.blocks {
public enum FrameworkType {
@ -158,31 +151,31 @@ namespace de4dot.blocks {
public static readonly TypeCaches typeCaches = new TypeCaches();
#endif
public static DN.TypeDef getModuleType(DN.ModuleDef module) {
public static TypeDef getModuleType(ModuleDef module) {
return module.GlobalType;
}
public static DN.MethodDef getModuleTypeCctor(DN.ModuleDef module) {
public static MethodDef getModuleTypeCctor(ModuleDef module) {
return module.GlobalType.FindClassConstructor();
}
public static bool isEmpty(DN.MethodDef method) {
public static bool isEmpty(MethodDef method) {
if (method.CilBody == null)
return false;
foreach (var instr in method.CilBody.Instructions) {
var code = instr.OpCode.Code;
if (code != DNE.Code.Nop && code != DNE.Code.Ret)
if (code != Code.Nop && code != Code.Ret)
return false;
}
return true;
}
public static bool isEmptyObfuscated(DN.MethodDef method) {
public static bool isEmptyObfuscated(MethodDef method) {
if (method.CilBody == null)
return false;
int index = 0;
var instr = getInstruction(method.CilBody.Instructions, ref index);
if (instr == null || instr.OpCode.Code != DNE.Code.Ret)
if (instr == null || instr.OpCode.Code != Code.Ret)
return false;
return true;
@ -223,14 +216,14 @@ namespace de4dot.blocks {
}
#endif
public static bool isDelegate(DN.IType type) {
public static bool isDelegate(IType type) {
if (type == null)
return false;
var fn = type.FullName;
return fn == "System.Delegate" || fn == "System.MulticastDelegate";
}
public static bool derivesFromDelegate(DN.TypeDef type) {
public static bool derivesFromDelegate(TypeDef type) {
return type != null && isDelegate(type.BaseType);
}
@ -244,10 +237,16 @@ namespace de4dot.blocks {
}
#endif
public static bool isMethod(DN.IMethod method, string returnType, string parameters) {
public static bool isMethod(IMethod method, string returnType, string parameters) {
return method != null && method.FullName == returnType + " " + method.DeclaringType.FullName + "::" + method.Name + parameters;
}
public static string getDllName(string dll) {
if (dll.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
return dll.Substring(0, dll.Length - 4);
return dll;
}
#if PORT
public static bool hasPinvokeMethod(TypeDefinition type, string methodName) {
return getPInvokeMethod(type, methodName) != null;
@ -281,12 +280,6 @@ namespace de4dot.blocks {
return getDllName(dll).Equals(getDllName(method.PInvokeInfo.Module.Name), StringComparison.OrdinalIgnoreCase);
}
public static string getDllName(string dll) {
if (dll.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
return dll.Substring(0, dll.Length - 4);
return dll;
}
public static MethodDefinition getMethod(TypeDefinition type, string name) {
if (type == null)
return null;
@ -338,37 +331,37 @@ namespace de4dot.blocks {
}
#endif
public static DN.MethodDef getMethod2(DN.ModuleDef module, DN.IMethod method) {
public static MethodDef getMethod2(ModuleDef module, IMethod method) {
if (method == null)
return null;
return getMethod(module, method, method.DeclaringType.ScopeType);
}
static DN.TypeDef getType(DN.ModuleDef module, DN.ITypeDefOrRef type) {
var td = type as DN.TypeDef;
static TypeDef getType(ModuleDef module, ITypeDefOrRef type) {
var td = type as TypeDef;
if (td != null)
return td;
var tr = type as DN.TypeRef;
var tr = type as TypeRef;
if (tr != null)
return tr.Resolve();
return null;
}
static DN.MethodDef getMethod(DN.ModuleDef module, DN.IMethod method, DN.ITypeDefOrRef declaringType) {
static MethodDef getMethod(ModuleDef module, IMethod method, ITypeDefOrRef declaringType) {
if (method == null)
return null;
if (method is DN.MethodDef)
return (DN.MethodDef)method;
if (method is MethodDef)
return (MethodDef)method;
return getMethod(getType(module, declaringType), method);
}
public static DN.MethodDef getMethod(DN.TypeDef type, DN.IMethod methodRef) {
public static MethodDef getMethod(TypeDef type, IMethod methodRef) {
if (type == null || methodRef == null)
return null;
if (methodRef is DN.MethodDef)
return (DN.MethodDef)methodRef;
if (methodRef is MethodDef)
return (MethodDef)methodRef;
return type.FindMethod(methodRef.Name, methodRef.MethodSig);
}
@ -472,22 +465,22 @@ namespace de4dot.blocks {
}
#endif
public static IList<string> getCodeStrings(DN.MethodDef method) {
public static IList<string> getCodeStrings(MethodDef method) {
var strings = new List<string>();
if (method != null && method.CilBody != null) {
foreach (var instr in method.CilBody.Instructions) {
if (instr.OpCode.Code == DNE.Code.Ldstr)
if (instr.OpCode.Code == Code.Ldstr)
strings.Add((string)instr.Operand);
}
}
return strings;
}
public static DN.Resource getResource(DN.ModuleDef module, string name) {
public static Resource getResource(ModuleDef module, string name) {
return getResource(module, new List<string> { name });
}
public static DN.Resource getResource(DN.ModuleDef module, IEnumerable<string> strings) {
public static Resource getResource(ModuleDef module, IEnumerable<string> strings) {
if (!module.HasResources)
return null;
@ -496,9 +489,9 @@ namespace de4dot.blocks {
var resourceName = removeFromNullChar(tmp);
if (resourceName == null)
continue;
var name = new DNM.UTF8String(resourceName);
var name = new UTF8String(resourceName);
foreach (var resource in resources) {
if (DNM.UTF8String.Equals(resource.Name, name))
if (UTF8String.Equals(resource.Name, name))
return resource;
}
}
@ -535,7 +528,7 @@ namespace de4dot.blocks {
#endif
// Copies most things but not everything
public static DN.MethodDef clone(DN.MethodDef method) {
public static MethodDef clone(MethodDef method) {
return null; //TODO:
}
@ -598,17 +591,17 @@ namespace de4dot.blocks {
}
#endif
public static void copyBody(DN.MethodDef method, out IList<DNE.Instruction> instructions, out IList<DNE.ExceptionHandler> exceptionHandlers) {
public static void copyBody(MethodDef method, out IList<Instruction> instructions, out IList<ExceptionHandler> exceptionHandlers) {
if (method == null || !method.HasCilBody) {
instructions = new List<DNE.Instruction>();
exceptionHandlers = new List<DNE.ExceptionHandler>();
instructions = new List<Instruction>();
exceptionHandlers = new List<ExceptionHandler>();
return;
}
var oldInstrs = method.CilBody.Instructions;
var oldExHandlers = method.CilBody.ExceptionHandlers;
instructions = new List<DNE.Instruction>(oldInstrs.Count);
exceptionHandlers = new List<DNE.ExceptionHandler>(oldExHandlers.Count);
instructions = new List<Instruction>(oldInstrs.Count);
exceptionHandlers = new List<ExceptionHandler>(oldExHandlers.Count);
var oldToIndex = Utils.createObjectToIndexDictionary(oldInstrs);
foreach (var oldInstr in oldInstrs)
@ -616,11 +609,11 @@ namespace de4dot.blocks {
foreach (var newInstr in instructions) {
var operand = newInstr.Operand;
if (operand is DNE.Instruction)
newInstr.Operand = instructions[oldToIndex[(DNE.Instruction)operand]];
else if (operand is IList<DNE.Instruction>) {
var oldArray = (IList<DNE.Instruction>)operand;
var newArray = new DNE.Instruction[oldArray.Count];
if (operand is Instruction)
newInstr.Operand = instructions[oldToIndex[(Instruction)operand]];
else if (operand is IList<Instruction>) {
var oldArray = (IList<Instruction>)operand;
var newArray = new Instruction[oldArray.Count];
for (int i = 0; i < oldArray.Count; i++)
newArray[i] = instructions[oldToIndex[oldArray[i]]];
newInstr.Operand = newArray;
@ -628,7 +621,7 @@ namespace de4dot.blocks {
}
foreach (var oldEx in oldExHandlers) {
var newEx = new DNE.ExceptionHandler(oldEx.HandlerType) {
var newEx = new ExceptionHandler(oldEx.HandlerType) {
TryStart = getInstruction(instructions, oldToIndex, oldEx.TryStart),
TryEnd = getInstruction(instructions, oldToIndex, oldEx.TryEnd),
FilterStart = getInstruction(instructions, oldToIndex, oldEx.FilterStart),
@ -640,7 +633,7 @@ namespace de4dot.blocks {
}
}
static DNE.Instruction getInstruction(IList<DNE.Instruction> instructions, IDictionary<DNE.Instruction, int> instructionToIndex, DNE.Instruction instruction) {
static Instruction getInstruction(IList<Instruction> instructions, IDictionary<Instruction, int> instructionToIndex, Instruction instruction) {
if (instruction == null)
return null;
return instructions[instructionToIndex[instruction]];
@ -663,7 +656,7 @@ namespace de4dot.blocks {
}
#endif
public static void restoreBody(DN.MethodDef method, IEnumerable<DNE.Instruction> instructions, IEnumerable<DNE.ExceptionHandler> exceptionHandlers) {
public static void restoreBody(MethodDef method, IEnumerable<Instruction> instructions, IEnumerable<ExceptionHandler> exceptionHandlers) {
if (method == null || method.CilBody == null)
return;
@ -788,11 +781,10 @@ namespace de4dot.blocks {
}
#endif
public static bool hasReturnValue(DN.IMethod method) {
if (method == null || method.MethodSig == null)
public static bool hasReturnValue(IMethod method) {
if (method == null || method.MethodSig == null || method.MethodSig.RetType == null)
return false;
//TODO: Also remove modifiers from RetType before comparing etype
return method.MethodSig.RetType.ElementType != DN.ElementType.Void;
return method.MethodSig.RetType.RemovePinnedAndModifiers().ElementType != ElementType.Void;
}
#if PORT
@ -1008,13 +1000,13 @@ namespace de4dot.blocks {
}
#endif
public static DN.Parameter getParameter(IList<DN.Parameter> parameters, int index) {
public static Parameter getParameter(IList<Parameter> parameters, int index) {
if (0 <= index && index < parameters.Count)
return parameters[index];
return null;
}
public static DN.TypeSig getArg(IList<DN.TypeSig> args, int index) {
public static TypeSig getArg(IList<TypeSig> args, int index) {
if (0 <= index && index < args.Count)
return args[index];
return null;
@ -1031,11 +1023,11 @@ namespace de4dot.blocks {
}
#endif
public static List<DN.TypeSig> getArgs(DN.IMethod method) {
public static List<TypeSig> getArgs(IMethod method) {
var sig = method.MethodSig;
var args = new List<DN.TypeSig>(sig.Params.Count + 1);
var args = new List<TypeSig>(sig.Params.Count + 1);
if (sig.ImplicitThis)
args.Add(DN.Extensions.ToTypeSig(method.DeclaringType));
args.Add(method.DeclaringType.ToTypeSig());
foreach (var arg in sig.Params)
args.Add(arg);
return args;
@ -1064,7 +1056,7 @@ namespace de4dot.blocks {
}
#endif
public static int getArgsCount(DN.IMethod method) {
public static int getArgsCount(IMethod method) {
var sig = method.MethodSig;
if (sig == null)
return 0;
@ -1117,18 +1109,18 @@ namespace de4dot.blocks {
}
#endif
public static DNE.Instruction getInstruction(IList<DNE.Instruction> instructions, ref int index) {
public static Instruction getInstruction(IList<Instruction> instructions, ref int index) {
for (int i = 0; i < 10; i++) {
if (index < 0 || index >= instructions.Count)
return null;
var instr = instructions[index++];
if (instr.OpCode.Code == DNE.Code.Nop)
if (instr.OpCode.Code == Code.Nop)
continue;
if (instr.OpCode.OpCodeType == DNE.OpCodeType.Prefix)
if (instr.OpCode.OpCodeType == OpCodeType.Prefix)
continue;
if (instr == null || (instr.OpCode.Code != DNE.Code.Br && instr.OpCode.Code != DNE.Code.Br_S))
if (instr == null || (instr.OpCode.Code != Code.Br && instr.OpCode.Code != Code.Br_S))
return instr;
instr = instr.Operand as DNE.Instruction;
instr = instr.Operand as Instruction;
if (instr == null)
return null;
index = instructions.IndexOf(instr);
@ -1207,12 +1199,12 @@ namespace de4dot.blocks {
}
#endif
public static DN.TypeDefOrRefSig findOrCreateTypeReference(DN.ModuleDef module, DN.AssemblyRef asmRef, string ns, string name, bool isValueType) {
var typeRef = module.UpdateRowId(new DN.TypeRefUser(module, ns, name, asmRef));
public static TypeDefOrRefSig findOrCreateTypeReference(ModuleDef module, AssemblyRef asmRef, string ns, string name, bool isValueType) {
var typeRef = module.UpdateRowId(new TypeRefUser(module, ns, name, asmRef));
if (isValueType)
return new DN.ValueTypeSig(typeRef);
return new ValueTypeSig(typeRef);
else
return new DN.ClassSig(typeRef);
return new ClassSig(typeRef);
}
#if PORT

View File

@ -20,9 +20,7 @@
using System.Collections.Generic;
using de4dot.code.deobfuscators;
using dot10.DotNet;
#if PORT
using de4dot.code.renamer;
#endif
namespace de4dot.code {
public interface IObfuscatedFile {
@ -31,9 +29,7 @@ namespace de4dot.code {
IDeobfuscatorContext DeobfuscatorContext { get; set; }
string Filename { get; }
string NewFilename { get; }
#if PORT
INameChecker NameChecker { get; }
#endif
bool RenameResourcesInCode { get; }
bool RemoveNamespaceWithOneType { get; }
bool RenameResourceKeys { get; }

View File

@ -29,9 +29,7 @@ using de4dot.code.deobfuscators;
using de4dot.blocks;
using de4dot.blocks.cflow;
using de4dot.code.AssemblyClient;
#if PORT
using de4dot.code.renamer;
#endif
namespace de4dot.code {
public class ObfuscatedFile : IObfuscatedFile, IDeobfuscatedFile {
@ -108,11 +106,9 @@ namespace de4dot.code {
get { return module; }
}
#if PORT
public INameChecker NameChecker {
get { return deob; }
}
#endif
public bool RenameResourcesInCode {
get { return deob.TheOptions.RenameResourcesInCode; }

View File

@ -22,6 +22,7 @@ using System.Collections.Generic;
using System.IO;
using System.Text;
using dot10.DotNet.MD;
using dot10.IO;
namespace de4dot.code {
// These are in .NET 3.5 and later...
@ -231,22 +232,5 @@ namespace de4dot.code {
return fileData;
}
}
public static uint readEncodedUInt32(BinaryReader reader) {
uint val = 0;
int bits = 0;
for (int i = 0; i < 5; i++) {
byte b = reader.ReadByte();
val |= (uint)(b & 0x7F) << bits;
if ((b & 0x80) == 0)
return val;
bits += 7;
}
throw new ApplicationException("Invalid encoded int32");
}
public static int readEncodedInt32(BinaryReader reader) {
return (int)readEncodedUInt32(reader);
}
}
}

View File

@ -287,18 +287,18 @@
<Compile Include="renamer\asmmodules\Ref.cs" />
<Compile Include="renamer\asmmodules\RefDict.cs" />
<Compile Include="renamer\asmmodules\TypeDef.cs" />
<None Include="renamer\DerivedFrom.cs" />
<None Include="renamer\ExistingNames.cs" />
<None Include="renamer\INameChecker.cs" />
<None Include="renamer\MemberInfos.cs" />
<None Include="renamer\NameCreators.cs" />
<None Include="renamer\Renamer.cs" />
<None Include="renamer\ResourceKeysRenamer.cs" />
<None Include="renamer\ResourceRenamer.cs" />
<None Include="renamer\TypeInfo.cs" />
<None Include="renamer\TypeNames.cs" />
<None Include="renamer\TypeRenamerState.cs" />
<None Include="renamer\VariableNameState.cs" />
<Compile Include="renamer\DerivedFrom.cs" />
<Compile Include="renamer\ExistingNames.cs" />
<Compile Include="renamer\INameChecker.cs" />
<Compile Include="renamer\MemberInfos.cs" />
<Compile Include="renamer\NameCreators.cs" />
<Compile Include="renamer\Renamer.cs" />
<Compile Include="renamer\ResourceKeysRenamer.cs" />
<Compile Include="renamer\ResourceRenamer.cs" />
<Compile Include="renamer\TypeInfo.cs" />
<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" />

View File

@ -23,9 +23,7 @@ using dot10.DotNet;
using dot10.PE;
using de4dot.blocks;
using de4dot.blocks.cflow;
#if PORT
using de4dot.code.renamer;
#endif
namespace de4dot.code.deobfuscators {
public interface IDeobfuscatorOptions {
@ -54,11 +52,7 @@ namespace de4dot.code.deobfuscators {
RenameResourceKeys = 2,
}
public interface IDeobfuscator
#if PORT
: INameChecker
#endif
{
public interface IDeobfuscator : INameChecker {
string Type { get; }
string TypeLong { get; }
string Name { get; }

View File

@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using dot10.DotNet.MD;
namespace de4dot.code.renamer {
class ExistingNames {
@ -32,10 +33,18 @@ namespace de4dot.code.renamer {
return allNames.ContainsKey(name);
}
public string getName(UTF8String oldName, INameCreator nameCreator) {
return getName(UTF8String.ToSystemStringOrEmpty(oldName), nameCreator);
}
public string getName(string oldName, INameCreator nameCreator) {
return getName(oldName, () => nameCreator.create());
}
public string getName(UTF8String oldName, Func<string> createNewName) {
return getName(UTF8String.ToSystemStringOrEmpty(oldName), createNewName);
}
public string getName(string oldName, Func<string> createNewName) {
string prevName = null;
while (true) {

View File

@ -32,8 +32,8 @@ namespace de4dot.code.renamer {
public MemberInfo(Ref memberRef) {
this.memberRef = memberRef;
oldFullName = memberRef.memberReference.FullName;
oldName = memberRef.memberReference.Name;
newName = memberRef.memberReference.Name;
oldName = memberRef.memberReference.Name.String;
newName = memberRef.memberReference.Name.String;
}
public void rename(string newTypeName) {

View File

@ -174,7 +174,7 @@ namespace de4dot.code.renamer {
public string create(TypeDef typeDefinition, string newBaseTypeName) {
var nameCreator = getNameCreator(typeDefinition, newBaseTypeName);
return existingNames.getName(typeDefinition.Name, nameCreator);
return existingNames.getName(typeDefinition.Name.String, nameCreator);
}
NameCreator getNameCreator(TypeDef typeDefinition, string newBaseTypeName) {
@ -185,12 +185,13 @@ namespace de4dot.code.renamer {
nameCreator = createStructName;
else if (typeDefinition.IsClass) {
if (typeDefinition.BaseType != null) {
if (MemberReferenceHelper.verifyType(typeDefinition.BaseType, "mscorlib", "System.Delegate"))
var fn = typeDefinition.BaseType.FullName;
if (fn == "System.Delegate")
nameCreator = createDelegateName;
else if (MemberReferenceHelper.verifyType(typeDefinition.BaseType, "mscorlib", "System.MulticastDelegate"))
else if (fn == "System.MulticastDelegate")
nameCreator = createDelegateName;
else {
nameCreator = nameInfos.find(newBaseTypeName ?? typeDefinition.BaseType.Name);
nameCreator = nameInfos.find(newBaseTypeName ?? typeDefinition.BaseType.Name.String);
if (nameCreator == null)
nameCreator = createClassName;
}

View File

@ -22,6 +22,7 @@ using System.Collections.Generic;
using System.Text.RegularExpressions;
using dot10.DotNet;
using dot10.DotNet.Emit;
using dot10.DotNet.MD;
using de4dot.code.renamer.asmmodules;
using de4dot.blocks;
@ -97,7 +98,7 @@ namespace de4dot.code.renamer {
foreach (var module in modules.TheModules) {
if (!module.ObfuscatedFile.RenameResourceKeys)
continue;
new ResourceKeysRenamer(module.ModuleDefinition, module.ObfuscatedFile.NameChecker).rename();
new ResourceKeysRenamer(module.ModuleDefMD, module.ObfuscatedFile.NameChecker).rename();
}
}
@ -110,7 +111,7 @@ namespace de4dot.code.renamer {
continue;
var overrides = method.MethodDef.Overrides;
for (int i = 0; i < overrides.Count; i++) {
var overrideMethod = overrides[i];
var overrideMethod = overrides[i].MethodDeclaration;
if (method.MethodDef.Name != overrideMethod.Name)
continue;
Log.v("Removed useless override from method {0} ({1:X8}), override: {2:X8}",
@ -145,7 +146,7 @@ namespace de4dot.code.renamer {
foreach (var typeDef in module.getAllTypes()) {
List<MTypeDef> list;
var ns = typeDef.TypeDef.Namespace;
var ns = typeDef.TypeDef.Namespace.String;
if (string.IsNullOrEmpty(ns))
continue;
if (module.ObfuscatedFile.NameChecker.isValidNamespaceName(ns))
@ -157,7 +158,7 @@ namespace de4dot.code.renamer {
var sortedNamespaces = new List<List<MTypeDef>>(nsToTypes.Values);
sortedNamespaces.Sort((a, b) => {
return string.CompareOrdinal(a[0].TypeDef.Namespace, b[0].TypeDef.Namespace);
return UTF8String.CompareTo(a[0].TypeDef.Namespace, b[0].TypeDef.Namespace);
});
foreach (var list in sortedNamespaces) {
const int maxClasses = 1;
@ -190,13 +191,13 @@ namespace de4dot.code.renamer {
if (RenameTypes && info.gotNewName()) {
var old = typeDefinition.Name;
typeDefinition.Name = info.newName;
typeDefinition.Name = new UTF8String(info.newName);
Log.v("Name: {0} => {1}", Utils.removeNewlines(old), Utils.removeNewlines(typeDefinition.Name));
}
if (RenameNamespaces && info.newNamespace != null) {
var old = typeDefinition.Namespace;
typeDefinition.Namespace = info.newNamespace;
typeDefinition.Namespace = new UTF8String(info.newNamespace);
Log.v("Namespace: {0} => {1}", Utils.removeNewlines(old), Utils.removeNewlines(typeDefinition.Namespace));
}
@ -210,7 +211,7 @@ namespace de4dot.code.renamer {
var info = memberInfos.gparam(param);
if (!info.gotNewName())
continue;
param.GenericParam.Name = info.newName;
param.GenericParam.Name = new UTF8String(info.newName);
Log.v("GenParam: {0} => {1}", Utils.removeNewlines(info.oldFullName), Utils.removeNewlines(param.GenericParam.FullName));
}
}
@ -219,7 +220,7 @@ namespace de4dot.code.renamer {
Log.v("Renaming member definitions #2");
var allTypes = new List<MTypeDef>(modules.AllTypes);
allTypes.Sort((a, b) => Utils.compareInt32(a.Index, b.Index));
allTypes.Sort((a, b) => a.Index.CompareTo(b.Index));
Log.indent();
foreach (var typeDef in allTypes)
@ -248,7 +249,7 @@ namespace de4dot.code.renamer {
var fieldInfo = memberInfos.field(fieldDef);
if (!fieldInfo.gotNewName())
continue;
fieldDef.FieldDef.Name = fieldInfo.newName;
fieldDef.FieldDef.Name = new UTF8String(fieldInfo.newName);
Log.v("Field: {0} ({1:X8}) => {2}",
Utils.removeNewlines(fieldInfo.oldFullName),
fieldDef.FieldDef.MDToken.ToUInt32(),
@ -263,7 +264,7 @@ namespace de4dot.code.renamer {
var propInfo = memberInfos.prop(propDef);
if (!propInfo.gotNewName())
continue;
propDef.PropertyDef.Name = propInfo.newName;
propDef.PropertyDef.Name = new UTF8String(propInfo.newName);
Log.v("Property: {0} ({1:X8}) => {2}",
Utils.removeNewlines(propInfo.oldFullName),
propDef.PropertyDef.MDToken.ToUInt32(),
@ -278,7 +279,7 @@ namespace de4dot.code.renamer {
var eventInfo = memberInfos.evt(eventDef);
if (!eventInfo.gotNewName())
continue;
eventDef.EventDef.Name = eventInfo.newName;
eventDef.EventDef.Name = new UTF8String(eventInfo.newName);
Log.v("Event: {0} ({1:X8}) => {2}",
Utils.removeNewlines(eventInfo.oldFullName),
eventDef.EventDef.MDToken.ToUInt32(),
@ -297,7 +298,7 @@ namespace de4dot.code.renamer {
renameGenericParams(methodDef.GenericParams);
if (RenameMethods && methodInfo.gotNewName()) {
methodDef.MethodDef.Name = methodInfo.newName;
methodDef.MethodDef.Name = new UTF8String(methodInfo.newName);
Log.v("Name: {0} => {1}", Utils.removeNewlines(methodInfo.oldFullName), Utils.removeNewlines(methodDef.MethodDef.FullName));
}
@ -325,14 +326,10 @@ namespace de4dot.code.renamer {
refToDef.reference.Name = refToDef.definition.Name;
foreach (var refToDef in module.FieldRefsToRename)
refToDef.reference.Name = refToDef.definition.Name;
foreach (var info in module.CustomAttributeFieldReferences) {
var field = info.cattr.Fields[info.index];
info.cattr.Fields[info.index] = new CustomAttributeNamedArgument(info.reference.Name, field.Argument);
}
foreach (var info in module.CustomAttributePropertyReferences) {
var prop = info.cattr.Properties[info.index];
info.cattr.Properties[info.index] = new CustomAttributeNamedArgument(info.reference.Name, prop.Argument);
}
foreach (var info in module.CustomAttributeFieldReferences)
info.cattr.NamedArguments[info.index].Name = info.reference.Name;
foreach (var info in module.CustomAttributePropertyReferences)
info.cattr.NamedArguments[info.index].Name = info.reference.Name;
Log.deIndent();
}
}
@ -431,7 +428,7 @@ namespace de4dot.code.renamer {
continue;
if (method.Property == null)
continue;
memberInfos.prop(method.Property).rename(prop.PropertyDef.Name);
memberInfos.prop(method.Property).rename(prop.PropertyDef.Name.String);
}
}
}
@ -456,7 +453,7 @@ namespace de4dot.code.renamer {
continue;
if (method.Event == null)
continue;
memberInfos.evt(method.Event).rename(evt.EventDef.Name);
memberInfos.evt(method.Event).rename(evt.EventDef.Name.String);
}
}
}
@ -527,7 +524,7 @@ namespace de4dot.code.renamer {
foreach (var group in allGroups) {
var groupMethod = group.Methods[0];
var methodName = groupMethod.MethodDef.Name;
var methodName = groupMethod.MethodDef.Name.String;
bool onlyRenamableMethods = !group.hasNonRenamableMethod();
if (Utils.StartsWith(methodName, "get_", StringComparison.Ordinal)) {
@ -554,7 +551,7 @@ namespace de4dot.code.renamer {
continue; // Virtual methods are in allGroups, so already fixed above
if (method.Property != null)
continue;
var methodName = method.MethodDef.Name;
var methodName = method.MethodDef.Name.String;
if (Utils.StartsWith(methodName, "get_", StringComparison.Ordinal))
createPropertyGetter(methodName.Substring(4), method);
else if (Utils.StartsWith(methodName, "set_", StringComparison.Ordinal))
@ -572,8 +569,8 @@ namespace de4dot.code.renamer {
if (propMethod.Property != null)
return null;
var method = propMethod.MethodDef;
var propType = method.MethodReturnType.ReturnType;
var sig = propMethod.MethodDef.MethodSig;
var propType = sig.RetType;
var propDef = createProperty(ownerType, name, propType, propMethod.MethodDef, null);
if (propDef == null)
return null;
@ -602,7 +599,7 @@ namespace de4dot.code.renamer {
var method = propMethod.MethodDef;
if (method.Parameters.Count == 0)
return null;
var propType = method.Parameters[method.Parameters.Count - 1].ParameterType;
var propType = method.Parameters[method.Parameters.Count - 1].Type;
var propDef = createProperty(ownerType, name, propType, null, propMethod.MethodDef);
if (propDef == null)
return null;
@ -619,10 +616,15 @@ namespace de4dot.code.renamer {
return propDef;
}
MPropertyDef createProperty(MTypeDef ownerType, string name, TypeReference propType, MethodDef getter, MethodDef setter) {
if (string.IsNullOrEmpty(name) || propType.FullName == "System.Void")
MPropertyDef createProperty(MTypeDef ownerType, string name, TypeSig propType, MethodDef getter, MethodDef setter) {
if (string.IsNullOrEmpty(name) || propType.ElementType == ElementType.Void)
return null;
var newProp = DotNetUtils.createPropertyDefinition(name, propType, getter, setter);
var newSig = createPropertySig(getter, propType, true) ?? createPropertySig(setter, propType, false);
if (newSig == null)
return null;
var newProp = ownerType.Module.ModuleDefMD.UpdateRowId(new PropertyDefUser(name, newSig, 0));
newProp.GetMethod = getter;
newProp.SetMethod = setter;
var propDef = ownerType.findAny(newProp);
if (propDef != null)
return propDef;
@ -633,6 +635,25 @@ namespace de4dot.code.renamer {
return propDef;
}
static PropertySig createPropertySig(MethodDef method, TypeSig propType, bool isGetter) {
if (method == null)
return null;
var sig = method.MethodSig;
if (sig == null)
return null;
var newSig = new PropertySig(sig.HasThis, propType);
newSig.GenParamCount = sig.GenParamCount;
int count = sig.Params.Count;
if (!isGetter)
count--;
for (int i = 0; i < count; i++)
newSig.Params.Add(sig.Params[i]);
return newSig;
}
void restoreVirtualEvents(IEnumerable<MethodNameGroup> allGroups) {
if (!RestoreEvents)
return;
@ -728,7 +749,7 @@ namespace de4dot.code.renamer {
foreach (var group in allGroups) {
var groupMethod = group.Methods[0];
var methodName = groupMethod.MethodDef.Name;
var methodName = groupMethod.MethodDef.Name.String;
bool onlyRenamableMethods = !group.hasNonRenamableMethod();
if (Utils.StartsWith(methodName, "add_", StringComparison.Ordinal)) {
@ -755,7 +776,7 @@ namespace de4dot.code.renamer {
continue; // Virtual methods are in allGroups, so already fixed above
if (method.Event != null)
continue;
var methodName = method.MethodDef.Name;
var methodName = method.MethodDef.Name.String;
if (Utils.StartsWith(methodName, "add_", StringComparison.Ordinal))
createEventAdder(methodName.Substring(4), method);
else if (Utils.StartsWith(methodName, "remove_", StringComparison.Ordinal))
@ -816,18 +837,19 @@ namespace de4dot.code.renamer {
return eventDef;
}
TypeReference getEventType(MethodReference method) {
TypeSig getEventType(IMethod method) {
if (DotNetUtils.hasReturnValue(method))
return null;
if (method.Parameters.Count != 1)
var sig = method.MethodSig;
if (sig == null || sig.Params.Count != 1)
return null;
return method.Parameters[0].ParameterType;
return sig.Params[0];
}
MEventDef createEvent(MTypeDef ownerType, string name, TypeReference eventType) {
if (string.IsNullOrEmpty(name) || eventType == null || eventType.FullName == "System.Void")
MEventDef createEvent(MTypeDef ownerType, string name, TypeSig eventType) {
if (string.IsNullOrEmpty(name) || eventType == null || eventType.ElementType == ElementType.Void)
return null;
var newEvent = DotNetUtils.createEventDefinition(name, eventType);
var newEvent = ownerType.Module.ModuleDefMD.UpdateRowId(new EventDefUser(name, eventType.ToTypeDefOrRef(), 0));
var eventDef = ownerType.findAny(newEvent);
if (eventDef != null)
return eventDef;
@ -912,13 +934,14 @@ namespace de4dot.code.renamer {
string[] getValidArgNames(MethodNameGroup group) {
var methods = new List<MMethodDef>(group.Methods);
foreach (var method in group.Methods) {
foreach (var overrideRef in method.MethodDef.Overrides) {
var overrideDef = modules.resolve(overrideRef);
foreach (var ovrd in method.MethodDef.Overrides) {
var overrideRef = ovrd.MethodDeclaration;
var overrideDef = modules.resolveMethod(overrideRef);
if (overrideDef == null) {
var typeDef = modules.resolve(overrideRef.DeclaringType) ?? modules.resolveOther(overrideRef.DeclaringType);
var typeDef = modules.resolveType(overrideRef.DeclaringType) ?? modules.resolveOther(overrideRef.DeclaringType);
if (typeDef == null)
continue;
overrideDef = typeDef.find(overrideRef);
overrideDef = typeDef.findMethod(overrideRef);
if (overrideDef == null)
continue;
}
@ -976,7 +999,7 @@ namespace de4dot.code.renamer {
static List<MethodNameGroup> getSorted(MethodNameGroups groups) {
var allGroups = new List<MethodNameGroup>(groups.getAllGroups());
allGroups.Sort((a, b) => Utils.compareInt32(b.Count, a.Count));
allGroups.Sort((a, b) => b.Count.CompareTo(a.Count));
return allGroups;
}
@ -1047,7 +1070,7 @@ namespace de4dot.code.renamer {
return "";
}
}
var overrideMethod = method.MethodDef.Overrides[0];
var overrideMethod = method.MethodDef.Overrides[0].MethodDeclaration;
var name = overrideMethod.DeclaringType.FullName.Replace('/', '.');
name = removeGenericsArityRegex.Replace(name, "");
return name + ".";
@ -1108,7 +1131,7 @@ namespace de4dot.code.renamer {
if (memberInfos.tryGetEvent(overriddenEventDef, out info))
oldEventName = getRealName(info.newName);
else
oldEventName = getRealName(overriddenEventDef.EventDef.Name);
oldEventName = getRealName(overriddenEventDef.EventDef.Name.String);
}
}
@ -1140,8 +1163,8 @@ namespace de4dot.code.renamer {
}
MEventDef getOverriddenEvent(MMethodDef overrideMethod, out MMethodDef overriddenMethod) {
var theMethod = overrideMethod.MethodDef.Overrides[0];
overriddenMethod = modules.resolve(theMethod);
var theMethod = overrideMethod.MethodDef.Overrides[0].MethodDeclaration;
overriddenMethod = modules.resolveMethod(theMethod);
if (overriddenMethod != null)
return overriddenMethod.Event;
@ -1151,7 +1174,7 @@ namespace de4dot.code.renamer {
var extTypeDef = modules.resolveOther(extType);
if (extTypeDef == null)
return null;
overriddenMethod = extTypeDef.find(theMethod);
overriddenMethod = extTypeDef.findMethod(theMethod);
if (overriddenMethod != null)
return overriddenMethod.Event;
@ -1218,7 +1241,7 @@ namespace de4dot.code.renamer {
if (memberInfos.tryGetProperty(overriddenPropDef, out info))
oldPropName = getRealName(info.newName);
else
oldPropName = getRealName(overriddenPropDef.PropertyDef.Name);
oldPropName = getRealName(overriddenPropDef.PropertyDef.Name.String);
}
}
@ -1261,8 +1284,8 @@ namespace de4dot.code.renamer {
}
MPropertyDef getOverriddenProperty(MMethodDef overrideMethod) {
var theMethod = overrideMethod.MethodDef.Overrides[0];
var overriddenMethod = modules.resolve(theMethod);
var theMethod = overrideMethod.MethodDef.Overrides[0].MethodDeclaration;
var overriddenMethod = modules.resolveMethod(theMethod);
if (overriddenMethod != null)
return overriddenMethod.Property;
@ -1272,7 +1295,7 @@ namespace de4dot.code.renamer {
var extTypeDef = modules.resolveOther(extType);
if (extTypeDef == null)
return null;
var theMethodDef = extTypeDef.find(theMethod);
var theMethodDef = extTypeDef.findMethod(theMethod);
if (theMethodDef != null)
return theMethodDef.Property;
@ -1305,13 +1328,13 @@ namespace de4dot.code.renamer {
if (propType == null)
return defaultVal;
var elementType = propType.GetElementType();
if (propType is GenericInstanceType || elementType is GenericParam)
var elementType = propType.ScopeType.ToTypeSig(false).RemovePinnedAndModifiers();
if (propType is GenericInstSig || elementType is GenericSig)
return defaultVal;
var prefix = getPrefix(propType);
string name = elementType.Name;
string name = elementType.TypeName;
int i;
if ((i = name.IndexOf('`')) >= 0)
name = name.Substring(0, i);
@ -1327,10 +1350,11 @@ namespace de4dot.code.renamer {
return s.Substring(0, 1).ToUpperInvariant() + s.Substring(1);
}
static string getPrefix(TypeReference typeRef) {
static string getPrefix(TypeSig typeRef) {
string prefix = "";
while (typeRef is PointerType) {
typeRef = ((PointerType)typeRef).ElementType;
typeRef = typeRef.RemovePinnedAndModifiers();
while (typeRef is PtrSig) {
typeRef = typeRef.Next;
prefix += "p";
}
return prefix;
@ -1351,21 +1375,21 @@ namespace de4dot.code.renamer {
}
// Returns property type, or null if not all methods have the same type
TypeReference getPropertyType(MethodNameGroup group) {
TypeSig getPropertyType(MethodNameGroup group) {
var methodType = getPropertyMethodType(group.Methods[0]);
if (methodType == PropertyMethodType.Other)
return null;
TypeReference type = null;
TypeSig type = null;
foreach (var propMethod in group.Methods) {
TypeReference propType;
TypeSig propType;
if (methodType == PropertyMethodType.Setter)
propType = propMethod.ParamDefs[propMethod.ParamDefs.Count - 1].ParameterDefinition.ParameterType;
propType = propMethod.ParamDefs[propMethod.ParamDefs.Count - 1].ParameterDefinition.Type;
else
propType = propMethod.MethodDef.MethodReturnType.ReturnType;
propType = propMethod.MethodDef.MethodSig.RetType;
if (type == null)
type = propType;
else if (!MemberReferenceHelper.compareTypes(type, propType))
else if (!new SigComparer().Equals(type, propType))
return null;
}
return type;
@ -1384,7 +1408,7 @@ namespace de4dot.code.renamer {
return;
if (hasDelegateOwner(group)) {
switch (group.Methods[0].MethodDef.Name) {
switch (group.Methods[0].MethodDef.Name.String) {
case "Invoke":
case "BeginInvoke":
case "EndInvoke":
@ -1404,7 +1428,7 @@ namespace de4dot.code.renamer {
var overrideInfo = memberInfos.method(overrideMethod);
var overriddenMethod = getOverriddenMethod(overrideMethod);
if (overriddenMethod == null)
newMethodName = getRealName(overrideMethod.MethodDef.Overrides[0].Name);
newMethodName = getRealName(overrideMethod.MethodDef.Overrides[0].MethodDeclaration.Name.String);
else
newMethodName = getRealName(memberInfos.method(overriddenMethod).newName);
}
@ -1480,7 +1504,7 @@ namespace de4dot.code.renamer {
}
MMethodDef getOverriddenMethod(MMethodDef overrideMethod) {
return modules.resolve(overrideMethod.MethodDef.Overrides[0]);
return modules.resolveMethod(overrideMethod.MethodDef.Overrides[0].MethodDeclaration);
}
string getSuggestedMethodName(MethodNameGroup group) {
@ -1544,12 +1568,12 @@ namespace de4dot.code.renamer {
void prepareRenameEntryPoints() {
foreach (var module in modules.TheModules) {
var entryPoint = module.ModuleDefinition.EntryPoint;
var entryPoint = module.ModuleDefMD.EntryPoint as MethodDef;
if (entryPoint == null)
continue;
var methodDef = modules.resolve(entryPoint);
var methodDef = modules.resolveMethod(entryPoint);
if (methodDef == null) {
Log.w(string.Format("Could not find entry point. Module: {0}, Method: {1}", module.ModuleDefinition.FullyQualifiedName, Utils.removeNewlines(entryPoint)));
Log.w(string.Format("Could not find entry point. Module: {0}, Method: {1}", module.ModuleDefMD.Location, Utils.removeNewlines(entryPoint)));
continue;
}
if (!methodDef.isStatic())
@ -1557,7 +1581,7 @@ namespace de4dot.code.renamer {
memberInfos.method(methodDef).suggestedName = "Main";
if (methodDef.ParamDefs.Count == 1) {
var paramDef = methodDef.ParamDefs[0];
var type = paramDef.ParameterDefinition.ParameterType;
var type = paramDef.ParameterDefinition.Type;
if (type.FullName == "System.String[]")
memberInfos.param(paramDef).newName = "args";
}

View File

@ -24,6 +24,7 @@ using System.Text;
using System.Text.RegularExpressions;
using dot10.DotNet;
using dot10.DotNet.Emit;
using dot10.IO;
using de4dot.blocks;
using de4dot.code.resources;
@ -32,11 +33,11 @@ namespace de4dot.code.renamer {
const int RESOURCE_KEY_MAX_LEN = 50;
const string DEFAULT_KEY_NAME = "Key";
ModuleDefinition module;
ModuleDefMD module;
INameChecker nameChecker;
Dictionary<string, bool> newNames = new Dictionary<string, bool>();
public ResourceKeysRenamer(ModuleDefinition module, INameChecker nameChecker) {
public ResourceKeysRenamer(ModuleDefMD module, INameChecker nameChecker) {
this.module = module;
this.nameChecker = nameChecker;
}
@ -80,9 +81,9 @@ namespace de4dot.code.renamer {
static string getResourceName(TypeDef type) {
foreach (var method in type.Methods) {
if (method.Body == null)
if (method.CilBody == null)
continue;
var instrs = method.Body.Instructions;
var instrs = method.CilBody.Instructions;
string resourceName = null;
for (int i = 0; i < instrs.Count; i++) {
var instr = instrs[i];
@ -92,7 +93,7 @@ namespace de4dot.code.renamer {
}
if (instr.OpCode.Code == Code.Newobj) {
var ctor = instr.Operand as MethodReference;
var ctor = instr.Operand as IMethod;
if (ctor.FullName != "System.Void System.Resources.ResourceManager::.ctor(System.String,System.Reflection.Assembly)")
continue;
if (resourceName == null) {
@ -123,7 +124,7 @@ namespace de4dot.code.renamer {
void rename(TypeDef type, EmbeddedResource resource) {
newNames.Clear();
var resourceSet = ResourceReader.read(module, resource.GetResourceStream());
var resourceSet = ResourceReader.read(module, resource.Data);
var renamed = new List<RenameInfo>();
foreach (var elem in resourceSet.ResourceElements) {
if (nameChecker.isValidResourceKeyName(elem.Name)) {
@ -141,8 +142,7 @@ namespace de4dot.code.renamer {
var outStream = new MemoryStream();
ResourceWriter.write(module, outStream, resourceSet);
outStream.Position = 0;
var newResource = new EmbeddedResource(resource.Name, resource.Attributes, outStream);
var newResource = new EmbeddedResource(resource.Name, outStream.ToArray(), resource.Flags);
int resourceIndex = module.Resources.IndexOf(resource);
if (resourceIndex < 0)
throw new ApplicationException("Could not find index of resource");
@ -155,15 +155,15 @@ namespace de4dot.code.renamer {
nameToInfo[info.element.Name] = info;
foreach (var method in type.Methods) {
if (method.Body == null)
if (method.CilBody == null)
continue;
var instrs = method.Body.Instructions;
var instrs = method.CilBody.Instructions;
for (int i = 0; i < instrs.Count; i++) {
var call = instrs[i];
if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt)
continue;
var calledMethod = call.Operand as MethodReference;
var calledMethod = call.Operand as IMethod;
if (calledMethod == null)
continue;

View File

@ -21,6 +21,7 @@ using System;
using System.Collections.Generic;
using dot10.DotNet;
using dot10.DotNet.Emit;
using dot10.DotNet.MD;
using de4dot.blocks;
using de4dot.code.renamer.asmmodules;
@ -36,11 +37,11 @@ namespace de4dot.code.renamer {
public void rename(List<TypeInfo> renamedTypes) {
// Rename the longest names first. Otherwise eg. b.g.resources could be renamed
// Class0.g.resources instead of Class1.resources when b.g was renamed Class1.
renamedTypes.Sort((a, b) => Utils.compareInt32(b.oldFullName.Length, a.oldFullName.Length));
renamedTypes.Sort((a, b) => b.oldFullName.Length.CompareTo(a.oldFullName.Length));
nameToResource = new Dictionary<string, Resource>(module.ModuleDefinition.Resources.Count * 3, StringComparer.Ordinal);
foreach (var resource in module.ModuleDefinition.Resources) {
var name = resource.Name;
nameToResource = new Dictionary<string, Resource>(module.ModuleDefMD.Resources.Count * 3, StringComparer.Ordinal);
foreach (var resource in module.ModuleDefMD.Resources) {
var name = resource.Name.String;
nameToResource[name] = resource;
if (name.EndsWith(".g.resources"))
nameToResource[name.Substring(0, name.Length - 12)] = resource;
@ -59,9 +60,9 @@ namespace de4dot.code.renamer {
oldNameToTypeInfo[info.oldFullName] = info;
foreach (var method in module.getAllMethods()) {
if (!method.HasBody)
if (!method.HasCilBody)
continue;
var instrs = method.Body.Instructions;
var instrs = method.CilBody.Instructions;
for (int i = 0; i < instrs.Count; i++) {
var instr = instrs[i];
if (instr.OpCode != OpCodes.Ldstr)
@ -98,7 +99,7 @@ namespace de4dot.code.renamer {
var ldtoken = instrs[index++];
if (ldtoken.OpCode.Code != Code.Ldtoken)
return false;
if (!MemberReferenceHelper.compareTypes(typeInfo.type.TypeDef, ldtoken.Operand as TypeReference))
if (!new SigComparer().Equals(typeInfo.type.TypeDef, ldtoken.Operand as ITypeDefOrRef))
return false;
if (!checkCalledMethod(instrs[index++], "System.Type", "(System.RuntimeTypeHandle)"))
@ -125,7 +126,7 @@ namespace de4dot.code.renamer {
static bool checkCalledMethod(Instruction instr, string returnType, string parameters) {
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt)
return false;
return DotNetUtils.isMethod(instr.Operand as MethodReference, returnType, parameters);
return DotNetUtils.isMethod(instr.Operand as IMethod, returnType, parameters);
}
class RenameInfo {
@ -152,11 +153,11 @@ namespace de4dot.code.renamer {
if (newNames.ContainsKey(resource))
continue;
var newTypeName = info.type.TypeDef.FullName;
var newName = newTypeName + resource.Name.Substring(oldFullName.Length);
var newName = newTypeName + resource.Name.String.Substring(oldFullName.Length);
newNames[resource] = new RenameInfo(resource, info, newName);
Log.v("Renamed resource in resources: {0} => {1}", Utils.removeNewlines(resource.Name), newName);
resource.Name = newName;
resource.Name = new UTF8String(newName);
}
}
}

View File

@ -41,7 +41,7 @@ namespace de4dot.code.renamer {
: base(typeDef) {
this.type = typeDef;
this.memberInfos = memberInfos;
oldNamespace = typeDef.TypeDef.Namespace;
oldNamespace = typeDef.TypeDef.Namespace.String;
}
bool isWinFormsClass() {
@ -82,7 +82,7 @@ namespace de4dot.code.renamer {
}
bool isModuleType() {
return type.TypeDef == DotNetUtils.getModuleType(type.TypeDef.Module);
return type.TypeDef.IsGlobalModuleType;
}
public void prepareRenameTypes(TypeRenamerState state) {
@ -371,10 +371,10 @@ namespace de4dot.code.renamer {
var checker = NameChecker;
// PInvoke methods' EntryPoint is always valid. It has to, so always rename.
if (!NameChecker.isValidMethodName(info.oldName) || methodDef.MethodDef.PInvokeInfo != null) {
if (!NameChecker.isValidMethodName(info.oldName) || methodDef.MethodDef.ImplMap != null) {
INameCreator nameCreator = null;
string newName = info.suggestedName;
if (methodDef.MethodDef.PInvokeInfo != null)
if (methodDef.MethodDef.ImplMap != null)
newName = getPinvokeName(methodDef);
else if (methodDef.isStatic())
nameCreator = variableNameState.staticMethodNameCreator;
@ -387,20 +387,24 @@ namespace de4dot.code.renamer {
}
string getPinvokeName(MMethodDef methodDef) {
var entryPoint = methodDef.MethodDef.PInvokeInfo.EntryPoint;
var entryPoint = methodDef.MethodDef.ImplMap.Name.String;
if (Regex.IsMatch(entryPoint, @"^#\d+$"))
entryPoint = DotNetUtils.getDllName(methodDef.MethodDef.PInvokeInfo.Module.Name) + "_" + entryPoint.Substring(1);
entryPoint = DotNetUtils.getDllName(methodDef.MethodDef.ImplMap.Scope.Name.String) + "_" + entryPoint.Substring(1);
return entryPoint;
}
static bool isEventHandler(MMethodDef methodDef) {
if (methodDef.MethodDef.Parameters.Count != 2)
var md = methodDef.MethodDef;
if (md.Parameters.Count != 2)
return false;
if (methodDef.MethodDef.MethodReturnType.ReturnType.FullName != "System.Void")
var sig = md.MethodSig;
if (sig == null)
return false;
if (methodDef.MethodDef.Parameters[0].ParameterType.FullName != "System.Object")
if (sig.RetType.ElementType != ElementType.Void)
return false;
if (!methodDef.MethodDef.Parameters[1].ParameterType.FullName.Contains("EventArgs"))
if (md.Parameters[0].Type.ElementType != ElementType.Object)
return false;
if (!md.Parameters[1].Type.FullName.Contains("EventArgs"))
return false;
return true;
}
@ -444,16 +448,16 @@ namespace de4dot.code.renamer {
ourMethods.add(methodDef.MethodDef, methodDef);
foreach (var methodDef in type.AllMethods) {
if (methodDef.MethodDef.Body == null)
if (methodDef.MethodDef.CilBody == null)
continue;
if (methodDef.MethodDef.IsStatic || methodDef.MethodDef.IsVirtual)
continue;
var instructions = methodDef.MethodDef.Body.Instructions;
var instructions = methodDef.MethodDef.CilBody.Instructions;
for (int i = 2; i < instructions.Count; i++) {
var call = instructions[i];
if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt)
continue;
if (!isWindowsFormsSetNameMethod(call.Operand as MethodReference))
if (!isWindowsFormsSetNameMethod(call.Operand as IMethod))
continue;
var ldstr = instructions[i - 1];
@ -464,9 +468,9 @@ namespace de4dot.code.renamer {
continue;
var instr = instructions[i - 2];
FieldReference fieldRef = null;
IField fieldRef = null;
if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) {
var calledMethod = instr.Operand as MethodReference;
var calledMethod = instr.Operand as IMethod;
if (calledMethod == null)
continue;
var calledMethodDef = ourMethods.find(calledMethod);
@ -482,7 +486,7 @@ namespace de4dot.code.renamer {
fieldName = "_" + fieldName;
}
else if (instr.OpCode.Code == Code.Ldfld) {
fieldRef = instr.Operand as FieldReference;
fieldRef = instr.Operand as IField;
}
if (fieldRef == null)
@ -500,13 +504,13 @@ namespace de4dot.code.renamer {
}
}
static FieldReference getFieldReference(MethodDef method) {
if (method == null || method.Body == null)
static IField getFieldReference(MethodDef method) {
if (method == null || method.CilBody == null)
return null;
var instructions = method.Body.Instructions;
var instructions = method.CilBody.Instructions;
int index = 0;
var ldarg0 = DotNetUtils.getInstruction(instructions, ref index);
if (ldarg0 == null || DotNetUtils.getArgIndex(ldarg0) != 0)
if (ldarg0 == null || ldarg0.GetParameterIndex() != 0)
return null;
var ldfld = DotNetUtils.getInstruction(instructions, ref index);
if (ldfld == null || ldfld.OpCode.Code != Code.Ldfld)
@ -514,18 +518,18 @@ namespace de4dot.code.renamer {
var ret = DotNetUtils.getInstruction(instructions, ref index);
if (ret == null)
return null;
if (DotNetUtils.isStloc(ret)) {
var local = DotNetUtils.getLocalVar(method.Body.Variables, ret);
if (ret.IsStloc()) {
var local = ret.GetLocal(method.CilBody.LocalList);
ret = DotNetUtils.getInstruction(instructions, ref index);
if (ret == null || !DotNetUtils.isLdloc(ret))
if (ret == null || !ret.IsLdloc())
return null;
if (DotNetUtils.getLocalVar(method.Body.Variables, ret) != local)
if (ret.GetLocal(method.CilBody.LocalList) != local)
return null;
ret = DotNetUtils.getInstruction(instructions, ref index);
}
if (ret == null || ret.OpCode.Code != Code.Ret)
return null;
return ldfld.Operand as FieldReference;
return ldfld.Operand as IField;
}
public void initializeEventHandlerNames() {
@ -566,41 +570,44 @@ namespace de4dot.code.renamer {
}
}
static MethodReference getVbHandler(MethodDef method, out string eventName) {
static IMethod getVbHandler(MethodDef method, out string eventName) {
eventName = null;
if (method.Body == null)
if (method.CilBody == null)
return null;
if (method.MethodReturnType.ReturnType.FullName != "System.Void")
var sig = method.MethodSig;
if (sig == null)
return null;
if (sig.RetType.ElementType != ElementType.Void)
return null;
if (method.Parameters.Count != 1)
return null;
if (method.Body.Variables.Count != 1)
if (method.CilBody.LocalList.Count != 1)
return null;
if (!isEventHandlerType(method.Body.Variables[0].VariableType))
if (!isEventHandlerType(method.CilBody.LocalList[0].Type))
return null;
var instructions = method.Body.Instructions;
var instructions = method.CilBody.Instructions;
int index = 0;
int newobjIndex = findInstruction(instructions, index, Code.Newobj);
if (newobjIndex == -1 || findInstruction(instructions, newobjIndex + 1, Code.Newobj) != -1)
return null;
if (!isEventHandlerCtor(instructions[newobjIndex].Operand as MethodReference))
if (!isEventHandlerCtor(instructions[newobjIndex].Operand as IMethod))
return null;
if (newobjIndex < 1)
return null;
var ldvirtftn = instructions[newobjIndex - 1];
if (ldvirtftn.OpCode.Code != Code.Ldvirtftn && ldvirtftn.OpCode.Code != Code.Ldftn)
return null;
var handlerMethod = ldvirtftn.Operand as MethodReference;
var handlerMethod = ldvirtftn.Operand as IMethod;
if (handlerMethod == null)
return null;
if (!MemberReferenceHelper.compareTypes(method.DeclaringType, handlerMethod.DeclaringType))
if (!new SigComparer().Equals(method.DeclaringType, handlerMethod.DeclaringType))
return null;
index = newobjIndex;
FieldReference addField, removeField;
MethodReference addMethod, removeMethod;
IField addField, removeField;
IMethod addMethod, removeMethod;
if (!findEventCall(instructions, ref index, out removeField, out removeMethod))
return null;
if (!findEventCall(instructions, ref index, out addField, out addMethod))
@ -608,18 +615,18 @@ namespace de4dot.code.renamer {
if (findInstruction(instructions, index, Code.Callvirt) != -1)
return null;
if (!MemberReferenceHelper.compareFieldReference(addField, removeField))
if (!new SigComparer().Equals(addField, removeField))
return null;
if (!MemberReferenceHelper.compareTypes(method.DeclaringType, addField.DeclaringType))
if (!new SigComparer().Equals(method.DeclaringType, addField.DeclaringType))
return null;
if (!MemberReferenceHelper.compareTypes(addMethod.DeclaringType, removeMethod.DeclaringType))
if (!new SigComparer().Equals(addMethod.DeclaringType, removeMethod.DeclaringType))
return null;
if (!Utils.StartsWith(addMethod.Name, "add_", StringComparison.Ordinal))
if (!Utils.StartsWith(addMethod.Name.String, "add_", StringComparison.Ordinal))
return null;
if (!Utils.StartsWith(removeMethod.Name, "remove_", StringComparison.Ordinal))
if (!Utils.StartsWith(removeMethod.Name.String, "remove_", StringComparison.Ordinal))
return null;
eventName = addMethod.Name.Substring(4);
if (eventName != removeMethod.Name.Substring(7))
eventName = addMethod.Name.String.Substring(4);
if (eventName != removeMethod.Name.String.Substring(7))
return null;
if (eventName == "")
return null;
@ -627,7 +634,7 @@ namespace de4dot.code.renamer {
return handlerMethod;
}
static bool findEventCall(IList<Instruction> instructions, ref int index, out FieldReference field, out MethodReference calledMethod) {
static bool findEventCall(IList<Instruction> instructions, ref int index, out IField field, out IMethod calledMethod) {
field = null;
calledMethod = null;
@ -644,8 +651,8 @@ namespace de4dot.code.renamer {
if (ldfld.OpCode.Code != Code.Ldfld)
return false;
field = ldfld.Operand as FieldReference;
calledMethod = instructions[callvirt].Operand as MethodReference;
field = ldfld.Operand as IField;
calledMethod = instructions[callvirt].Operand as IMethod;
return field != null && calledMethod != null;
}
@ -661,11 +668,11 @@ namespace de4dot.code.renamer {
var checker = NameChecker;
foreach (var methodDef in type.AllMethods) {
if (methodDef.MethodDef.Body == null)
if (methodDef.MethodDef.CilBody == null)
continue;
if (methodDef.MethodDef.IsStatic)
continue;
var instructions = methodDef.MethodDef.Body.Instructions;
var instructions = methodDef.MethodDef.CilBody.Instructions;
for (int i = 0; i < instructions.Count - 6; i++) {
// We're looking for this code pattern:
// ldarg.0
@ -675,36 +682,36 @@ namespace de4dot.code.renamer {
// newobj event_handler_ctor
// callvirt add_SomeEvent
if (DotNetUtils.getArgIndex(instructions[i]) != 0)
if (instructions[i].GetParameterIndex() != 0)
continue;
int index = i + 1;
var ldfld = instructions[index++];
if (ldfld.OpCode.Code != Code.Ldfld)
continue;
var fieldRef = ldfld.Operand as FieldReference;
var fieldRef = ldfld.Operand as IField;
if (fieldRef == null)
continue;
var fieldDef = ourFields.find(fieldRef);
if (fieldDef == null)
continue;
if (DotNetUtils.getArgIndex(instructions[index++]) != 0)
if (instructions[index++].GetParameterIndex() != 0)
continue;
MethodReference methodRef;
IMethod methodRef;
var instr = instructions[index + 1];
if (instr.OpCode.Code == Code.Ldvirtftn) {
if (!isThisOrDup(instructions[index++]))
continue;
var ldvirtftn = instructions[index++];
methodRef = ldvirtftn.Operand as MethodReference;
methodRef = ldvirtftn.Operand as IMethod;
}
else {
var ldftn = instructions[index++];
if (ldftn.OpCode.Code != Code.Ldftn)
continue;
methodRef = ldftn.Operand as MethodReference;
methodRef = ldftn.Operand as IMethod;
}
if (methodRef == null)
continue;
@ -715,19 +722,19 @@ namespace de4dot.code.renamer {
var newobj = instructions[index++];
if (newobj.OpCode.Code != Code.Newobj)
continue;
if (!isEventHandlerCtor(newobj.Operand as MethodReference))
if (!isEventHandlerCtor(newobj.Operand as IMethod))
continue;
var call = instructions[index++];
if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt)
continue;
var addHandler = call.Operand as MethodReference;
var addHandler = call.Operand as IMethod;
if (addHandler == null)
continue;
if (!Utils.StartsWith(addHandler.Name, "add_", StringComparison.Ordinal))
if (!Utils.StartsWith(addHandler.Name.String, "add_", StringComparison.Ordinal))
continue;
var eventName = addHandler.Name.Substring(4);
var eventName = addHandler.Name.String.Substring(4);
if (!checker.isValidEventName(eventName))
continue;
@ -740,12 +747,12 @@ namespace de4dot.code.renamer {
var checker = NameChecker;
foreach (var methodDef in type.AllMethods) {
if (methodDef.MethodDef.Body == null)
if (methodDef.MethodDef.CilBody == null)
continue;
if (methodDef.MethodDef.IsStatic)
continue;
var method = methodDef.MethodDef;
var instructions = method.Body.Instructions;
var instructions = method.CilBody.Instructions;
for (int i = 0; i < instructions.Count - 5; i++) {
// ldarg.0
// ldarg.0 / dup
@ -754,15 +761,15 @@ namespace de4dot.code.renamer {
// newobj event handler ctor
// call add_Xyz
if (DotNetUtils.getArgIndex(instructions[i]) != 0)
if (instructions[i].GetParameterIndex() != 0)
continue;
int index = i + 1;
if (!isThisOrDup(instructions[index++]))
continue;
MethodReference handler;
IMethod handler;
if (instructions[index].OpCode.Code == Code.Ldftn) {
handler = instructions[index++].Operand as MethodReference;
handler = instructions[index++].Operand as IMethod;
}
else {
if (!isThisOrDup(instructions[index++]))
@ -770,7 +777,7 @@ namespace de4dot.code.renamer {
var instr = instructions[index++];
if (instr.OpCode.Code != Code.Ldvirtftn)
continue;
handler = instr.Operand as MethodReference;
handler = instr.Operand as IMethod;
}
if (handler == null)
continue;
@ -781,19 +788,19 @@ namespace de4dot.code.renamer {
var newobj = instructions[index++];
if (newobj.OpCode.Code != Code.Newobj)
continue;
if (!isEventHandlerCtor(newobj.Operand as MethodReference))
if (!isEventHandlerCtor(newobj.Operand as IMethod))
continue;
var call = instructions[index++];
if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt)
continue;
var addMethod = call.Operand as MethodReference;
var addMethod = call.Operand as IMethod;
if (addMethod == null)
continue;
if (!Utils.StartsWith(addMethod.Name, "add_", StringComparison.Ordinal))
if (!Utils.StartsWith(addMethod.Name.String, "add_", StringComparison.Ordinal))
continue;
var eventName = addMethod.Name.Substring(4);
var eventName = addMethod.Name.String.Substring(4);
if (!checker.isValidEventName(eventName))
continue;
@ -803,10 +810,10 @@ namespace de4dot.code.renamer {
}
static bool isThisOrDup(Instruction instr) {
return DotNetUtils.getArgIndex(instr) == 0 || instr.OpCode.Code == Code.Dup;
return instr.GetParameterIndex() == 0 || instr.OpCode.Code == Code.Dup;
}
static bool isEventHandlerCtor(MethodReference method) {
static bool isEventHandlerCtor(IMethod method) {
if (method == null)
return false;
if (method.Name != ".ctor")
@ -818,22 +825,22 @@ namespace de4dot.code.renamer {
return true;
}
static bool isEventHandlerType(TypeReference type) {
static bool isEventHandlerType(IType type) {
return type.FullName.EndsWith("EventHandler", StringComparison.Ordinal);
}
string findWindowsFormsClassName(MTypeDef type) {
foreach (var methodDef in type.AllMethods) {
if (methodDef.MethodDef.Body == null)
if (methodDef.MethodDef.CilBody == null)
continue;
if (methodDef.MethodDef.IsStatic || methodDef.MethodDef.IsVirtual)
continue;
var instructions = methodDef.MethodDef.Body.Instructions;
var instructions = methodDef.MethodDef.CilBody.Instructions;
for (int i = 2; i < instructions.Count; i++) {
var call = instructions[i];
if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt)
continue;
if (!isWindowsFormsSetNameMethod(call.Operand as MethodReference))
if (!isWindowsFormsSetNameMethod(call.Operand as IMethod))
continue;
var ldstr = instructions[i - 1];
@ -843,7 +850,7 @@ namespace de4dot.code.renamer {
if (className == null)
continue;
if (DotNetUtils.getArgIndex(instructions[i - 2]) != 0)
if (instructions[i - 2].GetParameterIndex() != 0)
continue;
findInitializeComponentMethod(type, methodDef);
@ -857,12 +864,12 @@ namespace de4dot.code.renamer {
foreach (var methodDef in type.AllMethods) {
if (methodDef.MethodDef.Name != ".ctor")
continue;
if (methodDef.MethodDef.Body == null)
if (methodDef.MethodDef.CilBody == null)
continue;
foreach (var instr in methodDef.MethodDef.Body.Instructions) {
foreach (var instr in methodDef.MethodDef.CilBody.Instructions) {
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt)
continue;
if (!MemberReferenceHelper.compareMethodReferenceAndDeclaringType(possibleInitMethod.MethodDef, instr.Operand as MethodReference))
if (!MethodEqualityComparer.CompareDeclaringTypes.Equals(possibleInitMethod.MethodDef, instr.Operand as IMethod))
continue;
memberInfos.method(possibleInitMethod).suggestedName = "InitializeComponent";
@ -871,16 +878,19 @@ namespace de4dot.code.renamer {
}
}
static bool isWindowsFormsSetNameMethod(MethodReference method) {
static bool isWindowsFormsSetNameMethod(IMethod method) {
if (method == null)
return false;
if (method.Name != "set_Name")
if (method.Name.String != "set_Name")
return false;
if (method.MethodReturnType.ReturnType.FullName != "System.Void")
var sig = method.MethodSig;
if (sig == null)
return false;
if (method.Parameters.Count != 1)
if (sig.RetType.ElementType != ElementType.Void)
return false;
if (method.Parameters[0].ParameterType.FullName != "System.String")
if (sig.Params.Count != 1)
return false;
if (sig.Params[0].ElementType != ElementType.String)
return false;
return true;
}

View File

@ -28,19 +28,20 @@ namespace de4dot.code.renamer {
protected Dictionary<string, string> fullNameToShortName;
protected Dictionary<string, string> fullNameToShortNamePrefix;
public string create(TypeReference typeRef) {
if (typeRef.IsGenericInstance) {
var git = (GenericInstanceType)typeRef;
if (git.ElementType.FullName == "System.Nullable`1" &&
git.GenericArguments.Count == 1 && git.GenericArguments[0] != null) {
typeRef = git.GenericArguments[0];
public string create(TypeSig typeRef) {
typeRef = typeRef.RemovePinnedAndModifiers();
var gis = typeRef as GenericInstSig;
if (gis != null) {
if (gis.FullName == "System.Nullable`1" &&
gis.GenericArguments.Count == 1 && gis.GenericArguments[0] != null) {
typeRef = gis.GenericArguments[0];
}
}
string prefix = getPrefix(typeRef);
var elementType = typeRef.GetElementType();
if (elementType is GenericParam)
var elementType = typeRef.ScopeType;
if (isGenericParam(elementType))
return genericParamNameCreator.create();
NameCreator nc;
@ -64,12 +65,20 @@ namespace de4dot.code.renamer {
return addTypeName(typeFullName, shortName, prefix).create();
}
static string getPrefix(TypeReference typeRef) {
bool isGenericParam(ITypeDefOrRef tdr) {
var ts = tdr as TypeSpec;
if (ts != null)
return false;
var sig = ts.TypeSig.RemovePinnedAndModifiers();
return sig is GenericSig;
}
static string getPrefix(TypeSig typeRef) {
string prefix = "";
while (typeRef is TypeSpecification) {
while (typeRef != null) {
if (typeRef.IsPointer)
prefix += "p";
typeRef = ((TypeSpecification)typeRef).ElementType;
typeRef = typeRef.Next;
}
return prefix;
}

View File

@ -49,17 +49,17 @@ namespace de4dot.code.renamer {
string newName;
string asmFullName;
if (type.Module.Assembly != null)
asmFullName = type.Module.Assembly.FullName;
if (type.OwnerModule.Assembly != null)
asmFullName = type.OwnerModule.Assembly.FullName;
else
asmFullName = "<no assembly>";
// Make sure that two namespaces with the same names in different modules aren't renamed
// to the same name.
var key = string.Format(" [{0}] [{1}] [{2}] [{3}] ",
type.Module.FullyQualifiedName,
type.OwnerModule.Location,
asmFullName,
type.Module.Name,
type.OwnerModule.Name,
ns);
if (namespaceToNewName.TryGetValue(key, out newName))
return newName;

View File

@ -87,7 +87,7 @@ namespace de4dot.code.renamer {
}
public string getNewPropertyName(PropertyDef propertyDefinition) {
var propType = propertyDefinition.PropertyType;
var propType = propertyDefinition.PropertySig.RetType;
string newName;
if (isGeneric(propType))
newName = existingPropertyNames.getName(propertyDefinition.Name, genericPropertyNameCreator);
@ -97,15 +97,13 @@ namespace de4dot.code.renamer {
return newName;
}
static bool isGeneric(TypeReference type) {
while (true) {
if (type is GenericParam)
static bool isGeneric(TypeSig type) {
while (type != null) {
if (type.IsGenericParameter)
return true;
var ts = type as TypeSpecification;
if (ts == null)
return false;
type = ts.ElementType;
type = type.Next;
}
return false;
}
public string getNewEventName(EventDef eventDefinition) {
@ -147,15 +145,15 @@ namespace de4dot.code.renamer {
}
public string getNewFieldName(FieldDef field) {
return existingVariableNames.getName(field.Name, () => variableNameCreator.create(field.FieldType));
return existingVariableNames.getName(field.Name, () => variableNameCreator.create(field.FieldSig.Type));
}
public string getNewFieldName(string oldName, INameCreator nameCreator) {
return existingVariableNames.getName(oldName, () => nameCreator.create());
}
public string getNewParamName(string oldName, ParameterDefinition param) {
return existingVariableNames.getName(oldName, () => variableNameCreator.create(param.ParameterType));
public string getNewParamName(string oldName, Parameter param) {
return existingVariableNames.getName(oldName, () => variableNameCreator.create(param.Type));
}
public string getNewMethodName(string oldName, INameCreator nameCreator) {

View File

@ -22,7 +22,7 @@ using dot10.DotNet;
namespace de4dot.code.renamer.asmmodules {
interface IResolver {
MTypeDef resolveType(ITypeDefOrRef typeReference);
MMethodDef resolveMethod(MemberRef methodReference);
MMethodDef resolveMethod(IMethodDefOrRef methodReference);
MFieldDef resolveField(MemberRef fieldReference);
}
}

View File

@ -241,7 +241,7 @@ namespace de4dot.code.renamer.asmmodules {
return this.types.find(getNonGenericTypeReference(typeReference));
}
public MMethodDef resolveMethod(MemberRef methodRef) {
public MMethodDef resolveMethod(IMethodDefOrRef methodRef) {
var typeDef = this.types.find(getNonGenericTypeReference(methodRef.DeclaringType));
if (typeDef == null)
return null;

View File

@ -452,7 +452,7 @@ namespace de4dot.code.renamer.asmmodules {
return null;
}
public MMethodDef resolveMethod(MemberRef methodRef) {
public MMethodDef resolveMethod(IMethodDefOrRef methodRef) {
if (methodRef.DeclaringType == null)
return null;
var modules = findModules(methodRef.DeclaringType);

View File

@ -21,11 +21,11 @@ using dot10.DotNet;
namespace de4dot.code.renamer.asmmodules {
abstract class Ref {
public readonly ICodedToken memberReference;
public readonly IMemberRef memberReference;
public int Index { get; set; }
public MTypeDef Owner { get; set; }
protected Ref(ICodedToken memberReference, MTypeDef owner, int index) {
protected Ref(IMemberRef memberReference, MTypeDef owner, int index) {
this.memberReference = memberReference;
Owner = owner;
Index = index;

View File

@ -519,6 +519,10 @@ namespace de4dot.code.renamer.asmmodules {
return methods.find(mr);
}
public MMethodDef findMethod(IMethodDefOrRef md) {
return methods.find(md);
}
public MMethodDef findMethod(MethodDef md) {
return methods.find(md);
}

View File

@ -23,6 +23,7 @@ using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using dot10.DotNet;
using dot10.IO;
namespace de4dot.code.resources {
[Serializable]
@ -32,19 +33,19 @@ namespace de4dot.code.resources {
}
}
class ResourceReader {
struct ResourceReader {
ModuleDefMD module;
BinaryReader reader;
IBinaryReader reader;
ResourceDataCreator resourceDataCreator;
ResourceReader(ModuleDefMD module, Stream stream) {
ResourceReader(ModuleDefMD module, IBinaryReader reader) {
this.module = module;
this.reader = new BinaryReader(stream);
this.reader = reader;
this.resourceDataCreator = new ResourceDataCreator(module);
}
public static ResourceElementSet read(ModuleDefMD module, Stream stream) {
return new ResourceReader(module, stream).read();
public static ResourceElementSet read(ModuleDefMD module, IBinaryReader reader) {
return new ResourceReader(module, reader).read();
}
ResourceElementSet read() {
@ -68,7 +69,7 @@ namespace de4dot.code.resources {
var userTypes = new List<UserResourceType>();
for (int i = 0; i < numUserTypes; i++)
userTypes.Add(new UserResourceType(reader.ReadString(), ResourceTypeCode.UserTypes + i));
reader.BaseStream.Position = (reader.BaseStream.Position + 7) & ~7;
reader.Position = (reader.Position + 7) & ~7;
var hashes = new int[numResources];
for (int i = 0; i < numResources; i++)
@ -77,27 +78,26 @@ namespace de4dot.code.resources {
for (int i = 0; i < numResources; i++)
offsets[i] = reader.ReadInt32();
long baseOffset = reader.BaseStream.Position;
long baseOffset = reader.Position;
long dataBaseOffset = reader.ReadInt32();
long nameBaseOffset = reader.BaseStream.Position;
long end = reader.BaseStream.Length;
long nameBaseOffset = reader.Position;
long end = reader.Length;
var infos = new List<ResourceInfo>(numResources);
var nameReader = new BinaryReader(reader.BaseStream, Encoding.Unicode);
for (int i = 0; i < numResources; i++) {
nameReader.BaseStream.Position = nameBaseOffset + offsets[i];
var name = nameReader.ReadString();
long offset = dataBaseOffset + nameReader.ReadInt32();
reader.Position = nameBaseOffset + offsets[i];
var name = reader.ReadString(Encoding.Unicode);
long offset = dataBaseOffset + reader.ReadInt32();
infos.Add(new ResourceInfo(name, offset));
}
infos.Sort(sortResourceInfo);
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.BaseStream.Position = info.offset;
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);
@ -108,10 +108,6 @@ namespace de4dot.code.resources {
return resources;
}
static int sortResourceInfo(ResourceInfo a, ResourceInfo b) {
return ((int)a.offset).CompareTo((int)b.offset);
}
class ResourceInfo {
public string name;
public long offset;
@ -153,9 +149,9 @@ namespace de4dot.code.resources {
}
}
static uint readUInt32(BinaryReader reader) {
static uint readUInt32(IBinaryReader reader) {
try {
return Utils.readEncodedUInt32(reader);
return reader.Read7BitEncodedUInt32();
}
catch {
throw new ResourceReaderException("Invalid encoded int32");

2
dot10

@ -1 +1 @@
Subproject commit 4616892cf93d280c16be2c8b49dd4de7a9d0c92e
Subproject commit e203b3f5b67d7c0e737cb953c62ae99dde1340e7