From e5568d0dde3aa9b1da60a23ba3f8ace0abd249e9 Mon Sep 17 00:00:00 2001 From: Katy Coe Date: Fri, 20 Oct 2017 03:00:28 +0200 Subject: [PATCH] Support metadata v23 --- Bin2Object | 2 +- Il2CppInspector/Il2CppClasses.cs | 31 +++++++++++++++-- Il2CppInspector/Il2CppProcessor.cs | 2 +- Il2CppInspector/Il2CppReader.cs | 3 +- Il2CppInspector/Metadata.cs | 56 ++++++++++++++++-------------- Il2CppInspector/MetadataClass.cs | 29 ++++++++++++++-- 6 files changed, 88 insertions(+), 35 deletions(-) diff --git a/Bin2Object b/Bin2Object index aa9b6cf..d37491a 160000 --- a/Bin2Object +++ b/Bin2Object @@ -1 +1 @@ -Subproject commit aa9b6cfd3062178f669620e1fc86a79214b2e486 +Subproject commit d37491a83018289ffbeb2e73f14a25f88d124dcd diff --git a/Il2CppInspector/Il2CppClasses.cs b/Il2CppInspector/Il2CppClasses.cs index 575f643..51b74ef 100644 --- a/Il2CppInspector/Il2CppClasses.cs +++ b/Il2CppInspector/Il2CppClasses.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using NoisyCowStudios.Bin2Object; namespace Il2CppInspector { @@ -7,23 +8,49 @@ namespace Il2CppInspector { public uint methodPointersCount; public uint pmethodPointers; - public uint delegateWrappersFromNativeToManagedCount; - public uint delegateWrappersFromNativeToManaged; // note the double indirection to handle different calling conventions + public uint delegateWrappersFromNativeToManagedCount; // (was renamed to reversePInvokeWrapperCount in v22) + public uint delegateWrappersFromNativeToManaged; // (was renamed to reversePInvokeWrappers in v22) + + // Removed in metadata v23 + [Version(Max = 22)] public uint delegateWrappersFromManagedToNativeCount; + [Version(Max = 22)] public uint delegateWrappersFromManagedToNative; + [Version(Max = 22)] public uint marshalingFunctionsCount; + [Version(Max = 22)] public uint marshalingFunctions; + [Version(Max = 22)] public uint ccwMarshalingFunctionsCount; + [Version(Max = 22)] public uint ccwMarshalingFunctions; + public uint genericMethodPointersCount; public uint genericMethodPointers; public uint invokerPointersCount; public uint invokerPointers; public int customAttributeCount; public uint customAttributeGenerators; + + // Removed in metadata v23 + [Version(Max = 22)] public int guidCount; + [Version(Max = 22)] public uint guids; // Il2CppGuid + // Added in metadata v22 + [Version(Min = 22)] + public uint unresolvedVirtualCallCount; + [Version(Min = 22)] + public uint unresolvedVirtualCallPointers; + + // Added in metadata v23 + [Version(Min = 23)] + public uint interopDataCount; + [Version(Min = 23)] + public uint interopData; + + // Properties public uint[] methodPointers { get; set; diff --git a/Il2CppInspector/Il2CppProcessor.cs b/Il2CppInspector/Il2CppProcessor.cs index fde5119..7a5b7f2 100644 --- a/Il2CppInspector/Il2CppProcessor.cs +++ b/Il2CppInspector/Il2CppProcessor.cs @@ -55,7 +55,7 @@ namespace Il2CppInspector } // Find code and metadata regions - if (!il2cpp.Load()) { + if (!il2cpp.Load(metadata.Version)) { Console.Error.WriteLine("Could not process IL2CPP image"); return null; } diff --git a/Il2CppInspector/Il2CppReader.cs b/Il2CppInspector/Il2CppReader.cs index ee2c1db..2a153b1 100644 --- a/Il2CppInspector/Il2CppReader.cs +++ b/Il2CppInspector/Il2CppReader.cs @@ -27,7 +27,8 @@ namespace Il2CppInspector protected abstract (uint, uint) Search(uint loc, uint globalOffset); // Check all search locations - public bool Load() { + public bool Load(int version) { + Image.Stream.Version = version; var addrs = Image.GetSearchLocations(); foreach (var loc in addrs) if (loc != 0) { diff --git a/Il2CppInspector/Metadata.cs b/Il2CppInspector/Metadata.cs index d04b9a4..00591b2 100644 --- a/Il2CppInspector/Metadata.cs +++ b/Il2CppInspector/Metadata.cs @@ -28,32 +28,37 @@ namespace Il2CppInspector public string GetTypeNamespace(Il2CppTypeDefinition type) => GetString(type.namespaceIndex); public string GetTypeName(Il2CppTypeDefinition type) => GetString(type.nameIndex); - - public Metadata(Stream stream) : base(stream) { - pMetadataHdr = ReadObject(); - if (pMetadataHdr.sanity != 0xFAB11BAF) - { + // Read magic bytes + if (ReadUInt32() != 0xFAB11BAF) { throw new Exception("ERROR: Metadata file supplied is not valid metadata file."); } - if (pMetadataHdr.version != 21 && pMetadataHdr.version != 22) + + // Set object versioning for Bin2Object from metadata version + Version = ReadInt32(); + + // Rewind and read metadata header in full + Position -= 8; + pMetadataHdr = ReadObject(); + 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 / MySizeOf(typeof(Il2CppImageDefinition)); - var uiNumTypes = pMetadataHdr.typeDefinitionsCount / MySizeOf(typeof(Il2CppTypeDefinition)); + + var uiImageCount = pMetadataHdr.imagesCount / Sizeof(typeof(Il2CppImageDefinition)); + var uiNumTypes = pMetadataHdr.typeDefinitionsCount / Sizeof(typeof(Il2CppTypeDefinition)); Images = ReadArray(pMetadataHdr.imagesOffset, uiImageCount); //GetTypeDefFromIndex Types = ReadArray(pMetadataHdr.typeDefinitionsOffset, uiNumTypes); //GetMethodDefinition - Methods = ReadArray(pMetadataHdr.methodsOffset, pMetadataHdr.methodsCount / MySizeOf(typeof(Il2CppMethodDefinition))); + Methods = ReadArray(pMetadataHdr.methodsOffset, pMetadataHdr.methodsCount / Sizeof(typeof(Il2CppMethodDefinition))); //GetParameterFromIndex - parameterDefs = ReadArray(pMetadataHdr.parametersOffset, pMetadataHdr.parametersCount / MySizeOf(typeof(Il2CppParameterDefinition))); + parameterDefs = ReadArray(pMetadataHdr.parametersOffset, pMetadataHdr.parametersCount / Sizeof(typeof(Il2CppParameterDefinition))); //GetFieldDefFromIndex - Fields = ReadArray(pMetadataHdr.fieldsOffset, pMetadataHdr.fieldsCount / MySizeOf(typeof(Il2CppFieldDefinition))); + Fields = ReadArray(pMetadataHdr.fieldsOffset, pMetadataHdr.fieldsCount / Sizeof(typeof(Il2CppFieldDefinition))); //GetFieldDefaultFromIndex - fieldDefaultValues = ReadArray(pMetadataHdr.fieldDefaultValuesOffset, pMetadataHdr.fieldDefaultValuesCount / MySizeOf(typeof(Il2CppFieldDefaultValue))); + fieldDefaultValues = ReadArray(pMetadataHdr.fieldDefaultValuesOffset, pMetadataHdr.fieldDefaultValuesCount / Sizeof(typeof(Il2CppFieldDefaultValue))); } public Il2CppFieldDefaultValue GetFieldDefaultFromIndex(int idx) @@ -71,27 +76,24 @@ namespace Il2CppInspector return ReadNullTerminatedString(pMetadataHdr.stringOffset + idx); } - private int MySizeOf(Type type) + private int Sizeof(Type type) { int size = 0; foreach (var i in type.GetTypeInfo().GetFields()) { - if (i.FieldType == typeof(int)) - { + // Only process fields for our selected object versioning + var versionAttr = i.GetCustomAttribute(false); + if (versionAttr != null) { + if (versionAttr.Min != -1 && versionAttr.Min > Version) + continue; + if (versionAttr.Max != -1 && versionAttr.Max < Version) + continue; + } + + if (i.FieldType == typeof(int) || i.FieldType == typeof(uint)) size += 4; - } - else if (i.FieldType == typeof(uint)) - { - size += 4; - } - else if (i.FieldType == typeof(short)) - { + if (i.FieldType == typeof(short) || i.FieldType == typeof(ushort)) size += 2; - } - else if (i.FieldType == typeof(ushort)) - { - size += 2; - } } return size; } diff --git a/Il2CppInspector/MetadataClass.cs b/Il2CppInspector/MetadataClass.cs index a840f92..1fdea61 100644 --- a/Il2CppInspector/MetadataClass.cs +++ b/Il2CppInspector/MetadataClass.cs @@ -2,12 +2,14 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using NoisyCowStudios.Bin2Object; namespace Il2CppInspector { #pragma warning disable CS0649 public class Il2CppGlobalMetadataHeader { + // Metadata v21 public uint sanity; public int version; public int stringLiteralOffset; // string data for managed code @@ -68,6 +70,22 @@ namespace Il2CppInspector public int attributesInfoCount; public int attributeTypesOffset; // TypeIndex public int attributeTypesCount; + + // Added in metadata v22 + [Version(Min = 22)] + public int unresolvedVirtualCallParameterTypesOffset; // TypeIndex + [Version(Min = 22)] + public int unresolvedVirtualCallParameterTypesCount; + [Version(Min = 22)] + public int unresolvedVirtualCallParameterRangesOffset; // Il2CppRange + [Version(Min = 22)] + public int unresolvedVirtualCallParameterRangesCount; + + // Added in metadata v23 + [Version(Min = 23)] + public int windowsRuntimeTypeNamesOffset; // Il2CppWindowsRuntimeTypeNamePair + [Version(Min = 23)] + public int windowsRuntimeTypeNamesSize; } public class Il2CppImageDefinition @@ -100,9 +118,14 @@ namespace Il2CppInspector public int genericContainerIndex; - public int delegateWrapperFromManagedToNativeIndex; + // Removed in metadata v23 + [Version(Max = 22)] + public int delegateWrapperFromManagedToNativeIndex; // (was renamed to reversePInvokeWrapperIndex in v22) + [Version(Max = 22)] public int marshalingFunctionsIndex; + [Version(Max = 22)] public int ccwFunctionIndex; + [Version(Max = 22)] public int guidIndex; public uint flags; @@ -131,7 +154,7 @@ namespace Il2CppInspector // 03 - has_finalize; // 04 - has_cctor; // 05 - is_blittable; - // 06 - is_import; + // 06 - is_import; (from v22: is_import_or_windows_runtime) // 07-10 - One of nine possible PackingSize values (0, 1, 2, 4, 8, 16, 32, 64, or 128) public uint bitfield; public uint token; @@ -147,7 +170,7 @@ namespace Il2CppInspector public int genericContainerIndex; public int methodIndex; public int invokerIndex; - public int delegateWrapperIndex; + public int delegateWrapperIndex; // (was renamed to reversePInvokeWrapperIndex in v22) public int rgctxStartIndex; public int rgctxCount; public uint token;