Beispiel #1
0
        public Metadata(Stream stream) : base(stream)
        {
            pMetadataHdr = ReadObject <Il2CppGlobalMetadataHeader>();
            if (pMetadataHdr.sanity != 0xFAB11BAF)
            {
                throw new Exception("ERROR: Metadata file supplied is not valid metadata file.");
            }
            if (pMetadataHdr.version != 21 && pMetadataHdr.version != 22)
            {
                throw new Exception($"ERROR: Metadata file supplied is not a supported version[{pMetadataHdr.version}].");
            }
            var uiImageCount = pMetadataHdr.imagesCount / MySizeOf(typeof(Il2CppImageDefinition));
            var uiNumTypes   = pMetadataHdr.typeDefinitionsCount / MySizeOf(typeof(Il2CppTypeDefinition));

            Images = ReadArray <Il2CppImageDefinition>(pMetadataHdr.imagesOffset, uiImageCount);
            //GetTypeDefFromIndex
            Types = ReadArray <Il2CppTypeDefinition>(pMetadataHdr.typeDefinitionsOffset, uiNumTypes);
            //GetMethodDefinition
            Methods = ReadArray <Il2CppMethodDefinition>(pMetadataHdr.methodsOffset, pMetadataHdr.methodsCount / MySizeOf(typeof(Il2CppMethodDefinition)));
            //GetParameterFromIndex
            parameterDefs = ReadArray <Il2CppParameterDefinition>(pMetadataHdr.parametersOffset, pMetadataHdr.parametersCount / MySizeOf(typeof(Il2CppParameterDefinition)));
            //GetFieldDefFromIndex
            Fields = ReadArray <Il2CppFieldDefinition>(pMetadataHdr.fieldsOffset, pMetadataHdr.fieldsCount / MySizeOf(typeof(Il2CppFieldDefinition)));
            //GetFieldDefaultFromIndex
            fieldDefaultValues = ReadArray <Il2CppFieldDefaultValue>(pMetadataHdr.fieldDefaultValuesOffset, pMetadataHdr.fieldDefaultValuesCount / MySizeOf(typeof(Il2CppFieldDefaultValue)));
        }
Beispiel #2
0
        public Metadata(Stream stream) : base(stream)
        {
            // Read magic bytes
            if (ReadUInt32() != 0xFAB11BAF)
            {
                throw new Exception("ERROR: Metadata file supplied is not valid metadata file.");
            }

            // Set object versioning for Bin2Object from metadata version
            Version = ReadInt32();

            // Rewind and read metadata header in full
            Position    -= 8;
            pMetadataHdr = ReadObject <Il2CppGlobalMetadataHeader>();
            if (Version != 21 && Version != 22 && Version != 23)
            {
                throw new Exception($"ERROR: Metadata file supplied is not a supported version ({pMetadataHdr.version}).");
            }

            var uiImageCount = pMetadataHdr.imagesCount / Sizeof(typeof(Il2CppImageDefinition));
            var uiNumTypes   = pMetadataHdr.typeDefinitionsCount / Sizeof(typeof(Il2CppTypeDefinition));

            Images = ReadArray <Il2CppImageDefinition>(pMetadataHdr.imagesOffset, uiImageCount);
            //GetTypeDefFromIndex
            Types = ReadArray <Il2CppTypeDefinition>(pMetadataHdr.typeDefinitionsOffset, uiNumTypes);
            //GetMethodDefinition
            Methods = ReadArray <Il2CppMethodDefinition>(pMetadataHdr.methodsOffset, pMetadataHdr.methodsCount / Sizeof(typeof(Il2CppMethodDefinition)));
            //GetParameterFromIndex
            parameterDefs = ReadArray <Il2CppParameterDefinition>(pMetadataHdr.parametersOffset, pMetadataHdr.parametersCount / Sizeof(typeof(Il2CppParameterDefinition)));
            //GetFieldDefFromIndex
            Fields = ReadArray <Il2CppFieldDefinition>(pMetadataHdr.fieldsOffset, pMetadataHdr.fieldsCount / Sizeof(typeof(Il2CppFieldDefinition)));
            //GetFieldDefaultFromIndex
            fieldDefaultValues = ReadArray <Il2CppFieldDefaultValue>(pMetadataHdr.fieldDefaultValuesOffset, pMetadataHdr.fieldDefaultValuesCount / Sizeof(typeof(Il2CppFieldDefaultValue)));
        }
Beispiel #3
0
        public Metadata(Stream stream) : base(stream)
        {
            pMetadataHdr = ReadObject <Il2CppGlobalMetadataHeader>();
            if (pMetadataHdr.sanity != 0xFAB11BAF)
            {
                throw new Exception("ERROR: Metadata file supplied is not valid metadata file.");
            }
            if (pMetadataHdr.version != 21 && pMetadataHdr.version != 22)
            {
                throw new Exception($"ERROR: Metadata file supplied is not a supported version[{pMetadataHdr.version}].");
            }

            // Strings literals
            var uiStringLiteralCount = pMetadataHdr.stringLiteralCount / MySizeOf(typeof(Il2CppStringLiteral));
            var stringDefs           = ReadArray <Il2CppStringLiteral>(pMetadataHdr.stringLiteralOffset, uiStringLiteralCount);

            Strings = new string[stringDefs.Length];
            for (var idx = 0; idx < stringDefs.Length; idx++)
            {
                var raw = ReadArray <byte>(pMetadataHdr.stringLiteralDataOffset + stringDefs[idx].dataIndex, (int)stringDefs[idx].length);
                Strings[idx] = System.Text.Encoding.UTF8.GetString(raw);
            }

            // Images (.dll)
            var uiImageCount = pMetadataHdr.imagesCount / MySizeOf(typeof(Il2CppImageDefinition));

            Images = ReadArray <Il2CppImageDefinition>(pMetadataHdr.imagesOffset, uiImageCount);

            // Interfaces
            Interfaces = new Dictionary <int, Il2CppTypeDefinition>();
            //var uiInterfacePairCount = pMetadataHdr.interfaceOffsetsCount / MySizeOf(typeof(Il2CppInterfaceOffsetPair));
            //var interfacePairs = ReadArray<Il2CppInterfaceOffsetPair>(pMetadataHdr.interfaceOffsetsOffset, uiInterfacePairCount);
            //var uiInterfaceCount = pMetadataHdr.interfacesCount / MySizeOf(typeof(Il2CppTypeDefinition));
            //var interfaceDefs = ReadArray<Il2CppTypeDefinition>(pMetadataHdr.interfacesOffset, uiInterfaceCount);
            //for (var i = 0; i < interfacePairs.Count(); i++)
            //{
            //    Interfaces[i] = interfaceDefs[interfacePairs[i].interfaceTypeIndex];
            //}

            // EncodedMethods
            //EncodedMethods = ReadArray<uint>(pMetadataHdr.vtableMethodsOffset, pMetadataHdr.vtableMethodsCount);

            // GetTypeDefFromIndex
            var uiNumTypes = pMetadataHdr.typeDefinitionsCount / MySizeOf(typeof(Il2CppTypeDefinition));

            Types = ReadArray <Il2CppTypeDefinition>(pMetadataHdr.typeDefinitionsOffset, uiNumTypes);

            // GetMethodDefinition
            Methods = ReadArray <Il2CppMethodDefinition>(pMetadataHdr.methodsOffset, pMetadataHdr.methodsCount / MySizeOf(typeof(Il2CppMethodDefinition)));

            // GetParameterFromIndex
            parameterDefs = ReadArray <Il2CppParameterDefinition>(pMetadataHdr.parametersOffset, pMetadataHdr.parametersCount / MySizeOf(typeof(Il2CppParameterDefinition)));

            // GetFieldDefFromIndex
            Fields = ReadArray <Il2CppFieldDefinition>(pMetadataHdr.fieldsOffset, pMetadataHdr.fieldsCount / MySizeOf(typeof(Il2CppFieldDefinition)));

            // GetFieldDefaultFromIndex
            fieldDefaultValues = ReadArray <Il2CppFieldDefaultValue>(pMetadataHdr.fieldDefaultValuesOffset, pMetadataHdr.fieldDefaultValuesCount / MySizeOf(typeof(Il2CppFieldDefaultValue)));
        }
Beispiel #4
0
        public Metadata(Stream stream) : base(stream)
        {
            // Read magic bytes
            if (ReadUInt32() != 0xFAB11BAF)
            {
                throw new Exception("ERROR: Metadata file supplied is not valid metadata file.");
            }

            // Set object versioning for Bin2Object from metadata version
            Version = ReadInt32();

            // Rewind and read metadata header in full
            Position -= 8;
            Header    = ReadObject <Il2CppGlobalMetadataHeader>();
            if (Version < 21 || Version > 24)
            {
                throw new Exception($"ERROR: Metadata file supplied is not a supported version ({Header.version}).");
            }

            // Load all the relevant metadata using offsets provided in the header
            Images                = ReadArray <Il2CppImageDefinition>(Header.imagesOffset, Header.imagesCount / Sizeof(typeof(Il2CppImageDefinition)));
            Types                 = ReadArray <Il2CppTypeDefinition>(Header.typeDefinitionsOffset, Header.typeDefinitionsCount / Sizeof(typeof(Il2CppTypeDefinition)));
            Methods               = ReadArray <Il2CppMethodDefinition>(Header.methodsOffset, Header.methodsCount / Sizeof(typeof(Il2CppMethodDefinition)));
            Params                = ReadArray <Il2CppParameterDefinition>(Header.parametersOffset, Header.parametersCount / Sizeof(typeof(Il2CppParameterDefinition)));
            Fields                = ReadArray <Il2CppFieldDefinition>(Header.fieldsOffset, Header.fieldsCount / Sizeof(typeof(Il2CppFieldDefinition)));
            FieldDefaultValues    = ReadArray <Il2CppFieldDefaultValue>(Header.fieldDefaultValuesOffset, Header.fieldDefaultValuesCount / Sizeof(typeof(Il2CppFieldDefaultValue)));
            Properties            = ReadArray <Il2CppPropertyDefinition>(Header.propertiesOffset, Header.propertiesOffset / Sizeof(typeof(Il2CppPropertyDefinition)));
            Events                = ReadArray <Il2CppEventDefinition>(Header.eventsOffset, Header.eventsOffset / Sizeof(typeof(Il2CppEventDefinition)));
            InterfaceUsageIndices = ReadArray <int>(Header.interfacesOffset, Header.interfacesCount / sizeof(int));
            // TODO: ParameterDefaultValue, GenericParameters, ParameterConstraints, GenericContainers, MetadataUsage, CustomAttributes

            // Get all string literals
            Position = Header.stringOffset;
            while (Position < Header.stringOffset + Header.stringCount)
            {
                Strings.Add((int)Position - Header.stringOffset, ReadNullTerminatedString());
            }
        }
Beispiel #5
0
        public Metadata(Stream stream) : base(stream)
        {
            // Read magic bytes
            if (ReadUInt32() != 0xFAB11BAF)
            {
                throw new InvalidOperationException("The supplied metadata file is not valid.");
            }

            // Set object versioning for Bin2Object from metadata version
            Version = ReadInt32();

            // Rewind and read metadata header in full
            Header = ReadObject <Il2CppGlobalMetadataHeader>(0);
            if (Version < 16 || Version > 24)
            {
                throw new InvalidOperationException($"The supplied metadata file is not of a supported version ({Header.version}).");
            }

            // Sanity checking
            // Unity.IL2CPP.MetadataCacheWriter.WriteLibIl2CppMetadata always writes the metadata information in the same order it appears in the header,
            // with each block always coming directly after the previous block, 4-byte aligned. We can use this to check the integrity of the data and
            // detect sub-versions.

            // For metadata v24, the header can either be either 0x110 (24.0, 24.1) or 0x108 (24.2) bytes long. Since 'stringLiteralOffset' is the first thing
            // in the header after the sanity and version fields, and since it will always point directly to the first byte after the end of the header,
            // we can use this value to determine the actual header length and therefore narrow down the metadata version to 24.0/24.1 or 24.2.

            var realHeaderLength = Header.stringLiteralOffset;

            if (realHeaderLength != Sizeof(typeof(Il2CppGlobalMetadataHeader)))
            {
                if (Version == 24.0)
                {
                    Version = 24.2;
                    Header  = ReadObject <Il2CppGlobalMetadataHeader>(0);
                }
            }

            if (realHeaderLength != Sizeof(typeof(Il2CppGlobalMetadataHeader)))
            {
                throw new InvalidOperationException("Could not verify the integrity of the metadata file or accurately identify the metadata sub-version");
            }

            // Load all the relevant metadata using offsets provided in the header
            if (Version >= 16)
            {
                Images = ReadArray <Il2CppImageDefinition>(Header.imagesOffset, Header.imagesCount / Sizeof(typeof(Il2CppImageDefinition)));
            }

            // As an additional sanity check, all images in the metadata should have Mono.Cecil.MetadataToken == 1
            // In metadata v24.1, two extra fields were added which will cause the below test to fail.
            // In that case, we can then adjust the version number and reload
            // Tokens were introduced in v19 - we don't bother testing earlier versions
            if (Version >= 19 && Images.Any(x => x.token != 1))
            {
                if (Version == 24.0)
                {
                    Version = 24.1;

                    // No need to re-read the header, it's the same for both sub-versions
                    Images = ReadArray <Il2CppImageDefinition>(Header.imagesOffset, Header.imagesCount / Sizeof(typeof(Il2CppImageDefinition)));

                    if (Images.Any(x => x.token != 1))
                    {
                        throw new InvalidOperationException("Could not verify the integrity of the metadata file image list");
                    }
                }
            }

            Types                    = ReadArray <Il2CppTypeDefinition>(Header.typeDefinitionsOffset, Header.typeDefinitionsCount / Sizeof(typeof(Il2CppTypeDefinition)));
            Methods                  = ReadArray <Il2CppMethodDefinition>(Header.methodsOffset, Header.methodsCount / Sizeof(typeof(Il2CppMethodDefinition)));
            Params                   = ReadArray <Il2CppParameterDefinition>(Header.parametersOffset, Header.parametersCount / Sizeof(typeof(Il2CppParameterDefinition)));
            Fields                   = ReadArray <Il2CppFieldDefinition>(Header.fieldsOffset, Header.fieldsCount / Sizeof(typeof(Il2CppFieldDefinition)));
            FieldDefaultValues       = ReadArray <Il2CppFieldDefaultValue>(Header.fieldDefaultValuesOffset, Header.fieldDefaultValuesCount / Sizeof(typeof(Il2CppFieldDefaultValue)));
            Properties               = ReadArray <Il2CppPropertyDefinition>(Header.propertiesOffset, Header.propertiesCount / Sizeof(typeof(Il2CppPropertyDefinition)));
            Events                   = ReadArray <Il2CppEventDefinition>(Header.eventsOffset, Header.eventsCount / Sizeof(typeof(Il2CppEventDefinition)));
            InterfaceUsageIndices    = ReadArray <int>(Header.interfacesOffset, Header.interfacesCount / sizeof(int));
            NestedTypeIndices        = ReadArray <int>(Header.nestedTypesOffset, Header.nestedTypesCount / sizeof(int));
            GenericContainers        = ReadArray <Il2CppGenericContainer>(Header.genericContainersOffset, Header.genericContainersCount / Sizeof(typeof(Il2CppGenericContainer)));
            GenericParameters        = ReadArray <Il2CppGenericParameter>(Header.genericParametersOffset, Header.genericParametersCount / Sizeof(typeof(Il2CppGenericParameter)));
            GenericConstraintIndices = ReadArray <int>(Header.genericParameterConstraintsOffset, Header.genericParameterConstraintsCount / sizeof(int));
            InterfaceOffsets         = ReadArray <Il2CppInterfaceOffsetPair>(Header.interfaceOffsetsOffset, Header.interfaceOffsetsCount / Sizeof(typeof(Il2CppInterfaceOffsetPair)));
            VTableMethodIndices      = ReadArray <uint>(Header.vtableMethodsOffset, Header.vtableMethodsCount / sizeof(uint));

            if (Version >= 16)
            {
                Assemblies             = ReadArray <Il2CppAssemblyDefinition>(Header.assembliesOffset, Header.assembliesCount / Sizeof(typeof(Il2CppAssemblyDefinition)));
                ParameterDefaultValues = ReadArray <Il2CppParameterDefaultValue>(Header.parameterDefaultValuesOffset, Header.parameterDefaultValuesCount / Sizeof(typeof(Il2CppParameterDefaultValue)));
            }
            if (Version >= 19)
            {
                MetadataUsageLists = ReadArray <Il2CppMetadataUsageList>(Header.metadataUsageListsOffset, Header.metadataUsageListsCount / Sizeof(typeof(Il2CppMetadataUsageList)));
                MetadataUsagePairs = ReadArray <Il2CppMetadataUsagePair>(Header.metadataUsagePairsOffset, Header.metadataUsagePairsCount / Sizeof(typeof(Il2CppMetadataUsagePair)));
                FieldRefs          = ReadArray <Il2CppFieldRef>(Header.fieldRefsOffset, Header.fieldRefsCount / Sizeof(typeof(Il2CppFieldRef)));
            }
            if (Version >= 21)
            {
                AttributeTypeIndices = ReadArray <int>(Header.attributeTypesOffset, Header.attributeTypesCount / sizeof(int));
                AttributeTypeRanges  = ReadArray <Il2CppCustomAttributeTypeRange>(Header.attributesInfoOffset, Header.attributesInfoCount / Sizeof(typeof(Il2CppCustomAttributeTypeRange)));
            }

            // Get all metadata string literals
            Position = Header.stringOffset;
            while (Position < Header.stringOffset + Header.stringCount)
            {
                Strings.Add((int)Position - Header.stringOffset, ReadNullTerminatedString());
            }

            // Get all managed code string literals
            var stringLiteralList = ReadArray <Il2CppStringLiteral>(Header.stringLiteralOffset, Header.stringLiteralCount / Sizeof(typeof(Il2CppStringLiteral)));

            StringLiterals = new string[stringLiteralList.Length];
            for (var i = 0; i < stringLiteralList.Length; i++)
            {
                StringLiterals[i] = ReadFixedLengthString(Header.stringLiteralDataOffset + stringLiteralList[i].dataIndex, stringLiteralList[i].length);
            }
        }