private static MethodDef LookupMethod(IMethodDefOrRef method, ModuleDefMD sourceAssembly)
 {
     TypeDef type = sourceAssembly.Types.SingleOrDefault(x => x.FullName == method.DeclaringType.FullName);
     return type?.FindMethod(method.Name, method.MethodSig, SigComparerOptions.PrivateScopeMethodIsComparable);
 }
				public MethodAndOverride(MethodDef targetMethod, IMethodDefOrRef methodDeclaration) {
					TargetMethod = targetMethod;
					MethodDeclaration = methodDeclaration;
				}
		public static IMethodDefOrRef Create(IMethodDefOrRef method, GenericInstSig git) {
			if (git == null)
				return method;
			return Create(method, git.GenericArguments);
		}
		public static IMethodDefOrRef Create(IMethodDefOrRef method, GenericInstSig git, IList<TypeSig> genericMethodArgs) {
			return Create(method, git == null ? null : git.GenericArguments, genericMethodArgs);
		}
        public static void ApplyObjectCreationProxy(ITypeService service, ScannedItem parentItem, IList <Instruction> body, ref int index, IMethodDefOrRef operand)
        {
            if (operand.MethodSig.Params.Count > 0)
            {
                return;
            }                                                   //Not supporeted yet

            var proxyMethod = ObjectCreationFactory.Instance.GetCreationMethod(operand.MethodSig.Params.Count);

            if (proxyMethod == null)
            {
                return; //No factory for this parameter number (probaby disabled)
            }

            var typeSig = operand.DeclaringType.ToTypeSig();

            if (parentItem != null)
            {
                typeSig = parentItem.ToGenericIfAvalible(typeSig);
            }

            body[index].OpCode  = OpCodes.Call;
            body[index].Operand = new MethodSpecUser(proxyMethod, new GenericInstMethodSig(typeSig));
        }
Exemple #6
0
		public MMethodDef FindMethod(IMethodDefOrRef md) {
			return methods.Find(md);
		}
Exemple #7
0
 public MethodInst(MMethodDef origMethodDef, IMethodDefOrRef methodRef)
 {
     this.origMethodDef = origMethodDef;
     this.methodRef     = methodRef;
 }
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="methodBody">Method body</param>
		/// <param name="methodDeclaration">The method <paramref name="methodBody"/> implements</param>
		public MethodOverride(IMethodDefOrRef methodBody, IMethodDefOrRef methodDeclaration) {
			this.MethodBody = methodBody;
			this.MethodDeclaration = methodDeclaration;
		}
Exemple #9
0
 public MMethodDef FindMethod(IMethodDefOrRef md)
 {
     return(methods.Find(md));
 }
Exemple #10
0
        void InitializeInterfaceMethods(MethodNameGroups groups)
        {
            InitializeAllInterfaces();

            if (TypeDef.IsInterface)
            {
                return;
            }

            //--- Partition II 12.2 Implementing virtual methods on interfaces:
            //--- The VES shall use the following algorithm to determine the appropriate
            //--- implementation of an interface's virtual abstract methods:
            //---
            //--- * If the base class implements the interface, start with the same virtual methods
            //---	that it provides; otherwise, create an interface that has empty slots for all
            //---	virtual functions.
            // Done. See initializeAllInterfaces().

            var methodsDict = new Dictionary <IMethodDefOrRef, MMethodDef>(MethodEqualityComparer.DontCompareDeclaringTypes);

            //--- * If this class explicitly specifies that it implements the interface (i.e., the
            //---	interfaces that appear in this class‘ InterfaceImpl table, §22.23)
            //---	* If the class defines any public virtual newslot methods whose name and
            //---	  signature match a virtual method on the interface, then use these new virtual
            //---	  methods to implement the corresponding interface method.
            if (interfaces.Count > 0)
            {
                methodsDict.Clear();
                foreach (var method in methods.GetValues())
                {
                    if (!method.IsPublic() || !method.IsVirtual() || !method.IsNewSlot())
                    {
                        continue;
                    }
                    methodsDict[method.MethodDef] = method;
                }

                foreach (var ifaceInfo in interfaces)
                {
                    foreach (var methodsList in ifaceInfo.typeDef.virtualMethodInstances.GetMethods())
                    {
                        if (methodsList.Count < 1)
                        {
                            continue;
                        }
                        var methodInst  = methodsList[0];
                        var ifaceMethod = methodInst.origMethodDef;
                        if (!ifaceMethod.IsVirtual())
                        {
                            continue;
                        }
                        var        ifaceMethodRef = GenericArgsSubstitutor.Create(methodInst.methodRef, ifaceInfo.typeRef.TryGetGenericInstSig());
                        MMethodDef classMethod;
                        if (!methodsDict.TryGetValue(ifaceMethodRef, out classMethod))
                        {
                            continue;
                        }
                        interfaceMethodInfos.AddMethod(ifaceInfo, ifaceMethod, classMethod);
                    }
                }
            }

            //--- * If there are any virtual methods in the interface that still have empty slots,
            //---	see if there are any public virtual methods, but not public virtual newslot
            //---	methods, available on this class (directly or inherited) having the same name
            //---	and signature, then use these to implement the corresponding methods on the
            //---	interface.
            methodsDict.Clear();
            foreach (var methodInstList in virtualMethodInstances.GetMethods())
            {
                // This class' method is at the end
                for (int i = methodInstList.Count - 1; i >= 0; i--)
                {
                    var classMethod = methodInstList[i];
                    // These methods are guaranteed to be virtual.
                    // We should allow newslot methods, despite what the official doc says.
                    if (!classMethod.origMethodDef.IsPublic())
                    {
                        continue;
                    }
                    methodsDict[classMethod.methodRef] = classMethod.origMethodDef;
                    break;
                }
            }
            foreach (var ifaceInfo in allImplementedInterfaces.Keys)
            {
                foreach (var methodsList in ifaceInfo.typeDef.virtualMethodInstances.GetMethods())
                {
                    if (methodsList.Count < 1)
                    {
                        continue;
                    }
                    var ifaceMethod = methodsList[0].origMethodDef;
                    if (!ifaceMethod.IsVirtual())
                    {
                        continue;
                    }
                    var        ifaceMethodRef = GenericArgsSubstitutor.Create(ifaceMethod.MethodDef, ifaceInfo.typeRef.TryGetGenericInstSig());
                    MMethodDef classMethod;
                    if (!methodsDict.TryGetValue(ifaceMethodRef, out classMethod))
                    {
                        continue;
                    }
                    interfaceMethodInfos.AddMethodIfEmpty(ifaceInfo, ifaceMethod, classMethod);
                }
            }

            //--- * Apply all MethodImpls that are specified for this class, thereby placing
            //---	explicitly specified virtual methods into the interface in preference to those
            //---	inherited or chosen by name matching.
            methodsDict.Clear();
            var ifaceMethodsDict = new Dictionary <IMethodDefOrRef, MMethodDef>(MethodEqualityComparer.CompareDeclaringTypes);

            foreach (var ifaceInfo in allImplementedInterfaces.Keys)
            {
                var git = ifaceInfo.typeRef.TryGetGenericInstSig();
                foreach (var ifaceMethod in ifaceInfo.typeDef.methods.GetValues())
                {
                    IMethodDefOrRef ifaceMethodRef = ifaceMethod.MethodDef;
                    if (git != null)
                    {
                        ifaceMethodRef = SimpleClone(ifaceMethod.MethodDef, ifaceInfo.typeRef);
                    }
                    ifaceMethodsDict[ifaceMethodRef] = ifaceMethod;
                }
            }
            foreach (var classMethod in methods.GetValues())
            {
                if (!classMethod.IsVirtual())
                {
                    continue;
                }
                foreach (var overrideMethod in classMethod.MethodDef.Overrides)
                {
                    MMethodDef ifaceMethod;
                    if (!ifaceMethodsDict.TryGetValue(overrideMethod.MethodDeclaration, out ifaceMethod))
                    {
                        // We couldn't find the interface method (eg. interface not resolved) or
                        // it overrides a base class method, and not an interface method.
                        continue;
                    }

                    interfaceMethodInfos.AddMethod(overrideMethod.MethodDeclaration.DeclaringType, ifaceMethod, classMethod);
                }
            }

            //--- * If the current class is not abstract and there are any interface methods that
            //---	still have empty slots, then the program is invalid.
            // Check it anyway. C# requires a method, even if it's abstract. I don't think anyone
            // writes pure CIL assemblies.
            foreach (var info in interfaceMethodInfos.AllInfos)
            {
                foreach (var pair in info.IfaceMethodToClassMethod)
                {
                    if (pair.Value != null)
                    {
                        continue;
                    }
                    if (!ResolvedAllInterfaces() || !ResolvedBaseClasses())
                    {
                        continue;
                    }
                    // Ignore if COM class
                    if (!TypeDef.IsImport &&
                        !HasAttribute("System.Runtime.InteropServices.ComImportAttribute") &&
                        !HasAttribute("System.Runtime.InteropServices.TypeLibTypeAttribute"))
                    {
                        Logger.w("Could not find interface method {0} ({1:X8}). Type: {2} ({3:X8})",
                                 Utils.RemoveNewlines(pair.Key.methodDef.MethodDef),
                                 pair.Key.methodDef.MethodDef.MDToken.ToInt32(),
                                 Utils.RemoveNewlines(TypeDef),
                                 TypeDef.MDToken.ToInt32());
                    }
                }
            }

            foreach (var info in interfaceMethodInfos.AllInfos)
            {
                foreach (var pair in info.IfaceMethodToClassMethod)
                {
                    if (pair.Value == null)
                    {
                        continue;
                    }
                    if (pair.Key.methodDef.MethodDef.Name != pair.Value.MethodDef.Name)
                    {
                        continue;
                    }
                    groups.Same(pair.Key.methodDef, pair.Value);
                }
            }
        }
Exemple #11
0
 public bool ShouldCallInternal(IMethodDefOrRef method, FacelessValue[] args)
 {
     return(OnInternalCall?.Invoke(null, method, args) ?? true);
 }
Exemple #12
0
 public bool ShouldCallExternal(IMethodDefOrRef method, object[] args)
 {
     return(OnExternalCall?.Invoke(null, method, args) ?? true);
 }
Exemple #13
0
 /// <summary>
 /// Gets the advice handled interfaces.
 /// This is done by analyzing method body
 /// </summary>
 /// <param name="methodDefinition">The method definition.</param>
 /// <param name="invokedMethod">The invoked method.</param>
 /// <param name="genericParameterIndex">Index of the generic parameter.</param>
 /// <returns></returns>
 private static IEnumerable <Tuple <ITypeDefOrRef, MethodDef> > GetAdviceHandledInterfaces(MethodDef methodDefinition, IMethodDefOrRef invokedMethod, int genericParameterIndex)
 {
     foreach (var instruction in methodDefinition.Body.Instructions)
     {
         if (instruction.OpCode == OpCodes.Call || instruction.OpCode == OpCodes.Calli || instruction.OpCode == OpCodes.Callvirt)
         {
             var invokedMethodReference = (IMethod)instruction.Operand;
             if (invokedMethodReference.NumberOfGenericParameters > 0 && invokedMethodReference.SafeEquivalent(invokedMethod))
             {
                 var methodSpec       = (MethodSpec)invokedMethodReference;
                 var advisedInterface = methodSpec.GenericInstMethodSig.GenericArguments[genericParameterIndex];
                 //Logger.WriteDebug("Found Advice to '{0}'", advisedInterface);
                 yield return(Tuple.Create(advisedInterface.ToTypeDefOrRef(), methodDefinition));
             }
         }
     }
 }
Exemple #14
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="method">The generic method</param>
 public MethodSpecUser(IMethodDefOrRef method)
     : this(method, null)
 {
 }
Exemple #15
0
 public MethodOverrideOptions(MethodOverride mo)
 {
     MethodBody        = mo.MethodBody;
     MethodDeclaration = mo.MethodDeclaration;
 }
Exemple #16
0
 /// <summary>
 /// Gets the advice handled interfaces.
 /// This is done by analyzing calls in all methods from module
 /// </summary>
 /// <param name="moduleDefinition">The module definition.</param>
 /// <param name="invokedMethod">The invoked method.</param>
 /// <param name="genericParameterIndex">Index of the generic parameter.</param>
 /// <returns></returns>
 private static IEnumerable <Tuple <ITypeDefOrRef, MethodDef> > GetAdviceHandledInterfaces(ModuleDef moduleDefinition,
                                                                                           IMethodDefOrRef invokedMethod, int genericParameterIndex)
 {
     return(moduleDefinition.GetTypes().SelectMany(t => t.Methods.Where(m => m.HasBody)
                                                   .SelectMany(definition => GetAdviceHandledInterfaces(definition, invokedMethod, genericParameterIndex))));
 }
Exemple #17
0
 private void StartRecurseThread(IMethodDefOrRef cleanMethod, IMethodDefOrRef obfMethod) => StartRecurseThread(cleanMethod?.ResolveMethodDef(), obfMethod?.ResolveMethodDef());
Exemple #18
0
 public Instructions Emit(OpCode opCode, IMethodDefOrRef value)
 {
     return(Insert(Instruction.Create(opCode, value)));
 }
Exemple #19
0
 public MethodAndOverride(MethodDef targetMethod, IMethodDefOrRef methodDeclaration)
 {
     TargetMethod      = targetMethod;
     MethodDeclaration = methodDeclaration;
 }
Exemple #20
0
		public List<MethodInst> Lookup(IMethodDefOrRef methodRef) {
			List<MethodInst> list;
			methodInstances.TryGetValue(methodRef, out list);
			return list;
		}
 public static IMethodDefOrRef Create(IMethodDefOrRef method, IList <TypeSig> genericArgs)
 {
     return(Create(method, genericArgs, null));
 }
Exemple #22
0
		public MethodInst(MMethodDef origMethodDef, IMethodDefOrRef methodRef) {
			this.origMethodDef = origMethodDef;
			this.methodRef = methodRef;
		}
 public static IMethodDefOrRef Create(IMethodDefOrRef method, GenericInstSig git, IList <TypeSig> genericMethodArgs)
 {
     return(Create(method, git == null ? null : git.GenericArguments, genericMethodArgs));
 }
		public static IMethodDefOrRef Create(IMethodDefOrRef method, IList<TypeSig> genericArgs) {
			return Create(method, genericArgs, null);
		}
Exemple #25
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="method">The referenced method</param>
 public PdbForwardModuleInfoCustomDebugInfo(IMethodDefOrRef method)
 {
     this.method = method;
 }
		// Creates a new method but keeps declaring type as is
		public static IMethodDefOrRef Create(IMethodDefOrRef method, IList<TypeSig> genericArgs, IList<TypeSig> genericMethodArgs) {
			if (method == null)
				return method;
			if ((genericArgs == null || genericArgs.Count == 0) && (genericMethodArgs == null || genericMethodArgs.Count == 0))
				return method;

			var sig = method.MethodSig;
			if (sig == null)
				return method;

			var newSig = new GenericArgsSubstitutor(genericArgs, genericMethodArgs).Create(sig);
			if (newSig == sig)
				return method;

			return new MemberRefUser(method.DeclaringType.Module, method.Name, newSig, method.DeclaringType);
		}
Exemple #27
0
        public MosaMethod LoadGenericMethodInstance(IMethodDefOrRef method, IList <TypeSig> genericArguments, GenericArgumentResolver resolver)
        {
            var declType = GetType(resolver.Resolve(method.DeclaringType.ToTypeSig()));

            MDToken token;

            if (method is MethodDef)
            {
                token = ((MethodDef)method).MDToken;
            }
            else
            {
                token = ((MemberRef)method).ResolveMethodThrow().MDToken;
            }

            MosaMethod mosaMethod = null;
            UnitDesc <MethodDef, MethodSig> desc = null;

            foreach (var m in declType.Methods)
            {
                desc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >();
                if (desc.Token.Token == token)
                {
                    mosaMethod = m;
                    break;
                }
            }

            if (mosaMethod == null)
            {
                throw new AssemblyLoadException();
            }

            var genericArgs = new List <TypeSig>();

            foreach (var genericArg in genericArguments)
            {
                genericArgs.Add(resolver.Resolve(genericArg));
            }

            resolver.PushMethodGenericArguments(genericArgs);

            // Check for existing generic method instance
            var newSig = resolver.Resolve(method.MethodSig);

            // Need to make sure we pop otherwise it will cause bugs
            resolver.PopMethodGenericArguments();

            var comparer = new SigComparer();

            foreach (var m in declType.Methods)
            {
                var mDesc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >();
                if (mDesc.Definition != desc.Definition || !comparer.Equals(mDesc.Signature, newSig))
                {
                    continue;
                }

                if (!newSig.ContainsGenericParameter && newSig.GenParamCount > 0)
                {
                    return(m);
                }
            }

            mosaMethod = metadata.Controller.CreateMethod(mosaMethod);

            using (var _mosaMethod = metadata.Controller.MutateMethod(mosaMethod))
            {
                bool hasOpening = mosaMethod.DeclaringType.HasOpenGenericParams;
                foreach (var genericArg in genericArgs)
                {
                    hasOpening |= genericArg.HasOpenGenericParameter();
                    _mosaMethod.GenericArguments.Add(GetType(genericArg));
                }

                _mosaMethod.UnderlyingObject = desc.Clone(newSig);
                _mosaMethod.DeclaringType    = declType;

                _mosaMethod.HasOpenGenericParams = hasOpening;
            }

            using (var decl = metadata.Controller.MutateType(declType))
                decl.Methods.Add(mosaMethod);

            metadata.Resolver.EnqueueForResolve(mosaMethod);

            return(mosaMethod);
        }
Exemple #28
0
 public MethodSpecOptions(MethodSpec ms)
 {
     this.Method = ms.Method;
     this.Instantiation = ms.Instantiation;
     this.CustomAttributes.AddRange(ms.CustomAttributes);
 }
Exemple #29
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="methodBody">Method body</param>
 /// <param name="methodDeclaration">The method <paramref name="methodBody"/> implements</param>
 public MethodOverride(IMethodDefOrRef methodBody, IMethodDefOrRef methodDeclaration)
 {
     MethodBody        = methodBody;
     MethodDeclaration = methodDeclaration;
 }
		public MethodOverrideOptions(MethodOverride mo) {
			MethodBody = mo.MethodBody;
			MethodDeclaration = mo.MethodDeclaration;
		}
Exemple #31
0
        private void PopulateEverythingWithData()
        {
            // Populate types
            foreach (var kvp in _processedTypes)
            {
                var originalTypeDef = kvp.Value.OriginalDef;
                var hookTypeDef     = kvp.Value.HookDef;

                if (originalTypeDef.BaseType != null)                 // original has basetype && original's basetype is already processed
                {
                    hookTypeDef.BaseType = FindHookTypeDef(originalTypeDef.BaseType);
                }

                if (originalTypeDef.HasInterfaces)
                {
                    foreach (var originalInterface in originalTypeDef.Interfaces)
                    {
                        hookTypeDef.Interfaces.Add(new InterfaceImplUser(FindHookTypeDef(originalInterface.Interface)));
                    }

                    hookTypeDef.BaseType = FindHookTypeDef(originalTypeDef.BaseType);
                }

                if (originalTypeDef.HasGenericParameters)
                {
                    foreach (var originalParam in originalTypeDef.GenericParameters)
                    {
                        hookTypeDef.GenericParameters.Add(new GenericParamUser(originalParam.Number, GenericParamAttributes.NoSpecialConstraint, originalParam.Name));
                    }
                }
            }

            // Populate fields
            foreach (var kvp in _processedFields)
            {
                if (kvp.OriginalDef.FieldType != null)
                {
                    kvp.HookDef.FieldType = FindHookTypeSig(kvp.OriginalDef.FieldType);
                }
            }

            // Populate methods
            foreach (var kvp in _processedMethods)
            {
                var originalMethodDef = kvp.OriginalDef;
                var hookMethodDef     = kvp.HookDef;

                hookMethodDef.MethodSig = CreateHookMethodSig(originalMethodDef.MethodSig);

                if (originalMethodDef.HasParamDefs)
                {
                    var originalParamDefs = originalMethodDef.ParamDefs;
                    var hookParamDefs     = hookMethodDef.ParamDefs;

                    foreach (var originalParam in originalParamDefs)
                    {
                        hookParamDefs.Add(new ParamDefUser(originalParam.Name, originalParam.Sequence, originalParam.Attributes));
                    }
                }

                if (originalMethodDef.HasGenericParameters)
                {
                    foreach (var originalParam in originalMethodDef.GenericParameters)
                    {
                        hookMethodDef.GenericParameters.Add(new GenericParamUser(originalParam.Number, GenericParamAttributes.NoSpecialConstraint, originalParam.Name));
                    }
                }

                if (originalMethodDef.Overrides.Count > 0)
                {
                    var hookOverrides = new List <MethodOverride>();
                    foreach (var @override in originalMethodDef.Overrides)
                    {
                        IMethodDefOrRef newOverrideMethod = null;

                        if (@override.MethodDeclaration.IsSystemType())
                        {
                            newOverrideMethod = @override.MethodDeclaration;
                            var overrideTypeSig = newOverrideMethod.DeclaringType.ToTypeSig();
                            var genSig          = overrideTypeSig.ToGenericInstSig();
                            if (!(genSig is null))
                            {
                                var genArgs     = genSig.GenericArguments;
                                var newTypeSigs = new List <TypeSig>();
                                foreach (var genArg in genArgs)
                                {
                                    var newTypeDef = _processedTypes.FirstOrDefault(x => x.Value.HookDef.FullName == genArg.FullName).Value.HookDef;
                                    newTypeSigs.Add(newTypeDef.ToTypeSig());
                                }

                                genArgs.Clear();                                 // Remove old args
                                genArgs.AddRange(newTypeSigs);
                            }
                        }
                        else
                        {
                            newOverrideMethod = _processedMethods.FirstOrDefault(x => x.HookDef.FullName == @override.MethodDeclaration.FullName).HookDef;
                        }

                        if (newOverrideMethod != null)
                        {
                            hookOverrides.Add(new MethodOverride(hookMethodDef, newOverrideMethod));
                        }
                    }
                    hookMethodDef.Overrides.AddRange(hookOverrides);
                }
            }
        }
Exemple #32
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="method">The generic method</param>
 /// <param name="sig">The instantiated method sig</param>
 public MethodSpecUser(IMethodDefOrRef method, GenericInstMethodSig sig)
 {
     this.method = method;
     this.instantiation = sig;
 }
Exemple #33
0
 public static IMethodDefOrRef Create(IMethodDefOrRef method, GenericInstSig git, IList <TypeSig> genericMethodArgs) =>
 Create(method, git?.GenericArguments, genericMethodArgs);