Port more code

This commit is contained in:
de4dot 2012-10-31 22:44:54 +01:00
parent 2e0aa36362
commit 8d87fa02bc
14 changed files with 243 additions and 402 deletions

View File

@ -78,6 +78,10 @@
<Project>{5C93C5E2-196F-4877-BF65-96FEBFCEFCA1}</Project>
<Name>de4dot.mdecrypt</Name>
</ProjectReference>
<ProjectReference Include="..\dot10\src\dot10.csproj">
<Project>{FDFC1237-143F-4919-8318-4926901F4639}</Project>
<Name>dot10</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -20,7 +20,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Mono.Cecil;
using dot10.DotNet;
using de4dot.blocks;
namespace AssemblyData.methodsrewriter {
@ -48,38 +48,38 @@ namespace AssemblyData.methodsrewriter {
}
}
TypeResolver getTypeResolver(TypeReference typeReference) {
var key = typeReference.Namespace + "." + typeReference.Name;
TypeResolver getTypeResolver(ITypeDefOrRef typeRef) {
var key = typeRef.Namespace + "." + typeRef.Name;
List<TypeResolver> list;
if (!types.TryGetValue(key, out list))
return null;
if (typeReference is TypeDefinition) {
if (typeRef is TypeDef) {
foreach (var resolver in list) {
if (resolver.type.MetadataToken == typeReference.MetadataToken.ToInt32())
if (resolver.type.MetadataToken == typeRef.MDToken.Raw)
return resolver;
}
}
foreach (var resolver in list) {
if (ResolverUtils.compareTypes(resolver.type, typeReference))
if (ResolverUtils.compareTypes(resolver.type, typeRef))
return resolver;
}
return null;
}
public FieldInfo resolve(FieldReference fieldReference) {
var resolver = getTypeResolver(fieldReference.DeclaringType);
public FieldInfo resolve(IField fieldRef) {
var resolver = getTypeResolver(fieldRef.DeclaringType);
if (resolver != null)
return resolver.resolve(fieldReference);
return resolveGlobalField(fieldReference);
return resolver.resolve(fieldRef);
return resolveGlobalField(fieldRef);
}
FieldInfo resolveGlobalField(FieldReference fieldReference) {
FieldInfo resolveGlobalField(IField fieldRef) {
initGlobalFields();
foreach (var globalField in globalFields) {
if (ResolverUtils.compareFields(globalField, fieldReference))
if (ResolverUtils.compareFields(globalField, fieldRef))
return globalField;
}
return null;
@ -97,17 +97,17 @@ namespace AssemblyData.methodsrewriter {
}
}
public MethodBase resolve(MethodReference methodReference) {
var resolver = getTypeResolver(methodReference.DeclaringType);
public MethodBase resolve(IMethod methodRef) {
var resolver = getTypeResolver(methodRef.DeclaringType);
if (resolver != null)
return resolver.resolve(methodReference);
return resolveGlobalMethod(methodReference);
return resolver.resolve(methodRef);
return resolveGlobalMethod(methodRef);
}
MethodBase resolveGlobalMethod(MethodReference methodReference) {
MethodBase resolveGlobalMethod(IMethod methodRef) {
initGlobalMethods();
foreach (var globalMethod in globalMethods) {
if (ResolverUtils.compareMethods(globalMethod, methodReference))
if (ResolverUtils.compareMethods(globalMethod, methodRef))
return globalMethod;
}
return null;
@ -125,12 +125,12 @@ namespace AssemblyData.methodsrewriter {
}
}
public Type resolve(TypeReference typeReference) {
var resolver = getTypeResolver(typeReference);
public Type resolve(ITypeDefOrRef typeRef) {
var resolver = getTypeResolver(typeRef);
if (resolver != null)
return resolver.type;
if (typeReference.IsGenericParameter)
if (typeRef.IsGenericParameter)
return typeof(MGenericParameter);
return null;

View File

@ -22,13 +22,13 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using Mono.Cecil;
using Mono.Cecil.Cil;
using dot10.DotNet.Emit;
using dot10.DotNet;
using de4dot.blocks;
using OpCode = Mono.Cecil.Cil.OpCode;
using OpCodes = Mono.Cecil.Cil.OpCodes;
using OperandType = Mono.Cecil.Cil.OperandType;
using OpCode = dot10.DotNet.Emit.OpCode;
using OpCodes = dot10.DotNet.Emit.OpCodes;
using OperandType = dot10.DotNet.Emit.OperandType;
using ROpCode = System.Reflection.Emit.OpCode;
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 lastInstr = allInstructions[allInstructions.Count - 1];
ilg = dm.GetILGenerator(lastInstr.Offset + lastInstr.GetSize());
ilg = dm.GetILGenerator((int)lastInstr.Offset + lastInstr.GetSize());
initInstrToIndex();
initLocals();
@ -134,7 +134,7 @@ namespace AssemblyData.methodsrewriter {
if (ex.FilterStart == instr) {
}
if (ex.HandlerStart == instr) {
if (ex.HandlerType == ExceptionHandlerType.Finally)
if (ex.HandlerType == ExceptionClause.Finally)
ilg.BeginFinallyBlock();
else
ilg.BeginCatchBlock(Resolver.getRtType(ex.CatchType));
@ -178,7 +178,7 @@ namespace AssemblyData.methodsrewriter {
void initLocals() {
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));
tempObjLocal = ilg.DeclareLocal(typeof(object));
tempObjArrayLocal = ilg.DeclareLocal(typeof(object[]));
@ -256,11 +256,11 @@ namespace AssemblyData.methodsrewriter {
return labels;
}
int getArgIndex(ParameterDefinition arg) {
return arg.Sequence;
int getArgIndex(Parameter arg) {
return arg.Index;
}
int getLocalIndex(VariableDefinition local) {
int getLocalIndex(Local local) {
return local.Index;
}
@ -311,7 +311,7 @@ namespace AssemblyData.methodsrewriter {
case OperandType.InlineType:
case OperandType.InlineMethod:
case OperandType.InlineField:
var obj = Resolver.getRtObject((MemberReference)instr.Operand);
var obj = Resolver.getRtObject((ITokenOperand)instr.Operand);
if (obj is ConstructorInfo)
ilg.Emit(opcode, (ConstructorInfo)obj);
else if (obj is MethodInfo)
@ -325,19 +325,19 @@ namespace AssemblyData.methodsrewriter {
break;
case OperandType.InlineArg:
ilg.Emit(opcode, checked((short)getArgIndex((ParameterDefinition)instr.Operand)));
ilg.Emit(opcode, checked((short)getArgIndex((Parameter)instr.Operand)));
break;
case OperandType.ShortInlineArg:
ilg.Emit(opcode, checked((byte)getArgIndex((ParameterDefinition)instr.Operand)));
ilg.Emit(opcode, checked((byte)getArgIndex((Parameter)instr.Operand)));
break;
case OperandType.InlineVar:
ilg.Emit(opcode, checked((short)getLocalIndex((VariableDefinition)instr.Operand)));
ilg.Emit(opcode, checked((short)getLocalIndex((Local)instr.Operand)));
break;
case OperandType.ShortInlineVar:
ilg.Emit(opcode, checked((byte)getLocalIndex((VariableDefinition)instr.Operand)));
ilg.Emit(opcode, checked((byte)getLocalIndex((Local)instr.Operand)));
break;
case OperandType.InlineSig: //TODO:

View File

@ -19,7 +19,6 @@
using System;
using System.Reflection;
using Mono.Cecil;
namespace AssemblyData.methodsrewriter {
interface IMethodsRewriter {

View File

@ -18,20 +18,20 @@
*/
using System.Reflection;
using Mono.Cecil;
using dot10.DotNet;
namespace AssemblyData.methodsrewriter {
class MField {
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.fieldDefinition = fieldDefinition;
this.fieldDef = fieldDef;
}
public override string ToString() {
return fieldDefinition.ToString();
return fieldDef.ToString();
}
}
}

View File

@ -18,23 +18,23 @@
*/
using System.Reflection;
using Mono.Cecil;
using dot10.DotNet;
namespace AssemblyData.methodsrewriter {
class MMethod {
public MethodBase methodBase;
public MethodDefinition methodDefinition;
public MMethod(MethodBase methodBase, MethodDefinition methodDefinition) {
public MethodDef methodDef;
public MMethod(MethodBase methodBase, MethodDef methodDefinition) {
this.methodBase = methodBase;
this.methodDefinition = methodDefinition;
this.methodDef = methodDefinition;
}
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() {
return methodDefinition.ToString();
return methodDef.ToString();
}
}
}

View File

@ -20,74 +20,74 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Mono.Cecil;
using dot10.DotNet;
using de4dot.blocks;
namespace AssemblyData.methodsrewriter {
class MModule {
public Module module;
public ModuleDefinition moduleDefinition;
public ModuleDefMD moduleDef;
TypeDefinitionDict<MType> typeReferenceToType = new TypeDefinitionDict<MType>();
Dictionary<int, MType> tokenToType = new Dictionary<int, MType>();
Dictionary<int, MMethod> tokenToGlobalMethod;
Dictionary<int, MField> tokenToGlobalField;
TypeDefinition moduleType;
TypeDef moduleType;
public MModule(Module module, ModuleDefinition moduleDefinition) {
public MModule(Module module, ModuleDefMD moduleDefinition) {
this.module = module;
this.moduleDefinition = moduleDefinition;
this.moduleDef = moduleDefinition;
initTokenToType();
}
void initTokenToType() {
moduleType = DotNetUtils.getModuleType(moduleDefinition);
foreach (var typeDefinition in moduleDefinition.GetTypes()) {
int token = typeDefinition.MetadataToken.ToInt32();
moduleType = moduleDef.Types[0];
foreach (var typeDef in moduleDef.GetTypes()) {
int token = (int)typeDef.MDToken.Raw;
Type type;
try {
type = module.ResolveType(token);
}
catch {
tokenToType[token] = null;
typeReferenceToType.add(typeDefinition, null);
typeReferenceToType.add(typeDef, null);
continue;
}
var mtype = new MType(type, typeDefinition);
var mtype = new MType(type, typeDef);
tokenToType[token] = mtype;
typeReferenceToType.add(typeDefinition, mtype);
typeReferenceToType.add(typeDef, mtype);
}
}
public MType getType(TypeReference typeReference) {
return typeReferenceToType.find(typeReference);
public MType getType(ITypeDefOrRef typeRef) {
return typeReferenceToType.find(typeRef);
}
public MMethod getMethod(MethodReference methodReference) {
var type = getType(methodReference.DeclaringType);
public MMethod getMethod(IMethod methodRef) {
var type = getType(methodRef.DeclaringType);
if (type != null)
return type.getMethod(methodReference);
if (!MemberReferenceHelper.compareTypes(moduleType, methodReference.DeclaringType))
return type.getMethod(methodRef);
if (!new SigComparer().Equals(moduleType, methodRef.DeclaringType))
return null;
initGlobalMethods();
foreach (var method in tokenToGlobalMethod.Values) {
if (MemberReferenceHelper.compareMethodReference(methodReference, method.methodDefinition))
if (new SigComparer().Equals(methodRef, method.methodDef))
return method;
}
return null;
}
public MField getField(FieldReference fieldReference) {
var type = getType(fieldReference.DeclaringType);
public MField getField(IField fieldRef) {
var type = getType(fieldRef.DeclaringType);
if (type != null)
return type.getField(fieldReference);
if (!MemberReferenceHelper.compareTypes(moduleType, fieldReference.DeclaringType))
return type.getField(fieldRef);
if (!new SigComparer().Equals(moduleType, fieldRef.DeclaringType))
return null;
initGlobalFields();
foreach (var field in tokenToGlobalField.Values) {
if (MemberReferenceHelper.compareFieldReference(fieldReference, field.fieldDefinition))
if (new SigComparer().Equals(fieldRef, field.fieldDef))
return field;
}
@ -120,7 +120,7 @@ namespace AssemblyData.methodsrewriter {
foreach (var m in moduleType.Methods) {
if (m.Name == ".cctor") //TODO: Use module.GetMethod(token) to get .cctor method
continue;
var token = m.MetadataToken.ToInt32();
var token = (int)m.MDToken.Raw;
tokenToGlobalMethod[token] = new MMethod(tmpTokenToGlobalMethod[token], m);
}
}
@ -135,13 +135,13 @@ namespace AssemblyData.methodsrewriter {
foreach (var f in module.GetFields(flags))
tmpTokenToGlobalField[f.MetadataToken] = f;
foreach (var f in moduleType.Fields) {
var token = f.MetadataToken.ToInt32();
var token = (int)f.MDToken.Raw;
tokenToGlobalField[token] = new MField(tmpTokenToGlobalField[token], f);
}
}
public override string ToString() {
return moduleDefinition.FullyQualifiedName;
return moduleDef.Location;
}
}
}

View File

@ -20,31 +20,31 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Mono.Cecil;
using dot10.DotNet;
using de4dot.blocks;
namespace AssemblyData.methodsrewriter {
class MType {
public Type type;
public TypeDefinition typeDefinition;
public TypeDef typeDef;
Dictionary<int, MMethod> tokenToMethod;
MethodDefinitionDict<MMethod> methodReferenceToMethod;
Dictionary<int, MField> tokenToField;
FieldDefinitionDict<MField> fieldReferenceToField;
public MType(Type type, TypeDefinition typeDefinition) {
public MType(Type type, TypeDef typeDefinition) {
this.type = type;
this.typeDefinition = typeDefinition;
this.typeDef = typeDefinition;
}
public MMethod getMethod(MethodReference methodReference) {
public MMethod getMethod(IMethod methodRef) {
initMethods();
return methodReferenceToMethod.find(methodReference);
return methodReferenceToMethod.find(methodRef);
}
public MField getField(FieldReference fieldReference) {
public MField getField(IField fieldRef) {
initFields();
return fieldReferenceToField.find(fieldReference);
return fieldReferenceToField.find(fieldRef);
}
public MMethod getMethod(int token) {
@ -60,41 +60,41 @@ namespace AssemblyData.methodsrewriter {
void initMethods() {
if (tokenToMethod != null)
return;
tokenToMethod = new Dictionary<int, MMethod>(typeDefinition.Methods.Count);
tokenToMethod = new Dictionary<int, MMethod>(typeDef.Methods.Count);
methodReferenceToMethod = new MethodDefinitionDict<MMethod>();
var tmpTokenToMethod = new Dictionary<int, MethodBase>();
var flags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
foreach (var m in ResolverUtils.getMethodBases(type, flags))
tmpTokenToMethod[m.MetadataToken] = m;
foreach (var m in typeDefinition.Methods) {
var token = m.MetadataToken.ToInt32();
foreach (var m in typeDef.Methods) {
var token = (int)m.MDToken.Raw;
var method = new MMethod(tmpTokenToMethod[token], m);
tokenToMethod[token] = method;
methodReferenceToMethod.add(method.methodDefinition, method);
methodReferenceToMethod.add(method.methodDef, method);
}
}
void initFields() {
if (tokenToField != null)
return;
tokenToField = new Dictionary<int, MField>(typeDefinition.Fields.Count);
tokenToField = new Dictionary<int, MField>(typeDef.Fields.Count);
fieldReferenceToField = new FieldDefinitionDict<MField>();
var tmpTokenToField = new Dictionary<int, FieldInfo>();
var flags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
foreach (var f in type.GetFields(flags))
tmpTokenToField[f.MetadataToken] = f;
foreach (var f in typeDefinition.Fields) {
var token = f.MetadataToken.ToInt32();
foreach (var f in typeDef.Fields) {
var token = (int)f.MDToken.Raw;
var field = new MField(tmpTokenToField[token], f);
tokenToField[token] = field;
fieldReferenceToField.add(field.fieldDefinition, field);
fieldReferenceToField.add(field.fieldDef, field);
}
}
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);
}
}
}

View File

@ -22,12 +22,12 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using Mono.Cecil;
using Mono.Cecil.Cil;
using dot10.DotNet.Emit;
using dot10.DotNet;
using de4dot.blocks;
using OpCode = Mono.Cecil.Cil.OpCode;
using OpCodes = Mono.Cecil.Cil.OpCodes;
using OpCode = dot10.DotNet.Emit.OpCode;
using OpCodes = dot10.DotNet.Emit.OpCodes;
using ROpCode = System.Reflection.Emit.OpCode;
using ROpCodes = System.Reflection.Emit.OpCodes;
@ -191,13 +191,13 @@ namespace AssemblyData.methodsrewriter {
var moduleInfo = Resolver.loadAssembly(realMethod.Module);
var methodInfo = moduleInfo.getMethod(realMethod);
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);
codeGenerator.setMethodInfo(methodInfo);
newMethodInfo.delegateType = codeGenerator.DelegateType;
var blocks = new Blocks(methodInfo.methodDefinition);
var blocks = new Blocks(methodInfo.methodDef);
foreach (var block in blocks.MethodBlocks.getAllBlocks())
update(block, newMethodInfo);
@ -230,14 +230,15 @@ namespace AssemblyData.methodsrewriter {
for (int i = 0; i < instrs.Count; i++) {
var instr = instrs[i];
if (instr.OpCode == OpCodes.Newobj) {
var ctor = (MethodReference)instr.Operand;
if (MemberReferenceHelper.verifyType(ctor.DeclaringType, "mscorlib", "System.Diagnostics.StackTrace")) {
var ctor = (IMethod)instr.Operand;
var ctorTypeFullName = ctor.DeclaringType.FullName;
if (ctorTypeFullName == "System.Diagnostics.StackTrace") {
insertLoadThis(block, i + 1);
insertCallOurMethod(block, i + 2, "static_rtFixStackTrace");
i += 2;
continue;
}
else if (MemberReferenceHelper.verifyType(ctor.DeclaringType, "mscorlib", "System.Diagnostics.StackFrame")) {
else if (ctorTypeFullName == "System.Diagnostics.StackFrame") {
insertLoadThis(block, i + 1);
insertCallOurMethod(block, i + 2, "static_rtFixStackFrame");
i += 2;
@ -246,18 +247,19 @@ namespace AssemblyData.methodsrewriter {
}
if (instr.OpCode == OpCodes.Call || instr.OpCode == OpCodes.Callvirt) {
var calledMethod = (MethodReference)instr.Operand;
if (DotNetUtils.isSameAssembly(calledMethod.DeclaringType, "mscorlib")) {
if (calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetAssembly(System.Type)") {
var calledMethod = (IMethod)instr.Operand;
if (calledMethod.DeclaringType.DefinitionAssembly.IsCorLib()) {
var calledMethodFullName = calledMethod.FullName;
if (calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetAssembly(System.Type)") {
block.replace(i, 1, Instruction.Create(OpCodes.Nop));
insertLoadThis(block, i + 1);
insertCallOurMethod(block, i + 2, "static_rtGetAssembly_TypeArg");
i += 2;
continue;
}
else if (calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetCallingAssembly()" ||
calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetEntryAssembly()" ||
calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()") {
else if (calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetCallingAssembly()" ||
calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetEntryAssembly()" ||
calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()") {
block.replace(i, 1, Instruction.Create(OpCodes.Nop));
insertLoadThis(block, i + 1);
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) {
createMethod(method.methodBase);
var newMethodInfo = realMethodToNewMethod[method.methodBase];
@ -276,17 +278,17 @@ namespace AssemblyData.methodsrewriter {
int n = i + 1;
// Pop all pushed args to a temp array
var mparams = getParameters(method.methodDefinition);
var mparams = getParameters(method.methodDef);
if (mparams.Count > 0) {
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++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObjArray)));
for (int j = mparams.Count - 1; j >= 0; j--) {
var argType = mparams[j];
if (argType.IsValueType)
block.insert(n++, Instruction.Create(OpCodes.Box, argType));
if (argType.ElementType == ElementType.ValueType)
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.Ldloc, new Operand(Operand.Type.TempObjArray)));
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.Ldelem_Ref));
var argType = mparams[j];
if (argType.IsValueType)
block.insert(n++, Instruction.Create(OpCodes.Unbox_Any, argType));
if (argType.ElementType == ElementType.ValueType)
block.insert(n++, Instruction.Create(OpCodes.Unbox_Any, ((ValueTypeSig)argType).TypeDefOrRef));
else {
// Don't cast it to its correct type. This will sometimes cause
// an exception in some EF obfuscated assembly since we'll be
@ -329,13 +331,10 @@ namespace AssemblyData.methodsrewriter {
}
}
static List<TypeReference> getParameters(MethodDefinition method) {
int count = method.Parameters.Count + (method.HasImplicitThis ? 1 : 0);
var list = new List<TypeReference>(count);
if (method.HasImplicitThis)
list.Add(method.DeclaringType);
foreach (var argType in method.Parameters)
list.Add(argType.ParameterType);
static IList<TypeSig> getParameters(MethodDef method) {
var list = new List<TypeSig>(method.Parameters.Length + 1);
for (int i = 0; i < method.Parameters.Length; i++)
list.Add(method.Parameters[i].Type);
return list;
}

View File

@ -20,7 +20,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Mono.Cecil;
using dot10.DotNet;
using de4dot.blocks;
namespace AssemblyData.methodsrewriter {
@ -33,47 +33,47 @@ namespace AssemblyData.methodsrewriter {
if (modules.TryGetValue(module, out info))
return info;
info = new MModule(module, ModuleDefinition.ReadModule(module.FullyQualifiedName));
info = new MModule(module, ModuleDefMD.Load(module.FullyQualifiedName));
modules[module] = info;
return info;
}
static MModule getModule(ModuleDefinition moduleDefinition) {
static MModule getModule(ModuleDef moduleDef) {
foreach (var mm in modules.Values) {
if (mm.moduleDefinition == moduleDefinition)
if (mm.moduleDef == moduleDef)
return mm;
}
return null;
}
static MModule getModule(AssemblyNameReference assemblyRef) {
static MModule getModule(AssemblyRef asmRef) {
foreach (var mm in modules.Values) {
var asm = mm.moduleDefinition.Assembly;
if (asm != null && asm.Name.FullName == assemblyRef.FullName)
var asm = mm.moduleDef.Assembly;
if (asm != null && asm.FullName == asmRef.FullName)
return mm;
}
return null;
}
public static MModule getModule(IMetadataScope scope) {
if (scope is ModuleDefinition)
return getModule((ModuleDefinition)scope);
else if (scope is AssemblyNameReference)
return getModule((AssemblyNameReference)scope);
public static MModule getModule(IScope scope) {
if (scope.ScopeType == ScopeType.ModuleDef)
return getModule((ModuleDef)scope);
else if (scope.ScopeType == ScopeType.AssemblyRef)
return getModule((AssemblyRef)scope);
return null;
}
public static MType getType(TypeReference typeReference) {
if (typeReference == null)
public static MType getType(ITypeDefOrRef typeRef) {
if (typeRef == null)
return null;
var module = getModule(typeReference.Scope);
var module = getModule(typeRef.Scope);
if (module != null)
return module.getType(typeReference);
return module.getType(typeRef);
return null;
}
public static MMethod getMethod(MethodReference methodReference) {
public static MMethod getMethod(IMethod methodReference) {
if (methodReference == null)
return null;
var module = getModule(methodReference.DeclaringType.Scope);
@ -82,7 +82,7 @@ namespace AssemblyData.methodsrewriter {
return null;
}
public static MField getField(FieldReference fieldReference) {
public static MField getField(IField fieldReference) {
if (fieldReference == null)
return null;
var module = getModule(fieldReference.DeclaringType.Scope);
@ -91,114 +91,124 @@ namespace AssemblyData.methodsrewriter {
return null;
}
public static object getRtObject(MemberReference memberReference) {
if (memberReference == null)
public static object getRtObject(ITokenOperand memberRef) {
if (memberRef == null)
return null;
else if (memberReference is TypeReference)
return getRtType((TypeReference)memberReference);
else if (memberReference is FieldReference)
return getRtField((FieldReference)memberReference);
else if (memberReference is MethodReference)
return getRtMethod((MethodReference)memberReference);
else if (memberRef is ITypeDefOrRef)
return getRtType((ITypeDefOrRef)memberRef);
else if (memberRef is IField)
return getRtField((IField)memberRef);
else if (memberRef is IMethod)
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) {
var mtype = getType(typeReference);
public static Type getRtType(ITypeDefOrRef typeRef) {
var mtype = getType(typeRef);
if (mtype != null)
return mtype.type;
return Resolver.resolve(typeReference);
return Resolver.resolve(typeRef);
}
public static FieldInfo getRtField(FieldReference fieldReference) {
var mfield = getField(fieldReference);
public static FieldInfo getRtField(IField fieldRef) {
var mfield = getField(fieldRef);
if (mfield != null)
return mfield.fieldInfo;
return Resolver.resolve(fieldReference);
return Resolver.resolve(fieldRef);
}
public static MethodBase getRtMethod(MethodReference methodReference) {
var mmethod = getMethod(methodReference);
public static MethodBase getRtMethod(IMethod methodRef) {
var mmethod = getMethod(methodRef);
if (mmethod != null)
return mmethod.methodBase;
return Resolver.resolve(methodReference);
return Resolver.resolve(methodRef);
}
static AssemblyResolver getAssemblyResolver(TypeReference type) {
var asmName = DotNetUtils.getFullAssemblyName(type);
static AssemblyResolver getAssemblyResolver(ITypeDefOrRef type) {
var asmName = type.DefinitionAssembly.FullName;
AssemblyResolver resolver;
if (!assemblyResolvers.TryGetValue(asmName, out resolver))
assemblyResolvers[asmName] = resolver = new AssemblyResolver(asmName);
return resolver;
}
static Type resolve(TypeReference typeReference) {
if (typeReference == null)
static Type resolve(IType typeRef) {
if (typeRef == null)
return null;
var elemType = typeReference.GetElementType();
var elemType = typeRef.GetElementType();
var resolver = getAssemblyResolver(elemType);
var resolvedType = resolver.resolve(elemType);
if (resolvedType != null)
return fixType(typeReference, resolvedType);
throw new ApplicationException(string.Format("Could not resolve type {0} ({1:X8}) in assembly {2}", typeReference, typeReference.MetadataToken.ToUInt32(), resolver));
return fixType(typeRef, resolvedType);
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) {
if (fieldReference == null)
static FieldInfo resolve(IField fieldRef) {
if (fieldRef == null)
return null;
var resolver = getAssemblyResolver(fieldReference.DeclaringType);
var fieldInfo = resolver.resolve(fieldReference);
var resolver = getAssemblyResolver(fieldRef.DeclaringType);
var fieldInfo = resolver.resolve(fieldRef);
if (fieldInfo != null)
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) {
if (methodReference == null)
static MethodBase resolve(IMethod methodRef) {
if (methodRef == null)
return null;
var resolver = getAssemblyResolver(methodReference.DeclaringType);
var methodBase = resolver.resolve(methodReference);
var resolver = getAssemblyResolver(methodRef.DeclaringType);
var methodBase = resolver.resolve(methodRef);
if (methodBase != null)
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) {
while (typeReference is TypeSpecification) {
var ts = (TypeSpecification)typeReference;
static Type fixType(ITypeDefOrRef typeRef, Type type) {
var ts = typeRef as TypeSpec;
if (ts == null)
return type;
var sig = ts.TypeSig;
while (sig != null) {
switch (sig.ElementType) {
case ElementType.SZArray:
type = type.MakeArrayType();
break;
if (typeReference is ArrayType) {
var arrayType = (ArrayType)typeReference;
if (arrayType.IsVector)
type = type.MakeArrayType();
else
type = type.MakeArrayType(arrayType.Rank);
}
else if (typeReference is ByReferenceType) {
case ElementType.Array:
type = type.MakeArrayType((int)((ArraySig)sig).Rank);
break;
case ElementType.ByRef:
type = type.MakeByRefType();
}
else if (typeReference is PointerType) {
break;
case ElementType.Ptr:
type = type.MakePointerType();
}
else if (typeReference is GenericInstanceType) {
var git = (GenericInstanceType)typeReference;
break;
case ElementType.GenericInst:
var git = (GenericInstSig)sig;
var args = new Type[git.GenericArguments.Count];
bool isGenericTypeDef = true;
for (int i = 0; i < args.Length; i++) {
var typeRef = git.GenericArguments[i];
if (!(typeRef.GetElementType() is GenericParameter))
var arg = git.GenericArguments[i];
if (!(arg is GenericSig))
isGenericTypeDef = false;
args[i] = Resolver.resolve(typeRef);
args[i] = Resolver.resolve(arg);
}
if (!isGenericTypeDef)
type = type.MakeGenericType(args);
break;
default:
break;
}
typeReference = ts.ElementType;
sig = sig.Next;
}
return type;
}

View File

@ -20,146 +20,17 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Mono.Cecil;
using dot10.DotNet;
using de4dot.blocks;
namespace AssemblyData.methodsrewriter {
static class ResolverUtils {
public static bool compareTypes(Type a, TypeReference b) {
if (a == null && b == null)
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));
}
public static bool compareTypes(Type a, IType b) {
return new SigComparer().Equals(a, b);
}
static bool compareArrayTypes(Type a, ArrayType b) {
if (!a.IsArray)
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 compareFields(FieldInfo a, IField b) {
return new SigComparer().Equals(a, b);
}
public static bool hasThis(MethodBase method) {
@ -170,52 +41,8 @@ namespace AssemblyData.methodsrewriter {
return (method.CallingConvention & CallingConventions.ExplicitThis) != 0;
}
public static bool compareMethods(MethodBase a, MethodReference b) {
if (a == null && b == null)
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 bool compareMethods(MethodBase a, IMethod b) {
return new SigComparer().Equals(a, b);
}
public static Type getReturnType(MethodBase methodBase) {
@ -300,15 +127,18 @@ namespace AssemblyData.methodsrewriter {
return list;
}
public static Type makeInstanceType(Type type, TypeReference typeReference) {
var git = typeReference as GenericInstanceType;
public static Type makeInstanceType(Type type, ITypeDefOrRef typeRef) {
var ts = typeRef as TypeSpec;
if (ts == null)
return type;
var git = ts.TypeSig as GenericInstSig;
if (git == null)
return type;
var types = new Type[git.GenericArguments.Count];
bool isTypeDef = true;
for (int i = 0; i < git.GenericArguments.Count; i++) {
var arg = git.GenericArguments[i];
if (!(arg is GenericParameter))
if (!(arg is GenericSig))
isTypeDef = false;
types[i] = Resolver.getRtType(arg);
}

View File

@ -20,7 +20,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Mono.Cecil;
using dot10.DotNet;
using de4dot.blocks;
namespace AssemblyData.methodsrewriter {
@ -29,23 +29,23 @@ namespace AssemblyData.methodsrewriter {
Dictionary<string, List<MethodBase>> methods;
Dictionary<string, List<FieldInfo>> fields;
public TypeInstanceResolver(Type type, TypeReference typeReference) {
this.type = ResolverUtils.makeInstanceType(type, typeReference);
public TypeInstanceResolver(Type type, ITypeDefOrRef typeRef) {
this.type = ResolverUtils.makeInstanceType(type, typeRef);
}
public FieldInfo resolve(FieldReference fieldReference) {
public FieldInfo resolve(IField fieldRef) {
initFields();
List<FieldInfo> list;
if (!fields.TryGetValue(fieldReference.Name, out list))
if (!fields.TryGetValue(fieldRef.Name, out list))
return null;
var git = fieldReference.DeclaringType as GenericInstanceType;
var git = fieldRef.DeclaringType.ToGenericInstSig();
if (git != null)
fieldReference = FieldReferenceInstance.make(fieldReference, git);
fieldRef = FieldReferenceInstance.make(fieldRef, git);
foreach (var field in list) {
if (ResolverUtils.compareFields(field, fieldReference))
if (ResolverUtils.compareFields(field, fieldRef))
return field;
}
@ -66,19 +66,19 @@ namespace AssemblyData.methodsrewriter {
}
}
public MethodBase resolve(MethodReference methodReference) {
public MethodBase resolve(IMethod methodRef) {
initMethods();
List<MethodBase> list;
if (!methods.TryGetValue(methodReference.Name, out list))
if (!methods.TryGetValue(methodRef.Name, out list))
return null;
var git = methodReference.DeclaringType as GenericInstanceType;
var gim = methodReference as GenericInstanceMethod;
methodReference = MethodReferenceInstance.make(methodReference, git, gim);
var git = methodRef.DeclaringType.ToGenericInstSig();
var gim = methodRef as MethodSpec;
methodRef = MethodReferenceInstance.make(methodRef, git, gim);
foreach (var method in list) {
if (ResolverUtils.compareMethods(method, methodReference))
if (ResolverUtils.compareMethods(method, methodRef))
return method;
}

View File

@ -20,32 +20,31 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Mono.Cecil;
using dot10.DotNet;
using de4dot.blocks;
namespace AssemblyData.methodsrewriter {
class TypeResolver {
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) {
this.type = type;
}
TypeInstanceResolver getTypeInstance(TypeReference typeReference) {
var key = new TypeReferenceKey(typeReference);
TypeInstanceResolver getTypeInstance(ITypeDefOrRef typeRef) {
TypeInstanceResolver instance;
if (!typeRefToInstance.TryGetValue(key, out instance))
typeRefToInstance[key] = instance = new TypeInstanceResolver(type, typeReference);
if (!typeRefToInstance.TryGetValue(typeRef, out instance))
typeRefToInstance[typeRef] = instance = new TypeInstanceResolver(type, typeRef);
return instance;
}
public FieldInfo resolve(FieldReference fieldReference) {
return getTypeInstance(fieldReference.DeclaringType).resolve(fieldReference);
public FieldInfo resolve(IField fieldRef) {
return getTypeInstance(fieldRef.DeclaringType).resolve(fieldRef);
}
public MethodBase resolve(MethodReference methodReference) {
return getTypeInstance(methodReference.DeclaringType).resolve(methodReference);
public MethodBase resolve(IMethod methodRef) {
return getTypeInstance(methodRef.DeclaringType).resolve(methodRef);
}
}
}

2
dot10

@ -1 +1 @@
Subproject commit d6f36e4d8d75354483f57a4808dd0e2fe75c94aa
Subproject commit 5df20e544a7b220b3155dfc00c23c72362915806