From 5f7218f7df0b549d395cc4506b618a07cd507a28 Mon Sep 17 00:00:00 2001 From: Katy Coe Date: Sun, 16 Aug 2020 02:35:33 +0200 Subject: [PATCH] IL2CPP: Encoded tokens in metadata v27 must be shifted right 1 bit --- .../IL2CPP/Il2CppInspector.cs | 18 +++++++++++++++--- Il2CppInspector.Common/IL2CPP/MetadataUsage.cs | 4 ++++ Il2CppInspector.Common/Model/AppModel.cs | 4 ++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Il2CppInspector.Common/IL2CPP/Il2CppInspector.cs b/Il2CppInspector.Common/IL2CPP/Il2CppInspector.cs index 88398ee..36d4c6f 100644 --- a/Il2CppInspector.Common/IL2CPP/Il2CppInspector.cs +++ b/Il2CppInspector.Common/IL2CPP/Il2CppInspector.cs @@ -127,9 +127,17 @@ namespace Il2CppInspector return ((ulong) pValue, value); } - // TODO: The resolution of metadata usages is broken for metadata v27 (MetadataUsageLists, MetadataUsagePairs no longer exist) private List buildMetadataUsages() { + // No metadata usages for versions < 19 + if (Version < 19) + return null; + + // Metadata usages are lazily initialized during runtime for versions >= 27 + if (Version >= 27) + return buildLateBindingMetadataUsages(); + + // Version >= 19 && <= 24.3 var usages = new Dictionary(); foreach (var metadataUsageList in Metadata.MetadataUsageLists) { @@ -150,6 +158,11 @@ namespace Il2CppInspector return usages.Values.ToList(); } + public List buildLateBindingMetadataUsages() { + // TODO: Resolve late binding for metadata v27 + return null; + } + public Il2CppInspector(Il2CppBinary binary, Metadata metadata) { // Store stream representations Binary = binary; @@ -243,8 +256,7 @@ namespace Il2CppInspector } // Merge all metadata usage references into a single distinct list - if (Version >= 19) - MetadataUsages = buildMetadataUsages(); + MetadataUsages = buildMetadataUsages(); } // Get a method pointer if available diff --git a/Il2CppInspector.Common/IL2CPP/MetadataUsage.cs b/Il2CppInspector.Common/IL2CPP/MetadataUsage.cs index 17c1d27..7b1bb7f 100644 --- a/Il2CppInspector.Common/IL2CPP/MetadataUsage.cs +++ b/Il2CppInspector.Common/IL2CPP/MetadataUsage.cs @@ -42,6 +42,10 @@ namespace Il2CppInspector var encodedType = encodedIndex & 0xE0000000; usageType = (MetadataUsageType)(encodedType >> 29); 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 + if (package.Version >= 27) + index >>= 1; } return new MetadataUsage(usageType, (int)index); } diff --git a/Il2CppInspector.Common/Model/AppModel.cs b/Il2CppInspector.Common/Model/AppModel.cs index 681cdbd..4d0ceb6 100644 --- a/Il2CppInspector.Common/Model/AppModel.cs +++ b/Il2CppInspector.Common/Model/AppModel.cs @@ -51,7 +51,7 @@ namespace Il2CppInspector.Model // For il2cpp < 19, the key is the string literal ordinal instead of the address public Dictionary Strings { get; } = new Dictionary(); - public bool StringIndexesAreOrdinals => Package.MetadataUsages == null; + public bool StringIndexesAreOrdinals => Package.Version < 19; // The .NET type model for the application public TypeModel TypeModel { get; } @@ -239,7 +239,7 @@ namespace Il2CppInspector.Model } // Add string literals for metadata <19 to the model - else { + if (Package.Version < 19) { /* Version < 19 calls `il2cpp_codegen_string_literal_from_index` to get string literals. * 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. */