Ejemplo n.º 1
0
        private void Configure(IFileFormatReader image, ulong codeRegistration, ulong metadataRegistration)
        {
            CodeRegistration     = image.ReadMappedObject <Il2CppCodeRegistration>(codeRegistration);
            MetadataRegistration = image.ReadMappedObject <Il2CppMetadataRegistration>(metadataRegistration);
            MethodPointers       = image.ReadMappedArray <uint>(CodeRegistration.pmethodPointers, (int)CodeRegistration.methodPointersCount);
            FieldOffsetData      = image.ReadMappedArray <int>(MetadataRegistration.pfieldOffsets, MetadataRegistration.fieldOffsetsCount);
            var types = image.ReadMappedArray <uint>(MetadataRegistration.ptypes, MetadataRegistration.typesCount);

            for (int i = 0; i < MetadataRegistration.typesCount; i++)
            {
                Types.Add(image.ReadMappedObject <Il2CppType>(types[i]));
            }
        }
Ejemplo n.º 2
0
        private void Configure(IFileFormatReader image, ulong codeRegistration, ulong metadataRegistration)
        {
            // Output locations
            Console.WriteLine("CodeRegistration struct found at 0x{0:X16} (file offset 0x{1:X8})", image.Bits == 32 ? codeRegistration & 0xffff_ffff : codeRegistration, image.MapVATR(codeRegistration));
            Console.WriteLine("MetadataRegistration struct found at 0x{0:X16} (file offset 0x{1:X8})", image.Bits == 32 ? metadataRegistration & 0xffff_ffff : metadataRegistration, image.MapVATR(metadataRegistration));

            // Set width of long (convert to sizeof(int) for 32-bit files)
            if (image.Bits == 32)
            {
                image.Stream.PrimitiveMappings.Add(typeof(long), typeof(int));
                image.Stream.PrimitiveMappings.Add(typeof(ulong), typeof(uint));
            }

            // Root structures from which we find everything else
            CodeRegistration     = image.ReadMappedObject <Il2CppCodeRegistration>(codeRegistration);
            MetadataRegistration = image.ReadMappedObject <Il2CppMetadataRegistration>(metadataRegistration);

            // The global method pointer list was deprecated in v24.2 in favour of Il2CppCodeGenModule
            if (Image.Version <= 24.1)
            {
                GlobalMethodPointers = image.ReadMappedArray <ulong>(CodeRegistration.pmethodPointers, (int)CodeRegistration.methodPointersCount);
            }

            // After v24 method pointers and RGCTX data were stored in Il2CppCodeGenModules
            if (Image.Version >= 24.2)
            {
                Modules = new Dictionary <string, Il2CppCodeGenModule>();

                // Array of pointers to Il2CppCodeGenModule
                var modules = image.ReadMappedObjectPointerArray <Il2CppCodeGenModule>(CodeRegistration.pcodeGenModules, (int)CodeRegistration.codeGenModulesCount);

                foreach (var module in modules)
                {
                    var name = image.ReadMappedNullTerminatedString(module.moduleName);
                    Modules.Add(name, module);

                    // Read method pointers
                    ModuleMethodPointers.Add(module, image.ReadMappedArray <ulong>(module.methodPointers, (int)module.methodPointerCount));
                }
            }

            // Field offset data. Metadata <=21.x uses a value-type array; >=21.x uses a pointer array

            // Versions from 22 onwards use an array of pointers in Binary.FieldOffsetData
            bool fieldOffsetsArePointers = (image.Version >= 22);

            // Some variants of 21 also use an array of pointers
            if (image.Version == 21)
            {
                // Always 4-byte values even for 64-bit builds when array is NOT pointers
                var fieldTest = image.ReadMappedArray <uint>(MetadataRegistration.pfieldOffsets, 6);

                // We detect this by relying on the fact Module, Object, ValueType, Attribute, _Attribute and Int32
                // are always the first six defined types, and that all but Int32 have no fields
                fieldOffsetsArePointers = (fieldTest[0] == 0 && fieldTest[1] == 0 && fieldTest[2] == 0 && fieldTest[3] == 0 && fieldTest[4] == 0 && fieldTest[5] > 0);
            }

            // All older versions use values directly in the array
            if (!fieldOffsetsArePointers)
            {
                FieldOffsets = image.ReadMappedArray <uint>(MetadataRegistration.pfieldOffsets, (int)MetadataRegistration.fieldOffsetsCount);
            }
            else
            {
                FieldOffsetPointers = image.ReadMappedWordArray(MetadataRegistration.pfieldOffsets, (int)MetadataRegistration.fieldOffsetsCount);
            }

            // Type definitions (pointer array)
            Types = image.ReadMappedObjectPointerArray <Il2CppType>(MetadataRegistration.ptypes, (int)MetadataRegistration.typesCount);

            // Custom attribute constructors
            CustomAttributeGenerators = image.ReadMappedArray <ulong>(CodeRegistration.customAttributeGenerators, (int)CodeRegistration.customAttributeCount);

            // Generic method specs
            MethodSpecs = image.ReadMappedArray <Il2CppMethodSpec>(MetadataRegistration.methodSpecs, (int)MetadataRegistration.methodSpecsCount);
        }
Ejemplo n.º 3
0
        private void Configure(IFileFormatReader image, ulong codeRegistration, ulong metadataRegistration)
        {
            // Store locations
            CodeRegistrationPointer     = codeRegistration;
            MetadataRegistrationPointer = metadataRegistration;

            Console.WriteLine("CodeRegistration struct found at 0x{0:X16} (file offset 0x{1:X8})", image.Bits == 32 ? codeRegistration & 0xffff_ffff : codeRegistration, image.MapVATR(codeRegistration));
            Console.WriteLine("MetadataRegistration struct found at 0x{0:X16} (file offset 0x{1:X8})", image.Bits == 32 ? metadataRegistration & 0xffff_ffff : metadataRegistration, image.MapVATR(metadataRegistration));

            // Set width of long (convert to sizeof(int) for 32-bit files)
            if (image.Bits == 32)
            {
                image.Stream.PrimitiveMappings.Add(typeof(long), typeof(int));
                image.Stream.PrimitiveMappings.Add(typeof(ulong), typeof(uint));
            }

            // Root structures from which we find everything else
            CodeRegistration     = image.ReadMappedObject <Il2CppCodeRegistration>(codeRegistration);
            MetadataRegistration = image.ReadMappedObject <Il2CppMetadataRegistration>(metadataRegistration);

            // The global method pointer list was deprecated in v24.2 in favour of Il2CppCodeGenModule
            if (Image.Version <= 24.1)
            {
                GlobalMethodPointers = image.ReadMappedArray <ulong>(CodeRegistration.pmethodPointers, (int)CodeRegistration.methodPointersCount);
            }

            // After v24 method pointers and RGCTX data were stored in Il2CppCodeGenModules
            if (Image.Version >= 24.2)
            {
                Modules = new Dictionary <string, Il2CppCodeGenModule>();

                // Array of pointers to Il2CppCodeGenModule
                var codeGenModulePointers = image.ReadMappedArray <ulong>(CodeRegistration.pcodeGenModules, (int)CodeRegistration.codeGenModulesCount);
                var modules = image.ReadMappedObjectPointerArray <Il2CppCodeGenModule>(CodeRegistration.pcodeGenModules, (int)CodeRegistration.codeGenModulesCount);

                foreach (var mp in modules.Zip(codeGenModulePointers, (m, p) => new { Module = m, Pointer = p }))
                {
                    var module = mp.Module;

                    var name = image.ReadMappedNullTerminatedString(module.moduleName);
                    Modules.Add(name, module);
                    CodeGenModulePointers.Add(name, mp.Pointer);

                    // Read method pointers
                    ModuleMethodPointers.Add(module, image.ReadMappedArray <ulong>(module.methodPointers, (int)module.methodPointerCount));

                    // Read method invoker pointer indices - one per method
                    MethodInvokerIndices.Add(module, image.ReadMappedArray <int>(module.invokerIndices, (int)module.methodPointerCount));
                }
            }

            // Field offset data. Metadata <=21.x uses a value-type array; >=21.x uses a pointer array

            // Versions from 22 onwards use an array of pointers in Binary.FieldOffsetData
            bool fieldOffsetsArePointers = (image.Version >= 22);

            // Some variants of 21 also use an array of pointers
            if (image.Version == 21)
            {
                // Always 4-byte values even for 64-bit builds when array is NOT pointers
                var fieldTest = image.ReadMappedArray <uint>(MetadataRegistration.pfieldOffsets, 6);

                // We detect this by relying on the fact Module, Object, ValueType, Attribute, _Attribute and Int32
                // are always the first six defined types, and that all but Int32 have no fields
                fieldOffsetsArePointers = (fieldTest[0] == 0 && fieldTest[1] == 0 && fieldTest[2] == 0 && fieldTest[3] == 0 && fieldTest[4] == 0 && fieldTest[5] > 0);
            }

            // All older versions use values directly in the array
            if (!fieldOffsetsArePointers)
            {
                FieldOffsets = image.ReadMappedArray <uint>(MetadataRegistration.pfieldOffsets, (int)MetadataRegistration.fieldOffsetsCount);
            }
            else
            {
                FieldOffsetPointers = image.ReadMappedWordArray(MetadataRegistration.pfieldOffsets, (int)MetadataRegistration.fieldOffsetsCount);
            }

            // Type references (pointer array)
            var typeRefPointers = image.ReadMappedArray <ulong>(MetadataRegistration.ptypes, (int)MetadataRegistration.typesCount);

            TypeReferenceIndicesByAddress = typeRefPointers.Zip(Enumerable.Range(0, typeRefPointers.Length), (a, i) => new { a, i }).ToDictionary(x => x.a, x => x.i);
            TypeReferences = image.ReadMappedObjectPointerArray <Il2CppType>(MetadataRegistration.ptypes, (int)MetadataRegistration.typesCount);

            // Custom attribute constructors (function pointers)
            CustomAttributeGenerators = image.ReadMappedArray <ulong>(CodeRegistration.customAttributeGenerators, (int)CodeRegistration.customAttributeCount);

            // Method.Invoke function pointers
            MethodInvokePointers = image.ReadMappedArray <ulong>(CodeRegistration.invokerPointers, (int)CodeRegistration.invokerPointersCount);

            // TODO: Function pointers as shown below
            // reversePInvokeWrappers
            // <=22: delegateWrappersFromManagedToNative, marshalingFunctions;
            // >=21 <=22: ccwMarhsalingFunctions
            // >=22: unresolvedVirtualCallPointers
            // >=23: interopData

            // Generic type and method specs (open and closed constructed types)
            MethodSpecs = image.ReadMappedArray <Il2CppMethodSpec>(MetadataRegistration.methodSpecs, (int)MetadataRegistration.methodSpecsCount);

            // Concrete generic class and method signatures
            GenericInstances = image.ReadMappedObjectPointerArray <Il2CppGenericInst>(MetadataRegistration.genericInsts, (int)MetadataRegistration.genericInstsCount);

            // Concrete generic method pointers
            var genericMethodPointers = image.ReadMappedArray <ulong>(CodeRegistration.genericMethodPointers, (int)CodeRegistration.genericMethodPointersCount);
            var genericMethodTable    = image.ReadMappedArray <Il2CppGenericMethodFunctionsDefinitions>(MetadataRegistration.genericMethodTable, (int)MetadataRegistration.genericMethodTableCount);

            foreach (var tableEntry in genericMethodTable)
            {
                GenericMethodPointers.Add(MethodSpecs[tableEntry.genericMethodIndex], genericMethodPointers[tableEntry.indices.methodIndex]);
                GenericMethodInvokerIndices.Add(MethodSpecs[tableEntry.genericMethodIndex], tableEntry.indices.invokerIndex);
            }
        }