Skip to content

Commit 77b4b60

Browse files
committed
add untested support for metadata version v104
1 parent 9d6b0c0 commit 77b4b60

16 files changed

+269
-12
lines changed

Il2CppInspector.Common/IL2CPP/CustomAttributeDataReader.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ public IEnumerable<CustomAttributeCtor> Read()
5252
ctors[i] = new CustomAttributeCtor();
5353

5454
var ctorIndex = _data.ReadUInt32();
55-
ctors[i].Ctor = _assembly.Model.MethodsByDefinitionIndex[ctorIndex];
55+
ctors[i].Ctor = _assembly.Model.Package.Version >= MetadataVersions.V1040
56+
? _assembly.Model.GetMetadataUsageMethod(MetadataUsage.FromEncodedIndex(_assembly.Model.Package, ctorIndex))
57+
: _assembly.Model.MethodsByDefinitionIndex[ctorIndex];
5658
}
5759

5860
_data.Position = _dataBufferStart;
@@ -158,7 +160,9 @@ private TypeInfo ConvertTypeDef(Il2CppTypeDefinition typeDef, Il2CppTypeEnum typ
158160
memberIndex = -(memberIndex + 1);
159161

160162
var typeDefIndex = _data.ReadCompressedUInt32();
161-
var typeInfo = _assembly.Model.TypesByDefinitionIndex[typeDefIndex];
163+
var typeInfo = _assembly.Model.Package.Version >= MetadataVersions.V1040
164+
? _assembly.Model.TypesByReferenceIndex[typeDefIndex]
165+
: _assembly.Model.TypesByDefinitionIndex[typeDefIndex];
162166

163167
return (typeInfo, memberIndex);
164168
}

Il2CppInspector.Common/IL2CPP/Il2CppInspector.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public class Il2CppInspector
7575
public Dictionary<Il2CppMethodSpec, ulong> GenericMethodPointers { get; }
7676
public Dictionary<Il2CppMethodSpec, int> GenericMethodInvokerIndices => Binary.GenericMethodInvokerIndices;
7777
public ImmutableArray<Il2CppTypeDefinitionSizes> TypeDefinitionSizes => Binary.TypeDefinitionSizes;
78+
public Dictionary<TypeIndex, int> TypeInlineArrays { get; } = new();
7879

7980
// TODO: Finish all file access in the constructor and eliminate the need for this
8081
public IFileFormatStream BinaryImage => Binary.Image;
@@ -287,6 +288,11 @@ public Il2CppInspector(Il2CppBinary binary, Metadata metadata) {
287288
}
288289
}
289290

291+
if (Version >= MetadataVersions.V1040)
292+
{
293+
TypeInlineArrays = Metadata.TypeInlineArrays.ToDictionary(x => x.TypeIndex, x => x.Length);
294+
}
295+
290296
// Merge all metadata usage references into a single distinct list
291297
MetadataUsages = buildMetadataUsages();
292298

Il2CppInspector.Common/IL2CPP/Metadata.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public class Metadata : BinaryObjectStreamReader
4343
public ImmutableArray<uint> VTableMethodIndices { get; set; }
4444
public string[] StringLiterals { get; set; }
4545

46+
public ImmutableArray<Il2CppInlineArrayLength> TypeInlineArrays { get; set; }
47+
4648
public int FieldAndParameterDefaultValueDataOffset => Version >= MetadataVersions.V380
4749
? Header.FieldAndParameterDefaultValueData.Offset
4850
: Header.FieldAndParameterDefaultValueDataOffset;
@@ -95,7 +97,7 @@ private void Initialize()
9597
// Set object versioning for Bin2Object from metadata version
9698
Version = new StructVersion(Header.Version);
9799

98-
if (Version < MetadataVersions.V160 || Version > MetadataVersions.V390) {
100+
if (Version < MetadataVersions.V160 || Version > MetadataVersions.V1040) {
99101
throw new InvalidOperationException($"The supplied metadata file is not of a supported version ({Header.Version}).");
100102
}
101103

@@ -149,6 +151,18 @@ static int GetIndexSize(int elementCount)
149151
fullTag += $"_{ParameterIndex.TagPrefix}{parameterIndexSize}";
150152
}
151153

154+
if (Version >= MetadataVersions.V1040)
155+
{
156+
var eventIndexSize = GetIndexSize(Header.Events.Count);
157+
var interfacesIndexSize = GetIndexSize(Header.InterfaceOffsets.Count);
158+
var nestedTypeIndexSize = GetIndexSize(Header.NestedTypes.Count);
159+
var propertyIndexSize = GetIndexSize(Header.Properties.Count);
160+
fullTag += $"_{EventIndex.TagPrefix}{eventIndexSize}"
161+
+ $"_{InterfacesIndex.TagPrefix}{interfacesIndexSize}"
162+
+ $"_{NestedTypeIndex.TagPrefix}{nestedTypeIndexSize}"
163+
+ $"_{PropertyIndex.TagPrefix}{propertyIndexSize}";
164+
}
165+
152166
Version = new StructVersion(Version.Major, Version.Minor, fullTag);
153167
}
154168

@@ -259,6 +273,11 @@ static int GetIndexSize(int elementCount)
259273
Header.AttributeDataRangeSize, Header.AttributeDataRanges);
260274
}
261275

276+
if (Version >= MetadataVersions.V1040)
277+
{
278+
TypeInlineArrays = ReadMetadataArray<Il2CppInlineArrayLength>(0, 0, Header.TypeInlineArrays);
279+
}
280+
262281
// Get all metadata strings
263282
var pluginGetStringsResult = PluginHooks.GetStrings(this);
264283
if (pluginGetStringsResult.IsDataModified && !pluginGetStringsResult.IsInvalid)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using VersionedSerialization;
2+
3+
namespace Il2CppInspector.Next.Metadata;
4+
5+
public struct EventIndex(int value) : IIndexType<EventIndex>, IReadable, IEquatable<EventIndex>
6+
{
7+
public const string TagPrefix = nameof(EventIndex);
8+
9+
static string IIndexType<EventIndex>.TagPrefix => TagPrefix;
10+
static StructVersion IIndexType<EventIndex>.AddedVersion => MetadataVersions.V390;
11+
12+
private int _value = value;
13+
14+
public static int Size(in StructVersion version = default, bool is32Bit = false)
15+
=> IIndexType<EventIndex>.IndexSize(version, is32Bit);
16+
17+
public void Read<TReader>(ref TReader reader, in StructVersion version = default) where TReader : IReader, allows ref struct
18+
{
19+
_value = IIndexType<EventIndex>.ReadIndex(ref reader, in version);
20+
}
21+
22+
#region Operators + ToString
23+
24+
public static implicit operator int(EventIndex idx) => idx._value;
25+
public static implicit operator EventIndex(int idx) => new(idx);
26+
27+
public static bool operator ==(EventIndex left, EventIndex right)
28+
=> left._value == right._value;
29+
30+
public static bool operator !=(EventIndex left, EventIndex right)
31+
=> !(left == right);
32+
33+
public readonly override bool Equals(object obj)
34+
=> obj is EventIndex other && Equals(other);
35+
36+
public readonly bool Equals(EventIndex other)
37+
=> this == other;
38+
39+
public readonly override int GetHashCode()
40+
=> HashCode.Combine(_value);
41+
42+
public readonly override string ToString() => _value.ToString();
43+
44+
#endregion
45+
}

Il2CppInspector.Common/Next/Metadata/Il2CppGlobalMetadataHeader.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,9 @@ public partial record struct Il2CppGlobalMetadataHeader
310310
[VersionCondition(GreaterThan = "38.0")]
311311
public Il2CppSectionMetadata TypeDefinitions { get; private set; }
312312

313+
[VersionCondition(GreaterThan = "104.0")]
314+
public Il2CppSectionMetadata TypeInlineArrays { get; private set; }
315+
313316
[VersionCondition(GreaterThan = "38.0")]
314317
public Il2CppSectionMetadata Images { get; private set; }
315318

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using VersionedSerialization.Attributes;
2+
3+
namespace Il2CppInspector.Next.Metadata;
4+
5+
[VersionedStruct]
6+
public partial record struct Il2CppInlineArrayLength
7+
{
8+
public TypeIndex TypeIndex { get; private set; }
9+
public int Length { get; private set; }
10+
}

Il2CppInspector.Common/Next/Metadata/Il2CppTypeDefinition.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ namespace Il2CppInspector.Next.Metadata;
77
using StringIndex = int;
88
using FieldIndex = int;
99
using MethodIndex = int;
10-
using EventIndex = int;
11-
using PropertyIndex = int;
12-
using NestedTypeIndex = int;
13-
using InterfacesIndex = int;
1410
using VTableIndex = int;
1511

1612
[VersionedStruct]

Il2CppInspector.Common/Next/Metadata/Il2CppTypeDefinitionBitfield.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ public partial record struct Il2CppTypeDefinitionBitfield
1818
public bool DefaultClassSize => ((_value >> 11) & 1) == 1;
1919
public PackingSize ClassSize => (PackingSize)((_value >> 12) & 0b1111);
2020
public bool IsByRefLike => ((_value >> 13) & 1) == 1;
21+
public bool HasInlineArray => ((_value >> 14) & 1) == 1;
2122
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using VersionedSerialization;
2+
3+
namespace Il2CppInspector.Next.Metadata;
4+
5+
public struct InterfacesIndex(int value) : IIndexType<InterfacesIndex>, IReadable, IEquatable<InterfacesIndex>
6+
{
7+
public const string TagPrefix = nameof(InterfacesIndex);
8+
9+
static string IIndexType<InterfacesIndex>.TagPrefix => TagPrefix;
10+
static StructVersion IIndexType<InterfacesIndex>.AddedVersion => MetadataVersions.V390;
11+
12+
private int _value = value;
13+
14+
public static int Size(in StructVersion version = default, bool is32Bit = false)
15+
=> IIndexType<InterfacesIndex>.IndexSize(version, is32Bit);
16+
17+
public void Read<TReader>(ref TReader reader, in StructVersion version = default) where TReader : IReader, allows ref struct
18+
{
19+
_value = IIndexType<InterfacesIndex>.ReadIndex(ref reader, in version);
20+
}
21+
22+
#region Operators + ToString
23+
24+
public static implicit operator int(InterfacesIndex idx) => idx._value;
25+
public static implicit operator InterfacesIndex(int idx) => new(idx);
26+
27+
public static bool operator ==(InterfacesIndex left, InterfacesIndex right)
28+
=> left._value == right._value;
29+
30+
public static bool operator !=(InterfacesIndex left, InterfacesIndex right)
31+
=> !(left == right);
32+
33+
public readonly override bool Equals(object obj)
34+
=> obj is InterfacesIndex other && Equals(other);
35+
36+
public readonly bool Equals(InterfacesIndex other)
37+
=> this == other;
38+
39+
public readonly override int GetHashCode()
40+
=> HashCode.Combine(_value);
41+
42+
public readonly override string ToString() => _value.ToString();
43+
44+
#endregion
45+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using VersionedSerialization;
2+
3+
namespace Il2CppInspector.Next.Metadata;
4+
5+
public struct NestedTypeIndex(int value) : IIndexType<NestedTypeIndex>, IReadable, IEquatable<NestedTypeIndex>
6+
{
7+
public const string TagPrefix = nameof(NestedTypeIndex);
8+
9+
static string IIndexType<NestedTypeIndex>.TagPrefix => TagPrefix;
10+
static StructVersion IIndexType<NestedTypeIndex>.AddedVersion => MetadataVersions.V390;
11+
12+
private int _value = value;
13+
14+
public static int Size(in StructVersion version = default, bool is32Bit = false)
15+
=> IIndexType<NestedTypeIndex>.IndexSize(version, is32Bit);
16+
17+
public void Read<TReader>(ref TReader reader, in StructVersion version = default) where TReader : IReader, allows ref struct
18+
{
19+
_value = IIndexType<NestedTypeIndex>.ReadIndex(ref reader, in version);
20+
}
21+
22+
#region Operators + ToString
23+
24+
public static implicit operator int(NestedTypeIndex idx) => idx._value;
25+
public static implicit operator NestedTypeIndex(int idx) => new(idx);
26+
27+
public static bool operator ==(NestedTypeIndex left, NestedTypeIndex right)
28+
=> left._value == right._value;
29+
30+
public static bool operator !=(NestedTypeIndex left, NestedTypeIndex right)
31+
=> !(left == right);
32+
33+
public readonly override bool Equals(object obj)
34+
=> obj is NestedTypeIndex other && Equals(other);
35+
36+
public readonly bool Equals(NestedTypeIndex other)
37+
=> this == other;
38+
39+
public readonly override int GetHashCode()
40+
=> HashCode.Combine(_value);
41+
42+
public readonly override string ToString() => _value.ToString();
43+
44+
#endregion
45+
}

0 commit comments

Comments
 (0)