From 8ffd601ac34f40bbe5fc4a61d19797c2af127e60 Mon Sep 17 00:00:00 2001 From: sir0x <3425560+sir0x1@users.noreply.github.com> Date: Tue, 29 Aug 2023 14:22:04 +0200 Subject: [PATCH 1/2] Remember injected types and reuse in GetIl2CppTypeFullName --- Il2CppInterop.Runtime/Injection/ClassInjector.cs | 13 ++++++++++--- Il2CppInterop.Runtime/Injection/InjectorHelpers.cs | 13 ++++++++----- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Il2CppInterop.Runtime/Injection/ClassInjector.cs b/Il2CppInterop.Runtime/Injection/ClassInjector.cs index e287a086..5d0b3254 100644 --- a/Il2CppInterop.Runtime/Injection/ClassInjector.cs +++ b/Il2CppInterop.Runtime/Injection/ClassInjector.cs @@ -522,7 +522,8 @@ INativeMethodInfoStruct HandleAbstractMethod(int position) RuntimeSpecificsStore.SetClassInfo(classPointer.Pointer, true); Il2CppClassPointerStore.SetNativeClassPointer(type, classPointer.Pointer); - InjectorHelpers.AddTypeToLookup(type, classPointer.Pointer); + var classTypePtr = IL2CPP.il2cpp_class_get_type(classPointer.Pointer); + InjectorHelpers.AddTypeToLookup(type, classTypePtr); if (options.LogSuccess) Logger.Instance.LogInformation("Registered mono type {Type} in il2cpp domain", type); @@ -1147,10 +1148,16 @@ private static string GetIl2CppTypeFullName(Il2CppTypeStruct* typePointer) internal static Type SystemTypeFromIl2CppType(Il2CppTypeStruct* typePointer) { + INativeTypeStruct wrappedType = UnityVersionHandler.Wrap(typePointer); + + if (InjectorHelpers.TryGetType((IntPtr)wrappedType.TypePointer, out var type)) + { + return RewriteType(type); + } + var fullName = GetIl2CppTypeFullName(typePointer); - var type = Type.GetType(fullName) ?? throw new NullReferenceException($"Couldn't find System.Type for Il2Cpp type: {fullName}"); + type = Type.GetType(fullName) ?? throw new NullReferenceException($"Couldn't find System.Type for Il2Cpp type: {fullName}"); - INativeTypeStruct wrappedType = UnityVersionHandler.Wrap(typePointer); if (wrappedType.Type == Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST) { Il2CppGenericClass* genericClass = (Il2CppGenericClass*)wrappedType.Data; diff --git a/Il2CppInterop.Runtime/Injection/InjectorHelpers.cs b/Il2CppInterop.Runtime/Injection/InjectorHelpers.cs index b1729e42..3ae136ed 100644 --- a/Il2CppInterop.Runtime/Injection/InjectorHelpers.cs +++ b/Il2CppInterop.Runtime/Injection/InjectorHelpers.cs @@ -8,16 +8,11 @@ using System.Runtime.InteropServices; using System.Threading; using Il2CppInterop.Common; -using Il2CppInterop.Common.Extensions; -using Il2CppInterop.Common.XrefScans; using Il2CppInterop.Runtime.Injection.Hooks; using Il2CppInterop.Runtime.Runtime; using Il2CppInterop.Runtime.Runtime.VersionSpecific.Assembly; -using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class; -using Il2CppInterop.Runtime.Runtime.VersionSpecific.FieldInfo; using Il2CppInterop.Runtime.Runtime.VersionSpecific.Image; using Il2CppInterop.Runtime.Runtime.VersionSpecific.MethodInfo; -using Il2CppInterop.Runtime.Startup; using Microsoft.Extensions.Logging; namespace Il2CppInterop.Runtime.Injection @@ -100,6 +95,13 @@ internal static void AddTypeToLookup(Type type, IntPtr typePointer) { s_ClassNameLookup.Add((namespaze, klass, image), typePointer); } + + s_TypeLookup[typePointer] = type; + } + + internal static bool TryGetType(IntPtr typePointer, out Type type) + { + return s_TypeLookup.TryGetValue(typePointer, out type); } internal static IntPtr GetIl2CppExport(string name) @@ -139,6 +141,7 @@ internal static IntPtr GetIl2CppMethodPointer(MethodBase proxyMethod) internal static readonly ConcurrentDictionary s_InjectedClasses = new(); /// (namespace, class, image) : class internal static readonly Dictionary<(string _namespace, string _class, IntPtr imagePtr), IntPtr> s_ClassNameLookup = new(); + internal static readonly Dictionary s_TypeLookup = new(); #region Class::Init [UnmanagedFunctionPointer(CallingConvention.Cdecl)] From ad9b16fa2f38e3df26ea431a60cb564d81a1430c Mon Sep 17 00:00:00 2001 From: sir0x <3425560+sir0x1@users.noreply.github.com> Date: Tue, 29 Aug 2023 01:22:23 +0200 Subject: [PATCH 2/2] Fix "No method found for vtable entry" for methods with void* parameter --- Il2CppInterop.Runtime/Injection/ClassInjector.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Il2CppInterop.Runtime/Injection/ClassInjector.cs b/Il2CppInterop.Runtime/Injection/ClassInjector.cs index 5d0b3254..b54ed9cb 100644 --- a/Il2CppInterop.Runtime/Injection/ClassInjector.cs +++ b/Il2CppInterop.Runtime/Injection/ClassInjector.cs @@ -534,7 +534,7 @@ private static bool IsTypeSupported(Type type) if (type.IsValueType || type == typeof(string) || type.IsGenericParameter) return true; - if (type.IsByRef) return IsTypeSupported(type.GetElementType()); + if (type.IsByRef || type.IsPointer) return IsTypeSupported(type.GetElementType()); return typeof(Il2CppObjectBase).IsAssignableFrom(type); } @@ -655,7 +655,7 @@ private static bool IsMethodEligible(MethodInfo method) var parameterType = parameterInfo.ParameterType; if (!parameterType.IsGenericParameter) { - if (parameterType.IsByRef) + if (parameterType.IsByRef || parameterType.IsPointer) { var elementType = parameterType.GetElementType(); if (!elementType.IsGenericParameter) @@ -1083,7 +1083,7 @@ private static Type RewriteType(Type type) if (type.IsValueType && !type.IsEnum) return type; - if (type == typeof(string)) + if (type == typeof(string) || type == typeof(void*)) return type; if (type.IsArray)