diff --git a/Il2CppInspector/IL2CPP/Il2CppBinary.cs b/Il2CppInspector/IL2CPP/Il2CppBinary.cs index 9c44237..1f4666a 100644 --- a/Il2CppInspector/IL2CPP/Il2CppBinary.cs +++ b/Il2CppInspector/IL2CPP/Il2CppBinary.cs @@ -197,10 +197,6 @@ namespace Il2CppInspector // Generic method specs MethodSpecs = image.ReadMappedArray(MetadataRegistration.methodSpecs, (int) MetadataRegistration.methodSpecsCount); - - // Metadata usages (addresses) - if (image.Version >= 19) - MetadataUsages = image.ReadMappedArray(MetadataRegistration.metadataUsages, (int)MetadataRegistration.metadataUsagesCount); } } } diff --git a/Il2CppInspector/IL2CPP/Il2CppInspector.cs b/Il2CppInspector/IL2CPP/Il2CppInspector.cs index 3f6235e..1276c90 100644 --- a/Il2CppInspector/IL2CPP/Il2CppInspector.cs +++ b/Il2CppInspector/IL2CPP/Il2CppInspector.cs @@ -25,6 +25,10 @@ namespace Il2CppInspector // Attribute indexes (>=24.1) arranged by customAttributeStart and token public Dictionary> AttributeIndicesByToken { get; } + // Merged list of all metadata usage references + public List MetadataUsages { get; } + public ulong[] BinaryMetadataUsages { get; } // TODO: Make private + // Shortcuts public double Version => Metadata.Version; @@ -43,7 +47,6 @@ namespace Il2CppInspector public int[] GenericConstraintIndices => Metadata.GenericConstraintIndices; public Il2CppCustomAttributeTypeRange[] AttributeTypeRanges => Metadata.AttributeTypeRanges; public Il2CppInterfaceOffsetPair[] InterfaceOffsets => Metadata.InterfaceOffsets; - public List MetadataUsages => Metadata.MetadataUsages; public int[] InterfaceUsageIndices => Metadata.InterfaceUsageIndices; public int[] NestedTypeIndices => Metadata.NestedTypeIndices; public int[] AttributeTypeIndices => Metadata.AttributeTypeIndices; @@ -55,7 +58,6 @@ namespace Il2CppInspector public Dictionary Modules => Binary.Modules; public ulong[] CustomAttributeGenerators => Binary.CustomAttributeGenerators; public Il2CppMethodSpec[] MethodSpecs => Binary.MethodSpecs; - public ulong[] BinaryMetadataUsages => Binary.MetadataUsages; // TODO: Finish all file access in the constructor and eliminate the need for this public IFileFormatReader BinaryImage => Binary.Image; @@ -119,6 +121,27 @@ namespace Il2CppInspector return ((ulong) pValue, value); } + private List buildMetadataUsages() + { + var usages = new Dictionary(); + foreach (var metadataUsageList in Metadata.MetadataUsageLists) + { + for (var i = 0; i < metadataUsageList.count; i++) + { + var metadataUsagePair = Metadata.MetadataUsagePairs[metadataUsageList.start + i]; + + var encodedType = metadataUsagePair.encodedSourceIndex & 0xE0000000; + var usageType = (MetadataUsageType)(encodedType >> 29); + + var sourceIndex = metadataUsagePair.encodedSourceIndex & 0x1FFFFFFF; + var destinationIndex = metadataUsagePair.destinationindex; + + usages.TryAdd(destinationIndex, new MetadataUsage(usageType, (int)sourceIndex, (int)destinationIndex)); + } + } + return usages.Values.ToList(); + } + public Il2CppInspector(Il2CppBinary binary, Metadata metadata) { // Store stream representations Binary = binary; @@ -191,6 +214,16 @@ namespace Il2CppInspector AttributeIndicesByToken.Add(image.customAttributeStart, attsByToken); } } + + // Merge all metadata usage references into a single distinct list + if (Version >= 19) { + MetadataUsages = buildMetadataUsages(); + + // Metadata usages (addresses) + // Unfortunately the value supplied in MetadataRegistration.matadataUsagesCount seems to be incorrect, + // so we have to calculate the correct number of usages above before reading the usage address list from the binary + BinaryMetadataUsages = Binary.Image.ReadMappedArray(Binary.MetadataRegistration.metadataUsages, MetadataUsages.Count); + } } public (ulong Start, ulong End)? GetMethodPointer(Il2CppCodeGenModule module, Il2CppMethodDefinition methodDef) { diff --git a/Il2CppInspector/IL2CPP/Metadata.cs b/Il2CppInspector/IL2CPP/Metadata.cs index da598c7..55397ef 100644 --- a/Il2CppInspector/IL2CPP/Metadata.cs +++ b/Il2CppInspector/IL2CPP/Metadata.cs @@ -127,7 +127,6 @@ namespace Il2CppInspector if (Version >= 19) { MetadataUsageLists = ReadArray(Header.metadataUsageListsOffset, Header.metadataUsageListsCount / Sizeof(typeof(Il2CppMetadataUsageList))); MetadataUsagePairs = ReadArray(Header.metadataUsagePairsOffset, Header.metadataUsagePairsCount / Sizeof(typeof(Il2CppMetadataUsagePair))); - MetadataUsages = buildMetadataUsages(); } if (Version >= 21) { AttributeTypeIndices = ReadArray(Header.attributeTypesOffset, Header.attributeTypesCount / sizeof(int)); @@ -147,28 +146,6 @@ namespace Il2CppInspector StringLiterals[i] = ReadFixedLengthString(Header.stringLiteralDataOffset + stringLiteralList[i].dataIndex, stringLiteralList[i].length); } - private List buildMetadataUsages() - { - var usages = new Dictionary(); - foreach (var metadataUsageList in MetadataUsageLists) - { - for (var i = 0; i < metadataUsageList.count; i++) - { - var metadataUsagePair = MetadataUsagePairs[metadataUsageList.start + i]; - - var encodedType = metadataUsagePair.encodedSourceIndex & 0xE0000000; - var usageType = (MetadataUsageType)(encodedType >> 29); - - var sourceIndex = metadataUsagePair.encodedSourceIndex & 0x1FFFFFFF; - var destinationIndex = metadataUsagePair.destinationindex; - - usages.TryAdd(destinationIndex, new MetadataUsage(usageType, (int)sourceIndex, (int)destinationIndex)); - } - } - - return usages.Values.ToList(); - } - private int Sizeof(Type type) { int size = 0;