Exemple #1
0
        // Create type model
        public TypeModel(Il2CppInspector package)
        {
            Package = package;
            TypesByDefinitionIndex   = new TypeInfo[package.TypeDefinitions.Length];
            TypesByReferenceIndex    = new TypeInfo[package.TypeReferences.Count];
            GenericParameterTypes    = new TypeInfo[package.GenericParameters.Length];
            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++)
            {
                if (TypesByReferenceIndex[typeRefIndex] != null)
                {
                    /* type already generated - probably by forward reference through GetTypeFromVirtualAddress */
                    continue;
                }

                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)
            {
                var methodDefinition = MethodsByDefinitionIndex[spec.methodDefinitionIndex];
                var declaringType    = methodDefinition.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)
                {
                    var genericInstance  = Package.GenericInstances[spec.classIndexIndex];
                    var genericArguments = ResolveGenericArguments(genericInstance);
                    declaringType = declaringType.MakeGenericType(genericArguments);
                }

                MethodBase method;
                if (methodDefinition is ConstructorInfo)
                {
                    method = declaringType.GetConstructorByDefinition((ConstructorInfo)methodDefinition);
                }
                else
                {
                    method = declaringType.GetMethodByDefinition((MethodInfo)methodDefinition);
                }

                if (spec.methodIndexIndex != -1)
                {
                    var genericInstance  = Package.GenericInstances[spec.methodIndexIndex];
                    var genericArguments = ResolveGenericArguments(genericInstance);
                    method = method.MakeGenericMethod(genericArguments);
                }
                method.VirtualAddress = Package.GetGenericMethodPointer(spec);
                GenericMethods[spec]  = method;
            }

            // Generate a list of all namespaces used
            Namespaces = Assemblies.SelectMany(x => x.DefinedTypes).GroupBy(t => t.Namespace).Select(n => n.Key).Distinct().ToList();

            // Find all custom attribute generators (populate AttributesByIndices) (use ToList() to force evaluation)
            var allAssemblyAttributes  = Assemblies.Select(a => a.CustomAttributes).ToList();
            var allTypeAttributes      = TypesByDefinitionIndex.Select(t => t.CustomAttributes).ToList();
            var allEventAttributes     = TypesByDefinitionIndex.SelectMany(t => t.DeclaredEvents).Select(e => e.CustomAttributes).ToList();
            var allFieldAttributes     = TypesByDefinitionIndex.SelectMany(t => t.DeclaredFields).Select(f => f.CustomAttributes).ToList();
            var allPropertyAttributes  = TypesByDefinitionIndex.SelectMany(t => t.DeclaredProperties).Select(p => p.CustomAttributes).ToList();
            var allMethodAttributes    = MethodsByDefinitionIndex.Select(m => m.CustomAttributes).ToList();
            var allParameterAttributes = MethodsByDefinitionIndex.SelectMany(m => m.DeclaredParameters).Select(p => p.CustomAttributes).ToList();

            // 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];
                }
            }
        }
        // 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);
                    }
                }
            }

            // Find all custom attribute generators (populate AttributesByIndices) (use ToList() to force evaluation)
            var allAssemblyAttributes  = Assemblies.Select(a => a.CustomAttributes).ToList();
            var allTypeAttributes      = TypesByDefinitionIndex.Select(t => t.CustomAttributes).ToList();
            var allEventAttributes     = TypesByDefinitionIndex.SelectMany(t => t.DeclaredEvents).Select(e => e.CustomAttributes).ToList();
            var allFieldAttributes     = TypesByDefinitionIndex.SelectMany(t => t.DeclaredFields).Select(f => f.CustomAttributes).ToList();
            var allPropertyAttributes  = TypesByDefinitionIndex.SelectMany(t => t.DeclaredProperties).Select(p => p.CustomAttributes).ToList();
            var allMethodAttributes    = MethodsByDefinitionIndex.Select(m => m.CustomAttributes).ToList();
            var allParameterAttributes = MethodsByDefinitionIndex.SelectMany(m => m.DeclaredParameters).Select(p => p.CustomAttributes).ToList();

            // 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];
                }
            }
        }