Port more code
This commit is contained in:
parent
2e0aa36362
commit
8d87fa02bc
|
@ -78,6 +78,10 @@
|
||||||
<Project>{5C93C5E2-196F-4877-BF65-96FEBFCEFCA1}</Project>
|
<Project>{5C93C5E2-196F-4877-BF65-96FEBFCEFCA1}</Project>
|
||||||
<Name>de4dot.mdecrypt</Name>
|
<Name>de4dot.mdecrypt</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\dot10\src\dot10.csproj">
|
||||||
|
<Project>{FDFC1237-143F-4919-8318-4926901F4639}</Project>
|
||||||
|
<Name>dot10</Name>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace AssemblyData.methodsrewriter {
|
namespace AssemblyData.methodsrewriter {
|
||||||
|
@ -48,38 +48,38 @@ namespace AssemblyData.methodsrewriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeResolver getTypeResolver(TypeReference typeReference) {
|
TypeResolver getTypeResolver(ITypeDefOrRef typeRef) {
|
||||||
var key = typeReference.Namespace + "." + typeReference.Name;
|
var key = typeRef.Namespace + "." + typeRef.Name;
|
||||||
List<TypeResolver> list;
|
List<TypeResolver> list;
|
||||||
if (!types.TryGetValue(key, out list))
|
if (!types.TryGetValue(key, out list))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (typeReference is TypeDefinition) {
|
if (typeRef is TypeDef) {
|
||||||
foreach (var resolver in list) {
|
foreach (var resolver in list) {
|
||||||
if (resolver.type.MetadataToken == typeReference.MetadataToken.ToInt32())
|
if (resolver.type.MetadataToken == typeRef.MDToken.Raw)
|
||||||
return resolver;
|
return resolver;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var resolver in list) {
|
foreach (var resolver in list) {
|
||||||
if (ResolverUtils.compareTypes(resolver.type, typeReference))
|
if (ResolverUtils.compareTypes(resolver.type, typeRef))
|
||||||
return resolver;
|
return resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldInfo resolve(FieldReference fieldReference) {
|
public FieldInfo resolve(IField fieldRef) {
|
||||||
var resolver = getTypeResolver(fieldReference.DeclaringType);
|
var resolver = getTypeResolver(fieldRef.DeclaringType);
|
||||||
if (resolver != null)
|
if (resolver != null)
|
||||||
return resolver.resolve(fieldReference);
|
return resolver.resolve(fieldRef);
|
||||||
return resolveGlobalField(fieldReference);
|
return resolveGlobalField(fieldRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldInfo resolveGlobalField(FieldReference fieldReference) {
|
FieldInfo resolveGlobalField(IField fieldRef) {
|
||||||
initGlobalFields();
|
initGlobalFields();
|
||||||
foreach (var globalField in globalFields) {
|
foreach (var globalField in globalFields) {
|
||||||
if (ResolverUtils.compareFields(globalField, fieldReference))
|
if (ResolverUtils.compareFields(globalField, fieldRef))
|
||||||
return globalField;
|
return globalField;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -97,17 +97,17 @@ namespace AssemblyData.methodsrewriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodBase resolve(MethodReference methodReference) {
|
public MethodBase resolve(IMethod methodRef) {
|
||||||
var resolver = getTypeResolver(methodReference.DeclaringType);
|
var resolver = getTypeResolver(methodRef.DeclaringType);
|
||||||
if (resolver != null)
|
if (resolver != null)
|
||||||
return resolver.resolve(methodReference);
|
return resolver.resolve(methodRef);
|
||||||
return resolveGlobalMethod(methodReference);
|
return resolveGlobalMethod(methodRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodBase resolveGlobalMethod(MethodReference methodReference) {
|
MethodBase resolveGlobalMethod(IMethod methodRef) {
|
||||||
initGlobalMethods();
|
initGlobalMethods();
|
||||||
foreach (var globalMethod in globalMethods) {
|
foreach (var globalMethod in globalMethods) {
|
||||||
if (ResolverUtils.compareMethods(globalMethod, methodReference))
|
if (ResolverUtils.compareMethods(globalMethod, methodRef))
|
||||||
return globalMethod;
|
return globalMethod;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -125,12 +125,12 @@ namespace AssemblyData.methodsrewriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type resolve(TypeReference typeReference) {
|
public Type resolve(ITypeDefOrRef typeRef) {
|
||||||
var resolver = getTypeResolver(typeReference);
|
var resolver = getTypeResolver(typeRef);
|
||||||
if (resolver != null)
|
if (resolver != null)
|
||||||
return resolver.type;
|
return resolver.type;
|
||||||
|
|
||||||
if (typeReference.IsGenericParameter)
|
if (typeRef.IsGenericParameter)
|
||||||
return typeof(MGenericParameter);
|
return typeof(MGenericParameter);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -22,13 +22,13 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
using OpCode = Mono.Cecil.Cil.OpCode;
|
using OpCode = dot10.DotNet.Emit.OpCode;
|
||||||
using OpCodes = Mono.Cecil.Cil.OpCodes;
|
using OpCodes = dot10.DotNet.Emit.OpCodes;
|
||||||
using OperandType = Mono.Cecil.Cil.OperandType;
|
using OperandType = dot10.DotNet.Emit.OperandType;
|
||||||
using ROpCode = System.Reflection.Emit.OpCode;
|
using ROpCode = System.Reflection.Emit.OpCode;
|
||||||
using ROpCodes = System.Reflection.Emit.OpCodes;
|
using ROpCodes = System.Reflection.Emit.OpCodes;
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ namespace AssemblyData.methodsrewriter {
|
||||||
|
|
||||||
var dm = new DynamicMethod(methodName, methodReturnType, methodParameters, methodInfo.methodBase.Module, true);
|
var dm = new DynamicMethod(methodName, methodReturnType, methodParameters, methodInfo.methodBase.Module, true);
|
||||||
var lastInstr = allInstructions[allInstructions.Count - 1];
|
var lastInstr = allInstructions[allInstructions.Count - 1];
|
||||||
ilg = dm.GetILGenerator(lastInstr.Offset + lastInstr.GetSize());
|
ilg = dm.GetILGenerator((int)lastInstr.Offset + lastInstr.GetSize());
|
||||||
|
|
||||||
initInstrToIndex();
|
initInstrToIndex();
|
||||||
initLocals();
|
initLocals();
|
||||||
|
@ -134,7 +134,7 @@ namespace AssemblyData.methodsrewriter {
|
||||||
if (ex.FilterStart == instr) {
|
if (ex.FilterStart == instr) {
|
||||||
}
|
}
|
||||||
if (ex.HandlerStart == instr) {
|
if (ex.HandlerStart == instr) {
|
||||||
if (ex.HandlerType == ExceptionHandlerType.Finally)
|
if (ex.HandlerType == ExceptionClause.Finally)
|
||||||
ilg.BeginFinallyBlock();
|
ilg.BeginFinallyBlock();
|
||||||
else
|
else
|
||||||
ilg.BeginCatchBlock(Resolver.getRtType(ex.CatchType));
|
ilg.BeginCatchBlock(Resolver.getRtType(ex.CatchType));
|
||||||
|
@ -178,7 +178,7 @@ namespace AssemblyData.methodsrewriter {
|
||||||
|
|
||||||
void initLocals() {
|
void initLocals() {
|
||||||
locals = new List<LocalBuilder>();
|
locals = new List<LocalBuilder>();
|
||||||
foreach (var local in methodInfo.methodDefinition.Body.Variables)
|
foreach (var local in methodInfo.methodDef.CilBody.Variables)
|
||||||
locals.Add(ilg.DeclareLocal(Resolver.getRtType(local.VariableType), local.IsPinned));
|
locals.Add(ilg.DeclareLocal(Resolver.getRtType(local.VariableType), local.IsPinned));
|
||||||
tempObjLocal = ilg.DeclareLocal(typeof(object));
|
tempObjLocal = ilg.DeclareLocal(typeof(object));
|
||||||
tempObjArrayLocal = ilg.DeclareLocal(typeof(object[]));
|
tempObjArrayLocal = ilg.DeclareLocal(typeof(object[]));
|
||||||
|
@ -256,11 +256,11 @@ namespace AssemblyData.methodsrewriter {
|
||||||
return labels;
|
return labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getArgIndex(ParameterDefinition arg) {
|
int getArgIndex(Parameter arg) {
|
||||||
return arg.Sequence;
|
return arg.Index;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getLocalIndex(VariableDefinition local) {
|
int getLocalIndex(Local local) {
|
||||||
return local.Index;
|
return local.Index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +311,7 @@ namespace AssemblyData.methodsrewriter {
|
||||||
case OperandType.InlineType:
|
case OperandType.InlineType:
|
||||||
case OperandType.InlineMethod:
|
case OperandType.InlineMethod:
|
||||||
case OperandType.InlineField:
|
case OperandType.InlineField:
|
||||||
var obj = Resolver.getRtObject((MemberReference)instr.Operand);
|
var obj = Resolver.getRtObject((ITokenOperand)instr.Operand);
|
||||||
if (obj is ConstructorInfo)
|
if (obj is ConstructorInfo)
|
||||||
ilg.Emit(opcode, (ConstructorInfo)obj);
|
ilg.Emit(opcode, (ConstructorInfo)obj);
|
||||||
else if (obj is MethodInfo)
|
else if (obj is MethodInfo)
|
||||||
|
@ -325,19 +325,19 @@ namespace AssemblyData.methodsrewriter {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperandType.InlineArg:
|
case OperandType.InlineArg:
|
||||||
ilg.Emit(opcode, checked((short)getArgIndex((ParameterDefinition)instr.Operand)));
|
ilg.Emit(opcode, checked((short)getArgIndex((Parameter)instr.Operand)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperandType.ShortInlineArg:
|
case OperandType.ShortInlineArg:
|
||||||
ilg.Emit(opcode, checked((byte)getArgIndex((ParameterDefinition)instr.Operand)));
|
ilg.Emit(opcode, checked((byte)getArgIndex((Parameter)instr.Operand)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperandType.InlineVar:
|
case OperandType.InlineVar:
|
||||||
ilg.Emit(opcode, checked((short)getLocalIndex((VariableDefinition)instr.Operand)));
|
ilg.Emit(opcode, checked((short)getLocalIndex((Local)instr.Operand)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperandType.ShortInlineVar:
|
case OperandType.ShortInlineVar:
|
||||||
ilg.Emit(opcode, checked((byte)getLocalIndex((VariableDefinition)instr.Operand)));
|
ilg.Emit(opcode, checked((byte)getLocalIndex((Local)instr.Operand)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperandType.InlineSig: //TODO:
|
case OperandType.InlineSig: //TODO:
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Mono.Cecil;
|
|
||||||
|
|
||||||
namespace AssemblyData.methodsrewriter {
|
namespace AssemblyData.methodsrewriter {
|
||||||
interface IMethodsRewriter {
|
interface IMethodsRewriter {
|
||||||
|
|
|
@ -18,20 +18,20 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
|
|
||||||
namespace AssemblyData.methodsrewriter {
|
namespace AssemblyData.methodsrewriter {
|
||||||
class MField {
|
class MField {
|
||||||
public FieldInfo fieldInfo;
|
public FieldInfo fieldInfo;
|
||||||
public FieldDefinition fieldDefinition;
|
public FieldDef fieldDef;
|
||||||
|
|
||||||
public MField(FieldInfo fieldInfo, FieldDefinition fieldDefinition) {
|
public MField(FieldInfo fieldInfo, FieldDef fieldDef) {
|
||||||
this.fieldInfo = fieldInfo;
|
this.fieldInfo = fieldInfo;
|
||||||
this.fieldDefinition = fieldDefinition;
|
this.fieldDef = fieldDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return fieldDefinition.ToString();
|
return fieldDef.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,23 +18,23 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
|
|
||||||
namespace AssemblyData.methodsrewriter {
|
namespace AssemblyData.methodsrewriter {
|
||||||
class MMethod {
|
class MMethod {
|
||||||
public MethodBase methodBase;
|
public MethodBase methodBase;
|
||||||
public MethodDefinition methodDefinition;
|
public MethodDef methodDef;
|
||||||
public MMethod(MethodBase methodBase, MethodDefinition methodDefinition) {
|
public MMethod(MethodBase methodBase, MethodDef methodDefinition) {
|
||||||
this.methodBase = methodBase;
|
this.methodBase = methodBase;
|
||||||
this.methodDefinition = methodDefinition;
|
this.methodDef = methodDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool hasInstructions() {
|
public bool hasInstructions() {
|
||||||
return methodDefinition.Body != null && methodDefinition.Body.Instructions.Count != 0;
|
return methodDef.CilBody != null && methodDef.CilBody.Instructions.Count != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return methodDefinition.ToString();
|
return methodDef.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,74 +20,74 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace AssemblyData.methodsrewriter {
|
namespace AssemblyData.methodsrewriter {
|
||||||
class MModule {
|
class MModule {
|
||||||
public Module module;
|
public Module module;
|
||||||
public ModuleDefinition moduleDefinition;
|
public ModuleDefMD moduleDef;
|
||||||
TypeDefinitionDict<MType> typeReferenceToType = new TypeDefinitionDict<MType>();
|
TypeDefinitionDict<MType> typeReferenceToType = new TypeDefinitionDict<MType>();
|
||||||
Dictionary<int, MType> tokenToType = new Dictionary<int, MType>();
|
Dictionary<int, MType> tokenToType = new Dictionary<int, MType>();
|
||||||
Dictionary<int, MMethod> tokenToGlobalMethod;
|
Dictionary<int, MMethod> tokenToGlobalMethod;
|
||||||
Dictionary<int, MField> tokenToGlobalField;
|
Dictionary<int, MField> tokenToGlobalField;
|
||||||
TypeDefinition moduleType;
|
TypeDef moduleType;
|
||||||
|
|
||||||
public MModule(Module module, ModuleDefinition moduleDefinition) {
|
public MModule(Module module, ModuleDefMD moduleDefinition) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.moduleDefinition = moduleDefinition;
|
this.moduleDef = moduleDefinition;
|
||||||
initTokenToType();
|
initTokenToType();
|
||||||
}
|
}
|
||||||
|
|
||||||
void initTokenToType() {
|
void initTokenToType() {
|
||||||
moduleType = DotNetUtils.getModuleType(moduleDefinition);
|
moduleType = moduleDef.Types[0];
|
||||||
foreach (var typeDefinition in moduleDefinition.GetTypes()) {
|
foreach (var typeDef in moduleDef.GetTypes()) {
|
||||||
int token = typeDefinition.MetadataToken.ToInt32();
|
int token = (int)typeDef.MDToken.Raw;
|
||||||
Type type;
|
Type type;
|
||||||
try {
|
try {
|
||||||
type = module.ResolveType(token);
|
type = module.ResolveType(token);
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
tokenToType[token] = null;
|
tokenToType[token] = null;
|
||||||
typeReferenceToType.add(typeDefinition, null);
|
typeReferenceToType.add(typeDef, null);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var mtype = new MType(type, typeDefinition);
|
var mtype = new MType(type, typeDef);
|
||||||
tokenToType[token] = mtype;
|
tokenToType[token] = mtype;
|
||||||
typeReferenceToType.add(typeDefinition, mtype);
|
typeReferenceToType.add(typeDef, mtype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MType getType(TypeReference typeReference) {
|
public MType getType(ITypeDefOrRef typeRef) {
|
||||||
return typeReferenceToType.find(typeReference);
|
return typeReferenceToType.find(typeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MMethod getMethod(MethodReference methodReference) {
|
public MMethod getMethod(IMethod methodRef) {
|
||||||
var type = getType(methodReference.DeclaringType);
|
var type = getType(methodRef.DeclaringType);
|
||||||
if (type != null)
|
if (type != null)
|
||||||
return type.getMethod(methodReference);
|
return type.getMethod(methodRef);
|
||||||
if (!MemberReferenceHelper.compareTypes(moduleType, methodReference.DeclaringType))
|
if (!new SigComparer().Equals(moduleType, methodRef.DeclaringType))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
initGlobalMethods();
|
initGlobalMethods();
|
||||||
foreach (var method in tokenToGlobalMethod.Values) {
|
foreach (var method in tokenToGlobalMethod.Values) {
|
||||||
if (MemberReferenceHelper.compareMethodReference(methodReference, method.methodDefinition))
|
if (new SigComparer().Equals(methodRef, method.methodDef))
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MField getField(FieldReference fieldReference) {
|
public MField getField(IField fieldRef) {
|
||||||
var type = getType(fieldReference.DeclaringType);
|
var type = getType(fieldRef.DeclaringType);
|
||||||
if (type != null)
|
if (type != null)
|
||||||
return type.getField(fieldReference);
|
return type.getField(fieldRef);
|
||||||
if (!MemberReferenceHelper.compareTypes(moduleType, fieldReference.DeclaringType))
|
if (!new SigComparer().Equals(moduleType, fieldRef.DeclaringType))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
initGlobalFields();
|
initGlobalFields();
|
||||||
foreach (var field in tokenToGlobalField.Values) {
|
foreach (var field in tokenToGlobalField.Values) {
|
||||||
if (MemberReferenceHelper.compareFieldReference(fieldReference, field.fieldDefinition))
|
if (new SigComparer().Equals(fieldRef, field.fieldDef))
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ namespace AssemblyData.methodsrewriter {
|
||||||
foreach (var m in moduleType.Methods) {
|
foreach (var m in moduleType.Methods) {
|
||||||
if (m.Name == ".cctor") //TODO: Use module.GetMethod(token) to get .cctor method
|
if (m.Name == ".cctor") //TODO: Use module.GetMethod(token) to get .cctor method
|
||||||
continue;
|
continue;
|
||||||
var token = m.MetadataToken.ToInt32();
|
var token = (int)m.MDToken.Raw;
|
||||||
tokenToGlobalMethod[token] = new MMethod(tmpTokenToGlobalMethod[token], m);
|
tokenToGlobalMethod[token] = new MMethod(tmpTokenToGlobalMethod[token], m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,13 +135,13 @@ namespace AssemblyData.methodsrewriter {
|
||||||
foreach (var f in module.GetFields(flags))
|
foreach (var f in module.GetFields(flags))
|
||||||
tmpTokenToGlobalField[f.MetadataToken] = f;
|
tmpTokenToGlobalField[f.MetadataToken] = f;
|
||||||
foreach (var f in moduleType.Fields) {
|
foreach (var f in moduleType.Fields) {
|
||||||
var token = f.MetadataToken.ToInt32();
|
var token = (int)f.MDToken.Raw;
|
||||||
tokenToGlobalField[token] = new MField(tmpTokenToGlobalField[token], f);
|
tokenToGlobalField[token] = new MField(tmpTokenToGlobalField[token], f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return moduleDefinition.FullyQualifiedName;
|
return moduleDef.Location;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,31 +20,31 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace AssemblyData.methodsrewriter {
|
namespace AssemblyData.methodsrewriter {
|
||||||
class MType {
|
class MType {
|
||||||
public Type type;
|
public Type type;
|
||||||
public TypeDefinition typeDefinition;
|
public TypeDef typeDef;
|
||||||
Dictionary<int, MMethod> tokenToMethod;
|
Dictionary<int, MMethod> tokenToMethod;
|
||||||
MethodDefinitionDict<MMethod> methodReferenceToMethod;
|
MethodDefinitionDict<MMethod> methodReferenceToMethod;
|
||||||
Dictionary<int, MField> tokenToField;
|
Dictionary<int, MField> tokenToField;
|
||||||
FieldDefinitionDict<MField> fieldReferenceToField;
|
FieldDefinitionDict<MField> fieldReferenceToField;
|
||||||
|
|
||||||
public MType(Type type, TypeDefinition typeDefinition) {
|
public MType(Type type, TypeDef typeDefinition) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.typeDefinition = typeDefinition;
|
this.typeDef = typeDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MMethod getMethod(MethodReference methodReference) {
|
public MMethod getMethod(IMethod methodRef) {
|
||||||
initMethods();
|
initMethods();
|
||||||
return methodReferenceToMethod.find(methodReference);
|
return methodReferenceToMethod.find(methodRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MField getField(FieldReference fieldReference) {
|
public MField getField(IField fieldRef) {
|
||||||
initFields();
|
initFields();
|
||||||
return fieldReferenceToField.find(fieldReference);
|
return fieldReferenceToField.find(fieldRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MMethod getMethod(int token) {
|
public MMethod getMethod(int token) {
|
||||||
|
@ -60,41 +60,41 @@ namespace AssemblyData.methodsrewriter {
|
||||||
void initMethods() {
|
void initMethods() {
|
||||||
if (tokenToMethod != null)
|
if (tokenToMethod != null)
|
||||||
return;
|
return;
|
||||||
tokenToMethod = new Dictionary<int, MMethod>(typeDefinition.Methods.Count);
|
tokenToMethod = new Dictionary<int, MMethod>(typeDef.Methods.Count);
|
||||||
methodReferenceToMethod = new MethodDefinitionDict<MMethod>();
|
methodReferenceToMethod = new MethodDefinitionDict<MMethod>();
|
||||||
|
|
||||||
var tmpTokenToMethod = new Dictionary<int, MethodBase>();
|
var tmpTokenToMethod = new Dictionary<int, MethodBase>();
|
||||||
var flags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
|
var flags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
|
||||||
foreach (var m in ResolverUtils.getMethodBases(type, flags))
|
foreach (var m in ResolverUtils.getMethodBases(type, flags))
|
||||||
tmpTokenToMethod[m.MetadataToken] = m;
|
tmpTokenToMethod[m.MetadataToken] = m;
|
||||||
foreach (var m in typeDefinition.Methods) {
|
foreach (var m in typeDef.Methods) {
|
||||||
var token = m.MetadataToken.ToInt32();
|
var token = (int)m.MDToken.Raw;
|
||||||
var method = new MMethod(tmpTokenToMethod[token], m);
|
var method = new MMethod(tmpTokenToMethod[token], m);
|
||||||
tokenToMethod[token] = method;
|
tokenToMethod[token] = method;
|
||||||
methodReferenceToMethod.add(method.methodDefinition, method);
|
methodReferenceToMethod.add(method.methodDef, method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initFields() {
|
void initFields() {
|
||||||
if (tokenToField != null)
|
if (tokenToField != null)
|
||||||
return;
|
return;
|
||||||
tokenToField = new Dictionary<int, MField>(typeDefinition.Fields.Count);
|
tokenToField = new Dictionary<int, MField>(typeDef.Fields.Count);
|
||||||
fieldReferenceToField = new FieldDefinitionDict<MField>();
|
fieldReferenceToField = new FieldDefinitionDict<MField>();
|
||||||
|
|
||||||
var tmpTokenToField = new Dictionary<int, FieldInfo>();
|
var tmpTokenToField = new Dictionary<int, FieldInfo>();
|
||||||
var flags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
|
var flags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
|
||||||
foreach (var f in type.GetFields(flags))
|
foreach (var f in type.GetFields(flags))
|
||||||
tmpTokenToField[f.MetadataToken] = f;
|
tmpTokenToField[f.MetadataToken] = f;
|
||||||
foreach (var f in typeDefinition.Fields) {
|
foreach (var f in typeDef.Fields) {
|
||||||
var token = f.MetadataToken.ToInt32();
|
var token = (int)f.MDToken.Raw;
|
||||||
var field = new MField(tmpTokenToField[token], f);
|
var field = new MField(tmpTokenToField[token], f);
|
||||||
tokenToField[token] = field;
|
tokenToField[token] = field;
|
||||||
fieldReferenceToField.add(field.fieldDefinition, field);
|
fieldReferenceToField.add(field.fieldDef, field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return string.Format("{0:X8} - {1}", typeDefinition.MetadataToken.ToUInt32(), typeDefinition.FullName);
|
return string.Format("{0:X8} - {1}", typeDef.MDToken.Raw, typeDef.FullName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,12 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Cecil.Cil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
using OpCode = Mono.Cecil.Cil.OpCode;
|
using OpCode = dot10.DotNet.Emit.OpCode;
|
||||||
using OpCodes = Mono.Cecil.Cil.OpCodes;
|
using OpCodes = dot10.DotNet.Emit.OpCodes;
|
||||||
using ROpCode = System.Reflection.Emit.OpCode;
|
using ROpCode = System.Reflection.Emit.OpCode;
|
||||||
using ROpCodes = System.Reflection.Emit.OpCodes;
|
using ROpCodes = System.Reflection.Emit.OpCodes;
|
||||||
|
|
||||||
|
@ -191,13 +191,13 @@ namespace AssemblyData.methodsrewriter {
|
||||||
var moduleInfo = Resolver.loadAssembly(realMethod.Module);
|
var moduleInfo = Resolver.loadAssembly(realMethod.Module);
|
||||||
var methodInfo = moduleInfo.getMethod(realMethod);
|
var methodInfo = moduleInfo.getMethod(realMethod);
|
||||||
if (!methodInfo.hasInstructions())
|
if (!methodInfo.hasInstructions())
|
||||||
throw new ApplicationException(string.Format("Method {0} ({1:X8}) has no body", methodInfo.methodDefinition, methodInfo.methodDefinition.MetadataToken.ToUInt32()));
|
throw new ApplicationException(string.Format("Method {0} ({1:X8}) has no body", methodInfo.methodDef, methodInfo.methodDef.MDToken.Raw));
|
||||||
|
|
||||||
var codeGenerator = new CodeGenerator(this, newMethodInfo.delegateMethodName);
|
var codeGenerator = new CodeGenerator(this, newMethodInfo.delegateMethodName);
|
||||||
codeGenerator.setMethodInfo(methodInfo);
|
codeGenerator.setMethodInfo(methodInfo);
|
||||||
newMethodInfo.delegateType = codeGenerator.DelegateType;
|
newMethodInfo.delegateType = codeGenerator.DelegateType;
|
||||||
|
|
||||||
var blocks = new Blocks(methodInfo.methodDefinition);
|
var blocks = new Blocks(methodInfo.methodDef);
|
||||||
foreach (var block in blocks.MethodBlocks.getAllBlocks())
|
foreach (var block in blocks.MethodBlocks.getAllBlocks())
|
||||||
update(block, newMethodInfo);
|
update(block, newMethodInfo);
|
||||||
|
|
||||||
|
@ -230,14 +230,15 @@ namespace AssemblyData.methodsrewriter {
|
||||||
for (int i = 0; i < instrs.Count; i++) {
|
for (int i = 0; i < instrs.Count; i++) {
|
||||||
var instr = instrs[i];
|
var instr = instrs[i];
|
||||||
if (instr.OpCode == OpCodes.Newobj) {
|
if (instr.OpCode == OpCodes.Newobj) {
|
||||||
var ctor = (MethodReference)instr.Operand;
|
var ctor = (IMethod)instr.Operand;
|
||||||
if (MemberReferenceHelper.verifyType(ctor.DeclaringType, "mscorlib", "System.Diagnostics.StackTrace")) {
|
var ctorTypeFullName = ctor.DeclaringType.FullName;
|
||||||
|
if (ctorTypeFullName == "System.Diagnostics.StackTrace") {
|
||||||
insertLoadThis(block, i + 1);
|
insertLoadThis(block, i + 1);
|
||||||
insertCallOurMethod(block, i + 2, "static_rtFixStackTrace");
|
insertCallOurMethod(block, i + 2, "static_rtFixStackTrace");
|
||||||
i += 2;
|
i += 2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (MemberReferenceHelper.verifyType(ctor.DeclaringType, "mscorlib", "System.Diagnostics.StackFrame")) {
|
else if (ctorTypeFullName == "System.Diagnostics.StackFrame") {
|
||||||
insertLoadThis(block, i + 1);
|
insertLoadThis(block, i + 1);
|
||||||
insertCallOurMethod(block, i + 2, "static_rtFixStackFrame");
|
insertCallOurMethod(block, i + 2, "static_rtFixStackFrame");
|
||||||
i += 2;
|
i += 2;
|
||||||
|
@ -246,18 +247,19 @@ namespace AssemblyData.methodsrewriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instr.OpCode == OpCodes.Call || instr.OpCode == OpCodes.Callvirt) {
|
if (instr.OpCode == OpCodes.Call || instr.OpCode == OpCodes.Callvirt) {
|
||||||
var calledMethod = (MethodReference)instr.Operand;
|
var calledMethod = (IMethod)instr.Operand;
|
||||||
if (DotNetUtils.isSameAssembly(calledMethod.DeclaringType, "mscorlib")) {
|
if (calledMethod.DeclaringType.DefinitionAssembly.IsCorLib()) {
|
||||||
if (calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetAssembly(System.Type)") {
|
var calledMethodFullName = calledMethod.FullName;
|
||||||
|
if (calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetAssembly(System.Type)") {
|
||||||
block.replace(i, 1, Instruction.Create(OpCodes.Nop));
|
block.replace(i, 1, Instruction.Create(OpCodes.Nop));
|
||||||
insertLoadThis(block, i + 1);
|
insertLoadThis(block, i + 1);
|
||||||
insertCallOurMethod(block, i + 2, "static_rtGetAssembly_TypeArg");
|
insertCallOurMethod(block, i + 2, "static_rtGetAssembly_TypeArg");
|
||||||
i += 2;
|
i += 2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetCallingAssembly()" ||
|
else if (calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetCallingAssembly()" ||
|
||||||
calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetEntryAssembly()" ||
|
calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetEntryAssembly()" ||
|
||||||
calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()") {
|
calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()") {
|
||||||
block.replace(i, 1, Instruction.Create(OpCodes.Nop));
|
block.replace(i, 1, Instruction.Create(OpCodes.Nop));
|
||||||
insertLoadThis(block, i + 1);
|
insertLoadThis(block, i + 1);
|
||||||
block.insert(i + 2, Instruction.Create(OpCodes.Ldc_I4, currentMethodInfo.delegateIndex));
|
block.insert(i + 2, Instruction.Create(OpCodes.Ldc_I4, currentMethodInfo.delegateIndex));
|
||||||
|
@ -267,7 +269,7 @@ namespace AssemblyData.methodsrewriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var method = Resolver.getMethod((MethodReference)instr.Operand);
|
var method = Resolver.getMethod((IMethod)instr.Operand);
|
||||||
if (method != null) {
|
if (method != null) {
|
||||||
createMethod(method.methodBase);
|
createMethod(method.methodBase);
|
||||||
var newMethodInfo = realMethodToNewMethod[method.methodBase];
|
var newMethodInfo = realMethodToNewMethod[method.methodBase];
|
||||||
|
@ -276,17 +278,17 @@ namespace AssemblyData.methodsrewriter {
|
||||||
int n = i + 1;
|
int n = i + 1;
|
||||||
|
|
||||||
// Pop all pushed args to a temp array
|
// Pop all pushed args to a temp array
|
||||||
var mparams = getParameters(method.methodDefinition);
|
var mparams = getParameters(method.methodDef);
|
||||||
if (mparams.Count > 0) {
|
if (mparams.Count > 0) {
|
||||||
block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, mparams.Count));
|
block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, mparams.Count));
|
||||||
var objectType = method.methodDefinition.Module.TypeSystem.Object;
|
var objectType = method.methodDef.DeclaringType.OwnerModule.CorLibTypes.Object;
|
||||||
block.insert(n++, Instruction.Create(OpCodes.Newarr, objectType));
|
block.insert(n++, Instruction.Create(OpCodes.Newarr, objectType));
|
||||||
block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObjArray)));
|
block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObjArray)));
|
||||||
|
|
||||||
for (int j = mparams.Count - 1; j >= 0; j--) {
|
for (int j = mparams.Count - 1; j >= 0; j--) {
|
||||||
var argType = mparams[j];
|
var argType = mparams[j];
|
||||||
if (argType.IsValueType)
|
if (argType.ElementType == ElementType.ValueType)
|
||||||
block.insert(n++, Instruction.Create(OpCodes.Box, argType));
|
block.insert(n++, Instruction.Create(OpCodes.Box, ((ValueTypeSig)argType).TypeDefOrRef));
|
||||||
block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObj)));
|
block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObj)));
|
||||||
block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray)));
|
block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray)));
|
||||||
block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, j));
|
block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, j));
|
||||||
|
@ -308,8 +310,8 @@ namespace AssemblyData.methodsrewriter {
|
||||||
block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, j));
|
block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, j));
|
||||||
block.insert(n++, Instruction.Create(OpCodes.Ldelem_Ref));
|
block.insert(n++, Instruction.Create(OpCodes.Ldelem_Ref));
|
||||||
var argType = mparams[j];
|
var argType = mparams[j];
|
||||||
if (argType.IsValueType)
|
if (argType.ElementType == ElementType.ValueType)
|
||||||
block.insert(n++, Instruction.Create(OpCodes.Unbox_Any, argType));
|
block.insert(n++, Instruction.Create(OpCodes.Unbox_Any, ((ValueTypeSig)argType).TypeDefOrRef));
|
||||||
else {
|
else {
|
||||||
// Don't cast it to its correct type. This will sometimes cause
|
// Don't cast it to its correct type. This will sometimes cause
|
||||||
// an exception in some EF obfuscated assembly since we'll be
|
// an exception in some EF obfuscated assembly since we'll be
|
||||||
|
@ -329,13 +331,10 @@ namespace AssemblyData.methodsrewriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<TypeReference> getParameters(MethodDefinition method) {
|
static IList<TypeSig> getParameters(MethodDef method) {
|
||||||
int count = method.Parameters.Count + (method.HasImplicitThis ? 1 : 0);
|
var list = new List<TypeSig>(method.Parameters.Length + 1);
|
||||||
var list = new List<TypeReference>(count);
|
for (int i = 0; i < method.Parameters.Length; i++)
|
||||||
if (method.HasImplicitThis)
|
list.Add(method.Parameters[i].Type);
|
||||||
list.Add(method.DeclaringType);
|
|
||||||
foreach (var argType in method.Parameters)
|
|
||||||
list.Add(argType.ParameterType);
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace AssemblyData.methodsrewriter {
|
namespace AssemblyData.methodsrewriter {
|
||||||
|
@ -33,47 +33,47 @@ namespace AssemblyData.methodsrewriter {
|
||||||
if (modules.TryGetValue(module, out info))
|
if (modules.TryGetValue(module, out info))
|
||||||
return info;
|
return info;
|
||||||
|
|
||||||
info = new MModule(module, ModuleDefinition.ReadModule(module.FullyQualifiedName));
|
info = new MModule(module, ModuleDefMD.Load(module.FullyQualifiedName));
|
||||||
modules[module] = info;
|
modules[module] = info;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MModule getModule(ModuleDefinition moduleDefinition) {
|
static MModule getModule(ModuleDef moduleDef) {
|
||||||
foreach (var mm in modules.Values) {
|
foreach (var mm in modules.Values) {
|
||||||
if (mm.moduleDefinition == moduleDefinition)
|
if (mm.moduleDef == moduleDef)
|
||||||
return mm;
|
return mm;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MModule getModule(AssemblyNameReference assemblyRef) {
|
static MModule getModule(AssemblyRef asmRef) {
|
||||||
foreach (var mm in modules.Values) {
|
foreach (var mm in modules.Values) {
|
||||||
var asm = mm.moduleDefinition.Assembly;
|
var asm = mm.moduleDef.Assembly;
|
||||||
if (asm != null && asm.Name.FullName == assemblyRef.FullName)
|
if (asm != null && asm.FullName == asmRef.FullName)
|
||||||
return mm;
|
return mm;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MModule getModule(IMetadataScope scope) {
|
public static MModule getModule(IScope scope) {
|
||||||
if (scope is ModuleDefinition)
|
if (scope.ScopeType == ScopeType.ModuleDef)
|
||||||
return getModule((ModuleDefinition)scope);
|
return getModule((ModuleDef)scope);
|
||||||
else if (scope is AssemblyNameReference)
|
else if (scope.ScopeType == ScopeType.AssemblyRef)
|
||||||
return getModule((AssemblyNameReference)scope);
|
return getModule((AssemblyRef)scope);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MType getType(TypeReference typeReference) {
|
public static MType getType(ITypeDefOrRef typeRef) {
|
||||||
if (typeReference == null)
|
if (typeRef == null)
|
||||||
return null;
|
return null;
|
||||||
var module = getModule(typeReference.Scope);
|
var module = getModule(typeRef.Scope);
|
||||||
if (module != null)
|
if (module != null)
|
||||||
return module.getType(typeReference);
|
return module.getType(typeRef);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MMethod getMethod(MethodReference methodReference) {
|
public static MMethod getMethod(IMethod methodReference) {
|
||||||
if (methodReference == null)
|
if (methodReference == null)
|
||||||
return null;
|
return null;
|
||||||
var module = getModule(methodReference.DeclaringType.Scope);
|
var module = getModule(methodReference.DeclaringType.Scope);
|
||||||
|
@ -82,7 +82,7 @@ namespace AssemblyData.methodsrewriter {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MField getField(FieldReference fieldReference) {
|
public static MField getField(IField fieldReference) {
|
||||||
if (fieldReference == null)
|
if (fieldReference == null)
|
||||||
return null;
|
return null;
|
||||||
var module = getModule(fieldReference.DeclaringType.Scope);
|
var module = getModule(fieldReference.DeclaringType.Scope);
|
||||||
|
@ -91,114 +91,124 @@ namespace AssemblyData.methodsrewriter {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static object getRtObject(MemberReference memberReference) {
|
public static object getRtObject(ITokenOperand memberRef) {
|
||||||
if (memberReference == null)
|
if (memberRef == null)
|
||||||
return null;
|
return null;
|
||||||
else if (memberReference is TypeReference)
|
else if (memberRef is ITypeDefOrRef)
|
||||||
return getRtType((TypeReference)memberReference);
|
return getRtType((ITypeDefOrRef)memberRef);
|
||||||
else if (memberReference is FieldReference)
|
else if (memberRef is IField)
|
||||||
return getRtField((FieldReference)memberReference);
|
return getRtField((IField)memberRef);
|
||||||
else if (memberReference is MethodReference)
|
else if (memberRef is IMethod)
|
||||||
return getRtMethod((MethodReference)memberReference);
|
return getRtMethod((IMethod)memberRef);
|
||||||
|
|
||||||
throw new ApplicationException(string.Format("Unknown MemberReference: {0}", memberReference));
|
throw new ApplicationException(string.Format("Unknown MemberReference: {0}", memberRef));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type getRtType(TypeReference typeReference) {
|
public static Type getRtType(ITypeDefOrRef typeRef) {
|
||||||
var mtype = getType(typeReference);
|
var mtype = getType(typeRef);
|
||||||
if (mtype != null)
|
if (mtype != null)
|
||||||
return mtype.type;
|
return mtype.type;
|
||||||
|
|
||||||
return Resolver.resolve(typeReference);
|
return Resolver.resolve(typeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FieldInfo getRtField(FieldReference fieldReference) {
|
public static FieldInfo getRtField(IField fieldRef) {
|
||||||
var mfield = getField(fieldReference);
|
var mfield = getField(fieldRef);
|
||||||
if (mfield != null)
|
if (mfield != null)
|
||||||
return mfield.fieldInfo;
|
return mfield.fieldInfo;
|
||||||
|
|
||||||
return Resolver.resolve(fieldReference);
|
return Resolver.resolve(fieldRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MethodBase getRtMethod(MethodReference methodReference) {
|
public static MethodBase getRtMethod(IMethod methodRef) {
|
||||||
var mmethod = getMethod(methodReference);
|
var mmethod = getMethod(methodRef);
|
||||||
if (mmethod != null)
|
if (mmethod != null)
|
||||||
return mmethod.methodBase;
|
return mmethod.methodBase;
|
||||||
|
|
||||||
return Resolver.resolve(methodReference);
|
return Resolver.resolve(methodRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
static AssemblyResolver getAssemblyResolver(TypeReference type) {
|
static AssemblyResolver getAssemblyResolver(ITypeDefOrRef type) {
|
||||||
var asmName = DotNetUtils.getFullAssemblyName(type);
|
var asmName = type.DefinitionAssembly.FullName;
|
||||||
AssemblyResolver resolver;
|
AssemblyResolver resolver;
|
||||||
if (!assemblyResolvers.TryGetValue(asmName, out resolver))
|
if (!assemblyResolvers.TryGetValue(asmName, out resolver))
|
||||||
assemblyResolvers[asmName] = resolver = new AssemblyResolver(asmName);
|
assemblyResolvers[asmName] = resolver = new AssemblyResolver(asmName);
|
||||||
return resolver;
|
return resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Type resolve(TypeReference typeReference) {
|
static Type resolve(IType typeRef) {
|
||||||
if (typeReference == null)
|
if (typeRef == null)
|
||||||
return null;
|
return null;
|
||||||
var elemType = typeReference.GetElementType();
|
var elemType = typeRef.GetElementType();
|
||||||
var resolver = getAssemblyResolver(elemType);
|
var resolver = getAssemblyResolver(elemType);
|
||||||
var resolvedType = resolver.resolve(elemType);
|
var resolvedType = resolver.resolve(elemType);
|
||||||
if (resolvedType != null)
|
if (resolvedType != null)
|
||||||
return fixType(typeReference, resolvedType);
|
return fixType(typeRef, resolvedType);
|
||||||
throw new ApplicationException(string.Format("Could not resolve type {0} ({1:X8}) in assembly {2}", typeReference, typeReference.MetadataToken.ToUInt32(), resolver));
|
throw new ApplicationException(string.Format("Could not resolve type {0} ({1:X8}) in assembly {2}", typeRef, typeRef.MDToken.Raw, resolver));
|
||||||
}
|
}
|
||||||
|
|
||||||
static FieldInfo resolve(FieldReference fieldReference) {
|
static FieldInfo resolve(IField fieldRef) {
|
||||||
if (fieldReference == null)
|
if (fieldRef == null)
|
||||||
return null;
|
return null;
|
||||||
var resolver = getAssemblyResolver(fieldReference.DeclaringType);
|
var resolver = getAssemblyResolver(fieldRef.DeclaringType);
|
||||||
var fieldInfo = resolver.resolve(fieldReference);
|
var fieldInfo = resolver.resolve(fieldRef);
|
||||||
if (fieldInfo != null)
|
if (fieldInfo != null)
|
||||||
return fieldInfo;
|
return fieldInfo;
|
||||||
throw new ApplicationException(string.Format("Could not resolve field {0} ({1:X8}) in assembly {2}", fieldReference, fieldReference.MetadataToken.ToUInt32(), resolver));
|
throw new ApplicationException(string.Format("Could not resolve field {0} ({1:X8}) in assembly {2}", fieldRef, fieldRef.MDToken.Raw, resolver));
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodBase resolve(MethodReference methodReference) {
|
static MethodBase resolve(IMethod methodRef) {
|
||||||
if (methodReference == null)
|
if (methodRef == null)
|
||||||
return null;
|
return null;
|
||||||
var resolver = getAssemblyResolver(methodReference.DeclaringType);
|
var resolver = getAssemblyResolver(methodRef.DeclaringType);
|
||||||
var methodBase = resolver.resolve(methodReference);
|
var methodBase = resolver.resolve(methodRef);
|
||||||
if (methodBase != null)
|
if (methodBase != null)
|
||||||
return methodBase;
|
return methodBase;
|
||||||
throw new ApplicationException(string.Format("Could not resolve method {0} ({1:X8}) in assembly {2}", methodReference, methodReference.MetadataToken.ToUInt32(), resolver));
|
throw new ApplicationException(string.Format("Could not resolve method {0} ({1:X8}) in assembly {2}", methodRef, methodRef.MDToken.Raw, resolver));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Type fixType(TypeReference typeReference, Type type) {
|
static Type fixType(ITypeDefOrRef typeRef, Type type) {
|
||||||
while (typeReference is TypeSpecification) {
|
var ts = typeRef as TypeSpec;
|
||||||
var ts = (TypeSpecification)typeReference;
|
if (ts == null)
|
||||||
|
return type;
|
||||||
if (typeReference is ArrayType) {
|
var sig = ts.TypeSig;
|
||||||
var arrayType = (ArrayType)typeReference;
|
while (sig != null) {
|
||||||
if (arrayType.IsVector)
|
switch (sig.ElementType) {
|
||||||
|
case ElementType.SZArray:
|
||||||
type = type.MakeArrayType();
|
type = type.MakeArrayType();
|
||||||
else
|
break;
|
||||||
type = type.MakeArrayType(arrayType.Rank);
|
|
||||||
}
|
case ElementType.Array:
|
||||||
else if (typeReference is ByReferenceType) {
|
type = type.MakeArrayType((int)((ArraySig)sig).Rank);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ElementType.ByRef:
|
||||||
type = type.MakeByRefType();
|
type = type.MakeByRefType();
|
||||||
}
|
break;
|
||||||
else if (typeReference is PointerType) {
|
|
||||||
|
case ElementType.Ptr:
|
||||||
type = type.MakePointerType();
|
type = type.MakePointerType();
|
||||||
}
|
break;
|
||||||
else if (typeReference is GenericInstanceType) {
|
|
||||||
var git = (GenericInstanceType)typeReference;
|
case ElementType.GenericInst:
|
||||||
|
var git = (GenericInstSig)sig;
|
||||||
var args = new Type[git.GenericArguments.Count];
|
var args = new Type[git.GenericArguments.Count];
|
||||||
bool isGenericTypeDef = true;
|
bool isGenericTypeDef = true;
|
||||||
for (int i = 0; i < args.Length; i++) {
|
for (int i = 0; i < args.Length; i++) {
|
||||||
var typeRef = git.GenericArguments[i];
|
var arg = git.GenericArguments[i];
|
||||||
if (!(typeRef.GetElementType() is GenericParameter))
|
if (!(arg is GenericSig))
|
||||||
isGenericTypeDef = false;
|
isGenericTypeDef = false;
|
||||||
args[i] = Resolver.resolve(typeRef);
|
args[i] = Resolver.resolve(arg);
|
||||||
}
|
}
|
||||||
if (!isGenericTypeDef)
|
if (!isGenericTypeDef)
|
||||||
type = type.MakeGenericType(args);
|
type = type.MakeGenericType(args);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
typeReference = ts.ElementType;
|
sig = sig.Next;
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,146 +20,17 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace AssemblyData.methodsrewriter {
|
namespace AssemblyData.methodsrewriter {
|
||||||
static class ResolverUtils {
|
static class ResolverUtils {
|
||||||
public static bool compareTypes(Type a, TypeReference b) {
|
public static bool compareTypes(Type a, IType b) {
|
||||||
if (a == null && b == null)
|
return new SigComparer().Equals(a, b);
|
||||||
return true;
|
|
||||||
if (a == null || b == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var type = MemberReferenceHelper.getMemberReferenceType(b);
|
|
||||||
switch (type) {
|
|
||||||
case CecilType.ArrayType:
|
|
||||||
return compareArrayTypes(a, (ArrayType)b);
|
|
||||||
case CecilType.ByReferenceType:
|
|
||||||
return compareByReferenceTypes(a, (ByReferenceType)b);
|
|
||||||
case CecilType.FunctionPointerType:
|
|
||||||
return compareFunctionPointerTypes(a, (FunctionPointerType)b);
|
|
||||||
case CecilType.GenericInstanceType:
|
|
||||||
return compareGenericInstanceTypes(a, (GenericInstanceType)b);
|
|
||||||
case CecilType.GenericParameter:
|
|
||||||
return compareGenericParameters(a, (GenericParameter)b);
|
|
||||||
case CecilType.OptionalModifierType:
|
|
||||||
return compareOptionalModifierTypes(a, (OptionalModifierType)b);
|
|
||||||
case CecilType.PinnedType:
|
|
||||||
return comparePinnedTypes(a, (PinnedType)b);
|
|
||||||
case CecilType.PointerType:
|
|
||||||
return comparePointerTypes(a, (PointerType)b);
|
|
||||||
case CecilType.RequiredModifierType:
|
|
||||||
return compareRequiredModifierTypes(a, (RequiredModifierType)b);
|
|
||||||
case CecilType.SentinelType:
|
|
||||||
return compareSentinelTypes(a, (SentinelType)b);
|
|
||||||
case CecilType.TypeDefinition:
|
|
||||||
return compareTypeDefinitions(a, (TypeDefinition)b);
|
|
||||||
case CecilType.TypeReference:
|
|
||||||
return compareTypeReferences(a, (TypeReference)b);
|
|
||||||
default:
|
|
||||||
throw new ApplicationException(string.Format("Unknown cecil type {0}", type));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool compareArrayTypes(Type a, ArrayType b) {
|
public static bool compareFields(FieldInfo a, IField b) {
|
||||||
if (!a.IsArray)
|
return new SigComparer().Equals(a, b);
|
||||||
return false;
|
|
||||||
if (a.GetArrayRank() != b.Rank)
|
|
||||||
return false;
|
|
||||||
return compareTypes(a.GetElementType(), b.ElementType);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool compareByReferenceTypes(Type a, ByReferenceType b) {
|
|
||||||
if (!a.IsByRef)
|
|
||||||
return false;
|
|
||||||
return compareTypes(a.GetElementType(), b.ElementType);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool compareFunctionPointerTypes(Type a, FunctionPointerType b) {
|
|
||||||
return compareTypes(a, b.ElementType);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool compareGenericInstanceTypes(Type a, GenericInstanceType b) {
|
|
||||||
if (!a.IsGenericType)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var aGpargs = a.GetGenericArguments();
|
|
||||||
var bGpargs = b.GenericArguments;
|
|
||||||
if (aGpargs.Length != bGpargs.Count)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (int i = 0; i < aGpargs.Length; i++) {
|
|
||||||
var aArg = aGpargs[i];
|
|
||||||
var bArg = bGpargs[i];
|
|
||||||
if (aArg.IsGenericParameter)
|
|
||||||
continue;
|
|
||||||
if (!compareTypes(aArg, bArg))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return compareTypes(a, b.ElementType);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool compareGenericParameters(Type a, GenericParameter b) {
|
|
||||||
if (!a.IsGenericParameter)
|
|
||||||
return false;
|
|
||||||
if (a.GenericParameterPosition != b.Position)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool compareOptionalModifierTypes(Type a, OptionalModifierType b) {
|
|
||||||
return compareTypes(a, b.ElementType);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool comparePinnedTypes(Type a, PinnedType b) {
|
|
||||||
return compareTypes(a, b.ElementType);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool comparePointerTypes(Type a, PointerType b) {
|
|
||||||
if (!a.IsPointer)
|
|
||||||
return false;
|
|
||||||
return compareTypes(a.GetElementType(), b.ElementType);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool compareRequiredModifierTypes(Type a, RequiredModifierType b) {
|
|
||||||
return compareTypes(a, b.ElementType);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool compareSentinelTypes(Type a, SentinelType b) {
|
|
||||||
return compareTypes(a, b.ElementType);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool compareTypeDefinitions(Type a, TypeDefinition b) {
|
|
||||||
return compareTypeReferences(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool compareTypeReferences(Type a, TypeReference b) {
|
|
||||||
if (a.IsGenericParameter || a.IsPointer || a.IsByRef || a.IsArray)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (a.Name != b.Name)
|
|
||||||
return false;
|
|
||||||
if ((a.Namespace ?? "") != b.Namespace)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var asmRef = DotNetUtils.getAssemblyNameReference(b);
|
|
||||||
var asmName = a.Assembly.GetName();
|
|
||||||
if (asmRef == null || asmRef.Name != asmName.Name)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return compareTypes(a.DeclaringType, b.DeclaringType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool compareFields(FieldInfo a, FieldReference b) {
|
|
||||||
if (a == null && b == null)
|
|
||||||
return true;
|
|
||||||
if (a == null || b == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return a.Name == b.Name &&
|
|
||||||
compareTypes(a.FieldType, b.FieldType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool hasThis(MethodBase method) {
|
public static bool hasThis(MethodBase method) {
|
||||||
|
@ -170,52 +41,8 @@ namespace AssemblyData.methodsrewriter {
|
||||||
return (method.CallingConvention & CallingConventions.ExplicitThis) != 0;
|
return (method.CallingConvention & CallingConventions.ExplicitThis) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool compareMethods(MethodBase a, MethodReference b) {
|
public static bool compareMethods(MethodBase a, IMethod b) {
|
||||||
if (a == null && b == null)
|
return new SigComparer().Equals(a, b);
|
||||||
return true;
|
|
||||||
if (a == null || b == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (a.Name != b.Name)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (hasThis(a) != b.HasThis || explicitThis(a) != b.ExplicitThis)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
CallingConventions aCallingConvention = a.CallingConvention & (CallingConventions)7;
|
|
||||||
switch (b.CallingConvention) {
|
|
||||||
case MethodCallingConvention.Default:
|
|
||||||
if (aCallingConvention != CallingConventions.Standard && aCallingConvention != CallingConventions.Any)
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MethodCallingConvention.VarArg:
|
|
||||||
if (aCallingConvention != CallingConventions.VarArgs && aCallingConvention != CallingConventions.Any)
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!compareTypes(getReturnType(a), b.MethodReturnType.ReturnType))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var aParams = a.GetParameters();
|
|
||||||
var bParams = b.Parameters;
|
|
||||||
if (aParams.Length != bParams.Count)
|
|
||||||
return false;
|
|
||||||
for (int i = 0; i < aParams.Length; i++) {
|
|
||||||
if (!compareTypes(aParams[i].ParameterType, bParams[i].ParameterType))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var aGparams = getGenericArguments(a);
|
|
||||||
var bGparams = b.GenericParameters;
|
|
||||||
if (aGparams.Length != bGparams.Count)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type getReturnType(MethodBase methodBase) {
|
public static Type getReturnType(MethodBase methodBase) {
|
||||||
|
@ -300,15 +127,18 @@ namespace AssemblyData.methodsrewriter {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type makeInstanceType(Type type, TypeReference typeReference) {
|
public static Type makeInstanceType(Type type, ITypeDefOrRef typeRef) {
|
||||||
var git = typeReference as GenericInstanceType;
|
var ts = typeRef as TypeSpec;
|
||||||
|
if (ts == null)
|
||||||
|
return type;
|
||||||
|
var git = ts.TypeSig as GenericInstSig;
|
||||||
if (git == null)
|
if (git == null)
|
||||||
return type;
|
return type;
|
||||||
var types = new Type[git.GenericArguments.Count];
|
var types = new Type[git.GenericArguments.Count];
|
||||||
bool isTypeDef = true;
|
bool isTypeDef = true;
|
||||||
for (int i = 0; i < git.GenericArguments.Count; i++) {
|
for (int i = 0; i < git.GenericArguments.Count; i++) {
|
||||||
var arg = git.GenericArguments[i];
|
var arg = git.GenericArguments[i];
|
||||||
if (!(arg is GenericParameter))
|
if (!(arg is GenericSig))
|
||||||
isTypeDef = false;
|
isTypeDef = false;
|
||||||
types[i] = Resolver.getRtType(arg);
|
types[i] = Resolver.getRtType(arg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace AssemblyData.methodsrewriter {
|
namespace AssemblyData.methodsrewriter {
|
||||||
|
@ -29,23 +29,23 @@ namespace AssemblyData.methodsrewriter {
|
||||||
Dictionary<string, List<MethodBase>> methods;
|
Dictionary<string, List<MethodBase>> methods;
|
||||||
Dictionary<string, List<FieldInfo>> fields;
|
Dictionary<string, List<FieldInfo>> fields;
|
||||||
|
|
||||||
public TypeInstanceResolver(Type type, TypeReference typeReference) {
|
public TypeInstanceResolver(Type type, ITypeDefOrRef typeRef) {
|
||||||
this.type = ResolverUtils.makeInstanceType(type, typeReference);
|
this.type = ResolverUtils.makeInstanceType(type, typeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldInfo resolve(FieldReference fieldReference) {
|
public FieldInfo resolve(IField fieldRef) {
|
||||||
initFields();
|
initFields();
|
||||||
|
|
||||||
List<FieldInfo> list;
|
List<FieldInfo> list;
|
||||||
if (!fields.TryGetValue(fieldReference.Name, out list))
|
if (!fields.TryGetValue(fieldRef.Name, out list))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var git = fieldReference.DeclaringType as GenericInstanceType;
|
var git = fieldRef.DeclaringType.ToGenericInstSig();
|
||||||
if (git != null)
|
if (git != null)
|
||||||
fieldReference = FieldReferenceInstance.make(fieldReference, git);
|
fieldRef = FieldReferenceInstance.make(fieldRef, git);
|
||||||
|
|
||||||
foreach (var field in list) {
|
foreach (var field in list) {
|
||||||
if (ResolverUtils.compareFields(field, fieldReference))
|
if (ResolverUtils.compareFields(field, fieldRef))
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,19 +66,19 @@ namespace AssemblyData.methodsrewriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodBase resolve(MethodReference methodReference) {
|
public MethodBase resolve(IMethod methodRef) {
|
||||||
initMethods();
|
initMethods();
|
||||||
|
|
||||||
List<MethodBase> list;
|
List<MethodBase> list;
|
||||||
if (!methods.TryGetValue(methodReference.Name, out list))
|
if (!methods.TryGetValue(methodRef.Name, out list))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var git = methodReference.DeclaringType as GenericInstanceType;
|
var git = methodRef.DeclaringType.ToGenericInstSig();
|
||||||
var gim = methodReference as GenericInstanceMethod;
|
var gim = methodRef as MethodSpec;
|
||||||
methodReference = MethodReferenceInstance.make(methodReference, git, gim);
|
methodRef = MethodReferenceInstance.make(methodRef, git, gim);
|
||||||
|
|
||||||
foreach (var method in list) {
|
foreach (var method in list) {
|
||||||
if (ResolverUtils.compareMethods(method, methodReference))
|
if (ResolverUtils.compareMethods(method, methodRef))
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,32 +20,31 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Mono.Cecil;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace AssemblyData.methodsrewriter {
|
namespace AssemblyData.methodsrewriter {
|
||||||
class TypeResolver {
|
class TypeResolver {
|
||||||
public Type type;
|
public Type type;
|
||||||
Dictionary<TypeReferenceKey, TypeInstanceResolver> typeRefToInstance = new Dictionary<TypeReferenceKey, TypeInstanceResolver>();
|
Dictionary<ITypeDefOrRef, TypeInstanceResolver> typeRefToInstance = new Dictionary<ITypeDefOrRef, TypeInstanceResolver>(TypeEqualityComparer.Instance);
|
||||||
|
|
||||||
public TypeResolver(Type type) {
|
public TypeResolver(Type type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeInstanceResolver getTypeInstance(TypeReference typeReference) {
|
TypeInstanceResolver getTypeInstance(ITypeDefOrRef typeRef) {
|
||||||
var key = new TypeReferenceKey(typeReference);
|
|
||||||
TypeInstanceResolver instance;
|
TypeInstanceResolver instance;
|
||||||
if (!typeRefToInstance.TryGetValue(key, out instance))
|
if (!typeRefToInstance.TryGetValue(typeRef, out instance))
|
||||||
typeRefToInstance[key] = instance = new TypeInstanceResolver(type, typeReference);
|
typeRefToInstance[typeRef] = instance = new TypeInstanceResolver(type, typeRef);
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldInfo resolve(FieldReference fieldReference) {
|
public FieldInfo resolve(IField fieldRef) {
|
||||||
return getTypeInstance(fieldReference.DeclaringType).resolve(fieldReference);
|
return getTypeInstance(fieldRef.DeclaringType).resolve(fieldRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodBase resolve(MethodReference methodReference) {
|
public MethodBase resolve(IMethod methodRef) {
|
||||||
return getTypeInstance(methodReference.DeclaringType).resolve(methodReference);
|
return getTypeInstance(methodRef.DeclaringType).resolve(methodRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
dot10
2
dot10
|
@ -1 +1 @@
|
||||||
Subproject commit d6f36e4d8d75354483f57a4808dd0e2fe75c94aa
|
Subproject commit 5df20e544a7b220b3155dfc00c23c72362915806
|
Loading…
Reference in New Issue
Block a user