public DummyAssemblyGenerator(Il2CppExecutor il2CppExecutor, bool addToken) { executor = il2CppExecutor; metadata = il2CppExecutor.metadata; il2Cpp = il2CppExecutor.il2Cpp; //Il2CppDummyDll var il2CppDummyDll = Il2CppDummyDll.Create(); Assemblies.Add(il2CppDummyDll); var addressAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "AddressAttribute").Methods[0]; var fieldOffsetAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "FieldOffsetAttribute").Methods[0]; attributeAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "AttributeAttribute").Methods[0]; var metadataOffsetAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "MetadataOffsetAttribute").Methods[0]; var tokenAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "TokenAttribute").Methods[0]; stringType = il2CppDummyDll.MainModule.TypeSystem.String; var resolver = new MyAssemblyResolver(); var moduleParameters = new ModuleParameters { Kind = ModuleKind.Dll, AssemblyResolver = resolver }; resolver.Register(il2CppDummyDll); var parameterDefinitionDic = new Dictionary <int, ParameterDefinition>(); var eventDefinitionDic = new Dictionary <int, EventDefinition>(); //创建程序集,同时创建所有类 foreach (var imageDef in metadata.imageDefs) { var imageName = metadata.GetStringFromIndex(imageDef.nameIndex); var aname = metadata.assemblyDefs[imageDef.assemblyIndex].aname; var assemblyName = metadata.GetStringFromIndex(aname.nameIndex); Version vers; if (aname.build >= 0) { vers = new Version(aname.major, aname.minor, aname.build, aname.revision); } else { //__Generated vers = new Version(3, 7, 1, 6); } var assemblyNameDef = new AssemblyNameDefinition(assemblyName, vers); /*assemblyNameDef.Culture = metadata.GetStringFromIndex(aname.cultureIndex); * assemblyNameDef.PublicKey = Encoding.UTF8.GetBytes(metadata.GetStringFromIndex(aname.publicKeyIndex)); * assemblyNameDef.HashAlgorithm = (AssemblyHashAlgorithm)aname.hash_alg; * assemblyNameDef.Attributes = (AssemblyAttributes)aname.flags; * assemblyNameDef.PublicKeyToken = aname.public_key_token;*/ var assemblyDefinition = AssemblyDefinition.CreateAssembly(assemblyNameDef, imageName, moduleParameters); resolver.Register(assemblyDefinition); Assemblies.Add(assemblyDefinition); var moduleDefinition = assemblyDefinition.MainModule; moduleDefinition.Types.Clear();//清除自动创建的<Module>类 var typeEnd = imageDef.typeStart + imageDef.typeCount; for (var index = imageDef.typeStart; index < typeEnd; ++index) { var typeDef = metadata.typeDefs[index]; var namespaceName = metadata.GetStringFromIndex(typeDef.namespaceIndex); var typeName = metadata.GetStringFromIndex(typeDef.nameIndex); var typeDefinition = new TypeDefinition(namespaceName, typeName, (TypeAttributes)typeDef.flags); typeDefinitionDic.Add(typeDef, typeDefinition); if (typeDef.declaringTypeIndex == -1) { moduleDefinition.Types.Add(typeDefinition); } } } foreach (var imageDef in metadata.imageDefs) { var typeEnd = imageDef.typeStart + imageDef.typeCount; for (var index = imageDef.typeStart; index < typeEnd; ++index) { var typeDef = metadata.typeDefs[index]; var typeDefinition = typeDefinitionDic[typeDef]; //nestedtype for (int i = 0; i < typeDef.nested_type_count; i++) { var nestedIndex = metadata.nestedTypeIndices[typeDef.nestedTypesStart + i]; var nestedTypeDef = metadata.typeDefs[nestedIndex]; var nestedTypeDefinition = typeDefinitionDic[nestedTypeDef]; typeDefinition.NestedTypes.Add(nestedTypeDefinition); } } } //提前处理 foreach (var imageDef in metadata.imageDefs) { var typeEnd = imageDef.typeStart + imageDef.typeCount; for (var index = imageDef.typeStart; index < typeEnd; ++index) { var typeDef = metadata.typeDefs[index]; var typeDefinition = typeDefinitionDic[typeDef]; if (addToken) { var customTokenAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(tokenAttribute)); customTokenAttribute.Fields.Add(new CustomAttributeNamedArgument("Token", new CustomAttributeArgument(stringType, $"0x{typeDef.token:X}"))); typeDefinition.CustomAttributes.Add(customTokenAttribute); } //genericParameter if (typeDef.genericContainerIndex >= 0) { var genericContainer = metadata.genericContainers[typeDef.genericContainerIndex]; for (int i = 0; i < genericContainer.type_argc; i++) { var genericParameterIndex = genericContainer.genericParameterStart + i; var param = metadata.genericParameters[genericParameterIndex]; var genericParameter = CreateGenericParameter(param, typeDefinition); typeDefinition.GenericParameters.Add(genericParameter); } } //parent if (typeDef.parentIndex >= 0) { var parentType = il2Cpp.types[typeDef.parentIndex]; var parentTypeRef = GetTypeReference(typeDefinition, parentType); typeDefinition.BaseType = parentTypeRef; } //interfaces for (int i = 0; i < typeDef.interfaces_count; i++) { var interfaceType = il2Cpp.types[metadata.interfaceIndices[typeDef.interfacesStart + i]]; var interfaceTypeRef = GetTypeReference(typeDefinition, interfaceType); typeDefinition.Interfaces.Add(new InterfaceImplementation(interfaceTypeRef)); } } } //处理field, method, property等等 foreach (var imageDef in metadata.imageDefs) { var imageName = metadata.GetStringFromIndex(imageDef.nameIndex); var typeEnd = imageDef.typeStart + imageDef.typeCount; for (int index = imageDef.typeStart; index < typeEnd; index++) { var typeDef = metadata.typeDefs[index]; var typeDefinition = typeDefinitionDic[typeDef]; //field var fieldEnd = typeDef.fieldStart + typeDef.field_count; for (var i = typeDef.fieldStart; i < fieldEnd; ++i) { var fieldDef = metadata.fieldDefs[i]; var fieldType = il2Cpp.types[fieldDef.typeIndex]; var fieldName = metadata.GetStringFromIndex(fieldDef.nameIndex); var fieldTypeRef = GetTypeReference(typeDefinition, fieldType); var fieldDefinition = new FieldDefinition(fieldName, (FieldAttributes)fieldType.attrs, fieldTypeRef); typeDefinition.Fields.Add(fieldDefinition); fieldDefinitionDic.Add(i, fieldDefinition); if (addToken) { var customTokenAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(tokenAttribute)); customTokenAttribute.Fields.Add(new CustomAttributeNamedArgument("Token", new CustomAttributeArgument(stringType, $"0x{fieldDef.token:X}"))); fieldDefinition.CustomAttributes.Add(customTokenAttribute); } //fieldDefault if (metadata.GetFieldDefaultValueFromIndex(i, out var fieldDefault) && fieldDefault.dataIndex != -1) { if (executor.TryGetDefaultValue(fieldDefault.typeIndex, fieldDefault.dataIndex, out var value)) { fieldDefinition.Constant = value; } else { var customAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(metadataOffsetAttribute)); var offset = new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{value:X}")); customAttribute.Fields.Add(offset); fieldDefinition.CustomAttributes.Add(customAttribute); } } //fieldOffset if (!fieldDefinition.IsLiteral) { var fieldOffset = il2Cpp.GetFieldOffsetFromIndex(index, i - typeDef.fieldStart, i, typeDefinition.IsValueType, fieldDefinition.IsStatic); if (fieldOffset >= 0) { var customAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(fieldOffsetAttribute)); var offset = new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{fieldOffset:X}")); customAttribute.Fields.Add(offset); fieldDefinition.CustomAttributes.Add(customAttribute); } } } //method var methodEnd = typeDef.methodStart + typeDef.method_count; for (var i = typeDef.methodStart; i < methodEnd; ++i) { var methodDef = metadata.methodDefs[i]; var methodName = metadata.GetStringFromIndex(methodDef.nameIndex); var methodDefinition = new MethodDefinition(methodName, (MethodAttributes)methodDef.flags, typeDefinition.Module.ImportReference(typeof(void))); methodDefinition.ImplAttributes = (MethodImplAttributes)methodDef.iflags; typeDefinition.Methods.Add(methodDefinition); //genericParameter if (methodDef.genericContainerIndex >= 0) { var genericContainer = metadata.genericContainers[methodDef.genericContainerIndex]; for (int j = 0; j < genericContainer.type_argc; j++) { var genericParameterIndex = genericContainer.genericParameterStart + j; var param = metadata.genericParameters[genericParameterIndex]; var genericParameter = CreateGenericParameter(param, methodDefinition); methodDefinition.GenericParameters.Add(genericParameter); } } var methodReturnType = il2Cpp.types[methodDef.returnType]; var returnType = GetTypeReferenceWithByRef(methodDefinition, methodReturnType); methodDefinition.ReturnType = returnType; if (addToken) { var customTokenAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(tokenAttribute)); customTokenAttribute.Fields.Add(new CustomAttributeNamedArgument("Token", new CustomAttributeArgument(stringType, $"0x{methodDef.token:X}"))); methodDefinition.CustomAttributes.Add(customTokenAttribute); } if (methodDefinition.HasBody && typeDefinition.BaseType?.FullName != "System.MulticastDelegate") { var ilprocessor = methodDefinition.Body.GetILProcessor(); if (returnType.FullName == "System.Void") { ilprocessor.Append(ilprocessor.Create(OpCodes.Ret)); } else if (returnType.IsValueType) { var variable = new VariableDefinition(returnType); methodDefinition.Body.Variables.Add(variable); ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloca_S, variable)); ilprocessor.Append(ilprocessor.Create(OpCodes.Initobj, returnType)); ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0)); ilprocessor.Append(ilprocessor.Create(OpCodes.Ret)); } else { ilprocessor.Append(ilprocessor.Create(OpCodes.Ldnull)); ilprocessor.Append(ilprocessor.Create(OpCodes.Ret)); } } methodDefinitionDic.Add(i, methodDefinition); //method parameter for (var j = 0; j < methodDef.parameterCount; ++j) { var parameterDef = metadata.parameterDefs[methodDef.parameterStart + j]; var parameterName = metadata.GetStringFromIndex(parameterDef.nameIndex); var parameterType = il2Cpp.types[parameterDef.typeIndex]; var parameterTypeRef = GetTypeReferenceWithByRef(methodDefinition, parameterType); var parameterDefinition = new ParameterDefinition(parameterName, (ParameterAttributes)parameterType.attrs, parameterTypeRef); methodDefinition.Parameters.Add(parameterDefinition); parameterDefinitionDic.Add(methodDef.parameterStart + j, parameterDefinition); //ParameterDefault if (metadata.GetParameterDefaultValueFromIndex(methodDef.parameterStart + j, out var parameterDefault) && parameterDefault.dataIndex != -1) { if (executor.TryGetDefaultValue(parameterDefault.typeIndex, parameterDefault.dataIndex, out var value)) { parameterDefinition.Constant = value; } else { var customAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(metadataOffsetAttribute)); var offset = new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{value:X}")); customAttribute.Fields.Add(offset); parameterDefinition.CustomAttributes.Add(customAttribute); } } } //methodAddress if (!methodDefinition.IsAbstract) { var methodPointer = il2Cpp.GetMethodPointer(imageName, methodDef); if (methodPointer > 0) { var customAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(addressAttribute)); var fixedMethodPointer = il2Cpp.GetRVA(methodPointer); var rva = new CustomAttributeNamedArgument("RVA", new CustomAttributeArgument(stringType, $"0x{fixedMethodPointer:X}")); var offset = new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{il2Cpp.MapVATR(methodPointer):X}")); var va = new CustomAttributeNamedArgument("VA", new CustomAttributeArgument(stringType, $"0x{methodPointer:X}")); customAttribute.Fields.Add(rva); customAttribute.Fields.Add(offset); customAttribute.Fields.Add(va); if (methodDef.slot != ushort.MaxValue) { var slot = new CustomAttributeNamedArgument("Slot", new CustomAttributeArgument(stringType, methodDef.slot.ToString())); customAttribute.Fields.Add(slot); } methodDefinition.CustomAttributes.Add(customAttribute); } } } //property var propertyEnd = typeDef.propertyStart + typeDef.property_count; for (var i = typeDef.propertyStart; i < propertyEnd; ++i) { var propertyDef = metadata.propertyDefs[i]; var propertyName = metadata.GetStringFromIndex(propertyDef.nameIndex); TypeReference propertyType = null; MethodDefinition GetMethod = null; MethodDefinition SetMethod = null; if (propertyDef.get >= 0) { GetMethod = methodDefinitionDic[typeDef.methodStart + propertyDef.get]; propertyType = GetMethod.ReturnType; } if (propertyDef.set >= 0) { SetMethod = methodDefinitionDic[typeDef.methodStart + propertyDef.set]; if (propertyType == null) { propertyType = SetMethod.Parameters[0].ParameterType; } } var propertyDefinition = new PropertyDefinition(propertyName, (PropertyAttributes)propertyDef.attrs, propertyType) { GetMethod = GetMethod, SetMethod = SetMethod }; typeDefinition.Properties.Add(propertyDefinition); propertyDefinitionDic.Add(i, propertyDefinition); if (addToken) { var customTokenAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(tokenAttribute)); customTokenAttribute.Fields.Add(new CustomAttributeNamedArgument("Token", new CustomAttributeArgument(stringType, $"0x{propertyDef.token:X}"))); propertyDefinition.CustomAttributes.Add(customTokenAttribute); } } //event var eventEnd = typeDef.eventStart + typeDef.event_count; for (var i = typeDef.eventStart; i < eventEnd; ++i) { var eventDef = metadata.eventDefs[i]; var eventName = metadata.GetStringFromIndex(eventDef.nameIndex); var eventType = il2Cpp.types[eventDef.typeIndex]; var eventTypeRef = GetTypeReference(typeDefinition, eventType); var eventDefinition = new EventDefinition(eventName, (EventAttributes)eventType.attrs, eventTypeRef); if (eventDef.add >= 0) { eventDefinition.AddMethod = methodDefinitionDic[typeDef.methodStart + eventDef.add]; } if (eventDef.remove >= 0) { eventDefinition.RemoveMethod = methodDefinitionDic[typeDef.methodStart + eventDef.remove]; } if (eventDef.raise >= 0) { eventDefinition.InvokeMethod = methodDefinitionDic[typeDef.methodStart + eventDef.raise]; } typeDefinition.Events.Add(eventDefinition); eventDefinitionDic.Add(i, eventDefinition); if (addToken) { var customTokenAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(tokenAttribute)); customTokenAttribute.Fields.Add(new CustomAttributeNamedArgument("Token", new CustomAttributeArgument(stringType, $"0x{eventDef.token:X}"))); eventDefinition.CustomAttributes.Add(customTokenAttribute); } } } } //第三遍,添加CustomAttribute if (il2Cpp.Version > 20) { foreach (var imageDef in metadata.imageDefs) { var typeEnd = imageDef.typeStart + imageDef.typeCount; for (int index = imageDef.typeStart; index < typeEnd; index++) { var typeDef = metadata.typeDefs[index]; var typeDefinition = typeDefinitionDic[typeDef]; //typeAttribute CreateCustomAttribute(imageDef, typeDef.customAttributeIndex, typeDef.token, typeDefinition.Module, typeDefinition.CustomAttributes); //field var fieldEnd = typeDef.fieldStart + typeDef.field_count; for (var i = typeDef.fieldStart; i < fieldEnd; ++i) { var fieldDef = metadata.fieldDefs[i]; var fieldDefinition = fieldDefinitionDic[i]; //fieldAttribute CreateCustomAttribute(imageDef, fieldDef.customAttributeIndex, fieldDef.token, typeDefinition.Module, fieldDefinition.CustomAttributes); } //method var methodEnd = typeDef.methodStart + typeDef.method_count; for (var i = typeDef.methodStart; i < methodEnd; ++i) { var methodDef = metadata.methodDefs[i]; var methodDefinition = methodDefinitionDic[i]; //methodAttribute CreateCustomAttribute(imageDef, methodDef.customAttributeIndex, methodDef.token, typeDefinition.Module, methodDefinition.CustomAttributes); //method parameter for (var j = 0; j < methodDef.parameterCount; ++j) { var parameterDef = metadata.parameterDefs[methodDef.parameterStart + j]; var parameterDefinition = parameterDefinitionDic[methodDef.parameterStart + j]; //parameterAttribute CreateCustomAttribute(imageDef, parameterDef.customAttributeIndex, parameterDef.token, typeDefinition.Module, parameterDefinition.CustomAttributes); } } //property var propertyEnd = typeDef.propertyStart + typeDef.property_count; for (var i = typeDef.propertyStart; i < propertyEnd; ++i) { var propertyDef = metadata.propertyDefs[i]; var propertyDefinition = propertyDefinitionDic[i]; //propertyAttribute CreateCustomAttribute(imageDef, propertyDef.customAttributeIndex, propertyDef.token, typeDefinition.Module, propertyDefinition.CustomAttributes); } //event var eventEnd = typeDef.eventStart + typeDef.event_count; for (var i = typeDef.eventStart; i < eventEnd; ++i) { var eventDef = metadata.eventDefs[i]; var eventDefinition = eventDefinitionDic[i]; //eventAttribute CreateCustomAttribute(imageDef, eventDef.customAttributeIndex, eventDef.token, typeDefinition.Module, eventDefinition.CustomAttributes); } } } } }
public DummyAssemblyGenerator(Metadata metadata, Il2Cpp il2Cpp) { this.metadata = metadata; this.il2Cpp = il2Cpp; //Il2CppDummyDll var il2CppDummyDll = Il2CppDummyDll.Create(); Assemblies.Add(il2CppDummyDll); var addressAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "AddressAttribute").Methods[0]; var fieldOffsetAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "FieldOffsetAttribute").Methods[0]; attributeAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "AttributeAttribute").Methods[0]; var metadataOffsetAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "MetadataOffsetAttribute").Methods[0]; stringType = il2CppDummyDll.MainModule.TypeSystem.String; var resolver = new MyAssemblyResolver(); var moduleParameters = new ModuleParameters { Kind = ModuleKind.Dll, AssemblyResolver = resolver }; resolver.Register(il2CppDummyDll); var fieldDefinitionDic = new Dictionary <int, FieldDefinition>(); var methodDefinitionDic = new Dictionary <int, MethodDefinition>(); var parameterDefinitionDic = new Dictionary <int, ParameterDefinition>(); var propertyDefinitionDic = new Dictionary <int, PropertyDefinition>(); var eventDefinitionDic = new Dictionary <int, EventDefinition>(); //创建程序集,同时创建所有类 foreach (var imageDef in metadata.imageDefs) { var imageName = metadata.GetStringFromIndex(imageDef.nameIndex); var assemblyName = new AssemblyNameDefinition(imageName.Replace(".dll", ""), new Version("3.7.1.6")); var assemblyDefinition = AssemblyDefinition.CreateAssembly(assemblyName, imageName, moduleParameters); resolver.Register(assemblyDefinition); Assemblies.Add(assemblyDefinition); var moduleDefinition = assemblyDefinition.MainModule; moduleDefinition.Types.Clear();//清除自动创建的<Module>类 var typeEnd = imageDef.typeStart + imageDef.typeCount; for (var index = imageDef.typeStart; index < typeEnd; ++index) { var typeDef = metadata.typeDefs[index]; var namespaceName = metadata.GetStringFromIndex(typeDef.namespaceIndex); var typeName = metadata.GetStringFromIndex(typeDef.nameIndex); TypeDefinition typeDefinition; if (typeDef.declaringTypeIndex != -1)//nested types { typeDefinition = typeDefinitionDic[index]; } else { typeDefinition = new TypeDefinition(namespaceName, typeName, (TypeAttributes)typeDef.flags); moduleDefinition.Types.Add(typeDefinition); typeDefinitionDic.Add(index, typeDefinition); } //nestedtype for (int i = 0; i < typeDef.nested_type_count; i++) { var nestedIndex = metadata.nestedTypeIndices[typeDef.nestedTypesStart + i]; var nestedTypeDef = metadata.typeDefs[nestedIndex]; var nestedTypeDefinition = new TypeDefinition(metadata.GetStringFromIndex(nestedTypeDef.namespaceIndex), metadata.GetStringFromIndex(nestedTypeDef.nameIndex), (TypeAttributes)nestedTypeDef.flags); typeDefinition.NestedTypes.Add(nestedTypeDefinition); typeDefinitionDic.Add(nestedIndex, nestedTypeDefinition); } } } //先单独处理,因为不知道会不会有问题 for (var index = 0; index < metadata.typeDefs.Length; ++index) { var typeDef = metadata.typeDefs[index]; var typeDefinition = typeDefinitionDic[index]; //parent if (typeDef.parentIndex >= 0) { var parentType = il2Cpp.types[typeDef.parentIndex]; var parentTypeRef = GetTypeReference(typeDefinition, parentType); typeDefinition.BaseType = parentTypeRef; } //interfaces for (int i = 0; i < typeDef.interfaces_count; i++) { var interfaceType = il2Cpp.types[metadata.interfaceIndices[typeDef.interfacesStart + i]]; var interfaceTypeRef = GetTypeReference(typeDefinition, interfaceType); typeDefinition.Interfaces.Add(new InterfaceImplementation(interfaceTypeRef)); } } //处理field, method, property等等 for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++) { var imageDef = metadata.imageDefs[imageIndex]; var typeEnd = imageDef.typeStart + imageDef.typeCount; for (int index = imageDef.typeStart; index < typeEnd; index++) { var typeDef = metadata.typeDefs[index]; var typeDefinition = typeDefinitionDic[index]; //field var fieldEnd = typeDef.fieldStart + typeDef.field_count; for (var i = typeDef.fieldStart; i < fieldEnd; ++i) { var fieldDef = metadata.fieldDefs[i]; var fieldType = il2Cpp.types[fieldDef.typeIndex]; var fieldName = metadata.GetStringFromIndex(fieldDef.nameIndex); var fieldTypeRef = GetTypeReference(typeDefinition, fieldType); var fieldDefinition = new FieldDefinition(fieldName, (FieldAttributes)fieldType.attrs, fieldTypeRef); typeDefinition.Fields.Add(fieldDefinition); fieldDefinitionDic.Add(i, fieldDefinition); //fieldDefault if (metadata.GetFieldDefaultValueFromIndex(i, out var fieldDefault) && fieldDefault.dataIndex != -1) { if (TryGetDefaultValue(fieldDefault.typeIndex, fieldDefault.dataIndex, out var value)) { fieldDefinition.Constant = value; } else { var customAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(metadataOffsetAttribute)); var offset = new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{value:X}")); customAttribute.Fields.Add(offset); fieldDefinition.CustomAttributes.Add(customAttribute); } } //fieldOffset if (!fieldDefinition.IsLiteral) { var fieldOffset = il2Cpp.GetFieldOffsetFromIndex(index, i - typeDef.fieldStart, i, typeDefinition.IsValueType, fieldDefinition.IsStatic); if (fieldOffset >= 0) { var customAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(fieldOffsetAttribute)); var offset = new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{fieldOffset:X}")); customAttribute.Fields.Add(offset); fieldDefinition.CustomAttributes.Add(customAttribute); } } } //method var methodEnd = typeDef.methodStart + typeDef.method_count; for (var i = typeDef.methodStart; i < methodEnd; ++i) { var methodDef = metadata.methodDefs[i]; var methodName = metadata.GetStringFromIndex(methodDef.nameIndex); var methodDefinition = new MethodDefinition(methodName, (MethodAttributes)methodDef.flags, typeDefinition.Module.ImportReference(typeof(void))); methodDefinition.ImplAttributes = (MethodImplAttributes)methodDef.iflags; typeDefinition.Methods.Add(methodDefinition); var methodReturnType = il2Cpp.types[methodDef.returnType]; var returnType = GetTypeReferenceWithByRef(methodDefinition, methodReturnType); methodDefinition.ReturnType = returnType; if (methodDefinition.HasBody && typeDefinition.BaseType?.FullName != "System.MulticastDelegate") { var ilprocessor = methodDefinition.Body.GetILProcessor(); if (returnType.FullName == "System.Void") { ilprocessor.Append(ilprocessor.Create(OpCodes.Ret)); } else if (returnType.IsValueType) { var variable = new VariableDefinition(returnType); methodDefinition.Body.Variables.Add(variable); ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloca_S, variable)); ilprocessor.Append(ilprocessor.Create(OpCodes.Initobj, returnType)); ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0)); ilprocessor.Append(ilprocessor.Create(OpCodes.Ret)); } else { ilprocessor.Append(ilprocessor.Create(OpCodes.Ldnull)); ilprocessor.Append(ilprocessor.Create(OpCodes.Ret)); } } methodDefinitionDic.Add(i, methodDefinition); //method parameter for (var j = 0; j < methodDef.parameterCount; ++j) { var parameterDef = metadata.parameterDefs[methodDef.parameterStart + j]; var parameterName = metadata.GetStringFromIndex(parameterDef.nameIndex); var parameterType = il2Cpp.types[parameterDef.typeIndex]; var parameterTypeRef = GetTypeReferenceWithByRef(methodDefinition, parameterType); var parameterDefinition = new ParameterDefinition(parameterName, (ParameterAttributes)parameterType.attrs, parameterTypeRef); methodDefinition.Parameters.Add(parameterDefinition); parameterDefinitionDic.Add(methodDef.parameterStart + j, parameterDefinition); //ParameterDefault if (metadata.GetParameterDefaultValueFromIndex(methodDef.parameterStart + j, out var parameterDefault) && parameterDefault.dataIndex != -1) { if (TryGetDefaultValue(parameterDefault.typeIndex, parameterDefault.dataIndex, out var value)) { parameterDefinition.Constant = value; } else { var customAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(metadataOffsetAttribute)); var offset = new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{value:X}")); customAttribute.Fields.Add(offset); parameterDefinition.CustomAttributes.Add(customAttribute); } } } //补充泛型参数 if (methodDef.genericContainerIndex >= 0) { var genericContainer = metadata.genericContainers[methodDef.genericContainerIndex]; if (genericContainer.type_argc > methodDefinition.GenericParameters.Count) { for (int j = 0; j < genericContainer.type_argc; j++) { var genericParameterIndex = genericContainer.genericParameterStart + j; if (!genericParameterDic.TryGetValue(genericParameterIndex, out var genericParameter)) { CreateGenericParameter(genericParameterIndex, methodDefinition); } else { if (!methodDefinition.GenericParameters.Contains(genericParameter)) { methodDefinition.GenericParameters.Add(genericParameter); } } } } } //methodAddress var methodPointer = il2Cpp.GetMethodPointer(methodDef, imageIndex); if (methodPointer > 0) { var customAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(addressAttribute)); var fixedMethodPointer = il2Cpp.GetRVA(methodPointer); var rva = new CustomAttributeNamedArgument("RVA", new CustomAttributeArgument(stringType, $"0x{fixedMethodPointer:X}")); var offset = new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{il2Cpp.MapVATR(methodPointer):X}")); var va = new CustomAttributeNamedArgument("VA", new CustomAttributeArgument(stringType, $"0x{methodPointer:X}")); customAttribute.Fields.Add(rva); customAttribute.Fields.Add(offset); customAttribute.Fields.Add(va); if (methodDef.slot != ushort.MaxValue) { var slot = new CustomAttributeNamedArgument("Slot", new CustomAttributeArgument(stringType, methodDef.slot.ToString())); customAttribute.Fields.Add(slot); } methodDefinition.CustomAttributes.Add(customAttribute); } } //property var propertyEnd = typeDef.propertyStart + typeDef.property_count; for (var i = typeDef.propertyStart; i < propertyEnd; ++i) { var propertyDef = metadata.propertyDefs[i]; var propertyName = metadata.GetStringFromIndex(propertyDef.nameIndex); TypeReference propertyType = null; MethodDefinition GetMethod = null; MethodDefinition SetMethod = null; if (propertyDef.get >= 0) { GetMethod = methodDefinitionDic[typeDef.methodStart + propertyDef.get]; propertyType = GetMethod.ReturnType; } if (propertyDef.set >= 0) { SetMethod = methodDefinitionDic[typeDef.methodStart + propertyDef.set]; if (propertyType == null) { propertyType = SetMethod.Parameters[0].ParameterType; } } var propertyDefinition = new PropertyDefinition(propertyName, (PropertyAttributes)propertyDef.attrs, propertyType) { GetMethod = GetMethod, SetMethod = SetMethod }; typeDefinition.Properties.Add(propertyDefinition); propertyDefinitionDic.Add(i, propertyDefinition); } //event var eventEnd = typeDef.eventStart + typeDef.event_count; for (var i = typeDef.eventStart; i < eventEnd; ++i) { var eventDef = metadata.eventDefs[i]; var eventName = metadata.GetStringFromIndex(eventDef.nameIndex); var eventType = il2Cpp.types[eventDef.typeIndex]; var eventTypeRef = GetTypeReference(typeDefinition, eventType); var eventDefinition = new EventDefinition(eventName, (EventAttributes)eventType.attrs, eventTypeRef); if (eventDef.add >= 0) { eventDefinition.AddMethod = methodDefinitionDic[typeDef.methodStart + eventDef.add]; } if (eventDef.remove >= 0) { eventDefinition.RemoveMethod = methodDefinitionDic[typeDef.methodStart + eventDef.remove]; } if (eventDef.raise >= 0) { eventDefinition.InvokeMethod = methodDefinitionDic[typeDef.methodStart + eventDef.raise]; } typeDefinition.Events.Add(eventDefinition); eventDefinitionDic.Add(i, eventDefinition); } //补充泛型参数 if (typeDef.genericContainerIndex >= 0) { var genericContainer = metadata.genericContainers[typeDef.genericContainerIndex]; if (genericContainer.type_argc > typeDefinition.GenericParameters.Count) { for (int i = 0; i < genericContainer.type_argc; i++) { var genericParameterIndex = genericContainer.genericParameterStart + i; if (!genericParameterDic.TryGetValue(genericParameterIndex, out var genericParameter)) { CreateGenericParameter(genericParameterIndex, typeDefinition); } else { if (!typeDefinition.GenericParameters.Contains(genericParameter)) { typeDefinition.GenericParameters.Add(genericParameter); } } } } } } } //第三遍,添加CustomAttribute if (il2Cpp.Version > 20) { PrepareCustomAttribute(); foreach (var imageDef in metadata.imageDefs) { var typeEnd = imageDef.typeStart + imageDef.typeCount; for (int index = imageDef.typeStart; index < typeEnd; index++) { var typeDef = metadata.typeDefs[index]; var typeDefinition = typeDefinitionDic[index]; //typeAttribute CreateCustomAttribute(imageDef, typeDef.customAttributeIndex, typeDef.token, typeDefinition.Module, typeDefinition.CustomAttributes); //field var fieldEnd = typeDef.fieldStart + typeDef.field_count; for (var i = typeDef.fieldStart; i < fieldEnd; ++i) { var fieldDef = metadata.fieldDefs[i]; var fieldDefinition = fieldDefinitionDic[i]; //fieldAttribute CreateCustomAttribute(imageDef, fieldDef.customAttributeIndex, fieldDef.token, typeDefinition.Module, fieldDefinition.CustomAttributes); } //method var methodEnd = typeDef.methodStart + typeDef.method_count; for (var i = typeDef.methodStart; i < methodEnd; ++i) { var methodDef = metadata.methodDefs[i]; var methodDefinition = methodDefinitionDic[i]; //methodAttribute CreateCustomAttribute(imageDef, methodDef.customAttributeIndex, methodDef.token, typeDefinition.Module, methodDefinition.CustomAttributes); //method parameter for (var j = 0; j < methodDef.parameterCount; ++j) { var parameterDef = metadata.parameterDefs[methodDef.parameterStart + j]; var parameterDefinition = parameterDefinitionDic[methodDef.parameterStart + j]; //parameterAttribute CreateCustomAttribute(imageDef, parameterDef.customAttributeIndex, parameterDef.token, typeDefinition.Module, parameterDefinition.CustomAttributes); } } //property var propertyEnd = typeDef.propertyStart + typeDef.property_count; for (var i = typeDef.propertyStart; i < propertyEnd; ++i) { var propertyDef = metadata.propertyDefs[i]; var propertyDefinition = propertyDefinitionDic[i]; //propertyAttribute CreateCustomAttribute(imageDef, propertyDef.customAttributeIndex, propertyDef.token, typeDefinition.Module, propertyDefinition.CustomAttributes); } //event var eventEnd = typeDef.eventStart + typeDef.event_count; for (var i = typeDef.eventStart; i < eventEnd; ++i) { var eventDef = metadata.eventDefs[i]; var eventDefinition = eventDefinitionDic[i]; //eventAttribute CreateCustomAttribute(imageDef, eventDef.customAttributeIndex, eventDef.token, typeDefinition.Module, eventDefinition.CustomAttributes); } } } } }
public DummyAssemblyCreator(Metadata metadata, Il2Cpp il2cpp) { this.metadata = metadata; this.il2cpp = il2cpp; //Il2CppDummyDll var il2CppDummyDll = Il2CppDummyDll.Create(); Assemblies.Add(il2CppDummyDll); var addressAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "AddressAttribute").Methods[0]; var fieldOffsetAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "FieldOffsetAttribute").Methods[0]; attributeAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "AttributeAttribute").Methods[0]; stringType = il2CppDummyDll.MainModule.TypeSystem.String; var resolver = new MyAssemblyResolver(); var moduleParameters = new ModuleParameters { Kind = ModuleKind.Dll, AssemblyResolver = resolver }; resolver.Register(il2CppDummyDll); //创建程序集,同时创建所有类 foreach (var imageDef in metadata.imageDefs) { var imageName = metadata.GetStringFromIndex(imageDef.nameIndex); var assemblyName = new AssemblyNameDefinition(imageName.Replace(".dll", ""), new Version("3.7.1.6")); var assemblyDefinition = AssemblyDefinition.CreateAssembly(assemblyName, imageName, moduleParameters); resolver.Register(assemblyDefinition); Assemblies.Add(assemblyDefinition); var moduleDefinition = assemblyDefinition.MainModule; moduleDefinition.Types.Clear();//清除自动创建的<Module>类 var typeEnd = imageDef.typeStart + imageDef.typeCount; for (var index = imageDef.typeStart; index < typeEnd; ++index) { var typeDef = metadata.typeDefs[index]; var namespaceName = metadata.GetStringFromIndex(typeDef.namespaceIndex); var typeName = metadata.GetStringFromIndex(typeDef.nameIndex); TypeDefinition typeDefinition; if (typeDef.declaringTypeIndex != -1)//nested types { typeDefinition = typeDefinitionDic[index]; } else { typeDefinition = new TypeDefinition(namespaceName, typeName, (TypeAttributes)typeDef.flags); moduleDefinition.Types.Add(typeDefinition); typeDefinitionDic.Add(index, typeDefinition); } //nestedtype for (int i = 0; i < typeDef.nested_type_count; i++) { var nestedIndex = metadata.nestedTypeIndices[typeDef.nestedTypesStart + i]; var nestedTypeDef = metadata.typeDefs[nestedIndex]; var nestedTypeDefinition = new TypeDefinition(metadata.GetStringFromIndex(nestedTypeDef.namespaceIndex), metadata.GetStringFromIndex(nestedTypeDef.nameIndex), (TypeAttributes)nestedTypeDef.flags); typeDefinition.NestedTypes.Add(nestedTypeDefinition); typeDefinitionDic.Add(nestedIndex, nestedTypeDefinition); } } } //先单独处理,因为不知道会不会有问题 for (var index = 0; index < metadata.typeDefs.Length; ++index) { var typeDef = metadata.typeDefs[index]; var typeDefinition = typeDefinitionDic[index]; //parent if (typeDef.parentIndex >= 0) { var parentType = il2cpp.types[typeDef.parentIndex]; var parentTypeRef = GetTypeReference(typeDefinition, parentType); typeDefinition.BaseType = parentTypeRef; } //interfaces for (int i = 0; i < typeDef.interfaces_count; i++) { var interfaceType = il2cpp.types[metadata.interfaceIndices[typeDef.interfacesStart + i]]; var interfaceTypeRef = GetTypeReference(typeDefinition, interfaceType); typeDefinition.Interfaces.Add(new InterfaceImplementation(interfaceTypeRef)); } } //处理field, method, property等等 for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++) { var imageDef = metadata.imageDefs[imageIndex]; var typeEnd = imageDef.typeStart + imageDef.typeCount; for (int index = imageDef.typeStart; index < typeEnd; index++) { var typeDef = metadata.typeDefs[index]; var typeDefinition = typeDefinitionDic[index]; //typeAttribute CreateCustomAttribute(imageDef, typeDef.customAttributeIndex, typeDef.token, typeDefinition.Module, typeDefinition.CustomAttributes); //field var fieldEnd = typeDef.fieldStart + typeDef.field_count; for (var i = typeDef.fieldStart; i < fieldEnd; ++i) { var fieldDef = metadata.fieldDefs[i]; var fieldType = il2cpp.types[fieldDef.typeIndex]; var fieldName = metadata.GetStringFromIndex(fieldDef.nameIndex); var fieldTypeRef = GetTypeReference(typeDefinition, fieldType); var fieldDefinition = new FieldDefinition(fieldName, (FieldAttributes)fieldType.attrs, fieldTypeRef); typeDefinition.Fields.Add(fieldDefinition); //fieldDefault if (fieldDefinition.HasDefault) { var fieldDefault = metadata.GetFieldDefaultValueFromIndex(i); if (fieldDefault != null && fieldDefault.dataIndex != -1) { fieldDefinition.Constant = GetDefaultValue(fieldDefault.dataIndex, fieldDefault.typeIndex); } } //fieldOffset var fieldOffset = il2cpp.GetFieldOffsetFromIndex(index, i - typeDef.fieldStart, i); if (fieldOffset > 0) { var customAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(fieldOffsetAttribute)); var offset = new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{fieldOffset:X}")); customAttribute.Fields.Add(offset); fieldDefinition.CustomAttributes.Add(customAttribute); } //fieldAttribute CreateCustomAttribute(imageDef, fieldDef.customAttributeIndex, fieldDef.token, typeDefinition.Module, fieldDefinition.CustomAttributes); } //method var methodEnd = typeDef.methodStart + typeDef.method_count; for (var i = typeDef.methodStart; i < methodEnd; ++i) { var methodDef = metadata.methodDefs[i]; var methodReturnType = il2cpp.types[methodDef.returnType]; var methodName = metadata.GetStringFromIndex(methodDef.nameIndex); var methodDefinition = new MethodDefinition(methodName, (MethodAttributes)methodDef.flags, typeDefinition.Module.ImportReference(typeof(void))); typeDefinition.Methods.Add(methodDefinition); methodDefinition.ReturnType = GetTypeReference(methodDefinition, methodReturnType); if (methodDefinition.HasBody && typeDefinition.BaseType?.FullName != "System.MulticastDelegate") { var ilprocessor = methodDefinition.Body.GetILProcessor(); ilprocessor.Append(ilprocessor.Create(OpCodes.Nop)); } methodDefinitionDic.Add(i, methodDefinition); //method parameter for (var j = 0; j < methodDef.parameterCount; ++j) { var parameterDef = metadata.parameterDefs[methodDef.parameterStart + j]; var parameterName = metadata.GetStringFromIndex(parameterDef.nameIndex); var parameterType = il2cpp.types[parameterDef.typeIndex]; var parameterTypeRef = GetTypeReference(methodDefinition, parameterType); var parameterDefinition = new ParameterDefinition(parameterName, (ParameterAttributes)parameterType.attrs, parameterTypeRef); methodDefinition.Parameters.Add(parameterDefinition); //ParameterDefault if (parameterDefinition.HasDefault) { var parameterDefault = metadata.GetParameterDefaultValueFromIndex(methodDef.parameterStart + j); if (parameterDefault != null && parameterDefault.dataIndex != -1) { parameterDefinition.Constant = GetDefaultValue(parameterDefault.dataIndex, parameterDefault.typeIndex); } } } //补充泛型参数 if (methodDef.genericContainerIndex >= 0) { var genericContainer = metadata.genericContainers[methodDef.genericContainerIndex]; if (genericContainer.type_argc > methodDefinition.GenericParameters.Count) { for (int j = 0; j < genericContainer.type_argc; j++) { var genericParameterIndex = genericContainer.genericParameterStart + j; var param = metadata.genericParameters[genericParameterIndex]; var genericName = metadata.GetStringFromIndex(param.nameIndex); if (!genericParameterDic.TryGetValue(genericParameterIndex, out var genericParameter)) { genericParameter = new GenericParameter(genericName, methodDefinition); methodDefinition.GenericParameters.Add(genericParameter); genericParameterDic.Add(genericParameterIndex, genericParameter); } else { if (!methodDefinition.GenericParameters.Contains(genericParameter)) { methodDefinition.GenericParameters.Add(genericParameter); } } } } } //methodAddress var methodPointer = il2cpp.GetMethodPointer(methodDef.methodIndex, i, imageIndex, methodDef.token); if (methodPointer > 0) { var customAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(addressAttribute)); var fixedMethodPointer = il2cpp.FixPointer(methodPointer); var rva = new CustomAttributeNamedArgument("RVA", new CustomAttributeArgument(stringType, $"0x{fixedMethodPointer:X}")); var offset = new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{il2cpp.MapVATR(methodPointer):X}")); customAttribute.Fields.Add(rva); customAttribute.Fields.Add(offset); methodDefinition.CustomAttributes.Add(customAttribute); } //methodAttribute CreateCustomAttribute(imageDef, methodDef.customAttributeIndex, methodDef.token, typeDefinition.Module, methodDefinition.CustomAttributes); } //property var propertyEnd = typeDef.propertyStart + typeDef.property_count; for (var i = typeDef.propertyStart; i < propertyEnd; ++i) { var propertyDef = metadata.propertyDefs[i]; var propertyName = metadata.GetStringFromIndex(propertyDef.nameIndex); TypeReference propertyType = null; MethodDefinition GetMethod = null; MethodDefinition SetMethod = null; if (propertyDef.get >= 0) { GetMethod = methodDefinitionDic[typeDef.methodStart + propertyDef.get]; propertyType = GetMethod.ReturnType; } if (propertyDef.set >= 0) { SetMethod = methodDefinitionDic[typeDef.methodStart + propertyDef.set]; if (propertyType == null) { propertyType = SetMethod.Parameters[0].ParameterType; } } var propertyDefinition = new PropertyDefinition(propertyName, (PropertyAttributes)propertyDef.attrs, propertyType) { GetMethod = GetMethod, SetMethod = SetMethod }; typeDefinition.Properties.Add(propertyDefinition); //propertyAttribute CreateCustomAttribute(imageDef, propertyDef.customAttributeIndex, propertyDef.token, typeDefinition.Module, propertyDefinition.CustomAttributes); } //event var eventEnd = typeDef.eventStart + typeDef.event_count; for (var i = typeDef.eventStart; i < eventEnd; ++i) { var eventDef = metadata.eventDefs[i]; var eventName = metadata.GetStringFromIndex(eventDef.nameIndex); var eventType = il2cpp.types[eventDef.typeIndex]; var eventTypeRef = GetTypeReference(typeDefinition, eventType); var eventDefinition = new EventDefinition(eventName, (EventAttributes)eventType.attrs, eventTypeRef); if (eventDef.add >= 0) { eventDefinition.AddMethod = methodDefinitionDic[typeDef.methodStart + eventDef.add]; } if (eventDef.remove >= 0) { eventDefinition.RemoveMethod = methodDefinitionDic[typeDef.methodStart + eventDef.remove]; } if (eventDef.raise >= 0) { eventDefinition.InvokeMethod = methodDefinitionDic[typeDef.methodStart + eventDef.raise]; } typeDefinition.Events.Add(eventDefinition); //eventAttribute CreateCustomAttribute(imageDef, eventDef.customAttributeIndex, eventDef.token, typeDefinition.Module, eventDefinition.CustomAttributes); } //补充泛型参数 if (typeDef.genericContainerIndex >= 0) { var genericContainer = metadata.genericContainers[typeDef.genericContainerIndex]; if (genericContainer.type_argc > typeDefinition.GenericParameters.Count) { for (int i = 0; i < genericContainer.type_argc; i++) { var genericParameterIndex = genericContainer.genericParameterStart + i; var param = metadata.genericParameters[genericParameterIndex]; var genericName = metadata.GetStringFromIndex(param.nameIndex); if (!genericParameterDic.TryGetValue(genericParameterIndex, out var genericParameter)) { genericParameter = new GenericParameter(genericName, typeDefinition); typeDefinition.GenericParameters.Add(genericParameter); genericParameterDic.Add(genericParameterIndex, genericParameter); } else { if (!typeDefinition.GenericParameters.Contains(genericParameter)) { typeDefinition.GenericParameters.Add(genericParameter); } } } } } } } //第三遍,添加SerializeField用于MonoBehaviour的反序列化 if (il2cpp.version > 20) { var engine = Assemblies.Find(x => x.MainModule.Types.Any(t => t.Namespace == "UnityEngine" && t.Name == "SerializeField")); if (engine != null) { var serializeField = engine.MainModule.Types.First(x => x.Name == "SerializeField").Methods.First(); foreach (var imageDef in metadata.imageDefs) { var typeEnd = imageDef.typeStart + imageDef.typeCount; for (int index = imageDef.typeStart; index < typeEnd; index++) { var typeDef = metadata.typeDefs[index]; var typeDefinition = typeDefinitionDic[index]; //field var fieldEnd = typeDef.fieldStart + typeDef.field_count; for (var i = typeDef.fieldStart; i < fieldEnd; ++i) { var fieldDef = metadata.fieldDefs[i]; var fieldName = metadata.GetStringFromIndex(fieldDef.nameIndex); var fieldDefinition = typeDefinition.Fields.First(x => x.Name == fieldName); //fieldAttribute var attributeIndex = metadata.GetCustomAttributeIndex(imageDef, fieldDef.customAttributeIndex, fieldDef.token); if (attributeIndex >= 0) { var attributeTypeRange = metadata.attributeTypeRanges[attributeIndex]; for (int j = 0; j < attributeTypeRange.count; j++) { var attributeTypeIndex = metadata.attributeTypes[attributeTypeRange.start + j]; var attributeType = il2cpp.types[attributeTypeIndex]; if (attributeType.type == Il2CppTypeEnum.IL2CPP_TYPE_CLASS) { var klass = metadata.typeDefs[attributeType.data.klassIndex]; var attributeName = metadata.GetStringFromIndex(klass.nameIndex); if (attributeName == "SerializeField") { var customAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(serializeField)); fieldDefinition.CustomAttributes.Add(customAttribute); } } } } } } } } } }