Add support for parsing and interpreting VTables
This prepares for a future PR where we add types to the IDA script output.
This commit is contained in:
@@ -53,6 +53,9 @@ namespace Il2CppInspector
|
|||||||
// One invoker specifies a return type and argument list. Multiple methods with the same signature can be invoked with the same invoker
|
// One invoker specifies a return type and argument list. Multiple methods with the same signature can be invoked with the same invoker
|
||||||
public ulong[] MethodInvokePointers { get; private set; }
|
public ulong[] MethodInvokePointers { get; private set; }
|
||||||
|
|
||||||
|
// Version 16 and below: method references for vtable
|
||||||
|
public uint[] VTableMethodReferences { get; private set; }
|
||||||
|
|
||||||
// Generic method specs for vtables
|
// Generic method specs for vtables
|
||||||
public Il2CppMethodSpec[] MethodSpecs { get; private set; }
|
public Il2CppMethodSpec[] MethodSpecs { get; private set; }
|
||||||
|
|
||||||
@@ -245,6 +248,10 @@ namespace Il2CppInspector
|
|||||||
// >=22: unresolvedVirtualCallPointers
|
// >=22: unresolvedVirtualCallPointers
|
||||||
// >=23: interopData
|
// >=23: interopData
|
||||||
|
|
||||||
|
if (Image.Version < 19) {
|
||||||
|
VTableMethodReferences = image.ReadMappedArray<uint>(MetadataRegistration.methodReferences, (int)MetadataRegistration.methodReferencesCount);
|
||||||
|
}
|
||||||
|
|
||||||
// Generic type and method specs (open and closed constructed types)
|
// Generic type and method specs (open and closed constructed types)
|
||||||
MethodSpecs = image.ReadMappedArray<Il2CppMethodSpec>(MetadataRegistration.methodSpecs, (int) MetadataRegistration.methodSpecsCount);
|
MethodSpecs = image.ReadMappedArray<Il2CppMethodSpec>(MetadataRegistration.methodSpecs, (int) MetadataRegistration.methodSpecsCount);
|
||||||
|
|
||||||
|
|||||||
@@ -294,6 +294,27 @@ namespace Il2CppInspector
|
|||||||
return Binary.MethodInvokerIndices[module][methodInModule - 1];
|
return Binary.MethodInvokerIndices[module][methodInModule - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MetadataUsage[] GetVTable(Il2CppTypeDefinition definition) {
|
||||||
|
MetadataUsage[] res = new MetadataUsage[definition.vtable_count];
|
||||||
|
for (int i = 0; i < definition.vtable_count; i++) {
|
||||||
|
var encodedIndex = VTableMethodIndices[definition.vtableStart + i];
|
||||||
|
uint index;
|
||||||
|
MetadataUsageType usageType;
|
||||||
|
if (Version < 19) {
|
||||||
|
var flag = encodedIndex & 0x80000000;
|
||||||
|
index = Binary.VTableMethodReferences[encodedIndex & 0x7FFFFFFF];
|
||||||
|
usageType = (flag != 0) ? MetadataUsageType.MethodRef : MetadataUsageType.MethodDef;
|
||||||
|
} else {
|
||||||
|
var encodedType = encodedIndex & 0xE0000000;
|
||||||
|
usageType = (MetadataUsageType)(encodedType >> 29);
|
||||||
|
index = encodedIndex & 0x1FFFFFFF;
|
||||||
|
}
|
||||||
|
if (index != 0)
|
||||||
|
res[i] = new MetadataUsage(usageType, (int)index, i);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
public static List<Il2CppInspector> LoadFromFile(string codeFile, string metadataFile) {
|
public static List<Il2CppInspector> LoadFromFile(string codeFile, string metadataFile) {
|
||||||
// Load the metadata file
|
// Load the metadata file
|
||||||
Metadata metadata;
|
Metadata metadata;
|
||||||
|
|||||||
@@ -133,6 +133,18 @@ namespace Il2CppInspector.Reflection {
|
|||||||
// Get a property by its name
|
// Get a property by its name
|
||||||
public PropertyInfo GetProperty(string name) => DeclaredProperties.FirstOrDefault(p => p.Name == name);
|
public PropertyInfo GetProperty(string name) => DeclaredProperties.FirstOrDefault(p => p.Name == name);
|
||||||
|
|
||||||
|
public MethodBase[] GetVTable() {
|
||||||
|
var definition = Definition;
|
||||||
|
|
||||||
|
MetadataUsage[] vt = Assembly.Model.Package.GetVTable(definition);
|
||||||
|
MethodBase[] res = new MethodBase[vt.Length];
|
||||||
|
for (int i = 0; i < vt.Length; i++) {
|
||||||
|
if (vt[i] != null)
|
||||||
|
res[i] = Assembly.Model.GetMetadataUsageMethod(vt[i]);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
// Method that the type is declared in if this is a type parameter of a generic method
|
// Method that the type is declared in if this is a type parameter of a generic method
|
||||||
// TODO: Make a unit test from this: https://docs.microsoft.com/en-us/dotnet/api/system.type.declaringmethod?view=netframework-4.8
|
// TODO: Make a unit test from this: https://docs.microsoft.com/en-us/dotnet/api/system.type.declaringmethod?view=netframework-4.8
|
||||||
public MethodBase DeclaringMethod;
|
public MethodBase DeclaringMethod;
|
||||||
|
|||||||
Reference in New Issue
Block a user