migrate versioning to StructVersion class, add handling/detection for 29.2/31.2
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
All rights reserved.
|
All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using Il2CppInspector.Next;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -342,10 +343,10 @@ namespace Il2CppInspector
|
|||||||
// In v21 and later, R0-R2 + PC will be set and they will be the only registers set
|
// In v21 and later, R0-R2 + PC will be set and they will be the only registers set
|
||||||
// Pre-v21, R0-R1 + PC will be the only registers set
|
// Pre-v21, R0-R1 + PC will be the only registers set
|
||||||
|
|
||||||
if (image.Version >= 21 && regs.Count == 4 && regs.TryGetValue(0, out r0) && regs.TryGetValue(1, out r1) && regs.TryGetValue(2, out uint _))
|
if (image.Version >= MetadataVersions.V210 && regs.Count == 4 && regs.TryGetValue(0, out r0) && regs.TryGetValue(1, out r1) && regs.TryGetValue(2, out uint _))
|
||||||
return (r0 & 0xffff_fffe, r1 & 0xffff_fffe);
|
return (r0 & 0xffff_fffe, r1 & 0xffff_fffe);
|
||||||
|
|
||||||
if (image.Version < 21 && regs.Count == 3 && regs.TryGetValue(0, out r0) && regs.TryGetValue(1, out r1))
|
if (image.Version < MetadataVersions.V210 && regs.Count == 3 && regs.TryGetValue(0, out r0) && regs.TryGetValue(1, out r1))
|
||||||
return (r0 & 0xffff_fffe, r1 & 0xffff_fffe);
|
return (r0 & 0xffff_fffe, r1 & 0xffff_fffe);
|
||||||
|
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
All rights reserved.
|
All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using Il2CppInspector.Next;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
@@ -168,10 +169,10 @@ namespace Il2CppInspector
|
|||||||
// Is it Il2CppCodegenRegistration(void)?
|
// Is it Il2CppCodegenRegistration(void)?
|
||||||
// In v21 and later, X0-X2 will be set and they will be the only registers set
|
// In v21 and later, X0-X2 will be set and they will be the only registers set
|
||||||
// Pre-v21, X0-X1 will be the only registers set
|
// Pre-v21, X0-X1 will be the only registers set
|
||||||
if (image.Version >= 21 && regs.Count == 3 && regs.TryGetValue(0, out ulong x0) && regs.TryGetValue(1, out x1) && regs.TryGetValue(2, out ulong _))
|
if (image.Version >= MetadataVersions.V210 && regs.Count == 3 && regs.TryGetValue(0, out ulong x0) && regs.TryGetValue(1, out x1) && regs.TryGetValue(2, out ulong _))
|
||||||
return (x0, x1);
|
return (x0, x1);
|
||||||
|
|
||||||
if (image.Version < 21 && regs.Count == 2 && regs.TryGetValue(0, out x0) && regs.TryGetValue(1, out x1))
|
if (image.Version < MetadataVersions.V210 && regs.Count == 2 && regs.TryGetValue(0, out x0) && regs.TryGetValue(1, out x1))
|
||||||
return (x0, x1);
|
return (x0, x1);
|
||||||
|
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
All rights reserved.
|
All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using Il2CppInspector.Next;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
@@ -216,7 +217,7 @@ namespace Il2CppInspector
|
|||||||
offset = nextLea?.foundOffset + leaSize ?? buff2Size;
|
offset = nextLea?.foundOffset + leaSize ?? buff2Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((image.Version < 21 && leas.Count == 2) || (image.Version >= 21 && leas.Count == 3)) {
|
if ((image.Version < MetadataVersions.V210 && leas.Count == 2) || (image.Version >= MetadataVersions.V210 && leas.Count == 3)) {
|
||||||
// Register-based argument passing?
|
// Register-based argument passing?
|
||||||
var leaRSI = leas.FirstOrDefault(l => l.Value == RSI).Key.address;
|
var leaRSI = leas.FirstOrDefault(l => l.Value == RSI).Key.address;
|
||||||
var leaRDI = leas.FirstOrDefault(l => l.Value == RDI).Key.address;
|
var leaRDI = leas.FirstOrDefault(l => l.Value == RDI).Key.address;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
All rights reserved.
|
All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using Il2CppInspector.Next;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ namespace Il2CppInspector
|
|||||||
return (0, 0);
|
return (0, 0);
|
||||||
|
|
||||||
// Jump to Il2CppCodegenRegistration
|
// Jump to Il2CppCodegenRegistration
|
||||||
if(image.Version < 21) {
|
if(image.Version < MetadataVersions.V210) {
|
||||||
image.Position = image.MapVATR((ulong)pCgr + 1);
|
image.Position = image.MapVATR((ulong)pCgr + 1);
|
||||||
metadata = image.ReadUInt32();
|
metadata = image.ReadUInt32();
|
||||||
image.Position = image.MapVATR((ulong)pCgr + 6);
|
image.Position = image.MapVATR((ulong)pCgr + 6);
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using Il2CppInspector.Next;
|
||||||
|
using VersionedSerialization;
|
||||||
|
|
||||||
namespace Il2CppInspector.Cpp.UnityHeaders
|
namespace Il2CppInspector.Cpp.UnityHeaders
|
||||||
{
|
{
|
||||||
@@ -19,7 +21,7 @@ namespace Il2CppInspector.Cpp.UnityHeaders
|
|||||||
public class UnityHeaders : IEquatable<UnityHeaders>
|
public class UnityHeaders : IEquatable<UnityHeaders>
|
||||||
{
|
{
|
||||||
// Metadata version for which this group of headers are valid. Multiple headers may have the same metadata version
|
// Metadata version for which this group of headers are valid. Multiple headers may have the same metadata version
|
||||||
public double MetadataVersion { get; }
|
public StructVersion MetadataVersion { get; }
|
||||||
|
|
||||||
// Range of Unity versions for which this group of headers are valid
|
// Range of Unity versions for which this group of headers are valid
|
||||||
public UnityVersionRange VersionRange { get; }
|
public UnityVersionRange VersionRange { get; }
|
||||||
@@ -114,7 +116,7 @@ namespace Il2CppInspector.Cpp.UnityHeaders
|
|||||||
|
|
||||||
if (metadataVersion != binary.Image.Version)
|
if (metadataVersion != binary.Image.Version)
|
||||||
continue;
|
continue;
|
||||||
if (metadataVersion == 21) {
|
if (metadataVersion == MetadataVersions.V210) {
|
||||||
/* Special version logic for metadata version 21 based on the Il2CppMetadataRegistration.fieldOffsets field */
|
/* Special version logic for metadata version 21 based on the Il2CppMetadataRegistration.fieldOffsets field */
|
||||||
var headerFieldOffsetsArePointers = r.VersionRange.Min.CompareTo("5.3.7") >= 0 && r.VersionRange.Min.CompareTo("5.4.0") != 0;
|
var headerFieldOffsetsArePointers = r.VersionRange.Min.CompareTo("5.3.7") >= 0 && r.VersionRange.Min.CompareTo("5.4.0") != 0;
|
||||||
var binaryFieldOffsetsArePointers = binary.FieldOffsets == null;
|
var binaryFieldOffsetsArePointers = binary.FieldOffsets == null;
|
||||||
@@ -194,8 +196,8 @@ namespace Il2CppInspector.Cpp.UnityHeaders
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the metadata version from a type header resource name
|
// Get the metadata version from a type header resource name
|
||||||
private static double GetMetadataVersionFromFilename(string resourceName)
|
private static StructVersion GetMetadataVersionFromFilename(string resourceName)
|
||||||
=> double.Parse(resourceName.Substring(typeof(UnityHeaders).Namespace.Length + 1).Split('-')[0], NumberFormatInfo.InvariantInfo);
|
=> resourceName[(typeof(UnityHeaders).Namespace!.Length + 1)..].Split('-')[0];
|
||||||
|
|
||||||
// Equality comparisons
|
// Equality comparisons
|
||||||
public static bool operator ==(UnityHeaders first, UnityHeaders second) {
|
public static bool operator ==(UnityHeaders first, UnityHeaders second) {
|
||||||
|
|||||||
@@ -11,12 +11,13 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using NoisyCowStudios.Bin2Object;
|
using NoisyCowStudios.Bin2Object;
|
||||||
|
using VersionedSerialization;
|
||||||
|
|
||||||
namespace Il2CppInspector
|
namespace Il2CppInspector
|
||||||
{
|
{
|
||||||
public interface IFileFormatStream
|
public interface IFileFormatStream
|
||||||
{
|
{
|
||||||
double Version { get; set; }
|
StructVersion Version { get; set; }
|
||||||
long Length { get; }
|
long Length { get; }
|
||||||
uint NumImages { get; }
|
uint NumImages { get; }
|
||||||
string DefaultFilename { get; }
|
string DefaultFilename { get; }
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
All rights reserved.
|
All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using Il2CppInspector.Next;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -12,6 +13,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using VersionedSerialization;
|
||||||
|
|
||||||
namespace Il2CppInspector
|
namespace Il2CppInspector
|
||||||
{
|
{
|
||||||
@@ -135,7 +137,7 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load binary without a global-metadata.dat available
|
// Load binary without a global-metadata.dat available
|
||||||
public static Il2CppBinary Load(IFileFormatStream stream, double metadataVersion, EventHandler<string> statusCallback = null) {
|
public static Il2CppBinary Load(IFileFormatStream stream, StructVersion metadataVersion, EventHandler<string> statusCallback = null) {
|
||||||
foreach (var loadedImage in stream.TryNextLoadStrategy()) {
|
foreach (var loadedImage in stream.TryNextLoadStrategy()) {
|
||||||
var inst = LoadImpl(stream, statusCallback);
|
var inst = LoadImpl(stream, statusCallback);
|
||||||
if (inst.FindRegistrationStructs(metadataVersion))
|
if (inst.FindRegistrationStructs(metadataVersion))
|
||||||
@@ -167,7 +169,7 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize binary without a global-metadata.dat available
|
// Initialize binary without a global-metadata.dat available
|
||||||
public bool FindRegistrationStructs(double metadataVersion) {
|
public bool FindRegistrationStructs(StructVersion metadataVersion) {
|
||||||
Image.Version = metadataVersion;
|
Image.Version = metadataVersion;
|
||||||
|
|
||||||
StatusUpdate("Searching for binary metadata");
|
StatusUpdate("Searching for binary metadata");
|
||||||
@@ -282,21 +284,22 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
// genericAdjustorThunks was inserted before invokerPointersCount in 24.5 and 27.1
|
// genericAdjustorThunks was inserted before invokerPointersCount in 24.5 and 27.1
|
||||||
// pointer expected if we need to bump version
|
// pointer expected if we need to bump version
|
||||||
if (Image.Version == 24.4 && CodeRegistration.invokerPointersCount > 0x50000)
|
if (Image.Version == MetadataVersions.V244 && CodeRegistration.invokerPointersCount > 0x50000)
|
||||||
{
|
{
|
||||||
Image.Version = 24.5;
|
Image.Version = MetadataVersions.V245;
|
||||||
CodeRegistration = Image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration);
|
CodeRegistration = Image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Image.Version == 24.4 && CodeRegistration.reversePInvokeWrapperCount > 0x50000) {
|
if (Image.Version == MetadataVersions.V244 && CodeRegistration.reversePInvokeWrapperCount > 0x50000) {
|
||||||
Image.Version = 24.5;
|
Image.Version = MetadataVersions.V245;
|
||||||
codeRegistration -= 1 * pointerSize;
|
codeRegistration -= 1 * pointerSize;
|
||||||
CodeRegistration = Image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration);
|
CodeRegistration = Image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Image.Version == 29 && (long)CodeRegistration.genericMethodPointersCount - MetadataRegistration.genericMethodTableCount > 0x10000)
|
if ((Image.Version == MetadataVersions.V290 || Image.Version == MetadataVersions.V310) &&
|
||||||
|
(long)CodeRegistration.genericMethodPointersCount - MetadataRegistration.genericMethodTableCount > 0x10000)
|
||||||
{
|
{
|
||||||
Image.Version = 29.1;
|
Image.Version = new StructVersion(Image.Version.Major, 1, Image.Version.Tag);
|
||||||
codeRegistration -= 2 * pointerSize;
|
codeRegistration -= 2 * pointerSize;
|
||||||
CodeRegistration = Image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration);
|
CodeRegistration = Image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration);
|
||||||
}
|
}
|
||||||
@@ -317,21 +320,21 @@ namespace Il2CppInspector
|
|||||||
|| CodeRegistration.reversePInvokeWrapperCount > 0x10000
|
|| CodeRegistration.reversePInvokeWrapperCount > 0x10000
|
||||||
|| CodeRegistration.unresolvedVirtualCallCount > 0x4000 // >= 22
|
|| CodeRegistration.unresolvedVirtualCallCount > 0x4000 // >= 22
|
||||||
|| CodeRegistration.interopDataCount > 0x1000 // >= 23
|
|| CodeRegistration.interopDataCount > 0x1000 // >= 23
|
||||||
|| (Image.Version <= 24.1 && CodeRegistration.invokerPointersCount > CodeRegistration.methodPointersCount))
|
|| (Image.Version <= MetadataVersions.V241 && CodeRegistration.invokerPointersCount > CodeRegistration.methodPointersCount))
|
||||||
throw new NotSupportedException("The detected Il2CppCodeRegistration / Il2CppMetadataRegistration structs do not pass validation. This may mean that their fields have been re-ordered as a form of obfuscation and Il2CppInspector has not been able to restore the original order automatically. Consider re-ordering the fields in Il2CppBinaryClasses.cs and try again.");
|
throw new NotSupportedException("The detected Il2CppCodeRegistration / Il2CppMetadataRegistration structs do not pass validation. This may mean that their fields have been re-ordered as a form of obfuscation and Il2CppInspector has not been able to restore the original order automatically. Consider re-ordering the fields in Il2CppBinaryClasses.cs and try again.");
|
||||||
|
|
||||||
// The global method pointer list was deprecated in v24.2 in favour of Il2CppCodeGenModule
|
// The global method pointer list was deprecated in v24.2 in favour of Il2CppCodeGenModule
|
||||||
if (Image.Version <= 24.1)
|
if (Image.Version <= MetadataVersions.V241)
|
||||||
GlobalMethodPointers = Image.ReadMappedArray<ulong>(CodeRegistration.pmethodPointers, (int) CodeRegistration.methodPointersCount);
|
GlobalMethodPointers = Image.ReadMappedArray<ulong>(CodeRegistration.pmethodPointers, (int) CodeRegistration.methodPointersCount);
|
||||||
|
|
||||||
// After v24 method pointers and RGCTX data were stored in Il2CppCodeGenModules
|
// After v24 method pointers and RGCTX data were stored in Il2CppCodeGenModules
|
||||||
if (Image.Version >= 24.2) {
|
if (Image.Version >= MetadataVersions.V242) {
|
||||||
Modules = new Dictionary<string, Il2CppCodeGenModule>();
|
Modules = new Dictionary<string, Il2CppCodeGenModule>();
|
||||||
|
|
||||||
// In v24.3, windowsRuntimeFactoryTable collides with codeGenModules. So far no samples have had windowsRuntimeFactoryCount > 0;
|
// In v24.3, windowsRuntimeFactoryTable collides with codeGenModules. So far no samples have had windowsRuntimeFactoryCount > 0;
|
||||||
// if this changes we'll have to get smarter about disambiguating these two.
|
// if this changes we'll have to get smarter about disambiguating these two.
|
||||||
if (CodeRegistration.codeGenModulesCount == 0) {
|
if (CodeRegistration.codeGenModulesCount == 0) {
|
||||||
Image.Version = 24.3;
|
Image.Version = MetadataVersions.V243;
|
||||||
CodeRegistration = Image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration);
|
CodeRegistration = Image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,10 +367,10 @@ namespace Il2CppInspector
|
|||||||
// Field offset data. Metadata <=21.x uses a value-type array; >=21.x uses a pointer array
|
// 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
|
// Versions from 22 onwards use an array of pointers in Binary.FieldOffsetData
|
||||||
bool fieldOffsetsArePointers = (Image.Version >= 22);
|
bool fieldOffsetsArePointers = (Image.Version >= MetadataVersions.V220);
|
||||||
|
|
||||||
// Some variants of 21 also use an array of pointers
|
// Some variants of 21 also use an array of pointers
|
||||||
if (Image.Version == 21) {
|
if (Image.Version == MetadataVersions.V210) {
|
||||||
var fieldTest = Image.ReadMappedWordArray(MetadataRegistration.pfieldOffsets, 6);
|
var fieldTest = Image.ReadMappedWordArray(MetadataRegistration.pfieldOffsets, 6);
|
||||||
|
|
||||||
// We detect this by relying on the fact Module, Object, ValueType, Attribute, _Attribute and Int32
|
// We detect this by relying on the fact Module, Object, ValueType, Attribute, _Attribute and Int32
|
||||||
@@ -386,7 +389,7 @@ namespace Il2CppInspector
|
|||||||
TypeReferenceIndicesByAddress = typeRefPointers.Zip(Enumerable.Range(0, typeRefPointers.Length), (a, i) => new { a, i }).ToDictionary(x => x.a, x => x.i);
|
TypeReferenceIndicesByAddress = typeRefPointers.Zip(Enumerable.Range(0, typeRefPointers.Length), (a, i) => new { a, i }).ToDictionary(x => x.a, x => x.i);
|
||||||
|
|
||||||
TypeReferences =
|
TypeReferences =
|
||||||
Image.Version >= 27.2
|
Image.Version >= MetadataVersions.V272
|
||||||
? Image.ReadMappedObjectPointerArray<Il2CppTypeV272>(MetadataRegistration.ptypes, (int) MetadataRegistration.typesCount)
|
? Image.ReadMappedObjectPointerArray<Il2CppTypeV272>(MetadataRegistration.ptypes, (int) MetadataRegistration.typesCount)
|
||||||
.Cast<Il2CppType>()
|
.Cast<Il2CppType>()
|
||||||
.ToList()
|
.ToList()
|
||||||
@@ -394,7 +397,7 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
// Custom attribute constructors (function pointers)
|
// Custom attribute constructors (function pointers)
|
||||||
// This is managed in Il2CppInspector for metadata >= 27
|
// This is managed in Il2CppInspector for metadata >= 27
|
||||||
if (Image.Version < 27) {
|
if (Image.Version < MetadataVersions.V270) {
|
||||||
CustomAttributeGenerators = Image.ReadMappedArray<ulong>(CodeRegistration.customAttributeGenerators, (int) CodeRegistration.customAttributeCount);
|
CustomAttributeGenerators = Image.ReadMappedArray<ulong>(CodeRegistration.customAttributeGenerators, (int) CodeRegistration.customAttributeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,7 +411,7 @@ namespace Il2CppInspector
|
|||||||
// >=22: unresolvedVirtualCallPointers
|
// >=22: unresolvedVirtualCallPointers
|
||||||
// >=23: interopData
|
// >=23: interopData
|
||||||
|
|
||||||
if (Image.Version < 19) {
|
if (Image.Version < MetadataVersions.V190) {
|
||||||
VTableMethodReferences = Image.ReadMappedArray<uint>(MetadataRegistration.methodReferences, (int)MetadataRegistration.methodReferencesCount);
|
VTableMethodReferences = Image.ReadMappedArray<uint>(MetadataRegistration.methodReferences, (int)MetadataRegistration.methodReferencesCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,15 +60,19 @@ namespace Il2CppInspector
|
|||||||
[Version(Min = 22, Max = 29)]
|
[Version(Min = 22, Max = 29)]
|
||||||
public ulong unresolvedVirtualCallCount;
|
public ulong unresolvedVirtualCallCount;
|
||||||
|
|
||||||
[Version(Min = 29.1)]
|
[Version(Min = 29.1, Max = 29.2)]
|
||||||
|
[Version(Min = 31.1, Max = 31.2)]
|
||||||
public ulong unresolvedIndirectCallCount;
|
public ulong unresolvedIndirectCallCount;
|
||||||
|
|
||||||
[Version(Min = 22)]
|
[Version(Min = 22)]
|
||||||
public ulong unresolvedVirtualCallPointers;
|
public ulong unresolvedVirtualCallPointers;
|
||||||
|
|
||||||
[Version(Min = 29.1)]
|
[Version(Min = 29.1, Max = 29.2)]
|
||||||
|
[Version(Min = 31.1, Max = 31.2)]
|
||||||
public ulong unresolvedInstanceCallPointers;
|
public ulong unresolvedInstanceCallPointers;
|
||||||
[Version(Min = 29.1)]
|
|
||||||
|
[Version(Min = 29.1, Max = 29.2)]
|
||||||
|
[Version(Min = 31.1, Max = 31.2)]
|
||||||
public ulong unresolvedStaticCallPointers;
|
public ulong unresolvedStaticCallPointers;
|
||||||
|
|
||||||
// Added in metadata v23
|
// Added in metadata v23
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
All rights reserved.
|
All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using Il2CppInspector.Next;
|
||||||
using Il2CppInspector.Utils;
|
using Il2CppInspector.Utils;
|
||||||
using NoisyCowStudios.Bin2Object;
|
using NoisyCowStudios.Bin2Object;
|
||||||
using System;
|
using System;
|
||||||
@@ -12,6 +13,7 @@ using System.IO;
|
|||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using VersionedSerialization;
|
||||||
|
|
||||||
namespace Il2CppInspector
|
namespace Il2CppInspector
|
||||||
{
|
{
|
||||||
@@ -31,7 +33,9 @@ namespace Il2CppInspector
|
|||||||
public List<MetadataUsage> MetadataUsages { get; }
|
public List<MetadataUsage> MetadataUsages { get; }
|
||||||
|
|
||||||
// Shortcuts
|
// Shortcuts
|
||||||
public double Version => Math.Max(Metadata.Version, Binary.Image.Version);
|
public StructVersion Version => Metadata.Version > Binary.Image.Version
|
||||||
|
? Metadata.Version
|
||||||
|
: Binary.Image.Version;
|
||||||
|
|
||||||
public Dictionary<int, string> Strings => Metadata.Strings;
|
public Dictionary<int, string> Strings => Metadata.Strings;
|
||||||
public string[] StringLiterals => Metadata.StringLiterals;
|
public string[] StringLiterals => Metadata.StringLiterals;
|
||||||
@@ -93,11 +97,11 @@ namespace Il2CppInspector
|
|||||||
private List<MetadataUsage> buildMetadataUsages()
|
private List<MetadataUsage> buildMetadataUsages()
|
||||||
{
|
{
|
||||||
// No metadata usages for versions < 19
|
// No metadata usages for versions < 19
|
||||||
if (Version < 19)
|
if (Version < MetadataVersions.V190)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// Metadata usages are lazily initialized during runtime for versions >= 27
|
// Metadata usages are lazily initialized during runtime for versions >= 27
|
||||||
if (Version >= 27)
|
if (Version >= MetadataVersions.V270)
|
||||||
return buildLateBindingMetadataUsages();
|
return buildLateBindingMetadataUsages();
|
||||||
|
|
||||||
// Version >= 19 && < 27
|
// Version >= 19 && < 27
|
||||||
@@ -217,9 +221,9 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build list of custom attribute generators
|
// Build list of custom attribute generators
|
||||||
if (Version < 27)
|
if (Version < MetadataVersions.V270)
|
||||||
CustomAttributeGenerators = Binary.CustomAttributeGenerators;
|
CustomAttributeGenerators = Binary.CustomAttributeGenerators;
|
||||||
else if (Version < 29)
|
else if (Version < MetadataVersions.V290)
|
||||||
{
|
{
|
||||||
var cagCount = Images.Sum(i => i.customAttributeCount);
|
var cagCount = Images.Sum(i => i.customAttributeCount);
|
||||||
CustomAttributeGenerators = new ulong[cagCount];
|
CustomAttributeGenerators = new ulong[cagCount];
|
||||||
@@ -243,7 +247,7 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
// Get sorted list of function pointers from all sources
|
// Get sorted list of function pointers from all sources
|
||||||
// TODO: This does not include IL2CPP API functions
|
// TODO: This does not include IL2CPP API functions
|
||||||
var sortedFunctionPointers = (Version <= 24.1)?
|
var sortedFunctionPointers = (Version <= MetadataVersions.V241) ?
|
||||||
Binary.GlobalMethodPointers.Select(getDecodedAddress).ToList() :
|
Binary.GlobalMethodPointers.Select(getDecodedAddress).ToList() :
|
||||||
Binary.ModuleMethodPointers.SelectMany(module => module.Value).Select(getDecodedAddress).ToList();
|
Binary.ModuleMethodPointers.SelectMany(module => module.Value).Select(getDecodedAddress).ToList();
|
||||||
|
|
||||||
@@ -261,7 +265,7 @@ namespace Il2CppInspector
|
|||||||
FunctionAddresses.Add(sortedFunctionPointers[^1], sortedFunctionPointers[^1]);
|
FunctionAddresses.Add(sortedFunctionPointers[^1], sortedFunctionPointers[^1]);
|
||||||
|
|
||||||
// Organize custom attribute indices
|
// Organize custom attribute indices
|
||||||
if (Version >= 24.1) {
|
if (Version >= MetadataVersions.V241) {
|
||||||
AttributeIndicesByToken = [];
|
AttributeIndicesByToken = [];
|
||||||
foreach (var image in Images)
|
foreach (var image in Images)
|
||||||
{
|
{
|
||||||
@@ -269,7 +273,7 @@ namespace Il2CppInspector
|
|||||||
for (int i = 0; i < image.customAttributeCount; i++)
|
for (int i = 0; i < image.customAttributeCount; i++)
|
||||||
{
|
{
|
||||||
var index = image.customAttributeStart + i;
|
var index = image.customAttributeStart + i;
|
||||||
var token = Version >= 29 ? AttributeDataRanges[index].token : AttributeTypeRanges[index].token;
|
var token = Version >= MetadataVersions.V290 ? AttributeDataRanges[index].token : AttributeTypeRanges[index].token;
|
||||||
attsByToken.Add(token, index);
|
attsByToken.Add(token, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,13 +298,13 @@ namespace Il2CppInspector
|
|||||||
ulong start = 0;
|
ulong start = 0;
|
||||||
|
|
||||||
// Global method pointer array
|
// Global method pointer array
|
||||||
if (Version <= 24.1) {
|
if (Version <= MetadataVersions.V241) {
|
||||||
start = Binary.GlobalMethodPointers[methodDef.methodIndex];
|
start = Binary.GlobalMethodPointers[methodDef.methodIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Per-module method pointer array uses the bottom 24 bits of the method's metadata token
|
// Per-module method pointer array uses the bottom 24 bits of the method's metadata token
|
||||||
// Derived from il2cpp::vm::MetadataCache::GetMethodPointer
|
// Derived from il2cpp::vm::MetadataCache::GetMethodPointer
|
||||||
if (Version >= 24.2) {
|
if (Version >= MetadataVersions.V242) {
|
||||||
var method = (methodDef.token & 0xffffff);
|
var method = (methodDef.token & 0xffffff);
|
||||||
if (method == 0)
|
if (method == 0)
|
||||||
return null;
|
return null;
|
||||||
@@ -335,7 +339,7 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
// Get a method invoker index from a method definition
|
// Get a method invoker index from a method definition
|
||||||
public int GetInvokerIndex(Il2CppCodeGenModule module, Il2CppMethodDefinition methodDef) {
|
public int GetInvokerIndex(Il2CppCodeGenModule module, Il2CppMethodDefinition methodDef) {
|
||||||
if (Version <= 24.1) {
|
if (Version <= MetadataVersions.V241) {
|
||||||
return methodDef.invokerIndex;
|
return methodDef.invokerIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using System.Buffers;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Il2CppInspector.Next;
|
||||||
|
|
||||||
namespace Il2CppInspector
|
namespace Il2CppInspector
|
||||||
{
|
{
|
||||||
@@ -120,7 +121,7 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
// Find CodeRegistration
|
// Find CodeRegistration
|
||||||
// >= 24.2
|
// >= 24.2
|
||||||
if (metadata.Version >= 24.2) {
|
if (metadata.Version >= MetadataVersions.V242) {
|
||||||
|
|
||||||
// < 27: mscorlib.dll is always the first CodeGenModule
|
// < 27: mscorlib.dll is always the first CodeGenModule
|
||||||
// >= 27: mscorlib.dll is always the last CodeGenModule (Assembly-CSharp.dll is always the first but non-Unity builds don't have this DLL)
|
// >= 27: mscorlib.dll is always the last CodeGenModule (Assembly-CSharp.dll is always the first but non-Unity builds don't have this DLL)
|
||||||
@@ -137,7 +138,7 @@ namespace Il2CppInspector
|
|||||||
// Unwind from string pointer -> CodeGenModule -> CodeGenModules + x
|
// Unwind from string pointer -> CodeGenModule -> CodeGenModules + x
|
||||||
foreach (var potentialCodeGenModules in FindAllPointerChains(imageBytes, va, 2))
|
foreach (var potentialCodeGenModules in FindAllPointerChains(imageBytes, va, 2))
|
||||||
{
|
{
|
||||||
if (metadata.Version >= 27)
|
if (metadata.Version >= MetadataVersions.V270)
|
||||||
{
|
{
|
||||||
for (int i = imagesCount - 1; i >= 0; i--)
|
for (int i = imagesCount - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
@@ -210,16 +211,16 @@ namespace Il2CppInspector
|
|||||||
// if this changes we'll have to get smarter about disambiguating these two.
|
// if this changes we'll have to get smarter about disambiguating these two.
|
||||||
var cr = Image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration);
|
var cr = Image.ReadMappedObject<Il2CppCodeRegistration>(codeRegistration);
|
||||||
|
|
||||||
if (Image.Version == 24.2 && cr.interopDataCount == 0) {
|
if (Image.Version == MetadataVersions.V242 && cr.interopDataCount == 0) {
|
||||||
Image.Version = 24.3;
|
Image.Version = MetadataVersions.V243;
|
||||||
codeRegistration -= ptrSize * 2; // two extra words for WindowsRuntimeFactory
|
codeRegistration -= ptrSize * 2; // two extra words for WindowsRuntimeFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Image.Version == 27 && cr.reversePInvokeWrapperCount > 0x30000)
|
if (Image.Version == MetadataVersions.V270 && cr.reversePInvokeWrapperCount > 0x30000)
|
||||||
{
|
{
|
||||||
// If reversePInvokeWrapperCount is a pointer, then it's because we're actually on 27.1 and there's a genericAdjustorThunks pointer interfering.
|
// If reversePInvokeWrapperCount is a pointer, then it's because we're actually on 27.1 and there's a genericAdjustorThunks pointer interfering.
|
||||||
// We need to bump version to 27.1 and back up one more pointer.
|
// We need to bump version to 27.1 and back up one more pointer.
|
||||||
Image.Version = 27.1;
|
Image.Version = MetadataVersions.V271;
|
||||||
codeRegistration -= ptrSize;
|
codeRegistration -= ptrSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -259,7 +260,7 @@ namespace Il2CppInspector
|
|||||||
vas = FindAllMappedWords(imageBytes, typesLength).Select(a => a - mrSize + ptrSize * 4);
|
vas = FindAllMappedWords(imageBytes, typesLength).Select(a => a - mrSize + ptrSize * 4);
|
||||||
|
|
||||||
// >= 19 && < 27
|
// >= 19 && < 27
|
||||||
if (Image.Version < 27)
|
if (Image.Version < MetadataVersions.V270)
|
||||||
foreach (var va in vas) {
|
foreach (var va in vas) {
|
||||||
var mr = Image.ReadMappedObject<Il2CppMetadataRegistration>(va);
|
var mr = Image.ReadMappedObject<Il2CppMetadataRegistration>(va);
|
||||||
if (mr.metadataUsagesCount == (ulong) metadata.MetadataUsageLists.Length)
|
if (mr.metadataUsagesCount == (ulong) metadata.MetadataUsageLists.Length)
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using Il2CppInspector.Next;
|
||||||
using NoisyCowStudios.Bin2Object;
|
using NoisyCowStudios.Bin2Object;
|
||||||
|
using VersionedSerialization;
|
||||||
|
|
||||||
namespace Il2CppInspector
|
namespace Il2CppInspector
|
||||||
{
|
{
|
||||||
@@ -86,9 +88,9 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set object versioning for Bin2Object from metadata version
|
// Set object versioning for Bin2Object from metadata version
|
||||||
Version = Header.version;
|
Version = new StructVersion(Header.version);
|
||||||
|
|
||||||
if (Version < 16 || Version > 31) {
|
if (Version < MetadataVersions.V160 || Version > MetadataVersions.V310) {
|
||||||
throw new InvalidOperationException($"The supplied metadata file is not of a supported version ({Header.version}).");
|
throw new InvalidOperationException($"The supplied metadata file is not of a supported version ({Header.version}).");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,8 +110,8 @@ namespace Il2CppInspector
|
|||||||
var realHeaderLength = Header.stringLiteralOffset;
|
var realHeaderLength = Header.stringLiteralOffset;
|
||||||
|
|
||||||
if (realHeaderLength != Sizeof(typeof(Il2CppGlobalMetadataHeader))) {
|
if (realHeaderLength != Sizeof(typeof(Il2CppGlobalMetadataHeader))) {
|
||||||
if (Version == 24.0) {
|
if (Version == MetadataVersions.V240) {
|
||||||
Version = 24.2;
|
Version = MetadataVersions.V242;
|
||||||
Header = ReadObject<Il2CppGlobalMetadataHeader>(0);
|
Header = ReadObject<Il2CppGlobalMetadataHeader>(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,16 +122,16 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load all the relevant metadata using offsets provided in the header
|
// Load all the relevant metadata using offsets provided in the header
|
||||||
if (Version >= 16)
|
if (Version >= MetadataVersions.V160)
|
||||||
Images = ReadArray<Il2CppImageDefinition>(Header.imagesOffset, Header.imagesCount / Sizeof(typeof(Il2CppImageDefinition)));
|
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
|
// 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 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
|
// In that case, we can then adjust the version number and reload
|
||||||
// Tokens were introduced in v19 - we don't bother testing earlier versions
|
// Tokens were introduced in v19 - we don't bother testing earlier versions
|
||||||
if (Version >= 19 && Images.Any(x => x.token != 1))
|
if (Version >= MetadataVersions.V190 && Images.Any(x => x.token != 1))
|
||||||
if (Version == 24.0) {
|
if (Version == MetadataVersions.V240) {
|
||||||
Version = 24.1;
|
Version = MetadataVersions.V241;
|
||||||
|
|
||||||
// No need to re-read the header, it's the same for both sub-versions
|
// 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)));
|
Images = ReadArray<Il2CppImageDefinition>(Header.imagesOffset, Header.imagesCount / Sizeof(typeof(Il2CppImageDefinition)));
|
||||||
@@ -153,44 +155,63 @@ namespace Il2CppInspector
|
|||||||
InterfaceOffsets = ReadArray<Il2CppInterfaceOffsetPair>(Header.interfaceOffsetsOffset, Header.interfaceOffsetsCount / Sizeof(typeof(Il2CppInterfaceOffsetPair)));
|
InterfaceOffsets = ReadArray<Il2CppInterfaceOffsetPair>(Header.interfaceOffsetsOffset, Header.interfaceOffsetsCount / Sizeof(typeof(Il2CppInterfaceOffsetPair)));
|
||||||
VTableMethodIndices = ReadArray<uint>(Header.vtableMethodsOffset, Header.vtableMethodsCount / sizeof(uint));
|
VTableMethodIndices = ReadArray<uint>(Header.vtableMethodsOffset, Header.vtableMethodsCount / sizeof(uint));
|
||||||
|
|
||||||
if (Version >= 16) {
|
if (Version >= MetadataVersions.V160) {
|
||||||
// In v24.4 hashValueIndex was removed from Il2CppAssemblyNameDefinition, which is a field in Il2CppAssemblyDefinition
|
// In v24.4 hashValueIndex was removed from Il2CppAssemblyNameDefinition, which is a field in Il2CppAssemblyDefinition
|
||||||
// The number of images and assemblies should be the same. If they are not, we deduce that we are using v24.4
|
// The number of images and assemblies should be the same. If they are not, we deduce that we are using v24.4
|
||||||
// Note the version comparison matches both 24.2 and 24.3 here since 24.3 is tested for during binary loading
|
// Note the version comparison matches both 24.2 and 24.3 here since 24.3 is tested for during binary loading
|
||||||
var assemblyCount = Header.assembliesCount / Sizeof(typeof(Il2CppAssemblyDefinition));
|
var assemblyCount = Header.assembliesCount / Sizeof(typeof(Il2CppAssemblyDefinition));
|
||||||
var changedAssemblyDefStruct = false;
|
var changedAssemblyDefStruct = false;
|
||||||
if ((Version == 24.1 || Version == 24.2 || Version == 24.3) && assemblyCount < Images.Length)
|
if ((Version == MetadataVersions.V241 || Version == MetadataVersions.V242 || Version == MetadataVersions.V243) && assemblyCount < Images.Length)
|
||||||
{
|
{
|
||||||
if (Version == 24.1)
|
if (Version == MetadataVersions.V241)
|
||||||
changedAssemblyDefStruct = true;
|
changedAssemblyDefStruct = true;
|
||||||
Version = 24.4;
|
Version = MetadataVersions.V244;
|
||||||
}
|
}
|
||||||
|
|
||||||
Assemblies = ReadArray<Il2CppAssemblyDefinition>(Header.assembliesOffset, Images.Length);
|
Assemblies = ReadArray<Il2CppAssemblyDefinition>(Header.assembliesOffset, Images.Length);
|
||||||
|
|
||||||
if (changedAssemblyDefStruct)
|
if (changedAssemblyDefStruct)
|
||||||
Version = 24.1;
|
Version = MetadataVersions.V241;
|
||||||
|
|
||||||
ParameterDefaultValues = ReadArray<Il2CppParameterDefaultValue>(Header.parameterDefaultValuesOffset, Header.parameterDefaultValuesCount / Sizeof(typeof(Il2CppParameterDefaultValue)));
|
ParameterDefaultValues = ReadArray<Il2CppParameterDefaultValue>(Header.parameterDefaultValuesOffset, Header.parameterDefaultValuesCount / Sizeof(typeof(Il2CppParameterDefaultValue)));
|
||||||
}
|
}
|
||||||
if (Version >= 19 && Version < 27) {
|
if (Version >= MetadataVersions.V190 && Version < MetadataVersions.V270) {
|
||||||
MetadataUsageLists = ReadArray<Il2CppMetadataUsageList>(Header.metadataUsageListsOffset, Header.metadataUsageListsCount / Sizeof(typeof(Il2CppMetadataUsageList)));
|
MetadataUsageLists = ReadArray<Il2CppMetadataUsageList>(Header.metadataUsageListsOffset, Header.metadataUsageListsCount / Sizeof(typeof(Il2CppMetadataUsageList)));
|
||||||
MetadataUsagePairs = ReadArray<Il2CppMetadataUsagePair>(Header.metadataUsagePairsOffset, Header.metadataUsagePairsCount / Sizeof(typeof(Il2CppMetadataUsagePair)));
|
MetadataUsagePairs = ReadArray<Il2CppMetadataUsagePair>(Header.metadataUsagePairsOffset, Header.metadataUsagePairsCount / Sizeof(typeof(Il2CppMetadataUsagePair)));
|
||||||
}
|
}
|
||||||
if (Version >= 19) {
|
if (Version >= MetadataVersions.V190) {
|
||||||
FieldRefs = ReadArray<Il2CppFieldRef>(Header.fieldRefsOffset, Header.fieldRefsCount / Sizeof(typeof(Il2CppFieldRef)));
|
FieldRefs = ReadArray<Il2CppFieldRef>(Header.fieldRefsOffset, Header.fieldRefsCount / Sizeof(typeof(Il2CppFieldRef)));
|
||||||
}
|
}
|
||||||
if (Version >= 21 && Version < 29) {
|
if (Version >= MetadataVersions.V210 && Version < MetadataVersions.V290) {
|
||||||
AttributeTypeIndices = ReadArray<int>(Header.attributeTypesOffset, Header.attributeTypesCount / sizeof(int));
|
AttributeTypeIndices = ReadArray<int>(Header.attributeTypesOffset, Header.attributeTypesCount / sizeof(int));
|
||||||
AttributeTypeRanges = ReadArray<Il2CppCustomAttributeTypeRange>(Header.attributesInfoOffset, Header.attributesInfoCount / Sizeof(typeof(Il2CppCustomAttributeTypeRange)));
|
AttributeTypeRanges = ReadArray<Il2CppCustomAttributeTypeRange>(Header.attributesInfoOffset, Header.attributesInfoCount / Sizeof(typeof(Il2CppCustomAttributeTypeRange)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Version >= 29)
|
if (Version >= MetadataVersions.V290)
|
||||||
{
|
{
|
||||||
AttributeDataRanges = ReadArray<Il2CppCustomAttributeDataRange>(Header.attributeDataRangeOffset,
|
AttributeDataRanges = ReadArray<Il2CppCustomAttributeDataRange>(Header.attributeDataRangeOffset,
|
||||||
Header.attributeDataRangeSize / Sizeof(typeof(Il2CppCustomAttributeDataRange)));
|
Header.attributeDataRangeSize / Sizeof(typeof(Il2CppCustomAttributeDataRange)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Version == MetadataVersions.V290 || Version == MetadataVersions.V310)
|
||||||
|
{
|
||||||
|
// 29.2/31.2 added a new isUnmanagedCallersOnly flag to Il2CppMethodDefinition.
|
||||||
|
// This offsets all subsequent entries by one - we can detect this by checking the
|
||||||
|
// top token byte (which should always be 0x06).
|
||||||
|
|
||||||
|
if (Methods.Length >= 2)
|
||||||
|
{
|
||||||
|
var secondToken = Methods[1].token;
|
||||||
|
if (secondToken >> 24 != 0x6)
|
||||||
|
{
|
||||||
|
Version = new StructVersion(Version.Major, 1, Version.Tag);
|
||||||
|
|
||||||
|
Methods = ReadArray<Il2CppMethodDefinition>(Header.methodsOffset,
|
||||||
|
Header.methodsCount / Sizeof(typeof(Il2CppMethodDefinition)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get all metadata strings
|
// Get all metadata strings
|
||||||
var pluginGetStringsResult = PluginHooks.GetStrings(this);
|
var pluginGetStringsResult = PluginHooks.GetStrings(this);
|
||||||
if (pluginGetStringsResult.IsDataModified && !pluginGetStringsResult.IsInvalid)
|
if (pluginGetStringsResult.IsDataModified && !pluginGetStringsResult.IsInvalid)
|
||||||
@@ -229,7 +250,9 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
public int Sizeof(Type type) => Sizeof(type, Version);
|
public int Sizeof(Type type) => Sizeof(type, Version);
|
||||||
|
|
||||||
public int Sizeof(Type type, double metadataVersion, int longSizeBytes = 8) {
|
public int Sizeof(Type type, StructVersion metadataVersion, int longSizeBytes = 8)
|
||||||
|
{
|
||||||
|
var doubleRepresentation = metadataVersion.AsDouble;
|
||||||
|
|
||||||
if (Reader.ObjectMappings.TryGetValue(type, out var streamType))
|
if (Reader.ObjectMappings.TryGetValue(type, out var streamType))
|
||||||
type = streamType;
|
type = streamType;
|
||||||
@@ -239,7 +262,7 @@ namespace Il2CppInspector
|
|||||||
{
|
{
|
||||||
// Only process fields for our selected object versioning (always process if none supplied)
|
// Only process fields for our selected object versioning (always process if none supplied)
|
||||||
var versions = i.GetCustomAttributes<VersionAttribute>(false).Select(v => (v.Min, v.Max)).ToList();
|
var versions = i.GetCustomAttributes<VersionAttribute>(false).Select(v => (v.Min, v.Max)).ToList();
|
||||||
if (versions.Any() && !versions.Any(v => (v.Min <= metadataVersion || v.Min == -1) && (v.Max >= metadataVersion || v.Max == -1)))
|
if (versions.Any() && !versions.Any(v => (v.Min <= doubleRepresentation || v.Min == -1) && (v.Max >= doubleRepresentation || v.Max == -1)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (i.FieldType == typeof(long) || i.FieldType == typeof(ulong))
|
if (i.FieldType == typeof(long) || i.FieldType == typeof(ulong))
|
||||||
|
|||||||
@@ -342,7 +342,8 @@ namespace Il2CppInspector
|
|||||||
public ushort slot;
|
public ushort slot;
|
||||||
public ushort parameterCount;
|
public ushort parameterCount;
|
||||||
|
|
||||||
[Version(Min = 29.2, Max = 31)]
|
[Version(Min = 29.2, Max = 29.2)]
|
||||||
|
[Version(Min = 31.2, Max = 31.2)]
|
||||||
public bool isUnmanagedCallersOnly;
|
public bool isUnmanagedCallersOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
All rights reserved.
|
All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using Il2CppInspector.Next;
|
||||||
|
|
||||||
namespace Il2CppInspector
|
namespace Il2CppInspector
|
||||||
{
|
{
|
||||||
public enum MetadataUsageType
|
public enum MetadataUsageType
|
||||||
@@ -34,7 +36,7 @@ namespace Il2CppInspector
|
|||||||
public static MetadataUsage FromEncodedIndex(Il2CppInspector package, uint encodedIndex, ulong virtualAddress = 0) {
|
public static MetadataUsage FromEncodedIndex(Il2CppInspector package, uint encodedIndex, ulong virtualAddress = 0) {
|
||||||
uint index;
|
uint index;
|
||||||
MetadataUsageType usageType;
|
MetadataUsageType usageType;
|
||||||
if (package.Version < 19) {
|
if (package.Version < MetadataVersions.V190) {
|
||||||
/* These encoded indices appear only in vtables, and are decoded by IsGenericMethodIndex/GetDecodedMethodIndex */
|
/* These encoded indices appear only in vtables, and are decoded by IsGenericMethodIndex/GetDecodedMethodIndex */
|
||||||
var isGeneric = encodedIndex & 0x80000000;
|
var isGeneric = encodedIndex & 0x80000000;
|
||||||
index = package.Binary.VTableMethodReferences[encodedIndex & 0x7FFFFFFF];
|
index = package.Binary.VTableMethodReferences[encodedIndex & 0x7FFFFFFF];
|
||||||
@@ -46,7 +48,7 @@ namespace Il2CppInspector
|
|||||||
index = encodedIndex & 0x1FFFFFFF;
|
index = encodedIndex & 0x1FFFFFFF;
|
||||||
|
|
||||||
// From v27 the bottom bit is set to indicate the usage token hasn't been replaced with a pointer at runtime yet
|
// From v27 the bottom bit is set to indicate the usage token hasn't been replaced with a pointer at runtime yet
|
||||||
if (package.Version >= 27)
|
if (package.Version >= MetadataVersions.V270)
|
||||||
index >>= 1;
|
index >>= 1;
|
||||||
}
|
}
|
||||||
return new MetadataUsage(usageType, (int)index, virtualAddress);
|
return new MetadataUsage(usageType, (int)index, virtualAddress);
|
||||||
|
|||||||
@@ -47,6 +47,8 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Bin2Object\Bin2Object\Bin2Object.csproj" PrivateAssets="all" />
|
<ProjectReference Include="..\Bin2Object\Bin2Object\Bin2Object.csproj" PrivateAssets="all" />
|
||||||
|
<ProjectReference Include="..\VersionedSerialization.Generator\VersionedSerialization.Generator.csproj" ReferenceOutputAssembly="false" OutputType="Analyzer" />
|
||||||
|
<ProjectReference Include="..\VersionedSerialization\VersionedSerialization.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Il2CppInspector.Cpp;
|
using Il2CppInspector.Cpp;
|
||||||
|
using Il2CppInspector.Next;
|
||||||
using Il2CppInspector.Reflection;
|
using Il2CppInspector.Reflection;
|
||||||
|
|
||||||
namespace Il2CppInspector.Model
|
namespace Il2CppInspector.Model
|
||||||
@@ -123,7 +124,7 @@ namespace Il2CppInspector.Model
|
|||||||
Add(binary.CodeRegistrationPointer, binary.CodeRegistration);
|
Add(binary.CodeRegistrationPointer, binary.CodeRegistration);
|
||||||
Add(binary.MetadataRegistrationPointer, binary.MetadataRegistration);
|
Add(binary.MetadataRegistrationPointer, binary.MetadataRegistration);
|
||||||
|
|
||||||
if (Model.Package.Version >= 24.2) {
|
if (Model.Package.Version >= MetadataVersions.V242) {
|
||||||
// TODO: Add some kind of AppArray composite type for arrays as we'll be adding more later
|
// TODO: Add some kind of AppArray composite type for arrays as we'll be adding more later
|
||||||
Add(binary.CodeRegistration.pcodeGenModules, binary.CodeGenModulePointers);
|
Add(binary.CodeRegistration.pcodeGenModules, binary.CodeGenModulePointers);
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ using System.Linq;
|
|||||||
using Aron.Weiler;
|
using Aron.Weiler;
|
||||||
using Il2CppInspector.Cpp;
|
using Il2CppInspector.Cpp;
|
||||||
using Il2CppInspector.Cpp.UnityHeaders;
|
using Il2CppInspector.Cpp.UnityHeaders;
|
||||||
|
using Il2CppInspector.Next;
|
||||||
using Il2CppInspector.Reflection;
|
using Il2CppInspector.Reflection;
|
||||||
|
|
||||||
namespace Il2CppInspector.Model
|
namespace Il2CppInspector.Model
|
||||||
@@ -54,7 +55,7 @@ namespace Il2CppInspector.Model
|
|||||||
public Dictionary<ulong, (FieldInfo Field, string Value)> Fields { get; } = [];
|
public Dictionary<ulong, (FieldInfo Field, string Value)> Fields { get; } = [];
|
||||||
public Dictionary<ulong, (FieldInfo Field, string Value)> FieldRvas { get; } = [];
|
public Dictionary<ulong, (FieldInfo Field, string Value)> FieldRvas { get; } = [];
|
||||||
|
|
||||||
public bool StringIndexesAreOrdinals => Package.Version < 19;
|
public bool StringIndexesAreOrdinals => Package.Version < MetadataVersions.V190;
|
||||||
|
|
||||||
// The .NET type model for the application
|
// The .NET type model for the application
|
||||||
public TypeModel TypeModel { get; }
|
public TypeModel TypeModel { get; }
|
||||||
@@ -270,7 +271,7 @@ namespace Il2CppInspector.Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add string literals for metadata <19 to the model
|
// Add string literals for metadata <19 to the model
|
||||||
if (Package.Version < 19) {
|
if (Package.Version < MetadataVersions.V190) {
|
||||||
/* Version < 19 calls `il2cpp_codegen_string_literal_from_index` to get string literals.
|
/* Version < 19 calls `il2cpp_codegen_string_literal_from_index` to get string literals.
|
||||||
* Unfortunately, metadata references are just loose globals in Il2CppMetadataUsage.cpp
|
* Unfortunately, metadata references are just loose globals in Il2CppMetadataUsage.cpp
|
||||||
* so we can't automatically name those. Next best thing is to define an enum for the strings. */
|
* so we can't automatically name those. Next best thing is to define an enum for the strings. */
|
||||||
|
|||||||
33
Il2CppInspector.Common/Next/MetadataVersions.cs
Normal file
33
Il2CppInspector.Common/Next/MetadataVersions.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using VersionedSerialization;
|
||||||
|
|
||||||
|
namespace Il2CppInspector.Next;
|
||||||
|
|
||||||
|
public static class MetadataVersions
|
||||||
|
{
|
||||||
|
public static readonly StructVersion V160 = new(16);
|
||||||
|
|
||||||
|
public static readonly StructVersion V190 = new(19);
|
||||||
|
|
||||||
|
public static readonly StructVersion V210 = new(21);
|
||||||
|
public static readonly StructVersion V220 = new(22);
|
||||||
|
|
||||||
|
public static readonly StructVersion V240 = new(24);
|
||||||
|
public static readonly StructVersion V241 = new(24, 1);
|
||||||
|
public static readonly StructVersion V242 = new(24, 2);
|
||||||
|
public static readonly StructVersion V243 = new(24, 3);
|
||||||
|
public static readonly StructVersion V244 = new(24, 4);
|
||||||
|
public static readonly StructVersion V245 = new(24, 5);
|
||||||
|
|
||||||
|
public static readonly StructVersion V270 = new(27);
|
||||||
|
public static readonly StructVersion V271 = new(27, 1);
|
||||||
|
public static readonly StructVersion V272 = new(27, 2);
|
||||||
|
|
||||||
|
public static readonly StructVersion V290 = new(29);
|
||||||
|
public static readonly StructVersion V310 = new(31);
|
||||||
|
|
||||||
|
public static readonly StructVersion V291 = new(29, 1);
|
||||||
|
public static readonly StructVersion V311 = new(31, 1);
|
||||||
|
|
||||||
|
public static readonly StructVersion V292 = new(29, 2);
|
||||||
|
public static readonly StructVersion V312 = new(31, 2);
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
|
using Il2CppInspector.Next;
|
||||||
using Il2CppInspector.Reflection;
|
using Il2CppInspector.Reflection;
|
||||||
|
|
||||||
namespace Il2CppInspector.Outputs
|
namespace Il2CppInspector.Outputs
|
||||||
@@ -591,7 +592,7 @@ namespace Il2CppInspector.Outputs
|
|||||||
// Create folder for DLLs
|
// Create folder for DLLs
|
||||||
Directory.CreateDirectory(outputPath);
|
Directory.CreateDirectory(outputPath);
|
||||||
|
|
||||||
if (model.Package.Version >= 29)
|
if (model.Package.Version >= MetadataVersions.V290)
|
||||||
{
|
{
|
||||||
// We can now apply all attributes directly.
|
// We can now apply all attributes directly.
|
||||||
directApplyAttributes = model.TypesByDefinitionIndex
|
directApplyAttributes = model.TypesByDefinitionIndex
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ namespace Il2CppInspector.Outputs
|
|||||||
using (_writer)
|
using (_writer)
|
||||||
{
|
{
|
||||||
writeHeader();
|
writeHeader();
|
||||||
writeCode($"#define __IL2CPP_METADATA_VERSION {_model.Package.Version * 10:F0}");
|
writeCode($"#define __IL2CPP_METADATA_VERSION {_model.Package.Version.Major * 10 + _model.Package.Version.Minor * 10:F0}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write boilerplate code
|
// Write boilerplate code
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using System.IO;
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Il2CppInspector.Reflection;
|
using Il2CppInspector.Reflection;
|
||||||
using Il2CppInspector.Model;
|
using Il2CppInspector.Model;
|
||||||
|
using Il2CppInspector.Next;
|
||||||
|
|
||||||
namespace Il2CppInspector.Outputs
|
namespace Il2CppInspector.Outputs
|
||||||
{
|
{
|
||||||
@@ -182,7 +183,7 @@ namespace Il2CppInspector.Outputs
|
|||||||
|
|
||||||
// TODO: In the future, add data ranges for the entire IL2CPP metadata tree
|
// TODO: In the future, add data ranges for the entire IL2CPP metadata tree
|
||||||
writeArray("arrayMetadata", () => {
|
writeArray("arrayMetadata", () => {
|
||||||
if (model.Package.Version >= 24.2) {
|
if (model.Package.Version >= MetadataVersions.V242) {
|
||||||
writeObject(() => writeTypedArray(binary.CodeRegistration.pcodeGenModules, binary.Modules.Count, "struct Il2CppCodeGenModule *", "g_CodeGenModules"));
|
writeObject(() => writeTypedArray(binary.CodeRegistration.pcodeGenModules, binary.Modules.Count, "struct Il2CppCodeGenModule *", "g_CodeGenModules"));
|
||||||
}
|
}
|
||||||
}, "IL2CPP Array Metadata");
|
}, "IL2CPP Array Metadata");
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
All rights reserved.
|
All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using Il2CppInspector.Next;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -88,10 +89,10 @@ namespace Il2CppInspector.Reflection
|
|||||||
var pkg = asm.Model.Package;
|
var pkg = asm.Model.Package;
|
||||||
|
|
||||||
// Attribute type ranges weren't included before v21 (customASttributeGenerators was though)
|
// Attribute type ranges weren't included before v21 (customASttributeGenerators was though)
|
||||||
if (pkg.Version < 21)
|
if (pkg.Version < MetadataVersions.V210)
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
if (pkg.Version < 29)
|
if (pkg.Version < MetadataVersions.V290)
|
||||||
{
|
{
|
||||||
var range = pkg.AttributeTypeRanges[customAttributeIndex];
|
var range = pkg.AttributeTypeRanges[customAttributeIndex];
|
||||||
for (var i = range.start; i < range.start + range.count; i++)
|
for (var i = range.start; i < range.start + range.count; i++)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
All rights reserved.
|
All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using Il2CppInspector.Next;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -214,7 +215,7 @@ namespace Il2CppInspector.Reflection
|
|||||||
|
|
||||||
// Get generic type definition
|
// Get generic type definition
|
||||||
TypeInfo genericTypeDef;
|
TypeInfo genericTypeDef;
|
||||||
if (Package.Version < 27) {
|
if (Package.Version < MetadataVersions.V270) {
|
||||||
// It appears that TypeRef can be -1 if the generic depth recursion limit
|
// It appears that TypeRef can be -1 if the generic depth recursion limit
|
||||||
// (--maximum-recursive-generic-depth=) is reached in Il2Cpp. In this case,
|
// (--maximum-recursive-generic-depth=) is reached in Il2Cpp. In this case,
|
||||||
// no generic instance type is generated, so we just produce a null TypeInfo here.
|
// no generic instance type is generated, so we just produce a null TypeInfo here.
|
||||||
@@ -318,7 +319,7 @@ namespace Il2CppInspector.Reflection
|
|||||||
// The attribute index is an index into AttributeTypeRanges, each of which is a start-end range index into AttributeTypeIndices, each of which is a TypeIndex
|
// The attribute index is an index into AttributeTypeRanges, each of which is a start-end range index into AttributeTypeIndices, each of which is a TypeIndex
|
||||||
public int GetCustomAttributeIndex(Assembly asm, int token, int customAttributeIndex) {
|
public int GetCustomAttributeIndex(Assembly asm, int token, int customAttributeIndex) {
|
||||||
// Prior to v24.1, Type, Field, Parameter, Method, Event, Property, Assembly definitions had their own customAttributeIndex field
|
// Prior to v24.1, Type, Field, Parameter, Method, Event, Property, Assembly definitions had their own customAttributeIndex field
|
||||||
if (Package.Version <= 24.0)
|
if (Package.Version <= MetadataVersions.V240)
|
||||||
return customAttributeIndex;
|
return customAttributeIndex;
|
||||||
|
|
||||||
// From v24.1 onwards, token was added to Il2CppCustomAttributeTypeRange and each Il2CppImageDefinition noted the CustomAttributeTypeRanges for the image
|
// From v24.1 onwards, token was added to Il2CppCustomAttributeTypeRange and each Il2CppImageDefinition noted the CustomAttributeTypeRanges for the image
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Text;
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using Il2CppInspector.Next;
|
||||||
|
|
||||||
namespace Il2CppInspector.Utils;
|
namespace Il2CppInspector.Utils;
|
||||||
|
|
||||||
@@ -111,7 +112,7 @@ public static class BlobReader
|
|||||||
|
|
||||||
int ReadInt32()
|
int ReadInt32()
|
||||||
{
|
{
|
||||||
if (blob.Version >= 29)
|
if (blob.Version >= MetadataVersions.V290)
|
||||||
{
|
{
|
||||||
var address = blob.Position;
|
var address = blob.Position;
|
||||||
|
|
||||||
@@ -131,7 +132,7 @@ public static class BlobReader
|
|||||||
|
|
||||||
uint ReadUInt32()
|
uint ReadUInt32()
|
||||||
{
|
{
|
||||||
if (blob.Version >= 29)
|
if (blob.Version >= MetadataVersions.V290)
|
||||||
{
|
{
|
||||||
var address = blob.Position;
|
var address = blob.Position;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ public readonly struct StructVersion(int major = 0, int minor = 0, string? tag =
|
|||||||
public readonly int Minor = minor;
|
public readonly int Minor = minor;
|
||||||
public readonly string? Tag = tag;
|
public readonly string? Tag = tag;
|
||||||
|
|
||||||
|
public double AsDouble => Major + Minor / 10.0;
|
||||||
|
|
||||||
#region Equality operators
|
#region Equality operators
|
||||||
|
|
||||||
public static bool operator ==(StructVersion left, StructVersion right)
|
public static bool operator ==(StructVersion left, StructVersion right)
|
||||||
@@ -42,9 +44,17 @@ public readonly struct StructVersion(int major = 0, int minor = 0, string? tag =
|
|||||||
public static implicit operator StructVersion(string value)
|
public static implicit operator StructVersion(string value)
|
||||||
{
|
{
|
||||||
var versionParts = value.Split('.');
|
var versionParts = value.Split('.');
|
||||||
if (versionParts.Length is 1 or > 2)
|
if (versionParts.Length > 2)
|
||||||
throw new InvalidOperationException("Invalid version string.");
|
throw new InvalidOperationException("Invalid version string.");
|
||||||
|
|
||||||
|
if (versionParts.Length == 1)
|
||||||
|
{
|
||||||
|
if (!int.TryParse(versionParts[0], out var version))
|
||||||
|
throw new InvalidOperationException("Invalid single-number version string.");
|
||||||
|
|
||||||
|
return new StructVersion(version);
|
||||||
|
}
|
||||||
|
|
||||||
var tagParts = versionParts[1].Split("-");
|
var tagParts = versionParts[1].Split("-");
|
||||||
if (tagParts.Length > 2)
|
if (tagParts.Length > 2)
|
||||||
throw new InvalidOperationException("Invalid version string.");
|
throw new InvalidOperationException("Invalid version string.");
|
||||||
|
|||||||
Reference in New Issue
Block a user