IL2CPP/Model: Handle invokers from Il2CppGenericMethodFunctionsDefinitions

This commit is contained in:
Katy Coe
2020-02-05 05:21:02 +01:00
parent 896b3b6f69
commit ee97261242
4 changed files with 19 additions and 3 deletions

View File

@@ -56,6 +56,9 @@ namespace Il2CppInspector
// List of constructed generic method function pointers corresponding to each possible method instantiation // List of constructed generic method function pointers corresponding to each possible method instantiation
public Dictionary<Il2CppMethodSpec, ulong> GenericMethodPointers { get; } = new Dictionary<Il2CppMethodSpec, ulong>(); public Dictionary<Il2CppMethodSpec, ulong> GenericMethodPointers { get; } = new Dictionary<Il2CppMethodSpec, ulong>();
// List of invoker pointers for concrete generic methods from MethodSpecs (as above)
public Dictionary<Il2CppMethodSpec, int> GenericMethodInvokerIndices { get; } = new Dictionary<Il2CppMethodSpec, int>();
// Every type reference (TypeRef) sorted by index // Every type reference (TypeRef) sorted by index
public List<Il2CppType> TypeReferences { get; private set; } public List<Il2CppType> TypeReferences { get; private set; }
@@ -235,6 +238,7 @@ namespace Il2CppInspector
var genericMethodTable = image.ReadMappedArray<Il2CppGenericMethodFunctionsDefinitions>(MetadataRegistration.genericMethodTable, (int) MetadataRegistration.genericMethodTableCount); var genericMethodTable = image.ReadMappedArray<Il2CppGenericMethodFunctionsDefinitions>(MetadataRegistration.genericMethodTable, (int) MetadataRegistration.genericMethodTableCount);
foreach (var tableEntry in genericMethodTable) { foreach (var tableEntry in genericMethodTable) {
GenericMethodPointers.Add(MethodSpecs[tableEntry.genericMethodIndex], genericMethodPointers[tableEntry.indices.methodIndex]); GenericMethodPointers.Add(MethodSpecs[tableEntry.genericMethodIndex], genericMethodPointers[tableEntry.indices.methodIndex]);
GenericMethodInvokerIndices.Add(MethodSpecs[tableEntry.genericMethodIndex], tableEntry.indices.invokerIndex);
} }
} }
} }

View File

@@ -62,6 +62,7 @@ namespace Il2CppInspector
public ulong[] MethodInvokePointers => Binary.MethodInvokePointers; public ulong[] MethodInvokePointers => Binary.MethodInvokePointers;
public Il2CppMethodSpec[] MethodSpecs => Binary.MethodSpecs; public Il2CppMethodSpec[] MethodSpecs => Binary.MethodSpecs;
public Dictionary<Il2CppMethodSpec, ulong> GenericMethodPointers => Binary.GenericMethodPointers; public Dictionary<Il2CppMethodSpec, ulong> GenericMethodPointers => Binary.GenericMethodPointers;
public Dictionary<Il2CppMethodSpec, int> GenericMethodInvokerIndices => Binary.GenericMethodInvokerIndices;
// TODO: Finish all file access in the constructor and eliminate the need for this // TODO: Finish all file access in the constructor and eliminate the need for this
public IFileFormatReader BinaryImage => Binary.Image; public IFileFormatReader BinaryImage => Binary.Image;

View File

@@ -110,11 +110,22 @@ namespace Il2CppInspector.Reflection
var index = package.GetInvokerIndex(method.DeclaringType.Assembly.ModuleDefinition, method.Definition); var index = package.GetInvokerIndex(method.DeclaringType.Assembly.ModuleDefinition, method.Definition);
if (index != -1) { if (index != -1) {
if (MethodInvokers[index] == null) if (MethodInvokers[index] == null)
MethodInvokers[index] = new MethodInvoker(method); MethodInvokers[index] = new MethodInvoker(method, index);
method.Invoker = MethodInvokers[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 // Get generic arguments from either a type or method instanceIndex from a MethodSpec

View File

@@ -33,11 +33,11 @@ namespace Il2CppInspector.Reflection
public TypeInfo[] ParameterTypes { get; } public TypeInfo[] ParameterTypes { get; }
// Find the correct method invoker for a method with a specific signature // 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 model = exampleMethod.Assembly.Model;
var package = exampleMethod.Assembly.Model.Package; var package = exampleMethod.Assembly.Model.Package;
Index = package.GetInvokerIndex(exampleMethod.DeclaringType.Assembly.ModuleDefinition, exampleMethod.Definition); Index = index;
IsStatic = exampleMethod.IsStatic; IsStatic = exampleMethod.IsStatic;
ReturnType = exampleMethod.IsConstructor ? model.TypesByFullName["System.Void"] : mapParameterType(model, ((MethodInfo) exampleMethod).ReturnType); ReturnType = exampleMethod.IsConstructor ? model.TypesByFullName["System.Void"] : mapParameterType(model, ((MethodInfo) exampleMethod).ReturnType);