Merge branch 'port' into confuser
Conflicts: blocks/DotNetUtils.cs
This commit is contained in:
commit
a09bf43cde
|
@ -178,7 +178,7 @@ namespace AssemblyData.methodsrewriter {
|
||||||
|
|
||||||
void initLocals() {
|
void initLocals() {
|
||||||
locals = new List<LocalBuilder>();
|
locals = new List<LocalBuilder>();
|
||||||
foreach (var local in methodInfo.methodDef.Body.LocalList)
|
foreach (var local in methodInfo.methodDef.Body.Variables)
|
||||||
locals.Add(ilg.DeclareLocal(Resolver.getRtType(local.Type), local.Type.RemoveModifiers().IsPinned));
|
locals.Add(ilg.DeclareLocal(Resolver.getRtType(local.Type), local.Type.RemoveModifiers().IsPinned));
|
||||||
tempObjLocal = ilg.DeclareLocal(typeof(object));
|
tempObjLocal = ilg.DeclareLocal(typeof(object));
|
||||||
tempObjArrayLocal = ilg.DeclareLocal(typeof(object[]));
|
tempObjArrayLocal = ilg.DeclareLocal(typeof(object[]));
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace de4dot.blocks {
|
||||||
|
|
||||||
public void updateBlocks() {
|
public void updateBlocks() {
|
||||||
var body = method.Body;
|
var body = method.Body;
|
||||||
locals = body.LocalList;
|
locals = body.Variables;
|
||||||
methodBlocks = new InstructionListParser(body.Instructions, body.ExceptionHandlers).parse();
|
methodBlocks = new InstructionListParser(body.Instructions, body.ExceptionHandlers).parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,55 +32,6 @@ namespace de4dot.blocks {
|
||||||
Zune,
|
Zune,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
class TypeCache {
|
|
||||||
ModuleDefinition module;
|
|
||||||
de4dot.blocks.OLD_REMOVE.TypeDefinitionDict<TypeDefinition> typeRefToDef = new de4dot.blocks.OLD_REMOVE.TypeDefinitionDict<TypeDefinition>();
|
|
||||||
|
|
||||||
public TypeCache(ModuleDefinition module) {
|
|
||||||
this.module = module;
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void init() {
|
|
||||||
foreach (var type in module.GetTypes())
|
|
||||||
typeRefToDef.add(type, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TypeDefinition lookup(TypeReference typeReference) {
|
|
||||||
return typeRefToDef.find(typeReference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public class TypeCaches {
|
|
||||||
Dictionary<ModuleDefinition, TypeCache> typeCaches = new Dictionary<ModuleDefinition, TypeCache>();
|
|
||||||
|
|
||||||
// Should be called when the whole module is reloaded or when a lot of types have been
|
|
||||||
// modified (eg. renamed)
|
|
||||||
public void invalidate(ModuleDefinition module) {
|
|
||||||
if (module == null)
|
|
||||||
return;
|
|
||||||
typeCaches.Remove(module);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call this to invalidate all modules
|
|
||||||
public List<ModuleDefinition> invalidateAll() {
|
|
||||||
var list = new List<ModuleDefinition>(typeCaches.Keys);
|
|
||||||
typeCaches.Clear();
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TypeDefinition lookup(ModuleDefinition module, TypeReference typeReference) {
|
|
||||||
TypeCache typeCache;
|
|
||||||
if (!typeCaches.TryGetValue(module, out typeCache))
|
|
||||||
typeCaches[module] = typeCache = new TypeCache(module);
|
|
||||||
return typeCache.lookup(typeReference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public class CallCounter {
|
public class CallCounter {
|
||||||
Dictionary<IMethod, int> calls = new Dictionary<IMethod, int>(MethodEqualityComparer.CompareDeclaringTypes);
|
Dictionary<IMethod, int> calls = new Dictionary<IMethod, int>(MethodEqualityComparer.CompareDeclaringTypes);
|
||||||
|
|
||||||
|
@ -109,44 +60,7 @@ namespace de4dot.blocks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public class MethodCalls {
|
|
||||||
Dictionary<string, int> methodCalls = new Dictionary<string, int>(StringComparer.Ordinal);
|
|
||||||
|
|
||||||
public void addMethodCalls(MethodDef method) {
|
|
||||||
if (!method.HasBody)
|
|
||||||
return;
|
|
||||||
foreach (var instr in method.Body.Instructions) {
|
|
||||||
var calledMethod = instr.Operand as MethodReference;
|
|
||||||
if (calledMethod != null)
|
|
||||||
add(calledMethod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(MethodReference method) {
|
|
||||||
string key = method.FullName;
|
|
||||||
if (!methodCalls.ContainsKey(key))
|
|
||||||
methodCalls[key] = 0;
|
|
||||||
methodCalls[key]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int count(string methodFullName) {
|
|
||||||
int count;
|
|
||||||
methodCalls.TryGetValue(methodFullName, out count);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool called(string methodFullName) {
|
|
||||||
return count(methodFullName) != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static class DotNetUtils {
|
public static class DotNetUtils {
|
||||||
#if PORT
|
|
||||||
public static readonly TypeCaches typeCaches = new TypeCaches();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static TypeDef getModuleType(ModuleDef module) {
|
public static TypeDef getModuleType(ModuleDef module) {
|
||||||
return module.GlobalType;
|
return module.GlobalType;
|
||||||
}
|
}
|
||||||
|
@ -222,16 +136,6 @@ namespace de4dot.blocks {
|
||||||
return type != null && isDelegate(type.BaseType);
|
return type != null && isDelegate(type.BaseType);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static bool isSameAssembly(TypeReference type, string assembly) {
|
|
||||||
return MemberReferenceHelper.getCanonicalizedScopeName(type.Scope) == assembly.ToLowerInvariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool isMethod(MethodReference method, string returnType, string parameters) {
|
|
||||||
return method != null && method.FullName == returnType + " " + method.DeclaringType.FullName + "::" + method.Name + parameters;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static bool isMethod(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;
|
return method != null && method.FullName == returnType + " " + method.DeclaringType.FullName + "::" + method.Name + parameters;
|
||||||
}
|
}
|
||||||
|
@ -275,30 +179,6 @@ namespace de4dot.blocks {
|
||||||
return getDllName(dll).Equals(getDllName(method.ImplMap.Module.Name.String), StringComparison.OrdinalIgnoreCase);
|
return getDllName(dll).Equals(getDllName(method.ImplMap.Module.Name.String), StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static MethodDef getMethod(TypeDefinition type, string name) {
|
|
||||||
if (type == null)
|
|
||||||
return null;
|
|
||||||
foreach (var method in type.Methods) {
|
|
||||||
if (method.Name == name)
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MethodDef getMethod(TypeDefinition type, MethodReference methodReference) {
|
|
||||||
if (type == null || methodReference == null)
|
|
||||||
return null;
|
|
||||||
if (methodReference is MethodDef)
|
|
||||||
return (MethodDef)methodReference;
|
|
||||||
foreach (var method in type.Methods) {
|
|
||||||
if (MemberReferenceHelper.compareMethodReference(method, methodReference))
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static MethodDef getMethod(ModuleDefMD module, IMethod method) {
|
public static MethodDef getMethod(ModuleDefMD module, IMethod method) {
|
||||||
if (method == null)
|
if (method == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -386,16 +266,6 @@ namespace de4dot.blocks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static TypeDefinition getType(ModuleDefinition module, TypeReference typeReference) {
|
|
||||||
if (typeReference == null)
|
|
||||||
return null;
|
|
||||||
if (typeReference is TypeDefinition)
|
|
||||||
return (TypeDefinition)typeReference;
|
|
||||||
return typeCaches.lookup(module, typeReference);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static FieldDef getField(ModuleDef module, IField field) {
|
public static FieldDef getField(ModuleDef module, IField field) {
|
||||||
if (field == null)
|
if (field == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -422,18 +292,6 @@ namespace de4dot.blocks {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static FieldDefinition getFieldByName(TypeDefinition type, string name) {
|
|
||||||
if (type == null)
|
|
||||||
return null;
|
|
||||||
foreach (var field in type.Fields) {
|
|
||||||
if (field.Name == name)
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static IEnumerable<IMethod> getMethodCalls(MethodDef method) {
|
public static IEnumerable<IMethod> getMethodCalls(MethodDef method) {
|
||||||
var list = new List<IMethod>();
|
var list = new List<IMethod>();
|
||||||
if (method.HasBody) {
|
if (method.HasBody) {
|
||||||
|
@ -446,14 +304,6 @@ namespace de4dot.blocks {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static MethodCalls getMethodCallCounts(MethodDef method) {
|
|
||||||
var methodCalls = new MethodCalls();
|
|
||||||
methodCalls.addMethodCalls(method);
|
|
||||||
return methodCalls;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static bool hasString(MethodDef method, string s) {
|
public static bool hasString(MethodDef method, string s) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -464,19 +314,6 @@ namespace de4dot.blocks {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static IList<string> getCodeStrings(MethodDef method) {
|
|
||||||
var strings = new List<string>();
|
|
||||||
if (method != null && method.Body != null) {
|
|
||||||
foreach (var instr in method.Body.Instructions) {
|
|
||||||
if (instr.OpCode.Code == Code.Ldstr)
|
|
||||||
strings.Add((string)instr.Operand);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return strings;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static IList<string> getCodeStrings(MethodDef method) {
|
public static IList<string> getCodeStrings(MethodDef method) {
|
||||||
var strings = new List<string>();
|
var strings = new List<string>();
|
||||||
if (method != null && method.Body != null) {
|
if (method != null && method.Body != null) {
|
||||||
|
@ -518,27 +355,6 @@ namespace de4dot.blocks {
|
||||||
return s.Substring(0, index);
|
return s.Substring(0, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
// Copies most things but not everything
|
|
||||||
public static MethodDef clone(MethodDef method) {
|
|
||||||
var newMethod = new MethodDef(method.Name, method.Attributes, method.MethodReturnType.ReturnType);
|
|
||||||
newMethod.MetadataToken = method.MetadataToken;
|
|
||||||
newMethod.Attributes = method.Attributes;
|
|
||||||
newMethod.ImplAttributes = method.ImplAttributes;
|
|
||||||
newMethod.HasThis = method.HasThis;
|
|
||||||
newMethod.ExplicitThis = method.ExplicitThis;
|
|
||||||
newMethod.CallingConvention = method.CallingConvention;
|
|
||||||
newMethod.SemanticsAttributes = method.SemanticsAttributes;
|
|
||||||
newMethod.DeclaringType = method.DeclaringType;
|
|
||||||
foreach (var arg in method.Parameters)
|
|
||||||
newMethod.Parameters.Add(new ParameterDefinition(arg.Name, arg.Attributes, arg.ParameterType));
|
|
||||||
foreach (var gp in method.GenericParameters)
|
|
||||||
newMethod.GenericParameters.Add(new GenericParameter(gp.Name, newMethod) { Attributes = gp.Attributes });
|
|
||||||
copyBodyFromTo(method, newMethod);
|
|
||||||
return newMethod;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Copies most things but not everything
|
// Copies most things but not everything
|
||||||
public static MethodDef clone(MethodDef method) {
|
public static MethodDef clone(MethodDef method) {
|
||||||
var newMethod = new MethodDefUser(method.Name, method.MethodSig, method.ImplAttributes, method.Attributes);
|
var newMethod = new MethodDefUser(method.Name, method.MethodSig, method.ImplAttributes, method.Attributes);
|
||||||
|
@ -557,65 +373,6 @@ namespace de4dot.blocks {
|
||||||
return newMethod;
|
return newMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static Instruction clone(Instruction instr) {
|
|
||||||
return new Instruction {
|
|
||||||
Offset = instr.Offset,
|
|
||||||
OpCode = instr.OpCode,
|
|
||||||
Operand = instr.Operand,
|
|
||||||
SequencePoint = instr.SequencePoint,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void copyBody(MethodDef method, out IList<Instruction> instructions, out IList<ExceptionHandler> exceptionHandlers) {
|
|
||||||
if (method == null || !method.HasBody) {
|
|
||||||
instructions = new List<Instruction>();
|
|
||||||
exceptionHandlers = new List<ExceptionHandler>();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var oldInstrs = method.Body.Instructions;
|
|
||||||
var oldExHandlers = method.Body.ExceptionHandlers;
|
|
||||||
instructions = new List<Instruction>(oldInstrs.Count);
|
|
||||||
exceptionHandlers = new List<ExceptionHandler>(oldExHandlers.Count);
|
|
||||||
var oldToIndex = Utils.createObjectToIndexDictionary(oldInstrs);
|
|
||||||
|
|
||||||
foreach (var oldInstr in oldInstrs)
|
|
||||||
instructions.Add(clone(oldInstr));
|
|
||||||
|
|
||||||
foreach (var newInstr in instructions) {
|
|
||||||
var operand = newInstr.Operand;
|
|
||||||
if (operand is Instruction)
|
|
||||||
newInstr.Operand = instructions[oldToIndex[(Instruction)operand]];
|
|
||||||
else if (operand is Instruction[]) {
|
|
||||||
var oldArray = (Instruction[])operand;
|
|
||||||
var newArray = new Instruction[oldArray.Length];
|
|
||||||
for (int i = 0; i < oldArray.Length; i++)
|
|
||||||
newArray[i] = instructions[oldToIndex[oldArray[i]]];
|
|
||||||
newInstr.Operand = newArray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var oldEx in oldExHandlers) {
|
|
||||||
var newEx = new ExceptionHandler(oldEx.HandlerType) {
|
|
||||||
TryStart = getInstruction(instructions, oldToIndex, oldEx.TryStart),
|
|
||||||
TryEnd = getInstruction(instructions, oldToIndex, oldEx.TryEnd),
|
|
||||||
FilterStart = getInstruction(instructions, oldToIndex, oldEx.FilterStart),
|
|
||||||
HandlerStart= getInstruction(instructions, oldToIndex, oldEx.HandlerStart),
|
|
||||||
HandlerEnd = getInstruction(instructions, oldToIndex, oldEx.HandlerEnd),
|
|
||||||
CatchType = oldEx.CatchType,
|
|
||||||
};
|
|
||||||
exceptionHandlers.Add(newEx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Instruction getInstruction(IList<Instruction> instructions, IDictionary<Instruction, int> instructionToIndex, Instruction instruction) {
|
|
||||||
if (instruction == null)
|
|
||||||
return null;
|
|
||||||
return instructions[instructionToIndex[instruction]];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static void copyBody(MethodDef method, out IList<Instruction> instructions, out IList<ExceptionHandler> exceptionHandlers) {
|
public static void copyBody(MethodDef method, out IList<Instruction> instructions, out IList<ExceptionHandler> exceptionHandlers) {
|
||||||
if (method == null || !method.HasBody) {
|
if (method == null || !method.HasBody) {
|
||||||
instructions = new List<Instruction>();
|
instructions = new List<Instruction>();
|
||||||
|
@ -664,23 +421,6 @@ namespace de4dot.blocks {
|
||||||
return instructions[instructionToIndex[instruction]];
|
return instructions[instructionToIndex[instruction]];
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static void restoreBody(MethodDef method, IEnumerable<Instruction> instructions, IEnumerable<ExceptionHandler> exceptionHandlers) {
|
|
||||||
if (method == null || !method.HasBody)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var bodyInstrs = method.Body.Instructions;
|
|
||||||
bodyInstrs.Clear();
|
|
||||||
foreach (var instr in instructions)
|
|
||||||
bodyInstrs.Add(instr);
|
|
||||||
|
|
||||||
var bodyExceptionHandlers = method.Body.ExceptionHandlers;
|
|
||||||
bodyExceptionHandlers.Clear();
|
|
||||||
foreach (var eh in exceptionHandlers)
|
|
||||||
bodyExceptionHandlers.Add(eh);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static void restoreBody(MethodDef method, IEnumerable<Instruction> instructions, IEnumerable<ExceptionHandler> exceptionHandlers) {
|
public static void restoreBody(MethodDef method, IEnumerable<Instruction> instructions, IEnumerable<ExceptionHandler> exceptionHandlers) {
|
||||||
if (method == null || method.Body == null)
|
if (method == null || method.Body == null)
|
||||||
return;
|
return;
|
||||||
|
@ -712,9 +452,9 @@ namespace de4dot.blocks {
|
||||||
var fromBody = fromMethod.Body;
|
var fromBody = fromMethod.Body;
|
||||||
var toBody = toMethod.Body;
|
var toBody = toMethod.Body;
|
||||||
|
|
||||||
toBody.LocalList.Clear();
|
toBody.Variables.Clear();
|
||||||
foreach (var local in fromBody.LocalList)
|
foreach (var local in fromBody.Variables)
|
||||||
toBody.LocalList.Add(new Local(local.Type));
|
toBody.Variables.Add(new Local(local.Type));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateInstructionOperands(MethodDef fromMethod, MethodDef toMethod) {
|
static void updateInstructionOperands(MethodDef fromMethod, MethodDef toMethod) {
|
||||||
|
@ -729,8 +469,8 @@ namespace de4dot.blocks {
|
||||||
var toParams = toMethod.Parameters;
|
var toParams = toMethod.Parameters;
|
||||||
for (int i = 0; i < fromParams.Count; i++)
|
for (int i = 0; i < fromParams.Count; i++)
|
||||||
newOperands[fromParams[i]] = toParams[i];
|
newOperands[fromParams[i]] = toParams[i];
|
||||||
for (int i = 0; i < fromBody.LocalList.Count; i++)
|
for (int i = 0; i < fromBody.Variables.Count; i++)
|
||||||
newOperands[fromBody.LocalList[i]] = toBody.LocalList[i];
|
newOperands[fromBody.Variables[i]] = toBody.Variables[i];
|
||||||
|
|
||||||
foreach (var instr in toBody.Instructions) {
|
foreach (var instr in toBody.Instructions) {
|
||||||
if (instr.Operand == null)
|
if (instr.Operand == null)
|
||||||
|
@ -741,19 +481,6 @@ namespace de4dot.blocks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static IEnumerable<CustomAttribute> findAttributes(ICustomAttributeProvider custAttrProvider, TypeReference attr) {
|
|
||||||
var list = new List<CustomAttribute>();
|
|
||||||
if (custAttrProvider == null)
|
|
||||||
return list;
|
|
||||||
foreach (var cattr in custAttrProvider.CustomAttributes) {
|
|
||||||
if (MemberReferenceHelper.compareTypes(attr, cattr.AttributeType))
|
|
||||||
list.Add(cattr);
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static string getCustomArgAsString(CustomAttribute cattr, int arg) {
|
public static string getCustomArgAsString(CustomAttribute cattr, int arg) {
|
||||||
if (cattr == null || arg >= cattr.ConstructorArguments.Count)
|
if (cattr == null || arg >= cattr.ConstructorArguments.Count)
|
||||||
return null;
|
return null;
|
||||||
|
@ -797,234 +524,12 @@ namespace de4dot.blocks {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static bool hasReturnValue(IMethodSignature method) {
|
|
||||||
var type = method.MethodReturnType.ReturnType;
|
|
||||||
while (type.IsOptionalModifier || type.IsRequiredModifier)
|
|
||||||
type = ((TypeSpecification)type).ElementType;
|
|
||||||
return type.EType != ElementType.Void;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static bool hasReturnValue(IMethod method) {
|
public static bool hasReturnValue(IMethod method) {
|
||||||
if (method == null || method.MethodSig == null || method.MethodSig.RetType == null)
|
if (method == null || method.MethodSig == null || method.MethodSig.RetType == null)
|
||||||
return false;
|
return false;
|
||||||
return method.MethodSig.RetType.RemovePinnedAndModifiers().ElementType != ElementType.Void;
|
return method.MethodSig.RetType.RemovePinnedAndModifiers().ElementType != ElementType.Void;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static void updateStack(Instruction instr, ref int stack, bool methodHasReturnValue) {
|
|
||||||
int pushes, pops;
|
|
||||||
calculateStackUsage(instr, methodHasReturnValue, out pushes, out pops);
|
|
||||||
if (pops == -1)
|
|
||||||
stack = 0;
|
|
||||||
else
|
|
||||||
stack += pushes - pops;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets pops to -1 if the stack is supposed to be cleared
|
|
||||||
public static void calculateStackUsage(Instruction instr, bool methodHasReturnValue, out int pushes, out int pops) {
|
|
||||||
if (instr.OpCode.FlowControl == FlowControl.Call)
|
|
||||||
calculateStackUsage_call(instr, out pushes, out pops);
|
|
||||||
else
|
|
||||||
calculateStackUsage_nonCall(instr, methodHasReturnValue, out pushes, out pops);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void calculateStackUsage_call(Instruction instr, out int pushes, out int pops) {
|
|
||||||
pushes = 0;
|
|
||||||
pops = 0;
|
|
||||||
|
|
||||||
var method = (IMethodSignature)instr.Operand;
|
|
||||||
bool implicitThis = method.HasThis && !method.ExplicitThis;
|
|
||||||
if (hasReturnValue(method) || (instr.OpCode.Code == Code.Newobj && method.HasThis))
|
|
||||||
pushes++;
|
|
||||||
|
|
||||||
if (method.HasParameters)
|
|
||||||
pops += method.Parameters.Count;
|
|
||||||
if (implicitThis && instr.OpCode.Code != Code.Newobj)
|
|
||||||
pops++;
|
|
||||||
if (instr.OpCode.Code == Code.Calli)
|
|
||||||
pops++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets pops to -1 if the stack is supposed to be cleared
|
|
||||||
static void calculateStackUsage_nonCall(Instruction instr, bool methodHasReturnValue, out int pushes, out int pops) {
|
|
||||||
StackBehaviour stackBehavior;
|
|
||||||
|
|
||||||
pushes = 0;
|
|
||||||
pops = 0;
|
|
||||||
|
|
||||||
stackBehavior = instr.OpCode.StackBehaviourPush;
|
|
||||||
switch (stackBehavior) {
|
|
||||||
case StackBehaviour.Push0:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StackBehaviour.Push1:
|
|
||||||
case StackBehaviour.Pushi:
|
|
||||||
case StackBehaviour.Pushi8:
|
|
||||||
case StackBehaviour.Pushr4:
|
|
||||||
case StackBehaviour.Pushr8:
|
|
||||||
case StackBehaviour.Pushref:
|
|
||||||
pushes++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StackBehaviour.Push1_push1:
|
|
||||||
pushes += 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StackBehaviour.Varpush: // only call, calli, callvirt which are handled elsewhere
|
|
||||||
default:
|
|
||||||
throw new ApplicationException(string.Format("Unknown push StackBehavior {0}", stackBehavior));
|
|
||||||
}
|
|
||||||
|
|
||||||
stackBehavior = instr.OpCode.StackBehaviourPop;
|
|
||||||
switch (stackBehavior) {
|
|
||||||
case StackBehaviour.Pop0:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StackBehaviour.Pop1:
|
|
||||||
case StackBehaviour.Popi:
|
|
||||||
case StackBehaviour.Popref:
|
|
||||||
pops++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StackBehaviour.Pop1_pop1:
|
|
||||||
case StackBehaviour.Popi_pop1:
|
|
||||||
case StackBehaviour.Popi_popi:
|
|
||||||
case StackBehaviour.Popi_popi8:
|
|
||||||
case StackBehaviour.Popi_popr4:
|
|
||||||
case StackBehaviour.Popi_popr8:
|
|
||||||
case StackBehaviour.Popref_pop1:
|
|
||||||
case StackBehaviour.Popref_popi:
|
|
||||||
pops += 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StackBehaviour.Popi_popi_popi:
|
|
||||||
case StackBehaviour.Popref_popi_popi:
|
|
||||||
case StackBehaviour.Popref_popi_popi8:
|
|
||||||
case StackBehaviour.Popref_popi_popr4:
|
|
||||||
case StackBehaviour.Popref_popi_popr8:
|
|
||||||
case StackBehaviour.Popref_popi_popref:
|
|
||||||
pops += 3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StackBehaviour.PopAll:
|
|
||||||
pops = -1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StackBehaviour.Varpop: // call, calli, callvirt, newobj (all handled elsewhere), and ret
|
|
||||||
if (methodHasReturnValue)
|
|
||||||
pops++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new ApplicationException(string.Format("Unknown pop StackBehavior {0}", stackBehavior));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AssemblyNameReference getAssemblyNameReference(TypeReference type) {
|
|
||||||
var scope = type.Scope;
|
|
||||||
if (scope == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (scope is ModuleDefinition) {
|
|
||||||
var moduleDefinition = (ModuleDefinition)scope;
|
|
||||||
return moduleDefinition.Assembly.Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scope is AssemblyNameReference)
|
|
||||||
return (AssemblyNameReference)scope;
|
|
||||||
|
|
||||||
if (scope is ModuleReference && type.Module.Assembly != null) {
|
|
||||||
foreach (var module in type.Module.Assembly.Modules) {
|
|
||||||
if (scope.Name == module.Name)
|
|
||||||
return type.Module.Assembly.Name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new ApplicationException(string.Format("Unknown IMetadataScope type: {0}", scope.GetType()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string getFullAssemblyName(TypeReference type) {
|
|
||||||
var asmRef = getAssemblyNameReference(type);
|
|
||||||
return asmRef == null ? null : asmRef.FullName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool isAssembly(IMetadataScope scope, string assemblySimpleName) {
|
|
||||||
return scope.Name == assemblySimpleName ||
|
|
||||||
scope.Name.StartsWith(assemblySimpleName + ",", StringComparison.Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool isReferenceToModule(ModuleReference moduleReference, IMetadataScope scope) {
|
|
||||||
switch (scope.MetadataScopeType) {
|
|
||||||
case MetadataScopeType.AssemblyNameReference:
|
|
||||||
var asmRef = (AssemblyNameReference)scope;
|
|
||||||
var module = moduleReference as ModuleDefinition;
|
|
||||||
return module != null && module.Assembly != null && module.Assembly.Name.FullName == asmRef.FullName;
|
|
||||||
|
|
||||||
case MetadataScopeType.ModuleDefinition:
|
|
||||||
return moduleReference == scope;
|
|
||||||
|
|
||||||
case MetadataScopeType.ModuleReference:
|
|
||||||
return moduleReference.Name == ((ModuleReference)scope).Name;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new ApplicationException("Unknown MetadataScopeType");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getArgIndex(Instruction instr) {
|
|
||||||
switch (instr.OpCode.Code) {
|
|
||||||
case Code.Ldarg_0: return 0;
|
|
||||||
case Code.Ldarg_1: return 1;
|
|
||||||
case Code.Ldarg_2: return 2;
|
|
||||||
case Code.Ldarg_3: return 3;
|
|
||||||
|
|
||||||
case Code.Ldarga:
|
|
||||||
case Code.Ldarga_S:
|
|
||||||
case Code.Ldarg:
|
|
||||||
case Code.Ldarg_S:
|
|
||||||
return getArgIndex(instr.Operand as ParameterDefinition);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getArgIndex(ParameterDefinition arg) {
|
|
||||||
if (arg == null)
|
|
||||||
return -1;
|
|
||||||
return arg.Sequence;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<ParameterDefinition> getParameters(MethodReference method) {
|
|
||||||
var args = new List<ParameterDefinition>(method.Parameters.Count + 1);
|
|
||||||
if (method.HasImplicitThis) {
|
|
||||||
var methodDef = method as MethodDef;
|
|
||||||
if (methodDef != null && methodDef.Body != null)
|
|
||||||
args.Add(methodDef.Body.ThisParameter);
|
|
||||||
else
|
|
||||||
args.Add(new ParameterDefinition(method.DeclaringType, method));
|
|
||||||
}
|
|
||||||
foreach (var arg in method.Parameters)
|
|
||||||
args.Add(arg);
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ParameterDefinition getParameter(MethodReference method, Instruction instr) {
|
|
||||||
return getParameter(getParameters(method), instr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ParameterDefinition getParameter(IList<ParameterDefinition> parameters, Instruction instr) {
|
|
||||||
return getParameter(parameters, getArgIndex(instr));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ParameterDefinition getParameter(IList<ParameterDefinition> parameters, int index) {
|
|
||||||
if (0 <= index && index < parameters.Count)
|
|
||||||
return parameters[index];
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static Parameter getParameter(IList<Parameter> parameters, int index) {
|
public static Parameter getParameter(IList<Parameter> parameters, int index) {
|
||||||
if (0 <= index && index < parameters.Count)
|
if (0 <= index && index < parameters.Count)
|
||||||
return parameters[index];
|
return parameters[index];
|
||||||
|
@ -1037,17 +542,6 @@ namespace de4dot.blocks {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static List<TypeReference> getArgs(MethodReference method) {
|
|
||||||
var args = new List<TypeReference>(method.Parameters.Count + 1);
|
|
||||||
if (method.HasImplicitThis)
|
|
||||||
args.Add(method.DeclaringType);
|
|
||||||
foreach (var arg in method.Parameters)
|
|
||||||
args.Add(arg.ParameterType);
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static List<TypeSig> getArgs(IMethod method) {
|
public static List<TypeSig> getArgs(IMethod method) {
|
||||||
var sig = method.MethodSig;
|
var sig = method.MethodSig;
|
||||||
var args = new List<TypeSig>(sig.Params.Count + 1);
|
var args = new List<TypeSig>(sig.Params.Count + 1);
|
||||||
|
@ -1058,29 +552,6 @@ namespace de4dot.blocks {
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static TypeReference getArgType(MethodReference method, Instruction instr) {
|
|
||||||
return getArgType(getArgs(method), instr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TypeReference getArgType(IList<TypeReference> methodArgs, Instruction instr) {
|
|
||||||
return getArgType(methodArgs, getArgIndex(instr));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TypeReference getArgType(IList<TypeReference> methodArgs, int index) {
|
|
||||||
if (0 <= index && index < methodArgs.Count)
|
|
||||||
return methodArgs[index];
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getArgsCount(MethodReference method) {
|
|
||||||
int count = method.Parameters.Count;
|
|
||||||
if (method.HasImplicitThis)
|
|
||||||
count++;
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static int getArgsCount(IMethod method) {
|
public static int getArgsCount(IMethod method) {
|
||||||
var sig = method.MethodSig;
|
var sig = method.MethodSig;
|
||||||
if (sig == null)
|
if (sig == null)
|
||||||
|
@ -1106,7 +577,6 @@ namespace de4dot.blocks {
|
||||||
return GenericArgsSubstitutor.create(type, typeArgs, genMethodArgs);
|
return GenericArgsSubstitutor.create(type, typeArgs, genMethodArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static Instruction getInstruction(IList<Instruction> instructions, ref int index) {
|
public static Instruction getInstruction(IList<Instruction> instructions, ref int index) {
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
if (index < 0 || index >= instructions.Count)
|
if (index < 0 || index >= instructions.Count)
|
||||||
|
@ -1125,97 +595,6 @@ namespace de4dot.blocks {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
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 == Code.Nop)
|
|
||||||
continue;
|
|
||||||
if (instr.OpCode.OpCodeType == OpCodeType.Prefix)
|
|
||||||
continue;
|
|
||||||
if (instr == null || (instr.OpCode.Code != Code.Br && instr.OpCode.Code != Code.Br_S))
|
|
||||||
return instr;
|
|
||||||
instr = instr.Operand as Instruction;
|
|
||||||
if (instr == null)
|
|
||||||
return null;
|
|
||||||
index = instructions.IndexOf(instr);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static PropertyDefinition createPropertyDefinition(string name, TypeReference propType, MethodDef getter, MethodDef setter) {
|
|
||||||
return new PropertyDefinition(name, PropertyAttributes.None, propType) {
|
|
||||||
MetadataToken = nextPropertyToken(),
|
|
||||||
GetMethod = getter,
|
|
||||||
SetMethod = setter,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EventDefinition createEventDefinition(string name, TypeReference eventType) {
|
|
||||||
return new EventDefinition(name, EventAttributes.None, eventType) {
|
|
||||||
MetadataToken = nextEventToken(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FieldDefinition createFieldDefinition(string name, FieldAttributes attributes, TypeReference fieldType) {
|
|
||||||
return new FieldDefinition(name, attributes, fieldType) {
|
|
||||||
MetadataToken = nextFieldToken(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nextTokenRid = 0x00FFFFFF;
|
|
||||||
public static MetadataToken nextTypeRefToken() {
|
|
||||||
return new MetadataToken(TokenType.TypeRef, nextTokenRid--);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MetadataToken nextTypeDefToken() {
|
|
||||||
return new MetadataToken(TokenType.TypeDef, nextTokenRid--);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MetadataToken nextFieldToken() {
|
|
||||||
return new MetadataToken(TokenType.Field, nextTokenRid--);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MetadataToken nextMethodToken() {
|
|
||||||
return new MetadataToken(TokenType.Method, nextTokenRid--);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MetadataToken nextPropertyToken() {
|
|
||||||
return new MetadataToken(TokenType.Property, nextTokenRid--);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MetadataToken nextEventToken() {
|
|
||||||
return new MetadataToken(TokenType.Event, nextTokenRid--);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TypeReference findTypeReference(ModuleDefinition module, string asmSimpleName, string fullName) {
|
|
||||||
foreach (var type in module.GetTypeReferences()) {
|
|
||||||
if (type.FullName != fullName)
|
|
||||||
continue;
|
|
||||||
var asmRef = type.Scope as AssemblyNameReference;
|
|
||||||
if (asmRef == null || asmRef.Name != asmSimpleName)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TypeReference findOrCreateTypeReference(ModuleDefinition module, AssemblyNameReference asmRef, string ns, string name, bool isValueType) {
|
|
||||||
var typeRef = findTypeReference(module, asmRef.Name, ns + "." + name);
|
|
||||||
if (typeRef != null)
|
|
||||||
return typeRef;
|
|
||||||
|
|
||||||
typeRef = new TypeReference(ns, name, module, asmRef);
|
|
||||||
typeRef.MetadataToken = nextTypeRefToken();
|
|
||||||
typeRef.IsValueType = isValueType;
|
|
||||||
return typeRef;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public static TypeDefOrRefSig findOrCreateTypeReference(ModuleDef module, AssemblyRef asmRef, string ns, string name, bool isValueType) {
|
public static TypeDefOrRefSig findOrCreateTypeReference(ModuleDef module, AssemblyRef asmRef, string ns, string name, bool isValueType) {
|
||||||
var typeRef = module.UpdateRowId(new TypeRefUser(module, ns, name, asmRef));
|
var typeRef = module.UpdateRowId(new TypeRefUser(module, ns, name, asmRef));
|
||||||
|
@ -1341,29 +720,5 @@ namespace de4dot.blocks {
|
||||||
args.Reverse();
|
args.Reverse();
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT
|
|
||||||
public static AssemblyNameReference addAssemblyReference(ModuleDefinition module, AssemblyNameReference asmRef) {
|
|
||||||
foreach (var modAsmRef in module.AssemblyReferences) {
|
|
||||||
if (modAsmRef.FullName == asmRef.FullName)
|
|
||||||
return modAsmRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
var newAsmRef = AssemblyNameReference.Parse(asmRef.FullName);
|
|
||||||
module.AssemblyReferences.Add(newAsmRef);
|
|
||||||
return newAsmRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ModuleReference addModuleReference(ModuleDefinition module, ModuleReference modRef) {
|
|
||||||
foreach (var modModRef in module.ModuleReferences) {
|
|
||||||
if (modModRef.Name == modRef.Name)
|
|
||||||
return modModRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
var newModRef = new ModuleReference(modRef.Name);
|
|
||||||
module.ModuleReferences.Add(newModRef);
|
|
||||||
return newModRef;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,231 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2011-2012 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if PORT
|
|
||||||
|
|
||||||
// Create a new type, method, etc, where all generic parameters have been replaced with the
|
|
||||||
// corresponding generic argument.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using Mono.Cecil;
|
|
||||||
using de4dot.blocks;
|
|
||||||
|
|
||||||
namespace de4dot.blocks {
|
|
||||||
public class TypeReferenceInstance : TypeReferenceUpdaterBase {
|
|
||||||
TypeReference typeReference;
|
|
||||||
GenericInstanceType git;
|
|
||||||
IGenericInstance gim;
|
|
||||||
bool modified;
|
|
||||||
|
|
||||||
public static TypeReference make(TypeReference typeReference, GenericInstanceType git) {
|
|
||||||
return make(typeReference, git, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TypeReference make(TypeReference typeReference, GenericInstanceType git, IGenericInstance gim) {
|
|
||||||
if (git == null && gim == null)
|
|
||||||
return typeReference;
|
|
||||||
return new TypeReferenceInstance(typeReference, git, gim).makeInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeReferenceInstance(TypeReference typeReference, GenericInstanceType git, IGenericInstance gim) {
|
|
||||||
this.typeReference = typeReference;
|
|
||||||
this.git = git;
|
|
||||||
this.gim = gim;
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkModified(object a, object b) {
|
|
||||||
if (!ReferenceEquals(a, b))
|
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns same one if nothing was modified
|
|
||||||
TypeReference makeInstance() {
|
|
||||||
var rv = update(typeReference);
|
|
||||||
return modified ? rv : typeReference;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override FunctionPointerType updateFunctionPointerType(FunctionPointerType a) {
|
|
||||||
var rv = new FunctionPointerType();
|
|
||||||
rv.function = MethodReferenceInstance.make(a.function, git, gim);
|
|
||||||
checkModified(a.function, rv.function);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override TypeReference updateGenericParameter(GenericParameter a) {
|
|
||||||
switch (a.Type) {
|
|
||||||
case GenericParameterType.Type:
|
|
||||||
if (git == null || a.Position >= git.GenericArguments.Count ||
|
|
||||||
!MemberReferenceHelper.compareTypes(git.ElementType, a.Owner as TypeReference)) {
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
modified = true;
|
|
||||||
return update(git.GenericArguments[a.Position]);
|
|
||||||
|
|
||||||
case GenericParameterType.Method:
|
|
||||||
if (gim == null || a.Position >= gim.GenericArguments.Count)
|
|
||||||
return a;
|
|
||||||
modified = true;
|
|
||||||
return update(gim.GenericArguments[a.Position]);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class MultiTypeRefInstance {
|
|
||||||
GenericInstanceType git;
|
|
||||||
IGenericInstance gim;
|
|
||||||
bool modified;
|
|
||||||
|
|
||||||
public MultiTypeRefInstance(GenericInstanceType git)
|
|
||||||
: this(git, null) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public MultiTypeRefInstance(GenericInstanceType git, IGenericInstance gim) {
|
|
||||||
this.git = git;
|
|
||||||
this.gim = gim;
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkModified(object a, object b) {
|
|
||||||
if (!ReferenceEquals(a, b))
|
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected TypeReference makeInstance(TypeReference tr) {
|
|
||||||
var type = TypeReferenceInstance.make(tr, git, gim);
|
|
||||||
checkModified(type, tr);
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected T getResult<T>(T orig, T newOne) {
|
|
||||||
return modified ? newOne : orig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MethodReferenceInstance : MultiTypeRefInstance {
|
|
||||||
MethodReference methodReference;
|
|
||||||
|
|
||||||
public static MethodReference make(MethodReference methodReference, GenericInstanceType git) {
|
|
||||||
return make(methodReference, git, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MethodReference make(MethodReference methodReference, GenericInstanceType git, IGenericInstance gim) {
|
|
||||||
if (git == null && gim == null)
|
|
||||||
return methodReference;
|
|
||||||
return new MethodReferenceInstance(methodReference, git, gim).makeInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
MethodReferenceInstance(MethodReference methodReference, GenericInstanceType git, IGenericInstance gim)
|
|
||||||
: base(git, gim) {
|
|
||||||
this.methodReference = methodReference;
|
|
||||||
}
|
|
||||||
|
|
||||||
MethodReference makeInstance() {
|
|
||||||
var mr = new MethodReference(methodReference.Name, makeInstance(methodReference.MethodReturnType.ReturnType), methodReference.DeclaringType);
|
|
||||||
mr.HasThis = methodReference.HasThis;
|
|
||||||
mr.ExplicitThis = methodReference.ExplicitThis;
|
|
||||||
mr.CallingConvention = methodReference.CallingConvention;
|
|
||||||
|
|
||||||
if (methodReference.HasParameters) {
|
|
||||||
foreach (var param in methodReference.Parameters) {
|
|
||||||
var newParam = new ParameterDefinition(param.Name, param.Attributes, makeInstance(param.ParameterType));
|
|
||||||
mr.Parameters.Add(newParam);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (methodReference.HasGenericParameters) {
|
|
||||||
foreach (var param in methodReference.GenericParameters) {
|
|
||||||
var newParam = new GenericParameter(param.Name, mr);
|
|
||||||
mr.GenericParameters.Add(newParam);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return getResult(methodReference, mr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FieldReferenceInstance : MultiTypeRefInstance {
|
|
||||||
FieldReference fieldReference;
|
|
||||||
|
|
||||||
public static FieldReference make(FieldReference fieldReference, GenericInstanceType git) {
|
|
||||||
if (git == null)
|
|
||||||
return fieldReference;
|
|
||||||
return new FieldReferenceInstance(fieldReference, git).makeInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
FieldReferenceInstance(FieldReference fieldReference, GenericInstanceType git)
|
|
||||||
: base(git) {
|
|
||||||
this.fieldReference = fieldReference;
|
|
||||||
}
|
|
||||||
|
|
||||||
FieldReference makeInstance() {
|
|
||||||
var fr = new FieldReference(fieldReference.Name, makeInstance(fieldReference.FieldType));
|
|
||||||
return getResult(fieldReference, fr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class EventReferenceInstance : MultiTypeRefInstance {
|
|
||||||
EventReference eventReference;
|
|
||||||
|
|
||||||
public static EventReference make(EventReference eventReference, GenericInstanceType git) {
|
|
||||||
if (git == null)
|
|
||||||
return eventReference;
|
|
||||||
return new EventReferenceInstance(eventReference, git).makeInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
EventReferenceInstance(EventReference eventReference, GenericInstanceType git)
|
|
||||||
: base(git) {
|
|
||||||
this.eventReference = eventReference;
|
|
||||||
}
|
|
||||||
|
|
||||||
EventReference makeInstance() {
|
|
||||||
var er = new EventDefinition(eventReference.Name, (EventAttributes)0, makeInstance(eventReference.EventType));
|
|
||||||
return getResult(eventReference, er);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PropertyReferenceInstance : MultiTypeRefInstance {
|
|
||||||
PropertyReference propertyReference;
|
|
||||||
|
|
||||||
public static PropertyReference make(PropertyReference propertyReference, GenericInstanceType git) {
|
|
||||||
if (git == null)
|
|
||||||
return propertyReference;
|
|
||||||
return new PropertyReferenceInstance(propertyReference, git).makeInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyReferenceInstance(PropertyReference propertyReference, GenericInstanceType git)
|
|
||||||
: base(git) {
|
|
||||||
this.propertyReference = propertyReference;
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyReference makeInstance() {
|
|
||||||
var pr = new PropertyDefinition(propertyReference.Name, (PropertyAttributes)0, makeInstance(propertyReference.PropertyType));
|
|
||||||
if (propertyReference.Parameters != null) {
|
|
||||||
foreach (var param in propertyReference.Parameters) {
|
|
||||||
var newParam = new ParameterDefinition(param.Name, param.Attributes, makeInstance(param.ParameterType));
|
|
||||||
pr.Parameters.Add(newParam);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return getResult(propertyReference, pr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,862 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2011-2012 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if PORT
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Mono.Cecil;
|
|
||||||
using Mono.Cecil.Metadata;
|
|
||||||
|
|
||||||
namespace de4dot.blocks.OLD_REMOVE {
|
|
||||||
public class TypeDefinitionDict<TValue> {
|
|
||||||
Dictionary<ScopeAndTokenKey, TValue> tokenToValue = new Dictionary<ScopeAndTokenKey, TValue>();
|
|
||||||
Dictionary<ScopeAndTokenKey, TypeDefinition> tokenToKey = new Dictionary<ScopeAndTokenKey, TypeDefinition>();
|
|
||||||
Dictionary<TypeReferenceKey, TValue> refToValue = new Dictionary<TypeReferenceKey, TValue>();
|
|
||||||
Dictionary<TypeReferenceKey, TypeDefinition> refToKey = new Dictionary<TypeReferenceKey, TypeDefinition>();
|
|
||||||
|
|
||||||
public int Count {
|
|
||||||
get { return tokenToValue.Count; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<TypeDefinition> getKeys() {
|
|
||||||
return tokenToKey.Values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<TValue> getValues() {
|
|
||||||
return tokenToValue.Values;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopeAndTokenKey getTokenKey(TypeReference typeReference) {
|
|
||||||
return new ScopeAndTokenKey(typeReference);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeReferenceKey getReferenceKey(TypeReference typeReference) {
|
|
||||||
return new TypeReferenceKey(typeReference);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TValue find(TypeReference typeReference) {
|
|
||||||
TValue value;
|
|
||||||
if (typeReference is TypeDefinition)
|
|
||||||
tokenToValue.TryGetValue(getTokenKey(typeReference), out value);
|
|
||||||
else
|
|
||||||
refToValue.TryGetValue(getReferenceKey(typeReference), out value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TValue findAny(TypeReference typeReference) {
|
|
||||||
TValue value;
|
|
||||||
if (tokenToValue.TryGetValue(getTokenKey(typeReference), out value))
|
|
||||||
return value;
|
|
||||||
|
|
||||||
refToValue.TryGetValue(getReferenceKey(typeReference), out value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(TypeDefinition typeDefinition, TValue value) {
|
|
||||||
var tokenKey = getTokenKey(typeDefinition);
|
|
||||||
tokenToValue[tokenKey] = value;
|
|
||||||
tokenToKey[tokenKey] = typeDefinition;
|
|
||||||
|
|
||||||
var refKey = getReferenceKey(typeDefinition);
|
|
||||||
if (!refToValue.ContainsKey(refKey) ||
|
|
||||||
getAccessibilityOrder(typeDefinition) < getAccessibilityOrder(refToKey[refKey])) {
|
|
||||||
refToKey[refKey] = typeDefinition;
|
|
||||||
refToValue[refKey] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Order: public, family, assembly, private
|
|
||||||
static int[] accessibilityOrder = new int[8] {
|
|
||||||
40, // NotPublic
|
|
||||||
0, // Public
|
|
||||||
10, // NestedPublic
|
|
||||||
70, // NestedPrivate
|
|
||||||
20, // NestedFamily
|
|
||||||
50, // NestedAssembly
|
|
||||||
60, // NestedFamANDAssem
|
|
||||||
30, // NestedFamORAssem
|
|
||||||
};
|
|
||||||
static int getAccessibilityOrder(TypeDefinition typeDefinition) {
|
|
||||||
return accessibilityOrder[(int)typeDefinition.Attributes & 7];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTypesRenamed() {
|
|
||||||
var newTypeRefToValue = new Dictionary<TypeReferenceKey, TValue>(refToValue.Count);
|
|
||||||
foreach (var kvp in refToValue)
|
|
||||||
newTypeRefToValue[getReferenceKey((TypeDefinition)kvp.Key.TypeReference)] = kvp.Value;
|
|
||||||
refToValue = newTypeRefToValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class FieldDefinitionDictBase<TValue> {
|
|
||||||
Dictionary<ScopeAndTokenKey, TValue> tokenToValue = new Dictionary<ScopeAndTokenKey, TValue>();
|
|
||||||
Dictionary<ScopeAndTokenKey, FieldDefinition> tokenToKey = new Dictionary<ScopeAndTokenKey, FieldDefinition>();
|
|
||||||
Dictionary<IFieldReferenceKey, TValue> refToValue = new Dictionary<IFieldReferenceKey, TValue>();
|
|
||||||
Dictionary<IFieldReferenceKey, FieldDefinition> refToKey = new Dictionary<IFieldReferenceKey, FieldDefinition>();
|
|
||||||
|
|
||||||
public int Count {
|
|
||||||
get { return tokenToValue.Count; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<FieldDefinition> getKeys() {
|
|
||||||
return tokenToKey.Values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<TValue> getValues() {
|
|
||||||
return tokenToValue.Values;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopeAndTokenKey getTokenKey(FieldReference fieldReference) {
|
|
||||||
return new ScopeAndTokenKey(fieldReference);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract IFieldReferenceKey getReferenceKey(FieldReference fieldReference);
|
|
||||||
|
|
||||||
public TValue find(FieldReference fieldReference) {
|
|
||||||
TValue value;
|
|
||||||
if (fieldReference is FieldDefinition)
|
|
||||||
tokenToValue.TryGetValue(getTokenKey(fieldReference), out value);
|
|
||||||
else
|
|
||||||
refToValue.TryGetValue(getReferenceKey(fieldReference), out value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TValue findAny(FieldReference fieldReference) {
|
|
||||||
TValue value;
|
|
||||||
if (tokenToValue.TryGetValue(getTokenKey(fieldReference), out value))
|
|
||||||
return value;
|
|
||||||
|
|
||||||
refToValue.TryGetValue(getReferenceKey(fieldReference), out value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(FieldDefinition fieldDefinition, TValue value) {
|
|
||||||
var tokenKey = getTokenKey(fieldDefinition);
|
|
||||||
tokenToValue[tokenKey] = value;
|
|
||||||
tokenToKey[tokenKey] = fieldDefinition;
|
|
||||||
|
|
||||||
var refKey = getReferenceKey(fieldDefinition);
|
|
||||||
if (!refToValue.ContainsKey(refKey) ||
|
|
||||||
getAccessibilityOrder(fieldDefinition) < getAccessibilityOrder(refToKey[refKey])) {
|
|
||||||
refToKey[refKey] = fieldDefinition;
|
|
||||||
refToValue[refKey] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Order: public, family, assembly, private
|
|
||||||
static int[] accessibilityOrder = new int[8] {
|
|
||||||
60, // CompilerControlled
|
|
||||||
50, // Private
|
|
||||||
40, // FamANDAssem
|
|
||||||
30, // Assembly
|
|
||||||
10, // Family
|
|
||||||
20, // FamORAssem
|
|
||||||
0, // Public
|
|
||||||
70, // <reserved>
|
|
||||||
};
|
|
||||||
static int getAccessibilityOrder(FieldDefinition fieldDefinition) {
|
|
||||||
return accessibilityOrder[(int)fieldDefinition.Attributes & 7];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTypesRenamed() {
|
|
||||||
var newFieldRefToDef = new Dictionary<IFieldReferenceKey, TValue>(refToValue.Count);
|
|
||||||
foreach (var kvp in refToValue)
|
|
||||||
newFieldRefToDef[getReferenceKey((FieldDefinition)kvp.Key.FieldReference)] = kvp.Value;
|
|
||||||
refToValue = newFieldRefToDef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FieldDefinitionDict<TValue> : FieldDefinitionDictBase<TValue> {
|
|
||||||
protected override IFieldReferenceKey getReferenceKey(FieldReference fieldReference) {
|
|
||||||
return new FieldReferenceKey(fieldReference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FieldDefinitionAndDeclaringTypeDict<TValue> : FieldDefinitionDictBase<TValue> {
|
|
||||||
protected override IFieldReferenceKey getReferenceKey(FieldReference fieldReference) {
|
|
||||||
return new FieldReferenceAndDeclaringTypeKey(fieldReference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class MethodDefinitionDictBase<TValue> {
|
|
||||||
Dictionary<ScopeAndTokenKey, TValue> tokenToValue = new Dictionary<ScopeAndTokenKey, TValue>();
|
|
||||||
Dictionary<ScopeAndTokenKey, MethodDefinition> tokenToKey = new Dictionary<ScopeAndTokenKey, MethodDefinition>();
|
|
||||||
Dictionary<IMethodReferenceKey, TValue> refToValue = new Dictionary<IMethodReferenceKey, TValue>();
|
|
||||||
Dictionary<IMethodReferenceKey, MethodDefinition> refToKey = new Dictionary<IMethodReferenceKey, MethodDefinition>();
|
|
||||||
|
|
||||||
public int Count {
|
|
||||||
get { return tokenToValue.Count; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<MethodDefinition> getKeys() {
|
|
||||||
return tokenToKey.Values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<TValue> getValues() {
|
|
||||||
return tokenToValue.Values;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopeAndTokenKey getTokenKey(MethodReference methodReference) {
|
|
||||||
return new ScopeAndTokenKey(methodReference);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract IMethodReferenceKey getReferenceKey(MethodReference methodReference);
|
|
||||||
|
|
||||||
public TValue find(MethodReference methodReference) {
|
|
||||||
TValue value;
|
|
||||||
if (methodReference is MethodDefinition)
|
|
||||||
tokenToValue.TryGetValue(getTokenKey(methodReference), out value);
|
|
||||||
else
|
|
||||||
refToValue.TryGetValue(getReferenceKey(methodReference), out value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TValue findAny(MethodReference methodReference) {
|
|
||||||
TValue value;
|
|
||||||
if (tokenToValue.TryGetValue(getTokenKey(methodReference), out value))
|
|
||||||
return value;
|
|
||||||
|
|
||||||
refToValue.TryGetValue(getReferenceKey(methodReference), out value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(MethodDefinition methodDefinition, TValue value) {
|
|
||||||
var tokenKey = getTokenKey(methodDefinition);
|
|
||||||
tokenToValue[tokenKey] = value;
|
|
||||||
tokenToKey[tokenKey] = methodDefinition;
|
|
||||||
|
|
||||||
var refKey = getReferenceKey(methodDefinition);
|
|
||||||
if (!refToValue.ContainsKey(refKey) ||
|
|
||||||
getAccessibilityOrder(methodDefinition) < getAccessibilityOrder(refToKey[refKey])) {
|
|
||||||
refToKey[refKey] = methodDefinition;
|
|
||||||
refToValue[refKey] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Order: public, family, assembly, private
|
|
||||||
static int[] accessibilityOrder = new int[8] {
|
|
||||||
60, // CompilerControlled
|
|
||||||
50, // Private
|
|
||||||
40, // FamANDAssem
|
|
||||||
30, // Assembly
|
|
||||||
10, // Family
|
|
||||||
20, // FamORAssem
|
|
||||||
0, // Public
|
|
||||||
70, // <reserved>
|
|
||||||
};
|
|
||||||
static int getAccessibilityOrder(MethodDefinition methodDefinition) {
|
|
||||||
return accessibilityOrder[(int)methodDefinition.Attributes & 7];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTypesRenamed() {
|
|
||||||
var newFieldRefToDef = new Dictionary<IMethodReferenceKey, TValue>(refToValue.Count);
|
|
||||||
foreach (var kvp in refToValue)
|
|
||||||
newFieldRefToDef[getReferenceKey((MethodDefinition)kvp.Key.MethodReference)] = kvp.Value;
|
|
||||||
refToValue = newFieldRefToDef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MethodDefinitionDict<TValue> : MethodDefinitionDictBase<TValue> {
|
|
||||||
protected override IMethodReferenceKey getReferenceKey(MethodReference methodReference) {
|
|
||||||
return new MethodReferenceKey(methodReference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MethodDefinitionAndDeclaringTypeDict<TValue> : MethodDefinitionDictBase<TValue> {
|
|
||||||
protected override IMethodReferenceKey getReferenceKey(MethodReference methodReference) {
|
|
||||||
return new MethodReferenceAndDeclaringTypeKey(methodReference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class PropertyDefinitionDictBase<TValue> {
|
|
||||||
Dictionary<ScopeAndTokenKey, TValue> tokenToValue = new Dictionary<ScopeAndTokenKey, TValue>();
|
|
||||||
Dictionary<ScopeAndTokenKey, PropertyDefinition> tokenToKey = new Dictionary<ScopeAndTokenKey, PropertyDefinition>();
|
|
||||||
Dictionary<IPropertyReferenceKey, TValue> refToValue = new Dictionary<IPropertyReferenceKey, TValue>();
|
|
||||||
|
|
||||||
public int Count {
|
|
||||||
get { return tokenToValue.Count; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<PropertyDefinition> getKeys() {
|
|
||||||
return tokenToKey.Values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<TValue> getValues() {
|
|
||||||
return tokenToValue.Values;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopeAndTokenKey getTokenKey(PropertyReference propertyReference) {
|
|
||||||
return new ScopeAndTokenKey(propertyReference);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract IPropertyReferenceKey getReferenceKey(PropertyReference propertyReference);
|
|
||||||
|
|
||||||
public TValue find(PropertyReference propertyReference) {
|
|
||||||
TValue value;
|
|
||||||
if (propertyReference is PropertyDefinition)
|
|
||||||
tokenToValue.TryGetValue(getTokenKey(propertyReference), out value);
|
|
||||||
else
|
|
||||||
refToValue.TryGetValue(getReferenceKey(propertyReference), out value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TValue findAny(PropertyReference propertyReference) {
|
|
||||||
TValue value;
|
|
||||||
if (tokenToValue.TryGetValue(getTokenKey(propertyReference), out value))
|
|
||||||
return value;
|
|
||||||
|
|
||||||
refToValue.TryGetValue(getReferenceKey(propertyReference), out value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(PropertyDefinition propertyDefinition, TValue value) {
|
|
||||||
var tokenKey = getTokenKey(propertyDefinition);
|
|
||||||
tokenToValue[tokenKey] = value;
|
|
||||||
tokenToKey[tokenKey] = propertyDefinition;
|
|
||||||
|
|
||||||
refToValue[getReferenceKey(propertyDefinition)] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTypesRenamed() {
|
|
||||||
var newFieldRefToDef = new Dictionary<IPropertyReferenceKey, TValue>(refToValue.Count);
|
|
||||||
foreach (var kvp in refToValue)
|
|
||||||
newFieldRefToDef[getReferenceKey((PropertyDefinition)kvp.Key.PropertyReference)] = kvp.Value;
|
|
||||||
refToValue = newFieldRefToDef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PropertyDefinitionDict<TValue> : PropertyDefinitionDictBase<TValue> {
|
|
||||||
protected override IPropertyReferenceKey getReferenceKey(PropertyReference propertyReference) {
|
|
||||||
return new PropertyReferenceKey(propertyReference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PropertyDefinitionAndDeclaringTypeDict<TValue> : PropertyDefinitionDictBase<TValue> {
|
|
||||||
protected override IPropertyReferenceKey getReferenceKey(PropertyReference propertyReference) {
|
|
||||||
return new PropertyReferenceAndDeclaringTypeKey(propertyReference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class EventDefinitionDictBase<TValue> {
|
|
||||||
Dictionary<ScopeAndTokenKey, TValue> tokenToValue = new Dictionary<ScopeAndTokenKey, TValue>();
|
|
||||||
Dictionary<ScopeAndTokenKey, EventDefinition> tokenToKey = new Dictionary<ScopeAndTokenKey, EventDefinition>();
|
|
||||||
Dictionary<IEventReferenceKey, TValue> refToValue = new Dictionary<IEventReferenceKey, TValue>();
|
|
||||||
|
|
||||||
public int Count {
|
|
||||||
get { return tokenToValue.Count; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<EventDefinition> getKeys() {
|
|
||||||
return tokenToKey.Values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<TValue> getValues() {
|
|
||||||
return tokenToValue.Values;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopeAndTokenKey getTokenKey(EventReference eventReference) {
|
|
||||||
return new ScopeAndTokenKey(eventReference);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract IEventReferenceKey getReferenceKey(EventReference eventReference);
|
|
||||||
|
|
||||||
public TValue find(EventReference eventReference) {
|
|
||||||
TValue value;
|
|
||||||
if (eventReference is EventDefinition)
|
|
||||||
tokenToValue.TryGetValue(getTokenKey(eventReference), out value);
|
|
||||||
else
|
|
||||||
refToValue.TryGetValue(getReferenceKey(eventReference), out value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TValue findAny(EventReference eventReference) {
|
|
||||||
TValue value;
|
|
||||||
if (tokenToValue.TryGetValue(getTokenKey(eventReference), out value))
|
|
||||||
return value;
|
|
||||||
|
|
||||||
refToValue.TryGetValue(getReferenceKey(eventReference), out value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(EventDefinition eventDefinition, TValue value) {
|
|
||||||
var tokenKey = getTokenKey(eventDefinition);
|
|
||||||
tokenToValue[tokenKey] = value;
|
|
||||||
tokenToKey[tokenKey] = eventDefinition;
|
|
||||||
|
|
||||||
refToValue[getReferenceKey(eventDefinition)] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTypesRenamed() {
|
|
||||||
var newFieldRefToDef = new Dictionary<IEventReferenceKey, TValue>(refToValue.Count);
|
|
||||||
foreach (var kvp in refToValue)
|
|
||||||
newFieldRefToDef[getReferenceKey((EventDefinition)kvp.Key.EventReference)] = kvp.Value;
|
|
||||||
refToValue = newFieldRefToDef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class EventDefinitionDict<TValue> : EventDefinitionDictBase<TValue> {
|
|
||||||
protected override IEventReferenceKey getReferenceKey(EventReference eventReference) {
|
|
||||||
return new EventReferenceKey(eventReference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class EventDefinitionAndDeclaringTypeDict<TValue> : EventDefinitionDictBase<TValue> {
|
|
||||||
protected override IEventReferenceKey getReferenceKey(EventReference eventReference) {
|
|
||||||
return new EventReferenceAndDeclaringTypeKey(eventReference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ScopeAndTokenKey {
|
|
||||||
readonly IMetadataScope scope;
|
|
||||||
readonly int token;
|
|
||||||
|
|
||||||
public ScopeAndTokenKey(TypeReference type)
|
|
||||||
: this(type.Scope, type.MetadataToken.ToInt32()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScopeAndTokenKey(FieldReference field)
|
|
||||||
: this(field.DeclaringType == null ? null : field.DeclaringType.Scope, field.MetadataToken.ToInt32()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScopeAndTokenKey(MethodReference method)
|
|
||||||
: this(method.DeclaringType == null ? null : method.DeclaringType.Scope, method.MetadataToken.ToInt32()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScopeAndTokenKey(PropertyReference prop)
|
|
||||||
: this(prop.DeclaringType == null ? null : prop.DeclaringType.Scope, prop.MetadataToken.ToInt32()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScopeAndTokenKey(EventReference evt)
|
|
||||||
: this(evt.DeclaringType == null ? null : evt.DeclaringType.Scope, evt.MetadataToken.ToInt32()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScopeAndTokenKey(IMetadataScope scope, int token) {
|
|
||||||
this.scope = scope;
|
|
||||||
this.token = token;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
return token + MemberReferenceHelper.scopeHashCode(scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj) {
|
|
||||||
var other = obj as ScopeAndTokenKey;
|
|
||||||
if (other == null)
|
|
||||||
return false;
|
|
||||||
return token == other.token &&
|
|
||||||
MemberReferenceHelper.compareScope(scope, other.scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return string.Format("{0:X8} {1}", token, scope);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TypeReferenceKey {
|
|
||||||
readonly TypeReference typeRef;
|
|
||||||
|
|
||||||
public TypeReference TypeReference {
|
|
||||||
get { return typeRef; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public TypeReferenceKey(TypeReference typeRef) {
|
|
||||||
this.typeRef = typeRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj) {
|
|
||||||
var other = obj as TypeReferenceKey;
|
|
||||||
if (other == null)
|
|
||||||
return false;
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return typeRef.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TypeReferenceSameVersionKey {
|
|
||||||
readonly TypeReference typeRef;
|
|
||||||
|
|
||||||
public TypeReference TypeReference {
|
|
||||||
get { return typeRef; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public TypeReferenceSameVersionKey(TypeReference typeRef) {
|
|
||||||
this.typeRef = typeRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj) {
|
|
||||||
var other = obj as TypeReferenceSameVersionKey;
|
|
||||||
if (other == null)
|
|
||||||
return false;
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return typeRef.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IFieldReferenceKey {
|
|
||||||
FieldReference FieldReference { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IPropertyReferenceKey {
|
|
||||||
PropertyReference PropertyReference { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IEventReferenceKey {
|
|
||||||
EventReference EventReference { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IMethodReferenceKey {
|
|
||||||
MethodReference MethodReference { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FieldReferenceKey : IFieldReferenceKey {
|
|
||||||
readonly FieldReference fieldRef;
|
|
||||||
|
|
||||||
public FieldReference FieldReference {
|
|
||||||
get { return fieldRef; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public FieldReferenceKey(FieldReference fieldRef) {
|
|
||||||
this.fieldRef = fieldRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj) {
|
|
||||||
var other = obj as FieldReferenceKey;
|
|
||||||
if (other == null)
|
|
||||||
return false;
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return fieldRef.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PropertyReferenceKey : IPropertyReferenceKey {
|
|
||||||
readonly PropertyReference propRef;
|
|
||||||
|
|
||||||
public PropertyReference PropertyReference {
|
|
||||||
get { return propRef; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyReferenceKey(PropertyReference propRef) {
|
|
||||||
this.propRef = propRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj) {
|
|
||||||
var other = obj as PropertyReferenceKey;
|
|
||||||
if (other == null)
|
|
||||||
return false;
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return propRef.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class EventReferenceKey : IEventReferenceKey {
|
|
||||||
readonly EventReference eventRef;
|
|
||||||
|
|
||||||
public EventReference EventReference {
|
|
||||||
get { return eventRef; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public EventReferenceKey(EventReference eventRef) {
|
|
||||||
this.eventRef = eventRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj) {
|
|
||||||
var other = obj as EventReferenceKey;
|
|
||||||
if (other == null)
|
|
||||||
return false;
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return eventRef.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MethodReferenceKey : IMethodReferenceKey {
|
|
||||||
readonly MethodReference methodRef;
|
|
||||||
|
|
||||||
public MethodReference MethodReference {
|
|
||||||
get { return methodRef; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public MethodReferenceKey(MethodReference methodRef) {
|
|
||||||
this.methodRef = methodRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj) {
|
|
||||||
var other = obj as MethodReferenceKey;
|
|
||||||
if (other == null)
|
|
||||||
return false;
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return methodRef.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FieldReferenceAndDeclaringTypeKey : IFieldReferenceKey {
|
|
||||||
readonly FieldReference fieldRef;
|
|
||||||
|
|
||||||
public FieldReference FieldReference {
|
|
||||||
get { return fieldRef; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public FieldReferenceAndDeclaringTypeKey(FieldReference fieldRef) {
|
|
||||||
this.fieldRef = fieldRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj) {
|
|
||||||
var other = obj as FieldReferenceAndDeclaringTypeKey;
|
|
||||||
if (other == null)
|
|
||||||
return false;
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return fieldRef.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PropertyReferenceAndDeclaringTypeKey : IPropertyReferenceKey {
|
|
||||||
readonly PropertyReference propRef;
|
|
||||||
|
|
||||||
public PropertyReference PropertyReference {
|
|
||||||
get { return propRef; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyReferenceAndDeclaringTypeKey(PropertyReference propRef) {
|
|
||||||
this.propRef = propRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj) {
|
|
||||||
var other = obj as PropertyReferenceAndDeclaringTypeKey;
|
|
||||||
if (other == null)
|
|
||||||
return false;
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return propRef.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class EventReferenceAndDeclaringTypeKey : IEventReferenceKey {
|
|
||||||
readonly EventReference eventRef;
|
|
||||||
|
|
||||||
public EventReference EventReference {
|
|
||||||
get { return eventRef; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public EventReferenceAndDeclaringTypeKey(EventReference eventRef) {
|
|
||||||
this.eventRef = eventRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj) {
|
|
||||||
var other = obj as EventReferenceAndDeclaringTypeKey;
|
|
||||||
if (other == null)
|
|
||||||
return false;
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return eventRef.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MethodReferenceAndDeclaringTypeKey : IMethodReferenceKey {
|
|
||||||
readonly MethodReference methodRef;
|
|
||||||
|
|
||||||
public MethodReference MethodReference {
|
|
||||||
get { return methodRef; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public MethodReferenceAndDeclaringTypeKey(MethodReference methodRef) {
|
|
||||||
this.methodRef = methodRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode() {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj) {
|
|
||||||
var other = obj as MethodReferenceAndDeclaringTypeKey;
|
|
||||||
if (other == null)
|
|
||||||
return false;
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return methodRef.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace de4dot.blocks {
|
|
||||||
public static class MemberReferenceHelper {
|
|
||||||
public static bool verifyType(TypeReference typeReference, string assembly, string type) {
|
|
||||||
return verifyType(typeReference, assembly, type, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool verifyType(TypeReference typeReference, string assembly, string type, string extra) {
|
|
||||||
return typeReference != null &&
|
|
||||||
MemberReferenceHelper.getCanonicalizedTypeRefName(typeReference.GetElementType()) == "[" + assembly + "]" + type &&
|
|
||||||
typeReference.FullName == type + extra;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool isSystemObject(TypeReference typeReference) {
|
|
||||||
return typeReference != null && typeReference.EType == ElementType.Object;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string getCanonicalizedTypeRefName(TypeReference typeRef) {
|
|
||||||
return getCanonicalizedTypeRefName(typeRef.Scope, typeRef.FullName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string getCanonicalizedTypeRefName(IMetadataScope scope, string fullName) {
|
|
||||||
return string.Format("[{0}]{1}", getCanonicalizedScopeName(scope), fullName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AssemblyNameReference getAssemblyNameReference(IMetadataScope scope) {
|
|
||||||
switch (scope.MetadataScopeType) {
|
|
||||||
case MetadataScopeType.AssemblyNameReference:
|
|
||||||
return (AssemblyNameReference)scope;
|
|
||||||
case MetadataScopeType.ModuleDefinition:
|
|
||||||
var module = (ModuleDefinition)scope;
|
|
||||||
if (module.Assembly != null)
|
|
||||||
return module.Assembly.Name;
|
|
||||||
break;
|
|
||||||
case MetadataScopeType.ModuleReference:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ApplicationException(string.Format("Invalid scope type: {0}", scope.GetType()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string getCanonicalizedScopeName(IMetadataScope scope) {
|
|
||||||
var asmRef = getAssemblyNameReference(scope);
|
|
||||||
if (asmRef != null) {
|
|
||||||
// The version number should be ignored. Older code may reference an old version of
|
|
||||||
// the assembly, but if the newer one has been loaded, that one is used.
|
|
||||||
return asmRef.Name.ToLowerInvariant();
|
|
||||||
}
|
|
||||||
return string.Format("{0}", scope.ToString().ToLowerInvariant());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string getCanonicalizedScopeAndVersion(IMetadataScope scope) {
|
|
||||||
var asmRef = getAssemblyNameReference(scope);
|
|
||||||
if (asmRef != null)
|
|
||||||
return string.Format("{0}, Version={1}", asmRef.Name.ToLowerInvariant(), asmRef.Version);
|
|
||||||
return string.Format("{0}, Version=", scope.ToString().ToLowerInvariant());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool compareScope(IMetadataScope a, IMetadataScope b) {
|
|
||||||
if (ReferenceEquals(a, b))
|
|
||||||
return true;
|
|
||||||
if (a == null || b == null)
|
|
||||||
return false;
|
|
||||||
return getCanonicalizedScopeName(a) == getCanonicalizedScopeName(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int scopeHashCode(IMetadataScope a) {
|
|
||||||
if (a == null)
|
|
||||||
return 0;
|
|
||||||
return getCanonicalizedScopeName(a).GetHashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool compareScopeSameVersion(IMetadataScope a, IMetadataScope b) {
|
|
||||||
if (ReferenceEquals(a, b))
|
|
||||||
return true;
|
|
||||||
if (a == null || b == null)
|
|
||||||
return false;
|
|
||||||
return getCanonicalizedScopeAndVersion(a) == getCanonicalizedScopeAndVersion(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int scopeHashCodeSameVersion(IMetadataScope a) {
|
|
||||||
if (a == null)
|
|
||||||
return 0;
|
|
||||||
return getCanonicalizedScopeAndVersion(a).GetHashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool compareMethodReference(MethodReference a, MethodReference b) {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool compareMethodReferenceAndDeclaringType(MethodReference a, MethodReference b) {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool compareFieldReference(FieldReference a, FieldReference b) {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool compareTypes(TypeReference a, TypeReference b) {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,92 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2011-2012 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if PORT
|
|
||||||
using System;
|
|
||||||
using Mono.Cecil;
|
|
||||||
|
|
||||||
namespace de4dot.blocks {
|
|
||||||
public abstract class TypeReferenceUpdaterBase {
|
|
||||||
public TypeReference update(TypeReference a) {
|
|
||||||
if (a == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual ArrayType updateArrayType(ArrayType a) {
|
|
||||||
var rv = new ArrayType(update(a.ElementType));
|
|
||||||
if (!a.IsVector) {
|
|
||||||
foreach (var dim in a.Dimensions)
|
|
||||||
rv.Dimensions.Add(dim);
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual ByReferenceType updateByReferenceType(ByReferenceType a) {
|
|
||||||
return new ByReferenceType(update(a.ElementType));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual FunctionPointerType updateFunctionPointerType(FunctionPointerType a) {
|
|
||||||
var rv = new FunctionPointerType();
|
|
||||||
rv.function = a.function;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual GenericInstanceType updateGenericInstanceType(GenericInstanceType a) {
|
|
||||||
var rv = new GenericInstanceType(update(a.ElementType));
|
|
||||||
foreach (var arg in a.GenericArguments)
|
|
||||||
rv.GenericArguments.Add(update(arg));
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual TypeReference updateGenericParameter(GenericParameter a) {
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual OptionalModifierType updateOptionalModifierType(OptionalModifierType a) {
|
|
||||||
return new OptionalModifierType(update(a.ModifierType), update(a.ElementType));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual PinnedType updatePinnedType(PinnedType a) {
|
|
||||||
return new PinnedType(update(a.ElementType));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual PointerType updatePointerType(PointerType a) {
|
|
||||||
return new PointerType(update(a.ElementType));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual RequiredModifierType updateRequiredModifierType(RequiredModifierType a) {
|
|
||||||
return new RequiredModifierType(update(a.ModifierType), update(a.ElementType));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual SentinelType updateSentinelType(SentinelType a) {
|
|
||||||
return new SentinelType(update(a.ElementType));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual TypeReference updateTypeDefinition(TypeDefinition a) {
|
|
||||||
return updateTypeReference(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual TypeReference updateTypeReference(TypeReference a) {
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -72,8 +72,6 @@
|
||||||
<Compile Include="Instr.cs" />
|
<Compile Include="Instr.cs" />
|
||||||
<Compile Include="InstructionListParser.cs" />
|
<Compile Include="InstructionListParser.cs" />
|
||||||
<Compile Include="MemberDefDict.cs" />
|
<Compile Include="MemberDefDict.cs" />
|
||||||
<Compile Include="MemberReferenceHelper.cs" />
|
|
||||||
<Compile Include="MemberRefInstance.cs" />
|
|
||||||
<Compile Include="MethodBlocks.cs" />
|
<Compile Include="MethodBlocks.cs" />
|
||||||
<Compile Include="PE\Cor20Header.cs" />
|
<Compile Include="PE\Cor20Header.cs" />
|
||||||
<Compile Include="PE\DataDirectory.cs" />
|
<Compile Include="PE\DataDirectory.cs" />
|
||||||
|
@ -95,7 +93,6 @@
|
||||||
<Compile Include="ScopeBlock.cs" />
|
<Compile Include="ScopeBlock.cs" />
|
||||||
<Compile Include="TryBlock.cs" />
|
<Compile Include="TryBlock.cs" />
|
||||||
<Compile Include="TryHandlerBlock.cs" />
|
<Compile Include="TryHandlerBlock.cs" />
|
||||||
<Compile Include="TypeReferenceUpdaterBase.cs" />
|
|
||||||
<Compile Include="Utils.cs" />
|
<Compile Include="Utils.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public void init(MethodDef method) {
|
public void init(MethodDef method) {
|
||||||
this.parameterDefs = method.Parameters;
|
this.parameterDefs = method.Parameters;
|
||||||
this.localDefs = method.Body.LocalList;
|
this.localDefs = method.Body.Variables;
|
||||||
valueStack.init();
|
valueStack.init();
|
||||||
protectedStackValues.Clear();
|
protectedStackValues.Clear();
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace de4dot.code {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModuleDefMD reload(byte[] newModuleData, DumpedMethodsRestorer dumpedMethodsRestorer, IStringDecrypter stringDecrypter) {
|
public ModuleDefMD reload(byte[] newModuleData, DumpedMethodsRestorer dumpedMethodsRestorer, IStringDecrypter stringDecrypter) {
|
||||||
TheAssemblyResolver.Instance.removeModule(module);
|
TheAssemblyResolver.Instance.Remove(module);
|
||||||
var mod = ModuleDefMD.Load(newModuleData, moduleContext);
|
var mod = ModuleDefMD.Load(newModuleData, moduleContext);
|
||||||
if (dumpedMethodsRestorer != null)
|
if (dumpedMethodsRestorer != null)
|
||||||
dumpedMethodsRestorer.Module = mod;
|
dumpedMethodsRestorer.Module = mod;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
using dot10.DotNet;
|
using dot10.DotNet;
|
||||||
|
|
||||||
namespace de4dot.code {
|
namespace de4dot.code {
|
||||||
public class TheAssemblyResolver : dot10.DotNet.AssemblyResolver {
|
public class TheAssemblyResolver : AssemblyResolver {
|
||||||
public static readonly TheAssemblyResolver Instance = new TheAssemblyResolver();
|
public static readonly TheAssemblyResolver Instance = new TheAssemblyResolver();
|
||||||
|
|
||||||
public TheAssemblyResolver() {
|
public TheAssemblyResolver() {
|
||||||
|
@ -41,13 +41,7 @@ namespace de4dot.code {
|
||||||
if (assembly == null)
|
if (assembly == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
removeModule(assembly.FullName);
|
Remove(module.Assembly);
|
||||||
}
|
|
||||||
|
|
||||||
public void removeModule(string asmFullName) {
|
|
||||||
if (string.IsNullOrEmpty(asmFullName))
|
|
||||||
return;
|
|
||||||
//TODO: Remove it from the cache
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearAll() {
|
public void clearAll() {
|
||||||
|
|
|
@ -218,7 +218,7 @@ namespace de4dot.code {
|
||||||
|
|
||||||
bool getLocalVariableValue(Local variable, out object value) {
|
bool getLocalVariableValue(Local variable, out object value) {
|
||||||
if (variableValues == null)
|
if (variableValues == null)
|
||||||
variableValues = new VariableValues(theMethod.Body.LocalList, allBlocks);
|
variableValues = new VariableValues(theMethod.Body.Variables, allBlocks);
|
||||||
var val = variableValues.getValue(variable);
|
var val = variableValues.getValue(variable);
|
||||||
if (!val.isValid()) {
|
if (!val.isValid()) {
|
||||||
value = null;
|
value = null;
|
||||||
|
@ -342,7 +342,7 @@ namespace de4dot.code {
|
||||||
case Code.Ldloc_1:
|
case Code.Ldloc_1:
|
||||||
case Code.Ldloc_2:
|
case Code.Ldloc_2:
|
||||||
case Code.Ldloc_3:
|
case Code.Ldloc_3:
|
||||||
getLocalVariableValue(instr.Instruction.GetLocal(theMethod.Body.LocalList), out arg);
|
getLocalVariableValue(instr.Instruction.GetLocal(theMethod.Body.Variables), out arg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Code.Ldfld:
|
case Code.Ldfld:
|
||||||
|
|
|
@ -191,6 +191,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
void findCliSecureAttribute() {
|
void findCliSecureAttribute() {
|
||||||
|
obfuscatorName = "CliSecure";
|
||||||
foreach (var type in module.Types) {
|
foreach (var type in module.Types) {
|
||||||
if (Utils.StartsWith(type.FullName, "SecureTeam.Attributes.ObfuscatedByCliSecureAttribute", StringComparison.Ordinal)) {
|
if (Utils.StartsWith(type.FullName, "SecureTeam.Attributes.ObfuscatedByCliSecureAttribute", StringComparison.Ordinal)) {
|
||||||
cliSecureAttributes.Add(type);
|
cliSecureAttributes.Add(type);
|
||||||
|
|
|
@ -99,6 +99,24 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
|
||||||
case ElementType.Class:
|
case ElementType.Class:
|
||||||
case ElementType.ValueType:
|
case ElementType.ValueType:
|
||||||
case ElementType.FnPtr:
|
case ElementType.FnPtr:
|
||||||
|
case ElementType.Void:
|
||||||
|
case ElementType.Boolean:
|
||||||
|
case ElementType.Char:
|
||||||
|
case ElementType.I1:
|
||||||
|
case ElementType.U1:
|
||||||
|
case ElementType.I2:
|
||||||
|
case ElementType.U2:
|
||||||
|
case ElementType.I4:
|
||||||
|
case ElementType.U4:
|
||||||
|
case ElementType.I8:
|
||||||
|
case ElementType.U8:
|
||||||
|
case ElementType.R4:
|
||||||
|
case ElementType.R8:
|
||||||
|
case ElementType.TypedByRef:
|
||||||
|
case ElementType.I:
|
||||||
|
case ElementType.U:
|
||||||
|
case ElementType.String:
|
||||||
|
case ElementType.Object:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ElementType.MVar:
|
case ElementType.MVar:
|
||||||
|
@ -115,6 +133,15 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ElementType.ByRef:
|
case ElementType.ByRef:
|
||||||
|
case ElementType.CModOpt:
|
||||||
|
case ElementType.CModReqd:
|
||||||
|
case ElementType.Pinned:
|
||||||
|
case ElementType.Sentinel:
|
||||||
|
case ElementType.ValueArray:
|
||||||
|
case ElementType.R:
|
||||||
|
case ElementType.End:
|
||||||
|
case ElementType.Internal:
|
||||||
|
case ElementType.Module:
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,10 +38,6 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
|
||||||
get { return Detected ? resource : null; }
|
get { return Detected ? resource : null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public AssemblyRef VmAssemblyReference {
|
|
||||||
get { return Detected ? vmAssemblyReference : null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Csvm(IDeobfuscatorContext deobfuscatorContext, ModuleDefMD module) {
|
public Csvm(IDeobfuscatorContext deobfuscatorContext, ModuleDefMD module) {
|
||||||
this.deobfuscatorContext = deobfuscatorContext;
|
this.deobfuscatorContext = deobfuscatorContext;
|
||||||
this.module = module;
|
this.module = module;
|
||||||
|
@ -123,8 +119,8 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
|
||||||
|
|
||||||
Logger.v("Locals:");
|
Logger.v("Locals:");
|
||||||
Logger.Instance.indent();
|
Logger.Instance.indent();
|
||||||
for (int i = 0; i < method.Body.LocalList.Count; i++)
|
for (int i = 0; i < method.Body.Variables.Count; i++)
|
||||||
Logger.v("#{0}: {1}", i, method.Body.LocalList[i].Type);
|
Logger.v("#{0}: {1}", i, method.Body.Variables[i].Type);
|
||||||
Logger.Instance.deIndent();
|
Logger.Instance.deIndent();
|
||||||
|
|
||||||
Logger.v("Code:");
|
Logger.v("Code:");
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
|
||||||
IBinaryReader reader;
|
IBinaryReader reader;
|
||||||
|
|
||||||
public CsvmDataReader(IBinaryReader reader) {
|
public CsvmDataReader(IBinaryReader reader) {
|
||||||
|
reader.Position = 0;
|
||||||
this.reader = reader;
|
this.reader = reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
|
||||||
var newExceptions = readExceptions(cilMethod, csvmMethod, newInstructions);
|
var newExceptions = readExceptions(cilMethod, csvmMethod, newInstructions);
|
||||||
|
|
||||||
fixInstructionOperands(newInstructions);
|
fixInstructionOperands(newInstructions);
|
||||||
fixLocals(newInstructions, cilMethod.Body.LocalList);
|
fixLocals(newInstructions, cilMethod.Body.Variables);
|
||||||
fixArgs(newInstructions, cilMethod);
|
fixArgs(newInstructions, cilMethod);
|
||||||
|
|
||||||
DotNetUtils.restoreBody(cilMethod, newInstructions, newExceptions);
|
DotNetUtils.restoreBody(cilMethod, newInstructions, newExceptions);
|
||||||
|
|
|
@ -462,7 +462,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rethrow_check(UnknownHandlerInfo info) {
|
static bool rethrow_check(UnknownHandlerInfo info) {
|
||||||
return info.ExecuteMethod.Body.LocalList.Count == 0;
|
return info.ExecuteMethod.Body.Variables.Count == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Instruction rethrow_read(BinaryReader reader) {
|
static Instruction rethrow_read(BinaryReader reader) {
|
||||||
|
|
|
@ -115,9 +115,9 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
body.MaxStack = babelMethod.MaxStack;
|
body.MaxStack = babelMethod.MaxStack;
|
||||||
body.InitLocals = babelMethod.InitLocals;
|
body.InitLocals = babelMethod.InitLocals;
|
||||||
|
|
||||||
body.LocalList.Clear();
|
body.Variables.Clear();
|
||||||
foreach (var local in babelMethod.Locals)
|
foreach (var local in babelMethod.Locals)
|
||||||
body.LocalList.Add(local);
|
body.Variables.Add(local);
|
||||||
|
|
||||||
var toNewOperand = new Dictionary<object, object>();
|
var toNewOperand = new Dictionary<object, object>();
|
||||||
if (babelMethod.ThisParameter != null)
|
if (babelMethod.ThisParameter != null)
|
||||||
|
|
|
@ -193,6 +193,7 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
if (assemblyEncryptedResource == null)
|
if (assemblyEncryptedResource == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
assemblyEncryptedResource.Data.Position = 0;
|
||||||
var reader = new BinaryReader(assemblyEncryptedResource.Data.CreateStream());
|
var reader = new BinaryReader(assemblyEncryptedResource.Data.CreateStream());
|
||||||
var encryptedData = DeobUtils.gunzip(reader.BaseStream, reader.ReadInt32());
|
var encryptedData = DeobUtils.gunzip(reader.BaseStream, reader.ReadInt32());
|
||||||
reader = new BinaryReader(new MemoryStream(encryptedData));
|
reader = new BinaryReader(new MemoryStream(encryptedData));
|
||||||
|
|
|
@ -128,6 +128,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
var data = bundleData.Data.ReadAllBytes();
|
var data = bundleData.Data.ReadAllBytes();
|
||||||
|
|
||||||
var doc = new XmlDocument();
|
var doc = new XmlDocument();
|
||||||
|
bundleXmlFile.Data.Position = 0;
|
||||||
doc.Load(XmlReader.Create(bundleXmlFile.Data.CreateStream()));
|
doc.Load(XmlReader.Create(bundleXmlFile.Data.CreateStream()));
|
||||||
var manifest = doc.DocumentElement;
|
var manifest = doc.DocumentElement;
|
||||||
if (manifest.Name.ToLowerInvariant() != "manifest") {
|
if (manifest.Name.ToLowerInvariant() != "manifest") {
|
||||||
|
|
|
@ -39,6 +39,8 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
var sig = method.MethodSig;
|
var sig = method.MethodSig;
|
||||||
if (sig == null || sig.Params.Count != 0)
|
if (sig == null || sig.Params.Count != 0)
|
||||||
return false;
|
return false;
|
||||||
|
if (sig.RetType == null)
|
||||||
|
return true;
|
||||||
var retType = sig.RetType as GenericSig;
|
var retType = sig.RetType as GenericSig;
|
||||||
if (retType == null)
|
if (retType == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -217,6 +217,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
void decryptAllAssemblies() {
|
void decryptAllAssemblies() {
|
||||||
if (assemblyResource == null)
|
if (assemblyResource == null)
|
||||||
return;
|
return;
|
||||||
|
assemblyResource.Data.Position = 0;
|
||||||
var resourceSet = ResourceReader.read(resourceModule, assemblyResource.Data);
|
var resourceSet = ResourceReader.read(resourceModule, assemblyResource.Data);
|
||||||
foreach (var resourceElement in resourceSet.ResourceElements) {
|
foreach (var resourceElement in resourceSet.ResourceElements) {
|
||||||
if (resourceElement.ResourceData.Code != ResourceTypeCode.ByteArray)
|
if (resourceElement.ResourceData.Code != ResourceTypeCode.ByteArray)
|
||||||
|
|
|
@ -255,6 +255,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
info.Magic2 = findMagic2(info.Method);
|
info.Magic2 = findMagic2(info.Method);
|
||||||
info.Magic3 = findMagic3(info.Method);
|
info.Magic3 = findMagic3(info.Method);
|
||||||
info.Reader = info.Resource.Data;
|
info.Reader = info.Resource.Data;
|
||||||
|
info.Reader.Position = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
|
|
||||||
public ConstantsReader(MethodDef method)
|
public ConstantsReader(MethodDef method)
|
||||||
: this(method.Body.Instructions) {
|
: this(method.Body.Instructions) {
|
||||||
this.locals = method.Body.LocalList;
|
this.locals = method.Body.Variables;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConstantsReader(IList<Instr> instrs, IList<Local> locals)
|
public ConstantsReader(IList<Instr> instrs, IList<Local> locals)
|
||||||
|
|
|
@ -108,6 +108,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
encryptedResource = CoUtils.getResource(module, DotNetUtils.getCodeStrings(decrypterType.FindStaticConstructor()));
|
encryptedResource = CoUtils.getResource(module, DotNetUtils.getCodeStrings(decrypterType.FindStaticConstructor()));
|
||||||
|
encryptedResource.Data.Position = 0;
|
||||||
constantsData = resourceDecrypter.decrypt(encryptedResource.Data.CreateStream());
|
constantsData = resourceDecrypter.decrypt(encryptedResource.Data.CreateStream());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
static IList<Local> getLocals(MethodDef method) {
|
static IList<Local> getLocals(MethodDef method) {
|
||||||
if (method.Body == null)
|
if (method.Body == null)
|
||||||
return new List<Local>();
|
return new List<Local>();
|
||||||
return method.Body.LocalList;
|
return method.Body.Variables;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IField ReadInlineField(Instruction instr) {
|
protected override IField ReadInlineField(Instruction instr) {
|
||||||
|
|
|
@ -159,7 +159,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
Utils.removeNewlines(encMethod.FullName),
|
Utils.removeNewlines(encMethod.FullName),
|
||||||
encMethod.MDToken.ToInt32(),
|
encMethod.MDToken.ToInt32(),
|
||||||
encMethod.Body.Instructions.Count,
|
encMethod.Body.Instructions.Count,
|
||||||
encMethod.Body.LocalList.Count,
|
encMethod.Body.Variables.Count,
|
||||||
encMethod.Body.ExceptionHandlers.Count);
|
encMethod.Body.ExceptionHandlers.Count);
|
||||||
delegateTypes.Add(delegateType);
|
delegateTypes.Add(delegateType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
var ldloc = instrs[i];
|
var ldloc = instrs[i];
|
||||||
if (!ldloc.IsLdloc())
|
if (!ldloc.IsLdloc())
|
||||||
continue;
|
continue;
|
||||||
var local = ldloc.GetLocal(method.Body.LocalList);
|
var local = ldloc.GetLocal(method.Body.Variables);
|
||||||
if (local == null || local.Type.GetElementType().GetPrimitiveSize() < 0)
|
if (local == null || local.Type.GetElementType().GetPrimitiveSize() < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
var ldloc = instructions[i - 2];
|
var ldloc = instructions[i - 2];
|
||||||
if (!ldloc.IsLdloc())
|
if (!ldloc.IsLdloc())
|
||||||
continue;
|
continue;
|
||||||
var local = ldloc.GetLocal(method.Body.LocalList);
|
var local = ldloc.GetLocal(method.Body.Variables);
|
||||||
if (local.Type.GetElementType().GetPrimitiveSize() < 0)
|
if (local.Type.GetElementType().GetPrimitiveSize() < 0)
|
||||||
continue;
|
continue;
|
||||||
constants.Add(flagValue);
|
constants.Add(flagValue);
|
||||||
|
|
|
@ -75,6 +75,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
if (resource == null)
|
if (resource == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
resource.Data.Position = 0;
|
||||||
DeobUtils.decryptAndAddResources(module, resource.Name.String, () => resourceDecrypter.decrypt(resource.Data.CreateStream()));
|
DeobUtils.decryptAndAddResources(module, resource.Name.String, () => resourceDecrypter.decrypt(resource.Data.CreateStream()));
|
||||||
mergedIt = true;
|
mergedIt = true;
|
||||||
return resource;
|
return resource;
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(ResourceDecrypter resourceDecrypter) {
|
public void init(ResourceDecrypter resourceDecrypter) {
|
||||||
if (decryptedData != null)
|
if (decryptedData != null || stringDecrypterType == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var resourceName = getResourceName();
|
var resourceName = getResourceName();
|
||||||
|
|
|
@ -134,7 +134,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
foreach (var parameter in method.MethodSig.GetParams())
|
foreach (var parameter in method.MethodSig.GetParams())
|
||||||
removeType(candidates, parameter);
|
removeType(candidates, parameter);
|
||||||
if (method.Body != null) {
|
if (method.Body != null) {
|
||||||
foreach (var local in method.Body.LocalList)
|
foreach (var local in method.Body.Variables)
|
||||||
removeType(candidates, local.Type);
|
removeType(candidates, local.Type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
var stloc = instrs[i + 2];
|
var stloc = instrs[i + 2];
|
||||||
if (!stloc.IsStloc())
|
if (!stloc.IsStloc())
|
||||||
continue;
|
continue;
|
||||||
var local = stloc.GetLocal(initMethod.Body.LocalList);
|
var local = stloc.GetLocal(initMethod.Body.Variables);
|
||||||
|
|
||||||
int startInitIndex = i;
|
int startInitIndex = i;
|
||||||
i++;
|
i++;
|
||||||
|
@ -89,7 +89,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
var ldloc = instrs[i];
|
var ldloc = instrs[i];
|
||||||
if (!ldloc.IsLdloc())
|
if (!ldloc.IsLdloc())
|
||||||
continue;
|
continue;
|
||||||
if (ldloc.GetLocal(method.Body.LocalList) != local)
|
if (ldloc.GetLocal(method.Body.Variables) != local)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var stsfld = instrs[i + 1];
|
var stsfld = instrs[i + 1];
|
||||||
|
@ -185,7 +185,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
Method = method;
|
Method = method;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool isPossibleDecrypterMethod(MethodDef method, bool firstTime) {
|
public static bool isPossibleDecrypterMethod(MethodDef method, ref bool? state) {
|
||||||
if (!checkMethodSignature(method))
|
if (!checkMethodSignature(method))
|
||||||
return false;
|
return false;
|
||||||
var fields = getFields(method);
|
var fields = getFields(method);
|
||||||
|
@ -406,8 +406,10 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
this.Method = method;
|
this.Method = method;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool isPossibleDecrypterMethod(MethodDef method, bool firstTime) {
|
public static bool isPossibleDecrypterMethod(MethodDef method, ref bool? state) {
|
||||||
if (!firstTime || !checkFields(method.DeclaringType.Fields))
|
if (state == null)
|
||||||
|
state = checkFields(method.DeclaringType.Fields);
|
||||||
|
if (!state.Value)
|
||||||
return false;
|
return false;
|
||||||
return DotNetUtils.isMethod(method, "System.String", "(System.Int32,System.Int32)");
|
return DotNetUtils.isMethod(method, "System.String", "(System.Int32,System.Int32)");
|
||||||
}
|
}
|
||||||
|
@ -559,8 +561,10 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
get { return DecrypterVersion.V1_3; }
|
get { return DecrypterVersion.V1_3; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool isPossibleDecrypterMethod(MethodDef method, bool firstTime) {
|
public static bool isPossibleDecrypterMethod(MethodDef method, ref bool? state) {
|
||||||
if (!firstTime || !checkFields(method.DeclaringType.Fields))
|
if (state == null)
|
||||||
|
state = checkFields(method.DeclaringType.Fields);
|
||||||
|
if (!state.Value)
|
||||||
return false;
|
return false;
|
||||||
return DotNetUtils.isMethod(method, "System.String", "(System.Int32)");
|
return DotNetUtils.isMethod(method, "System.String", "(System.Int32)");
|
||||||
}
|
}
|
||||||
|
@ -737,29 +741,28 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool deobfuscatedCctor = false;
|
bool deobfuscatedCctor = false;
|
||||||
bool firstTime = true;
|
bool? v13State = null, v40State = null, v41State = null;
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (!method.IsStatic || method.Body == null)
|
if (!method.IsStatic || method.Body == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
IDecrypterInfo info = null;
|
IDecrypterInfo info = null;
|
||||||
|
|
||||||
if (DecrypterInfo13.isPossibleDecrypterMethod(method, firstTime)) {
|
if (DecrypterInfo13.isPossibleDecrypterMethod(method, ref v13State)) {
|
||||||
deobfuscateCctor(simpleDeobfuscator, cctor, ref deobfuscatedCctor, hasPublicKeyToken);
|
deobfuscateCctor(simpleDeobfuscator, cctor, ref deobfuscatedCctor, hasPublicKeyToken);
|
||||||
simpleDeobfuscator.deobfuscate(method);
|
simpleDeobfuscator.deobfuscate(method);
|
||||||
info = getInfoV13(cctor, method);
|
info = getInfoV13(cctor, method);
|
||||||
}
|
}
|
||||||
else if (DecrypterInfo40.isPossibleDecrypterMethod(method, firstTime)) {
|
else if (DecrypterInfo40.isPossibleDecrypterMethod(method, ref v40State)) {
|
||||||
deobfuscateCctor(simpleDeobfuscator, cctor, ref deobfuscatedCctor, hasPublicKeyToken);
|
deobfuscateCctor(simpleDeobfuscator, cctor, ref deobfuscatedCctor, hasPublicKeyToken);
|
||||||
simpleDeobfuscator.deobfuscate(method);
|
simpleDeobfuscator.deobfuscate(method);
|
||||||
info = getInfoV40(cctor, method);
|
info = getInfoV40(cctor, method);
|
||||||
}
|
}
|
||||||
else if (DecrypterInfo41.isPossibleDecrypterMethod(method, firstTime)) {
|
else if (DecrypterInfo41.isPossibleDecrypterMethod(method, ref v41State)) {
|
||||||
deobfuscateCctor(simpleDeobfuscator, cctor, ref deobfuscatedCctor, hasPublicKeyToken);
|
deobfuscateCctor(simpleDeobfuscator, cctor, ref deobfuscatedCctor, hasPublicKeyToken);
|
||||||
simpleDeobfuscator.deobfuscate(method);
|
simpleDeobfuscator.deobfuscate(method);
|
||||||
info = getInfoV41(cctor, method);
|
info = getInfoV41(cctor, method);
|
||||||
}
|
}
|
||||||
firstTime = false;
|
|
||||||
|
|
||||||
if (info == null)
|
if (info == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -555,7 +555,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
var body = method.Body;
|
var body = method.Body;
|
||||||
if (body.InitLocals || body.MaxStack > 8)
|
if (body.InitLocals || body.MaxStack > 8)
|
||||||
return true;
|
return true;
|
||||||
if (body.LocalList.Count > 0)
|
if (body.Variables.Count > 0)
|
||||||
return true;
|
return true;
|
||||||
if (body.ExceptionHandlers.Count > 0)
|
if (body.ExceptionHandlers.Count > 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -349,7 +349,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
var ldloc = instrs[index];
|
var ldloc = instrs[index];
|
||||||
if (!ldloc.IsLdloc())
|
if (!ldloc.IsLdloc())
|
||||||
continue;
|
continue;
|
||||||
if (ldloc.GetLocal(method.Body.LocalList) != local)
|
if (ldloc.GetLocal(method.Body.Variables) != local)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
|
@ -374,7 +374,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
var stloc = instrs[index++];
|
var stloc = instrs[index++];
|
||||||
if (!stloc.IsStloc())
|
if (!stloc.IsStloc())
|
||||||
return null;
|
return null;
|
||||||
return stloc.GetLocal(method.Body.LocalList);
|
return stloc.GetLocal(method.Body.Variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize() {
|
void initialize() {
|
||||||
|
|
|
@ -97,7 +97,7 @@ namespace de4dot.code.deobfuscators.ILProtector {
|
||||||
var cctor = DotNetUtils.getModuleTypeCctor(module);
|
var cctor = DotNetUtils.getModuleTypeCctor(module);
|
||||||
if (cctor != null) {
|
if (cctor != null) {
|
||||||
cctor.Body.InitLocals = false;
|
cctor.Body.InitLocals = false;
|
||||||
cctor.Body.LocalList.Clear();
|
cctor.Body.Variables.Clear();
|
||||||
cctor.Body.Instructions.Clear();
|
cctor.Body.Instructions.Clear();
|
||||||
cctor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
|
cctor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
|
||||||
cctor.Body.ExceptionHandlers.Clear();
|
cctor.Body.ExceptionHandlers.Clear();
|
||||||
|
|
|
@ -83,6 +83,7 @@ namespace de4dot.code.deobfuscators.ILProtector {
|
||||||
if (resource == null)
|
if (resource == null)
|
||||||
continue;
|
continue;
|
||||||
var reader = resource.Data;
|
var reader = resource.Data;
|
||||||
|
reader.Position = 0;
|
||||||
if (!checkResourceV100(reader) &&
|
if (!checkResourceV100(reader) &&
|
||||||
!checkResourceV105(reader))
|
!checkResourceV105(reader))
|
||||||
continue;
|
continue;
|
||||||
|
@ -133,6 +134,7 @@ namespace de4dot.code.deobfuscators.ILProtector {
|
||||||
|
|
||||||
byte[] getMethodsData(EmbeddedResource resource) {
|
byte[] getMethodsData(EmbeddedResource resource) {
|
||||||
var reader = resource.Data;
|
var reader = resource.Data;
|
||||||
|
reader.Position = 0;
|
||||||
reader.Position = startOffset;
|
reader.Position = startOffset;
|
||||||
if ((reader.ReadInt32() & 1) != 0)
|
if ((reader.ReadInt32() & 1) != 0)
|
||||||
return decompress(reader);
|
return decompress(reader);
|
||||||
|
@ -212,7 +214,7 @@ namespace de4dot.code.deobfuscators.ILProtector {
|
||||||
Utils.removeNewlines(method.FullName),
|
Utils.removeNewlines(method.FullName),
|
||||||
method.MDToken.ToInt32(),
|
method.MDToken.ToInt32(),
|
||||||
method.Body.Instructions.Count,
|
method.Body.Instructions.Count,
|
||||||
method.Body.LocalList.Count,
|
method.Body.Variables.Count,
|
||||||
method.Body.ExceptionHandlers.Count);
|
method.Body.ExceptionHandlers.Count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
|
||||||
addCctorInitCallToBeRemoved(method);
|
addCctorInitCallToBeRemoved(method);
|
||||||
addTypeToBeRemoved(mainType.Type, "Obfuscator type");
|
addTypeToBeRemoved(mainType.Type, "Obfuscator type");
|
||||||
removeDuplicateEmbeddedResources();
|
removeDuplicateEmbeddedResources();
|
||||||
|
removeInvalidResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Encoding getEncoding(int cp) {
|
static Encoding getEncoding(int cp) {
|
||||||
|
@ -160,6 +161,8 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
|
||||||
|
|
||||||
public override int GetHashCode() {
|
public override int GetHashCode() {
|
||||||
int hash = 0;
|
int hash = 0;
|
||||||
|
if (resource.Offset != null)
|
||||||
|
hash ^= resource.Offset.GetHashCode();
|
||||||
hash ^= (int)resource.Data.Position;
|
hash ^= (int)resource.Data.Position;
|
||||||
hash ^= (int)resource.Data.Length;
|
hash ^= (int)resource.Data.Length;
|
||||||
return hash;
|
return hash;
|
||||||
|
@ -184,7 +187,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
|
||||||
var rsrc = tmp as EmbeddedResource;
|
var rsrc = tmp as EmbeddedResource;
|
||||||
if (rsrc == null)
|
if (rsrc == null)
|
||||||
continue;
|
continue;
|
||||||
if (rsrc.Data.FileOffset == 0)
|
if (rsrc.Offset == null)
|
||||||
continue;
|
continue;
|
||||||
List<EmbeddedResource> list;
|
List<EmbeddedResource> list;
|
||||||
var key = new ResourceKey(rsrc);
|
var key = new ResourceKey(rsrc);
|
||||||
|
@ -216,6 +219,16 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void removeInvalidResources() {
|
||||||
|
foreach (var tmp in module.Resources) {
|
||||||
|
var resource = tmp as EmbeddedResource;
|
||||||
|
if (resource == null)
|
||||||
|
continue;
|
||||||
|
if (resource.Offset == null || (resource.Data.FileOffset == 0 && resource.Data.Length == 0))
|
||||||
|
addResourceToBeRemoved(resource, "Invalid resource");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override IEnumerable<int> getStringDecrypterMethods() {
|
public override IEnumerable<int> getStringDecrypterMethods() {
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
if (stringDecrypter != null && stringDecrypter.Detected)
|
if (stringDecrypter != null && stringDecrypter.Detected)
|
||||||
|
|
|
@ -141,8 +141,8 @@ namespace de4dot.code.deobfuscators {
|
||||||
return (ClassOrValueTypeSig)add(type);
|
return (ClassOrValueTypeSig)add(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArraySig array(TypeSig typeRef) {
|
public SZArraySig array(TypeSig typeRef) {
|
||||||
return (ArraySig)add(new ArraySig(typeRef));
|
return (SZArraySig)add(new SZArraySig(typeRef));
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeSig add(TypeSig typeRef) {
|
TypeSig add(TypeSig typeRef) {
|
||||||
|
|
|
@ -246,7 +246,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
case Code.Ldloc_1:
|
case Code.Ldloc_1:
|
||||||
case Code.Ldloc_2:
|
case Code.Ldloc_2:
|
||||||
case Code.Ldloc_3:
|
case Code.Ldloc_3:
|
||||||
local = pushInstr.GetLocal(method.Body.LocalList);
|
local = pushInstr.GetLocal(method.Body.Variables);
|
||||||
if (local == null)
|
if (local == null)
|
||||||
return null;
|
return null;
|
||||||
type = local.Type.RemovePinned();
|
type = local.Type.RemovePinned();
|
||||||
|
|
|
@ -102,7 +102,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
calledMethod = null;
|
calledMethod = null;
|
||||||
if (method.Body == null)
|
if (method.Body == null)
|
||||||
return false;
|
return false;
|
||||||
if (method.Body.LocalList.Count > 0)
|
if (method.Body.Variables.Count > 0)
|
||||||
return false;
|
return false;
|
||||||
if (method.Body.ExceptionHandlers.Count > 0)
|
if (method.Body.ExceptionHandlers.Count > 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -88,7 +88,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
class LocalTypes : StringCounts {
|
class LocalTypes : StringCounts {
|
||||||
public LocalTypes(MethodDef method) {
|
public LocalTypes(MethodDef method) {
|
||||||
if (method != null && method.Body != null)
|
if (method != null && method.Body != null)
|
||||||
init(method.Body.LocalList);
|
init(method.Body.Variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalTypes(IEnumerable<Local> locals) {
|
public LocalTypes(IEnumerable<Local> locals) {
|
||||||
|
|
|
@ -329,7 +329,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
pushedArgs = MethodStack.getPushedArgInstructions(instructions, i);
|
pushedArgs = MethodStack.getPushedArgInstructions(instructions, i);
|
||||||
if (pushedArgs.NumValidArgs < 1)
|
if (pushedArgs.NumValidArgs < 1)
|
||||||
break;
|
break;
|
||||||
addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), instr.GetLocal(method.Body.LocalList));
|
addMethodArgType(method, getParameter(methodParams, pushedArgs.getEnd(0)), instr.GetLocal(method.Body.Variables));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Code.Stsfld:
|
case Code.Stsfld:
|
||||||
|
|
|
@ -106,7 +106,7 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor {
|
||||||
return false;
|
return false;
|
||||||
if (intersect(offset, length, dnFile.MetaData.ImageCor20Header))
|
if (intersect(offset, length, dnFile.MetaData.ImageCor20Header))
|
||||||
return false;
|
return false;
|
||||||
if (intersect(offset, length, (uint)dnFile.MetaData.TablesStream.FileOffset, dnFile.MetaData.TablesStream.HeaderLength))
|
if (intersect(offset, length, dnFile.MetaData.MetaDataHeader))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor.v4 {
|
||||||
continue;
|
continue;
|
||||||
if (!DotNetUtils.isMethod(method, "System.Void", "()"))
|
if (!DotNetUtils.isMethod(method, "System.Void", "()"))
|
||||||
continue;
|
continue;
|
||||||
if (method.Body.LocalList.Count > 1)
|
if (method.Body.Variables.Count > 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
simpleDeobfuscator.deobfuscate(method);
|
simpleDeobfuscator.deobfuscate(method);
|
||||||
|
|
|
@ -124,6 +124,7 @@ namespace de4dot.code.renamer {
|
||||||
|
|
||||||
void rename(TypeDef type, EmbeddedResource resource) {
|
void rename(TypeDef type, EmbeddedResource resource) {
|
||||||
newNames.Clear();
|
newNames.Clear();
|
||||||
|
resource.Data.Position = 0;
|
||||||
var resourceSet = ResourceReader.read(module, resource.Data);
|
var resourceSet = ResourceReader.read(module, resource.Data);
|
||||||
var renamed = new List<RenameInfo>();
|
var renamed = new List<RenameInfo>();
|
||||||
foreach (var elem in resourceSet.ResourceElements) {
|
foreach (var elem in resourceSet.ResourceElements) {
|
||||||
|
|
|
@ -530,11 +530,11 @@ namespace de4dot.code.renamer {
|
||||||
if (ret == null)
|
if (ret == null)
|
||||||
return null;
|
return null;
|
||||||
if (ret.IsStloc()) {
|
if (ret.IsStloc()) {
|
||||||
var local = ret.GetLocal(method.Body.LocalList);
|
var local = ret.GetLocal(method.Body.Variables);
|
||||||
ret = DotNetUtils.getInstruction(instructions, ref index);
|
ret = DotNetUtils.getInstruction(instructions, ref index);
|
||||||
if (ret == null || !ret.IsLdloc())
|
if (ret == null || !ret.IsLdloc())
|
||||||
return null;
|
return null;
|
||||||
if (ret.GetLocal(method.Body.LocalList) != local)
|
if (ret.GetLocal(method.Body.Variables) != local)
|
||||||
return null;
|
return null;
|
||||||
ret = DotNetUtils.getInstruction(instructions, ref index);
|
ret = DotNetUtils.getInstruction(instructions, ref index);
|
||||||
}
|
}
|
||||||
|
@ -592,9 +592,9 @@ namespace de4dot.code.renamer {
|
||||||
return null;
|
return null;
|
||||||
if (sig.Params.Count != 1)
|
if (sig.Params.Count != 1)
|
||||||
return null;
|
return null;
|
||||||
if (method.Body.LocalList.Count != 1)
|
if (method.Body.Variables.Count != 1)
|
||||||
return null;
|
return null;
|
||||||
if (!isEventHandlerType(method.Body.LocalList[0].Type))
|
if (!isEventHandlerType(method.Body.Variables[0].Type))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var instructions = method.Body.Instructions;
|
var instructions = method.Body.Instructions;
|
||||||
|
|
|
@ -405,7 +405,7 @@ namespace de4dot.code.renamer.asmmodules {
|
||||||
return;
|
return;
|
||||||
add(cb.Instructions);
|
add(cb.Instructions);
|
||||||
add(cb.ExceptionHandlers);
|
add(cb.ExceptionHandlers);
|
||||||
add(cb.LocalList);
|
add(cb.Variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(IEnumerable<Instruction> instrs) {
|
void add(IEnumerable<Instruction> instrs) {
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace de4dot.cui {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void removeModule(ModuleDef module) {
|
static void removeModule(ModuleDef module) {
|
||||||
TheAssemblyResolver.Instance.removeModule(module);
|
TheAssemblyResolver.Instance.Remove(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
void detectObfuscators() {
|
void detectObfuscators() {
|
||||||
|
|
2
dot10
2
dot10
|
@ -1 +1 @@
|
||||||
Subproject commit 9efe77cebda9b8d3b667fa6404c2805036b967cd
|
Subproject commit 9acb5896ba1f08802f77c0d0240ce3404a39e254
|
Loading…
Reference in New Issue
Block a user