diff --git a/UnhollowerBaseLib/UnhollowerUtils.cs b/UnhollowerBaseLib/UnhollowerUtils.cs index 030c779..2761c22 100644 --- a/UnhollowerBaseLib/UnhollowerUtils.cs +++ b/UnhollowerBaseLib/UnhollowerUtils.cs @@ -7,7 +7,10 @@ namespace UnhollowerBaseLib { public class UnhollowerUtils { - private static FieldInfo GetFieldInfoFromMethod(MethodBase method, string prefix) + private const string GenericDeclaringTypeName = "MethodInfoStoreGeneric_"; + private const string GenericFieldName = "Pointer"; + + private static FieldInfo GetFieldInfoFromMethod(MethodBase method, string prefix, FieldType type = FieldType.None) { var body = method.GetMethodBody(); if (body == null) throw new ArgumentException("Target method may not be abstract"); @@ -16,20 +19,53 @@ private static FieldInfo GetFieldInfoFromMethod(MethodBase method, string prefix { if (opCode != OpCodes.Ldsfld) continue; var fieldInfo = methodModule.ResolveField((int) opArg); - if (fieldInfo?.FieldType != typeof(IntPtr) || !fieldInfo.Name.StartsWith(prefix)) continue; - return fieldInfo; + if (fieldInfo?.FieldType != typeof(IntPtr)) + continue; + + switch (type) + { + case FieldType.None: + if (fieldInfo.Name.StartsWith(prefix)) + return fieldInfo; + + break; + + case FieldType.GenericMethod: + + if (fieldInfo.Name.Equals(GenericFieldName) && + fieldInfo.DeclaringType.Name.StartsWith(GenericDeclaringTypeName)) + { + var genericType = fieldInfo.DeclaringType.GetGenericTypeDefinition().MakeGenericType(method.GetGenericArguments()); + return genericType.GetField(GenericFieldName, BindingFlags.NonPublic | BindingFlags.Static); + } + + break; + + default: + throw new ArgumentOutOfRangeException(nameof(type), type, null); + } } return null; } public static FieldInfo GetIl2CppMethodInfoPointerFieldForGeneratedMethod(MethodBase method) { - return GetFieldInfoFromMethod(method, "NativeMethodInfoPtr_"); + const string prefix = "NativeMethodInfoPtr_"; + if (method.IsGenericMethod) + return GetFieldInfoFromMethod(method, prefix, FieldType.GenericMethod); + + return GetFieldInfoFromMethod(method, prefix); } public static FieldInfo GetIl2CppFieldInfoPointerFieldForGeneratedFieldAccessor(MethodBase method) { return GetFieldInfoFromMethod(method, "NativeFieldInfoPtr_"); } + + private enum FieldType + { + None, + GenericMethod + } } } \ No newline at end of file