Example #1
0
        private void Collect(MethodDefinition meth, MethodReference mref)
        {
            GenericInstanceMethod genMeth = null;

            if (Methods.Contains(meth) || ((genMeth = mref as GenericInstanceMethod) != null &&
                                           GenericMethods.Contains(genMeth)))
            {
                return;
            }
            if (genMeth != null)
            {
                GenericMethods.Add(genMeth);
            }
            else
            {
                Methods.Add(meth);
            }
            Collect(genMeth?.ReturnType ?? meth.ReturnType);
            foreach (var param in genMeth?.Parameters ?? meth.Parameters)
            {
                Collect(param);
            }
            if (meth.HasBody)
            {
                Collect(meth.Body);
            }
        }
Example #2
0
        // Create type model
        public Il2CppModel(Il2CppInspector package)
        {
            Package = package;
            TypesByDefinitionIndex   = new TypeInfo[package.TypeDefinitions.Length];
            TypesByReferenceIndex    = new TypeInfo[package.TypeReferences.Count];
            MethodsByDefinitionIndex = new MethodBase[package.Methods.Length];
            MethodInvokers           = new MethodInvoker[package.MethodInvokePointers.Length];

            // Recursively create hierarchy of assemblies and types from TypeDefs
            // No code that executes here can access any type through a TypeRef (ie. via TypesByReferenceIndex)
            for (var image = 0; image < package.Images.Length; image++)
            {
                Assemblies.Add(new Assembly(this, image));
            }

            // Create and reference types from TypeRefs
            // Note that you can't resolve any TypeRefs until all the TypeDefs have been processed
            for (int typeRefIndex = 0; typeRefIndex < package.TypeReferences.Count; typeRefIndex++)
            {
                var typeRef        = Package.TypeReferences[typeRefIndex];
                var referencedType = resolveTypeReference(typeRef);

                TypesByReferenceIndex[typeRefIndex] = referencedType;
            }

            // Create types and methods from MethodSpec (which incorporates TypeSpec in IL2CPP)
            foreach (var spec in Package.MethodSpecs)
            {
                TypeInfo declaringType;

                // Concrete instance of a generic class
                // If the class index is not specified, we will later create a generic method in a non-generic class
                if (spec.classIndexIndex != -1)
                {
                    if (!TypesByMethodSpecClassIndex.ContainsKey(spec.classIndexIndex))
                    {
                        TypesByMethodSpecClassIndex.Add(spec.classIndexIndex, new TypeInfo(this, spec));
                    }

                    declaringType = TypesByMethodSpecClassIndex[spec.classIndexIndex];
                }
                else
                {
                    declaringType = MethodsByDefinitionIndex[spec.methodDefinitionIndex].DeclaringType;
                }

                // Concrete instance of a generic method
                if (spec.methodIndexIndex != -1)
                {
                    // Method or constructor
                    var concreteMethod = new MethodInfo(this, spec, declaringType);
                    if (concreteMethod.Name == ConstructorInfo.ConstructorName || concreteMethod.Name == ConstructorInfo.TypeConstructorName)
                    {
                        GenericMethods.Add(spec, new ConstructorInfo(this, spec, declaringType));
                    }
                    else
                    {
                        GenericMethods.Add(spec, concreteMethod);
                    }
                }
            }

            // Create method invokers (one per signature, in invoker index order)
            foreach (var method in MethodsByDefinitionIndex)
            {
                var index = package.GetInvokerIndex(method.DeclaringType.Assembly.ModuleDefinition, method.Definition);
                if (index != -1)
                {
                    if (MethodInvokers[index] == null)
                    {
                        MethodInvokers[index] = new MethodInvoker(method, index);
                    }

                    method.Invoker = MethodInvokers[index];
                }
            }

            // TODO: Some invokers are not initialized or missing, need to find out why
            // Create method invokers sourced from generic method invoker indices
            foreach (var spec in GenericMethods.Keys)
            {
                if (package.GenericMethodInvokerIndices.TryGetValue(spec, out var index))
                {
                    if (MethodInvokers[index] == null)
                    {
                        MethodInvokers[index] = new MethodInvoker(GenericMethods[spec], index);
                    }

                    GenericMethods[spec].Invoker = MethodInvokers[index];
                }
            }
        }