internal static string GetGenericTypeParams(Il2CppMetadata metadata, PE.PE cppAssembly, Il2CppGenericInst genericInst) { var typeNames = new List <string>(); var pointers = cppAssembly.ReadClassArrayAtVirtualAddress <ulong>(genericInst.type_argv, (long)genericInst.type_argc); for (uint i = 0; i < genericInst.type_argc; ++i) { var oriType = cppAssembly.GetIl2CppType(pointers[i]); typeNames.Add(GetTypeName(metadata, cppAssembly, oriType)); } return($"<{String.Join(", ", typeNames)}>"); }
public static TypeReference ImportTypeInto(MemberReference importInto, Il2CppType toImport, PE.PE theDll, Il2CppMetadata metadata) { var moduleDefinition = importInto.Module; switch (toImport.type) { case Il2CppTypeEnum.IL2CPP_TYPE_OBJECT: return(moduleDefinition.ImportReference(typeof(object))); case Il2CppTypeEnum.IL2CPP_TYPE_VOID: return(moduleDefinition.ImportReference(typeof(void))); case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN: return(moduleDefinition.ImportReference(typeof(bool))); case Il2CppTypeEnum.IL2CPP_TYPE_CHAR: return(moduleDefinition.ImportReference(typeof(char))); case Il2CppTypeEnum.IL2CPP_TYPE_I1: return(moduleDefinition.ImportReference(typeof(sbyte))); case Il2CppTypeEnum.IL2CPP_TYPE_U1: return(moduleDefinition.ImportReference(typeof(byte))); case Il2CppTypeEnum.IL2CPP_TYPE_I2: return(moduleDefinition.ImportReference(typeof(short))); case Il2CppTypeEnum.IL2CPP_TYPE_U2: return(moduleDefinition.ImportReference(typeof(ushort))); case Il2CppTypeEnum.IL2CPP_TYPE_I4: return(moduleDefinition.ImportReference(typeof(int))); case Il2CppTypeEnum.IL2CPP_TYPE_U4: return(moduleDefinition.ImportReference(typeof(uint))); case Il2CppTypeEnum.IL2CPP_TYPE_I: return(moduleDefinition.ImportReference(typeof(IntPtr))); case Il2CppTypeEnum.IL2CPP_TYPE_U: return(moduleDefinition.ImportReference(typeof(UIntPtr))); case Il2CppTypeEnum.IL2CPP_TYPE_I8: return(moduleDefinition.ImportReference(typeof(long))); case Il2CppTypeEnum.IL2CPP_TYPE_U8: return(moduleDefinition.ImportReference(typeof(ulong))); case Il2CppTypeEnum.IL2CPP_TYPE_R4: return(moduleDefinition.ImportReference(typeof(float))); case Il2CppTypeEnum.IL2CPP_TYPE_R8: return(moduleDefinition.ImportReference(typeof(double))); case Il2CppTypeEnum.IL2CPP_TYPE_STRING: return(moduleDefinition.ImportReference(typeof(string))); case Il2CppTypeEnum.IL2CPP_TYPE_TYPEDBYREF: return(moduleDefinition.ImportReference(typeof(TypedReference))); case Il2CppTypeEnum.IL2CPP_TYPE_CLASS: case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE: { var typeDefinition = SharedState.TypeDefsByIndex[toImport.data.classIndex]; return(moduleDefinition.ImportReference(typeDefinition)); } case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY: { var arrayType = theDll.ReadClassAtVirtualAddress <Il2CppArrayType>(toImport.data.array); var oriType = theDll.GetIl2CppType(arrayType.etype); return(new ArrayType(ImportTypeInto(importInto, oriType, theDll, metadata), arrayType.rank)); } case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST: { var genericClass = theDll.ReadClassAtVirtualAddress <Il2CppGenericClass>(toImport.data.generic_class); var typeDefinition = SharedState.TypeDefsByIndex[genericClass.typeDefinitionIndex]; var genericInstanceType = new GenericInstanceType(moduleDefinition.ImportReference(typeDefinition)); var genericInst = theDll.ReadClassAtVirtualAddress <Il2CppGenericInst>(genericClass.context.class_inst); var pointers = theDll.GetPointers(genericInst.type_argv, (long)genericInst.type_argc); foreach (var pointer in pointers) { var oriType = theDll.GetIl2CppType(pointer); genericInstanceType.GenericArguments.Add(ImportTypeInto(importInto, oriType, theDll, metadata)); } return(genericInstanceType); } case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY: { var oriType = theDll.GetIl2CppType(toImport.data.type); return(new ArrayType(ImportTypeInto(importInto, oriType, theDll, metadata))); } case Il2CppTypeEnum.IL2CPP_TYPE_VAR: { if (SharedState.GenericParamsByIndex.TryGetValue(toImport.data.genericParameterIndex, out var genericParameter)) { return(genericParameter); } var param = metadata.genericParameters[toImport.data.genericParameterIndex]; var genericName = metadata.GetStringFromIndex(param.nameIndex); if (importInto is MethodDefinition methodDefinition) { genericParameter = new GenericParameter(genericName, methodDefinition.DeclaringType); methodDefinition.DeclaringType.GenericParameters.Add(genericParameter); SharedState.GenericParamsByIndex.Add(toImport.data.genericParameterIndex, genericParameter); return(genericParameter); } var typeDefinition = (TypeDefinition)importInto; genericParameter = new GenericParameter(genericName, typeDefinition); typeDefinition.GenericParameters.Add(genericParameter); SharedState.GenericParamsByIndex.Add(toImport.data.genericParameterIndex, genericParameter); return(genericParameter); } case Il2CppTypeEnum.IL2CPP_TYPE_MVAR: { if (SharedState.GenericParamsByIndex.TryGetValue(toImport.data.genericParameterIndex, out var genericParameter)) { return(genericParameter); } var methodDefinition = (MethodDefinition)importInto; var param = metadata.genericParameters[toImport.data.genericParameterIndex]; var genericName = metadata.GetStringFromIndex(param.nameIndex); genericParameter = new GenericParameter(genericName, methodDefinition); methodDefinition.GenericParameters.Add(genericParameter); SharedState.GenericParamsByIndex.Add(toImport.data.genericParameterIndex, genericParameter); return(genericParameter); } case Il2CppTypeEnum.IL2CPP_TYPE_PTR: { var oriType = theDll.GetIl2CppType(toImport.data.type); return(new PointerType(ImportTypeInto(importInto, oriType, theDll, metadata))); } default: return(moduleDefinition.ImportReference(typeof(object))); } }
internal static string GetTypeName(Il2CppMetadata metadata, PE.PE cppAssembly, Il2CppType type, bool fullName = false) { string ret; switch (type.type) { case Il2CppTypeEnum.IL2CPP_TYPE_CLASS: case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE: { var typeDef = metadata.typeDefs[type.data.classIndex]; ret = String.Empty; if (fullName) { ret = metadata.GetStringFromIndex(typeDef.namespaceIndex); if (ret != String.Empty) { ret += "."; } } ret += GetTypeName(metadata, cppAssembly, typeDef); break; } case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST: { var genericClass = cppAssembly.ReadClassAtVirtualAddress <Il2CppGenericClass>(type.data.generic_class); var typeDef = metadata.typeDefs[genericClass.typeDefinitionIndex]; ret = metadata.GetStringFromIndex(typeDef.nameIndex); var genericInst = cppAssembly.ReadClassAtVirtualAddress <Il2CppGenericInst>(genericClass.context.class_inst); ret = ret.Replace($"`{genericInst.type_argc}", ""); ret += GetGenericTypeParams(metadata, cppAssembly, genericInst); break; } case Il2CppTypeEnum.IL2CPP_TYPE_VAR: case Il2CppTypeEnum.IL2CPP_TYPE_MVAR: { var param = metadata.genericParameters[type.data.genericParameterIndex]; ret = metadata.GetStringFromIndex(param.nameIndex); break; } case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY: { var arrayType = cppAssembly.ReadClassAtVirtualAddress <Il2CppArrayType>(type.data.array); var oriType = cppAssembly.GetIl2CppType(arrayType.etype); ret = $"{GetTypeName(metadata, cppAssembly, oriType)}[{new string(',', arrayType.rank - 1)}]"; break; } case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY: { var oriType = cppAssembly.GetIl2CppType(type.data.type); ret = $"{GetTypeName(metadata, cppAssembly, oriType)}[]"; break; } case Il2CppTypeEnum.IL2CPP_TYPE_PTR: { var oriType = cppAssembly.GetIl2CppType(type.data.type); ret = $"{GetTypeName(metadata, cppAssembly, oriType)}*"; break; } default: ret = TypeString[(int)type.type]; break; } return(ret); }