Exemple #1
0
 private void CreateCustomAttribute(Il2CppImageDefinition imageDef, int customAttributeIndex, uint token, ModuleDefinition moduleDefinition, Collection <CustomAttribute> customAttributes)
 {
     if (il2cpp.version > 20)
     {
         var attributeIndex = metadata.GetCustomAttributeIndex(imageDef, customAttributeIndex, 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];
                 var attributeName      = GetTypeName(attributeType);
                 if (attributeName == "CompilerGeneratedAttribute" ||
                     attributeName == "DebuggerBrowsableAttribute" ||
                     attributeName == "SerializeField")
                 {
                     continue;
                 }
                 var methodPointer      = il2cpp.customAttributeGenerators[attributeIndex];
                 var fixedMethodPointer = il2cpp.FixPointer(methodPointer);
                 var customAttribute    = new CustomAttribute(moduleDefinition.ImportReference(attributeAttribute));
                 var name   = new CustomAttributeNamedArgument("Name", new CustomAttributeArgument(stringType, attributeName));
                 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(name);
                 customAttribute.Fields.Add(rva);
                 customAttribute.Fields.Add(offset);
                 customAttributes.Add(customAttribute);
             }
         }
     }
 }
        public string GetCustomAttribute(Il2CppImageDefinition imageDef, int customAttributeIndex, uint token, string padding = "")
        {
            if (il2Cpp.Version < 21)
            {
                return(string.Empty);
            }
            var attributeIndex = metadata.GetCustomAttributeIndex(imageDef, customAttributeIndex, token);

            if (attributeIndex >= 0)
            {
                var methodPointer      = executor.customAttributeGenerators[attributeIndex];
                var fixedMethodPointer = il2Cpp.GetRVA(methodPointer);
                var attributeTypeRange = metadata.attributeTypeRanges[attributeIndex];
                var sb = new StringBuilder();
                for (var i = 0; i < attributeTypeRange.count; i++)
                {
                    var typeIndex = metadata.attributeTypes[attributeTypeRange.start + i];
                    sb.AppendFormat("{0}[{1}] // RVA: 0x{2:X} Offset: 0x{3:X} VA: 0x{4:X}\n",
                                    padding,
                                    executor.GetTypeName(il2Cpp.types[typeIndex], false, false),
                                    fixedMethodPointer,
                                    il2Cpp.MapVATR(methodPointer),
                                    methodPointer);
                }
                return(sb.ToString());
            }
            else
            {
                return(string.Empty);
            }
        }
Exemple #3
0
        private void CreateCustomAttribute(Il2CppImageDefinition imageDef, int customAttributeIndex, uint token, ModuleDefinition moduleDefinition, Collection <CustomAttribute> customAttributes)
        {
            var attributeIndex = metadata.GetCustomAttributeIndex(imageDef, customAttributeIndex, token);

            if (attributeIndex >= 0)
            {
                var attributeTypeRange = metadata.attributeTypeRanges[attributeIndex];
                for (int i = 0; i < attributeTypeRange.count; i++)
                {
                    var attributeTypeIndex = metadata.attributeTypes[attributeTypeRange.start + i];
                    var attributeType      = il2Cpp.types[attributeTypeIndex];
                    var typeDefinition     = typeDefinitionDic[attributeType.data.klassIndex];
                    if (knownAttributes.TryGetValue(typeDefinition.FullName, out var methodDefinition))
                    {
                        var customAttribute = new CustomAttribute(moduleDefinition.ImportReference(methodDefinition));
                        customAttributes.Add(customAttribute);
                    }
                    else
                    {
                        var methodPointer      = il2Cpp.customAttributeGenerators[attributeIndex];
                        var fixedMethodPointer = il2Cpp.FixPointer(methodPointer);
                        var customAttribute    = new CustomAttribute(moduleDefinition.ImportReference(attributeAttribute));
                        var name   = new CustomAttributeNamedArgument("Name", new CustomAttributeArgument(stringType, typeDefinition.Name));
                        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(name);
                        customAttribute.Fields.Add(rva);
                        customAttribute.Fields.Add(offset);
                        customAttributes.Add(customAttribute);
                    }
                }
            }
        }
Exemple #4
0
        private static string GetCustomAttribute(Il2CppImageDefinition image, int customAttributeIndex, uint token, string padding = "")
        {
            if (!config.DumpAttribute || il2cpp.version < 21)
            {
                return(string.Empty);
            }
            var index = metadata.GetCustomAttributeIndex(image, customAttributeIndex, token);

            if (index >= 0)
            {
                var attributeTypeRange = metadata.attributeTypeRanges[index];
                var sb = new StringBuilder();
                for (var i = 0; i < attributeTypeRange.count; i++)
                {
                    var typeIndex     = metadata.attributeTypes[attributeTypeRange.start + i];
                    var methodPointer = il2cpp.customAttributeGenerators[index];
                    sb.AppendFormat("{0}[{1}] // RVA: 0x{2:X} Offset: 0x{3:X}\n", padding, GetTypeName(il2cpp.types[typeIndex]), methodPointer, il2cpp.MapVATR(methodPointer));
                }
                return(sb.ToString());
            }
            else
            {
                return(string.Empty);
            }
        }
        public string GetCustomAttribute(Il2CppImageDefinition imageDef, int customAttributeIndex, uint token, string padding = "")
        {
            if (il2Cpp.Version < 21)
            {
                return(string.Empty);
            }
            var attributeIndex = metadata.GetCustomAttributeIndex(imageDef, customAttributeIndex, token);

            if (attributeIndex >= 0)
            {
                if (il2Cpp.Version < 29)
                {
                    var methodPointer      = executor.customAttributeGenerators[attributeIndex];
                    var fixedMethodPointer = il2Cpp.GetRVA(methodPointer);
                    var attributeTypeRange = metadata.attributeTypeRanges[attributeIndex];
                    var sb = new StringBuilder();
                    for (var i = 0; i < attributeTypeRange.count; i++)
                    {
                        var typeIndex = metadata.attributeTypes[attributeTypeRange.start + i];
                        sb.AppendFormat("{0}[{1}] // RVA: 0x{2:X} Offset: 0x{3:X} VA: 0x{4:X}\n",
                                        padding,
                                        executor.GetTypeName(il2Cpp.types[typeIndex], false, false),
                                        fixedMethodPointer,
                                        il2Cpp.MapVATR(methodPointer),
                                        methodPointer);
                    }
                    return(sb.ToString());
                }
                else
                {
                    var startRange = metadata.attributeDataRanges[attributeIndex];
                    var endRange   = metadata.attributeDataRanges[attributeIndex + 1];
                    metadata.Position = metadata.header.attributeDataOffset + startRange.startOffset;
                    var buff   = metadata.ReadBytes((int)(endRange.startOffset - startRange.startOffset));
                    var reader = new CustomAttributeDataReader(executor, buff);
                    if (reader.Count == 0)
                    {
                        return(string.Empty);
                    }
                    var sb = new StringBuilder();
                    for (var i = 0; i < reader.Count; i++)
                    {
                        sb.Append(padding);
                        sb.Append(reader.GetStringCustomAttributeData());
                        sb.Append("\n");
                    }
                    return(sb.ToString());
                }
            }
            else
            {
                return(string.Empty);
            }
        }
        public DummyAssemblyCreator(Metadata metadata, Il2Cpp il2cpp)
        {
            this.metadata = metadata;
            this.il2cpp   = il2cpp;
            //Il2CppDummyDll
            var il2CppDummyDll       = AssemblyDefinition.ReadAssembly(new MemoryStream(Resource1.Il2CppDummyDll));
            var addressAttribute     = il2CppDummyDll.MainModule.Types.First(x => x.Name == "AddressAttribute").Methods.First();
            var fieldOffsetAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "FieldOffsetAttribute").Methods.First();
            var stringType           = il2CppDummyDll.MainModule.TypeSystem.String;
            var resolver             = new MyAssemblyResolver();
            var moduleParameters     = new ModuleParameters
            {
                Kind             = ModuleKind.Dll,
                AssemblyResolver = resolver
            };

            //创建程序集,同时创建所有类
            foreach (var imageDef in metadata.imageDefs)
            {
                var assemblyName       = new AssemblyNameDefinition(metadata.GetStringFromIndex(imageDef.nameIndex).Replace(".dll", ""), new Version("3.7.1.6"));
                var assemblyDefinition = AssemblyDefinition.CreateAssembly(assemblyName, metadata.GetStringFromIndex(imageDef.nameIndex), 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.uiNumTypes; ++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(interfaceTypeRef);
                }
            }
            //处理field, method, property等等
            for (var index = 0; index < metadata.uiNumTypes; ++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);
                    //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.Import(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 methodReturnType = il2cpp.types[methodDef.returnType];
                    var methodName       = metadata.GetStringFromIndex(methodDef.nameIndex);
                    var methodDefinition = new MethodDefinition(methodName, (MethodAttributes)methodDef.flags, typeDefinition.Module.Import(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 = methodDefinition.GenericParameters.Count + 1; j <= genericContainer.type_argc; j++)
                            {
                                var genericParameter = new GenericParameter("T" + j, methodDefinition);
                                methodDefinition.GenericParameters.Add(genericParameter);
                            }
                        }
                    }
                    //address
                    ulong methodPointer;
                    if (methodDef.methodIndex >= 0)
                    {
                        methodPointer = il2cpp.methodPointers[methodDef.methodIndex];
                    }
                    else
                    {
                        il2cpp.genericMethoddDictionary.TryGetValue(i, out methodPointer);
                    }
                    if (methodPointer > 0)
                    {
                        var customAttribute = new CustomAttribute(typeDefinition.Module.Import(addressAttribute));
                        var rva             = new CustomAttributeNamedArgument("RVA", new CustomAttributeArgument(stringType, $"0x{methodPointer: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);
                    }
                }
                //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);
                }
                //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);
                }
                //补充泛型参数
                if (typeDef.genericContainerIndex >= 0)
                {
                    var genericContainer = metadata.genericContainers[typeDef.genericContainerIndex];
                    if (genericContainer.type_argc > typeDefinition.GenericParameters.Count)
                    {
                        for (int j = typeDefinition.GenericParameters.Count + 1; j <= genericContainer.type_argc; j++)
                        {
                            var genericParameter = new GenericParameter("T" + j, typeDefinition);
                            typeDefinition.GenericParameters.Add(genericParameter);
                        }
                    }
                }
            }
            //第三遍,添加CustomAttribute。只添加SerializeField用于MonoBehaviour的反序列化
            if (il2cpp.version > 20)
            {
                var engine         = Assemblies.Find(x => x.MainModule.Types.Any(t => t.Namespace == "UnityEngine" && t.Name == "SerializeField"));
                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.Import(serializeField));
                                            fieldDefinition.CustomAttributes.Add(customAttribute);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Exemple #7
0
        private void CreateCustomAttribute(Il2CppImageDefinition imageDef, int customAttributeIndex, uint token, ModuleDefinition moduleDefinition, Collection <CustomAttribute> customAttributes)
        {
            var attributeIndex = metadata.GetCustomAttributeIndex(imageDef, customAttributeIndex, token);

            if (attributeIndex >= 0)
            {
                try
                {
                    if (il2Cpp.Version < 29)
                    {
                        var attributeTypeRange = metadata.attributeTypeRanges[attributeIndex];
                        for (int i = 0; i < attributeTypeRange.count; i++)
                        {
                            var attributeTypeIndex = metadata.attributeTypes[attributeTypeRange.start + i];
                            var attributeType      = il2Cpp.types[attributeTypeIndex];
                            var typeDef            = executor.GetTypeDefinitionFromIl2CppType(attributeType);
                            var typeDefinition     = typeDefinitionDic[typeDef];
                            if (!TryRestoreCustomAttribute(typeDefinition, moduleDefinition, customAttributes))
                            {
                                var methodPointer      = executor.customAttributeGenerators[attributeIndex];
                                var fixedMethodPointer = il2Cpp.GetRVA(methodPointer);
                                var customAttribute    = new CustomAttribute(moduleDefinition.ImportReference(attributeAttribute));
                                var name   = new CustomAttributeNamedArgument("Name", new CustomAttributeArgument(stringType, typeDefinition.Name));
                                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(name);
                                customAttribute.Fields.Add(rva);
                                customAttribute.Fields.Add(offset);
                                customAttributes.Add(customAttribute);
                            }
                        }
                    }
                    else
                    {
                        var startRange = metadata.attributeDataRanges[attributeIndex];
                        var endRange   = metadata.attributeDataRanges[attributeIndex + 1];
                        metadata.Position = metadata.header.attributeDataOffset + startRange.startOffset;
                        var buff   = metadata.ReadBytes((int)(endRange.startOffset - startRange.startOffset));
                        var reader = new CustomAttributeDataReader(executor, buff);
                        if (reader.Count != 0)
                        {
                            for (var i = 0; i < reader.Count; i++)
                            {
                                var visitor          = reader.VisitCustomAttributeData();
                                var methodDefinition = methodDefinitionDic[visitor.CtorIndex];
                                var customAttribute  = new CustomAttribute(moduleDefinition.ImportReference(methodDefinition));
                                foreach (var argument in visitor.Arguments)
                                {
                                    var parameterDefinition     = methodDefinition.Parameters[argument.Index];
                                    var customAttributeArgument = CreateCustomAttributeArgument(parameterDefinition.ParameterType, argument.Value, methodDefinition);
                                    customAttribute.ConstructorArguments.Add(customAttributeArgument);
                                }
                                foreach (var field in visitor.Fields)
                                {
                                    var fieldDefinition              = fieldDefinitionDic[field.Index];
                                    var customAttributeArgument      = CreateCustomAttributeArgument(fieldDefinition.FieldType, field.Value, fieldDefinition);
                                    var customAttributeNamedArgument = new CustomAttributeNamedArgument(fieldDefinition.Name, customAttributeArgument);
                                    customAttribute.Fields.Add(customAttributeNamedArgument);
                                }
                                foreach (var property in visitor.Properties)
                                {
                                    var propertyDefinition           = propertyDefinitionDic[property.Index];
                                    var customAttributeArgument      = CreateCustomAttributeArgument(propertyDefinition.PropertyType, property.Value, propertyDefinition);
                                    var customAttributeNamedArgument = new CustomAttributeNamedArgument(propertyDefinition.Name, customAttributeArgument);
                                    customAttribute.Properties.Add(customAttributeNamedArgument);
                                }
                                customAttributes.Add(customAttribute);
                            }
                        }
                    }
                }
                catch
                {
                    Console.WriteLine($"ERROR: Error while restoring attributeIndex {attributeIndex}");
                }
            }
        }