diff --git a/Il2CppInspector/IL2CPP/Il2CppBinary.cs b/Il2CppInspector/IL2CPP/Il2CppBinary.cs index 372014b..de0f617 100644 --- a/Il2CppInspector/IL2CPP/Il2CppBinary.cs +++ b/Il2CppInspector/IL2CPP/Il2CppBinary.cs @@ -56,6 +56,9 @@ namespace Il2CppInspector // List of constructed generic method function pointers corresponding to each possible method instantiation public Dictionary GenericMethodPointers { get; } = new Dictionary(); + // List of invoker pointers for concrete generic methods from MethodSpecs (as above) + public Dictionary GenericMethodInvokerIndices { get; } = new Dictionary(); + // Every type reference (TypeRef) sorted by index public List TypeReferences { get; private set; } @@ -235,6 +238,7 @@ namespace Il2CppInspector var genericMethodTable = image.ReadMappedArray(MetadataRegistration.genericMethodTable, (int) MetadataRegistration.genericMethodTableCount); foreach (var tableEntry in genericMethodTable) { GenericMethodPointers.Add(MethodSpecs[tableEntry.genericMethodIndex], genericMethodPointers[tableEntry.indices.methodIndex]); + GenericMethodInvokerIndices.Add(MethodSpecs[tableEntry.genericMethodIndex], tableEntry.indices.invokerIndex); } } } diff --git a/Il2CppInspector/IL2CPP/Il2CppInspector.cs b/Il2CppInspector/IL2CPP/Il2CppInspector.cs index 3298553..3a4a3d8 100644 --- a/Il2CppInspector/IL2CPP/Il2CppInspector.cs +++ b/Il2CppInspector/IL2CPP/Il2CppInspector.cs @@ -62,6 +62,7 @@ namespace Il2CppInspector public ulong[] MethodInvokePointers => Binary.MethodInvokePointers; public Il2CppMethodSpec[] MethodSpecs => Binary.MethodSpecs; public Dictionary GenericMethodPointers => Binary.GenericMethodPointers; + public Dictionary GenericMethodInvokerIndices => Binary.GenericMethodInvokerIndices; // TODO: Finish all file access in the constructor and eliminate the need for this public IFileFormatReader BinaryImage => Binary.Image; diff --git a/Il2CppInspector/Reflection/Il2CppModel.cs b/Il2CppInspector/Reflection/Il2CppModel.cs index bf9e2b8..7c9f1aa 100644 --- a/Il2CppInspector/Reflection/Il2CppModel.cs +++ b/Il2CppInspector/Reflection/Il2CppModel.cs @@ -110,11 +110,22 @@ namespace Il2CppInspector.Reflection var index = package.GetInvokerIndex(method.DeclaringType.Assembly.ModuleDefinition, method.Definition); if (index != -1) { if (MethodInvokers[index] == null) - MethodInvokers[index] = new MethodInvoker(method); + MethodInvokers[index] = new MethodInvoker(method, index); method.Invoker = MethodInvokers[index]; } } + + // TODO: Some invokers are not initialized or missing, need to find out why + // Create method invokers sourced from generic method invoker indices + foreach (var spec in GenericMethods.Keys) { + if (package.GenericMethodInvokerIndices.TryGetValue(spec, out var index)) { + if (MethodInvokers[index] == null) + MethodInvokers[index] = new MethodInvoker(GenericMethods[spec], index); + + GenericMethods[spec].Invoker = MethodInvokers[index]; + } + } } // Get generic arguments from either a type or method instanceIndex from a MethodSpec diff --git a/Il2CppInspector/Reflection/MethodInvoker.cs b/Il2CppInspector/Reflection/MethodInvoker.cs index 0ccba08..45c4967 100644 --- a/Il2CppInspector/Reflection/MethodInvoker.cs +++ b/Il2CppInspector/Reflection/MethodInvoker.cs @@ -33,11 +33,11 @@ namespace Il2CppInspector.Reflection public TypeInfo[] ParameterTypes { get; } // Find the correct method invoker for a method with a specific signature - public MethodInvoker(MethodBase exampleMethod) { + public MethodInvoker(MethodBase exampleMethod, int index) { var model = exampleMethod.Assembly.Model; var package = exampleMethod.Assembly.Model.Package; - Index = package.GetInvokerIndex(exampleMethod.DeclaringType.Assembly.ModuleDefinition, exampleMethod.Definition); + Index = index; IsStatic = exampleMethod.IsStatic; ReturnType = exampleMethod.IsConstructor ? model.TypesByFullName["System.Void"] : mapParameterType(model, ((MethodInfo) exampleMethod).ReturnType);