support auto-recovering type indices from type handles

fixes loading of memory-dumped v29+ libraries since those replacee their class indices on load with a pointer to the corresponding type
This commit is contained in:
LukeFZ
2024-10-13 21:54:59 +02:00
parent 095bfa16e8
commit d59f67216a
2 changed files with 74 additions and 4 deletions

View File

@@ -6,15 +6,12 @@
*/
using Il2CppInspector.Next;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using Il2CppInspector.Next.BinaryMetadata;
using Il2CppInspector.Next.Metadata;
using VersionedSerialization;
namespace Il2CppInspector
@@ -370,6 +367,48 @@ namespace Il2CppInspector
TypeReferences = Image.ReadMappedVersionedObjectPointerArray<Il2CppType>(MetadataRegistration.Types, (int)MetadataRegistration.TypesCount);
if (TypeReferences.Any(x =>
x.Type.IsTypeDefinitionEnum()
&& (uint)x.Data.KlassIndex >= (uint)Metadata.Types.Length))
{
// This is a memory-dumped binary.
// We need to fix the remapped type indices from their pointer form back to the indices.
var baseDefinitionPtr = ulong.MaxValue;
var baseGenericPtr = ulong.MaxValue;
foreach (var entry in TypeReferences)
{
if (entry.Type.IsTypeDefinitionEnum())
{
baseDefinitionPtr = Math.Min(baseDefinitionPtr, entry.Data.Type.PointerValue);
}
else if (entry.Type.IsGenericParameterEnum())
{
baseGenericPtr = Math.Min(baseGenericPtr, entry.Data.GenericParameterHandle.PointerValue);
}
}
var definitionSize = (ulong)Il2CppTypeDefinition.Size(Image.Version);
var genericParameterSize = (ulong)Il2CppGenericParameter.Size(Image.Version);
var builder = ImmutableArray.CreateBuilder<Il2CppType>(TypeReferences.Length);
for (var i = 0; i < TypeReferences.Length; i++)
{
var type = TypeReferences[i];
if (type.Type.IsTypeDefinitionEnum())
{
type.Data.Value = (type.Data.Type.PointerValue - baseDefinitionPtr) / definitionSize;
}
else if (type.Type.IsGenericParameterEnum())
{
type.Data.Value = (type.Data.Type.PointerValue - baseGenericPtr) / genericParameterSize;
}
builder.Add(type);
}
TypeReferences = builder.MoveToImmutable();
}
// Custom attribute constructors (function pointers)
// This is managed in Il2CppInspector for metadata >= 27
if (Image.Version < MetadataVersions.V270) {

View File

@@ -43,3 +43,34 @@ public enum Il2CppTypeEnum : byte
IL2CPP_TYPE_ENUM = 0x55,
IL2CPP_TYPE_IL2CPP_TYPE_INDEX = 0xff
}
public static class Il2CppTypeEnumExtensions
{
public static bool IsTypeDefinitionEnum(this Il2CppTypeEnum value)
=> value
is Il2CppTypeEnum.IL2CPP_TYPE_VOID
or Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN
or Il2CppTypeEnum.IL2CPP_TYPE_CHAR
or Il2CppTypeEnum.IL2CPP_TYPE_I1
or Il2CppTypeEnum.IL2CPP_TYPE_U1
or Il2CppTypeEnum.IL2CPP_TYPE_I2
or Il2CppTypeEnum.IL2CPP_TYPE_U2
or Il2CppTypeEnum.IL2CPP_TYPE_I4
or Il2CppTypeEnum.IL2CPP_TYPE_U4
or Il2CppTypeEnum.IL2CPP_TYPE_I8
or Il2CppTypeEnum.IL2CPP_TYPE_U8
or Il2CppTypeEnum.IL2CPP_TYPE_R4
or Il2CppTypeEnum.IL2CPP_TYPE_R8
or Il2CppTypeEnum.IL2CPP_TYPE_STRING
or Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE
or Il2CppTypeEnum.IL2CPP_TYPE_CLASS
or Il2CppTypeEnum.IL2CPP_TYPE_I
or Il2CppTypeEnum.IL2CPP_TYPE_U
or Il2CppTypeEnum.IL2CPP_TYPE_OBJECT
or Il2CppTypeEnum.IL2CPP_TYPE_TYPEDBYREF;
public static bool IsGenericParameterEnum(this Il2CppTypeEnum value)
=> value
is Il2CppTypeEnum.IL2CPP_TYPE_VAR
or Il2CppTypeEnum.IL2CPP_TYPE_MVAR;
}