From f7eb9395a5cae60f22994210071086f13862265b Mon Sep 17 00:00:00 2001 From: Katy Coe Date: Tue, 29 Oct 2019 20:53:22 +0100 Subject: [PATCH] Move method pointer logic from Model to Inspector --- Il2CppInspector/Il2CppInspector.cs | 30 +++++++++++++++++++++++- Il2CppInspector/Reflection/Assembly.cs | 3 +-- Il2CppInspector/Reflection/MethodBase.cs | 27 ++------------------- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/Il2CppInspector/Il2CppInspector.cs b/Il2CppInspector/Il2CppInspector.cs index d8dbe23..6e98b4b 100644 --- a/Il2CppInspector/Il2CppInspector.cs +++ b/Il2CppInspector/Il2CppInspector.cs @@ -35,7 +35,6 @@ namespace Il2CppInspector public List FieldOffsets { get; } public List TypeUsages => Binary.Types; public Dictionary Modules => Binary.Modules; - public ulong[] GlobalMethodPointers => Binary.GlobalMethodPointers; // <=v24.1 only // TODO: Finish all file access in the constructor and eliminate the need for this public IFileFormatReader BinaryImage => Binary.Image; @@ -141,6 +140,35 @@ namespace Il2CppInspector } } + public ulong GetMethodPointer(Il2CppCodeGenModule module, Il2CppMethodDefinition methodDef) { + // Find method pointer + if (methodDef.methodIndex < 0) + return 0; + + // Global method pointer array + if (Version <= 24.1) { + return Binary.GlobalMethodPointers[methodDef.methodIndex] & 0xffff_ffff_ffff_fffe; + } + + // Per-module method pointer array uses the bottom 24 bits of the method's metadata token + // Derived from il2cpp::vm::MetadataCache::GetMethodPointer + var method = (methodDef.token & 0xffffff); + if (method == 0) + return 0; + + // In the event of an exception, the method pointer is not set in the file + // This probably means it has been optimized away by the compiler, or is an unused generic method + try { + BinaryImage.Position = BinaryImage.MapVATR(module.methodPointers + (ulong)((method - 1) * (BinaryImage.Bits / 8))); + + // Remove ARM Thumb marker LSB if necessary + return (ulong) BinaryImage.ReadWord() & 0xffff_ffff_ffff_fffe; + } + catch (Exception) { } + + return 0; + } + public static List LoadFromFile(string codeFile, string metadataFile) { // Load the metadata file Metadata metadata; diff --git a/Il2CppInspector/Reflection/Assembly.cs b/Il2CppInspector/Reflection/Assembly.cs index e58fefa..2760a76 100644 --- a/Il2CppInspector/Reflection/Assembly.cs +++ b/Il2CppInspector/Reflection/Assembly.cs @@ -43,8 +43,7 @@ namespace Il2CppInspector.Reflection { } // Find corresponding module (we'll need this for method pointers) - if (Model.Package.Version >= 24.2) - Module = Model.Package.Modules[FullName]; + Module = Model.Package.Modules?[FullName]; // Generate types in DefinedTypes from typeStart to typeStart+typeCount-1 for (var t = Definition.typeStart; t < Definition.typeStart + Definition.typeCount; t++) { diff --git a/Il2CppInspector/Reflection/MethodBase.cs b/Il2CppInspector/Reflection/MethodBase.cs index 9c0bc71..d435e59 100644 --- a/Il2CppInspector/Reflection/MethodBase.cs +++ b/Il2CppInspector/Reflection/MethodBase.cs @@ -52,32 +52,9 @@ namespace Il2CppInspector.Reflection Name = pkg.Strings[Definition.nameIndex]; // Find method pointer - if (Definition.methodIndex >= 0) { - - // Global method pointer array - if (pkg.Version <= 24.1) { - VirtualAddress = pkg.GlobalMethodPointers[Definition.methodIndex]; - } - - // Per-module method pointer array uses the bottom 24 bits of the method's metadata token - // Derived from il2cpp::vm::MetadataCache::GetMethodPointer - else { - var method = (Definition.token & 0xffffff); - if (method != 0) { - // In the event of an exception, the method pointer is not set in the file - // This probably means it has been optimized away by the compiler, or is an unused generic method - try { - pkg.BinaryImage.Position = pkg.BinaryImage.MapVATR(Assembly.Module.methodPointers + (ulong)((method - 1) * (pkg.BinaryImage.Bits / 8))); - VirtualAddress = (ulong)pkg.BinaryImage.ReadWord(); - } - catch (Exception) { } - } - } - - // Remove ARM Thumb marker LSB if necessary - VirtualAddress &= 0xffff_ffff_ffff_fffe; - } + VirtualAddress = pkg.GetMethodPointer(Assembly.Module, Definition); + // Set method attributes if ((Definition.flags & Il2CppConstants.METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == Il2CppConstants.METHOD_ATTRIBUTE_PRIVATE) Attributes |= MethodAttributes.Private; if ((Definition.flags & Il2CppConstants.METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == Il2CppConstants.METHOD_ATTRIBUTE_PUBLIC)