Ejemplo n.º 1
0
        private static RipResult NSODump(BinaryReader br, uint header, string path, ContainerHandler handler)
        {
            if (header != NSOHeader.ExpectedMagic)
            {
                return(new RipResult(RipResultCode.UnknownFormat));
            }

            br.BaseStream.Position = 0;
            var nso = new NSO(br);

            var dir        = Path.GetDirectoryName(path);
            var folder     = Path.GetFileNameWithoutExtension(path);
            var resultPath = Path.Combine(dir, folder);

            if (resultPath == path)
            {
                resultPath += "_nso";
            }
            Directory.CreateDirectory(resultPath);

            File.WriteAllBytes(Path.Combine(resultPath, "text.bin"), nso.DecompressedText);
            File.WriteAllBytes(Path.Combine(resultPath, "data.bin"), nso.DecompressedData);
            File.WriteAllBytes(Path.Combine(resultPath, "ro.bin"), nso.DecompressedRO);

            return(new RipResult(RipResultCode.Success)
            {
                ResultPath = resultPath
            });
        }
Ejemplo n.º 2
0
        public void EditShinyRate()
        {
            var path = Path.Combine(ROM.PathExeFS, "main");
            var data = FileMitm.ReadAllBytes(path);
            var nso  = new NSO(data);

            var shiny = new ShinyRateGG(nso.DecompressedText);

            if (!shiny.IsEditable)
            {
                WinFormsUtil.Alert("Not able to find shiny rate logic in exefs.");
                return;
            }

            var editor = new ShinyRate(shiny);

            editor.ShowDialog();
            if (!editor.Modified)
            {
                return;
            }

            nso.DecompressedText = shiny.Data;
            FileMitm.WriteAllBytes(path, nso.Write());
        }
Ejemplo n.º 3
0
        public TMEditorGG(byte[] data)
        {
            NSO  = new NSO(data);
            Data = NSO.DecompressedRO;

            // tm list is stored immediately after TM item index list
            var pattern = CodePattern.TMHM_GG;

            Offset = CodePattern.IndexOfBytes(Data, pattern, 0x200_000);
            if (Valid)
            {
                Offset += pattern.Length;
            }
        }
Ejemplo n.º 4
0
        public void EditTypeChart()
        {
            var path = Path.Combine(ROM.PathExeFS, "main");
            var data = FileMitm.ReadAllBytes(path);
            var nso  = new NSO(data);

            byte[] pattern = // N2nn3pia9transport18UnreliableProtocolE
            {
                0x4E, 0x32, 0x6E, 0x6E, 0x33, 0x70, 0x69, 0x61, 0x39, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72,
                0x74, 0x31, 0x38, 0x55, 0x6E, 0x72, 0x65, 0x6C, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x50, 0x72, 0x6F, 0x74,
                0x6F, 0x63, 0x6F, 0x6C, 0x45, 0x00
            };
            int ofs = CodePattern.IndexOfBytes(nso.DecompressedRO, pattern);

            if (ofs < 0)
            {
                WinFormsUtil.Alert("Not able to find type chart data in ExeFS.");
                return;
            }
            ofs += pattern.Length + 0x24; // 0x5B4C0C in lgpe 1.0 RO

            var cdata = new byte[18 * 18];
            var types = ROM.GetStrings(TextName.Types);

            Array.Copy(nso.DecompressedRO, ofs, cdata, 0, cdata.Length);
            var chart = new TypeChartEditor(cdata);

            using var editor = new TypeChart(chart, types);
            editor.ShowDialog();
            if (!editor.Modified)
            {
                return;
            }

            chart.Data.CopyTo(nso.DecompressedRO, ofs);
            data = nso.Write();
            FileMitm.WriteAllBytes(path, data);
        }
Ejemplo n.º 5
0
        private bool Init(string il2CppPath, string metadataPath, out Metadata metadata, out Il2Cpp il2Cpp)
        {
            WriteOutput("Read config...", Color.Black);
            if (File.Exists(realPath + "config.json"))
            {
                _config = JsonConvert.DeserializeObject <Config>(File.ReadAllText(Application.StartupPath + Path.DirectorySeparatorChar + "config.json"));
            }
            else
            {
                _config = new Config();
                WriteOutput("config.json file does not exist. Using defaults", Color.Yellow);
            }

            WriteOutput("Initializing metadata...");
            var metadataBytes = File.ReadAllBytes(metadataPath);

            metadata = new Metadata(new MemoryStream(metadataBytes));
            WriteOutput($"Metadata Version: {metadata.Version}");

            WriteOutput("Initializing il2cpp file...");
            var il2CppBytes  = File.ReadAllBytes(il2CppPath);
            var il2CppMagic  = BitConverter.ToUInt32(il2CppBytes, 0);
            var il2CppMemory = new MemoryStream(il2CppBytes);

            switch (il2CppMagic)
            {
            default:
                WriteOutput("ERROR: il2cpp file not supported.");
                throw new NotSupportedException("ERROR: il2cpp file not supported.");

            case 0x6D736100:
                var web = new WebAssembly(il2CppMemory);
                il2Cpp = web.CreateMemory();
                break;

            case 0x304F534E:
                var nso = new NSO(il2CppMemory);
                il2Cpp = nso.UnCompress();
                break;

            case 0x905A4D:     //PE
                il2Cpp = new PE(il2CppMemory);
                break;

            case 0x464c457f:             //ELF
                if (il2CppBytes[4] == 2) //ELF64
                {
                    var addressValue = "";
                    il2Cpp =
                        InputBox.Show("Input il2cpp dump address or leave empty to force continue:", "", ref addressValue) !=
                        DialogResult.OK
                                ? string.IsNullOrWhiteSpace(addressValue) ? new Elf64(il2CppMemory) :
                        new Elf64(il2CppMemory, addressValue)
                                : new Elf64(il2CppMemory);
                }
                else
                {
                    var addressValue = "";
                    il2Cpp =
                        InputBox.Show("Input il2cpp dump address or leave empty to force continue:", "", ref addressValue) !=
                        DialogResult.OK
                                ? string.IsNullOrWhiteSpace(addressValue) ? new Elf(il2CppMemory) :
                        new Elf(il2CppMemory, addressValue)
                                : new Elf(il2CppMemory);
                }
                break;

            case 0xCAFEBABE:     //FAT Mach-O
            case 0xBEBAFECA:
                var machofat = new MachoFat(new MemoryStream(il2CppBytes));
                WriteOutput("Select Platform: ");
                for (var i = 0; i < machofat.fats.Length; i++)
                {
                    var fat = machofat.fats[i];
                    WriteOutput(fat.magic == 0xFEEDFACF ? $"{i + 1}.64bit " : $"{i + 1}.32bit ");
                }
                WriteOutput("");
                var key   = Console.ReadKey(true);
                var index = int.Parse(key.KeyChar.ToString()) - 1;
                var magic = machofat.fats[index % 2].magic;
                il2CppBytes  = machofat.GetMacho(index % 2);
                il2CppMemory = new MemoryStream(il2CppBytes);
                if (magic == 0xFEEDFACF)
                {
                    goto case 0xFEEDFACF;
                }
                else
                {
                    goto case 0xFEEDFACE;
                }

            case 0xFEEDFACF:     // 64bit Mach-O
                il2Cpp = new Macho64(il2CppMemory);
                break;

            case 0xFEEDFACE:     // 32bit Mach-O
                il2Cpp = new Macho(il2CppMemory);
                break;
            }
            var version = _config.ForceIl2CppVersion ? _config.ForceVersion : metadata.Version;

            il2Cpp.SetProperties(version, metadata.maxMetadataUsages);
            WriteOutput($"Il2Cpp Version: {il2Cpp.Version}");
            if (il2Cpp.Version >= 27 && il2Cpp is ElfBase elf && elf.IsDumped)
            {
                var metadataValue = "";
                if (InputBox.Show("Input global-metadata.dat dump address:", "", ref metadataValue) != DialogResult.OK)
                {
                    return(false);
                }
                metadata.Address = Convert.ToUInt64(metadataValue, 16);
                WriteOutput($"global-metadata.dat dump address: {metadataValue}");
            }

            WriteOutput("Searching...");
            try
            {
                var flag = il2Cpp.PlusSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length, metadata.imageDefs.Length);
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !flag && il2Cpp is PE)
                {
                    WriteOutput("Use custom PE loader");
                    il2Cpp = PELoader.Load(il2CppPath);
                    il2Cpp.SetProperties(version, metadata.maxMetadataUsages);
                    flag = il2Cpp.PlusSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length, metadata.imageDefs.Length);
                }
                if (!flag)
                {
                    flag = il2Cpp.Search();
                }
                if (!flag)
                {
                    flag = il2Cpp.SymbolSearch();
                }
                if (!flag)
                {
                    WriteOutput("ERROR: Can't use auto mode to process file, try manual mode.");
                    WriteOutput("Input CodeRegistration: ");

                    var codeValue = "";
                    if (InputBox.Show(@"Input CodeRegistration: ", "", ref codeValue) != DialogResult.OK)
                    {
                        return(false);
                    }
                    var codeRegistration = Convert.ToUInt64(codeValue, 16);
                    WriteOutput($"CodeRegistration: {codeValue}");

                    var metadataValue = "";
                    if (InputBox.Show("Input MetadataRegistration: ", "", ref metadataValue) != DialogResult.OK)
                    {
                        return(false);
                    }
                    var metadataRegistration = Convert.ToUInt64(metadataValue, 16);
                    WriteOutput($"MetadataRegistration: {metadataValue}");

                    il2Cpp.Init(codeRegistration, metadataRegistration);
                    return(true);
                }
            }
            catch (Exception e)
            {
                WriteOutput(e.Message);
                WriteOutput("ERROR: An error occurred while processing.");
                return(false);
            }
            return(true);
        }
Ejemplo n.º 6
0
        public static DumpType[] Dump(string metadataPath, string il2cppPath, string stringVersion)
        {
            // From Program.cs

            config = new JavaScriptSerializer().Deserialize <Config>(CONFIG_JSON);

            var metadataBytes = File.ReadAllBytes(metadataPath);
            var il2cppBytes   = File.ReadAllBytes(il2cppPath);

            var sanity = BitConverter.ToUInt32(metadataBytes, 0);

            if (sanity != 0xFAB11BAF)
            {
                throw new Exception("ERROR: Metadata file supplied is not valid metadata file.");
            }
            float fixedMetadataVersion;
            var   metadataVersion = BitConverter.ToInt32(metadataBytes, 4);

            if (metadataVersion == 24)
            {
                var versionSplit = Array.ConvertAll(Regex.Replace(stringVersion, @"\D", ".").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries), int.Parse);
                var unityVersion = new Version(versionSplit[0], versionSplit[1]);
                if (unityVersion >= Unity20191)
                {
                    fixedMetadataVersion = 24.2f;
                }
                else if (unityVersion >= Unity20183)
                {
                    fixedMetadataVersion = 24.1f;
                }
                else
                {
                    fixedMetadataVersion = metadataVersion;
                }
            }
            else
            {
                fixedMetadataVersion = metadataVersion;
            }
            Console.WriteLine("Initializing metadata...");
            metadata = new Metadata(new MemoryStream(metadataBytes), fixedMetadataVersion);
            //判断il2cpp的magic
            var il2cppMagic = BitConverter.ToUInt32(il2cppBytes, 0);
            var isElf       = false;
            var isPE        = false;
            var is64bit     = false;
            var isNSO       = false;

            switch (il2cppMagic)
            {
            default:
                throw new Exception("ERROR: il2cpp file not supported.");

            case 0x304F534E:
                isNSO   = true;
                is64bit = true;
                break;

            case 0x905A4D:     //PE
                isPE = true;
                break;

            case 0x464c457f:             //ELF
                isElf = true;
                if (il2cppBytes[4] == 2) //ELF64
                {
                    is64bit = true;
                }
                break;

            case 0xCAFEBABE:     //FAT Mach-O
            case 0xBEBAFECA:
            // To 64bit
            case 0xFEEDFACF:     // 64bit Mach-O
                is64bit = true;
                break;

            case 0xFEEDFACE:     // 32bit Mach-O
                break;
            }

            var version = config.ForceIl2CppVersion ? config.ForceVersion : metadata.version;

            if (isNSO)
            {
                var nso = new NSO(new MemoryStream(il2cppBytes), version, metadata.maxMetadataUsages);
                il2cpp = nso.UnCompress();
            }
            else if (isPE)
            {
                il2cpp = new PE(new MemoryStream(il2cppBytes), version, metadata.maxMetadataUsages);
            }
            else if (isElf)
            {
                if (is64bit)
                {
                    il2cpp = new Elf64(new MemoryStream(il2cppBytes), version, metadata.maxMetadataUsages);
                }
                else
                {
                    il2cpp = new Elf(new MemoryStream(il2cppBytes), version, metadata.maxMetadataUsages);
                }
            }
            else if (is64bit)
            {
                il2cpp = new Macho64(new MemoryStream(il2cppBytes), version, metadata.maxMetadataUsages);
            }
            else
            {
                il2cpp = new Macho(new MemoryStream(il2cppBytes), version, metadata.maxMetadataUsages);
            }
            Console.WriteLine("Searching...");
            try
            {
                // Select Auto(Plus)
                bool flag = il2cpp.PlusSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length);
                if (!flag)
                {
                    throw new Exception();
                }
            }
            catch
            {
                throw new Exception("ERROR: Can't use this mode to process file, try another mode.");
            }

            Console.WriteLine("Dumping...");
            //dump type
            var dumpTypes = new List <DumpType>();

            for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++)
            {
                try
                {
                    var imageDef = metadata.imageDefs[imageIndex];
                    var typeEnd  = imageDef.typeStart + imageDef.typeCount;
                    for (int idx = imageDef.typeStart; idx < typeEnd; idx++)
                    {
                        var dumpType = new DumpType();
                        var typeDef  = metadata.typeDefs[idx];
                        typeDefImageIndices.Add(typeDef, imageIndex);
                        var isStruct = false;
                        var isEnum   = false;
                        var extends  = new List <string>();
                        if (typeDef.parentIndex >= 0)
                        {
                            var parent     = il2cpp.types[typeDef.parentIndex];
                            var parentName = GetTypeName(parent);
                            if (parentName == "ValueType")
                            {
                                isStruct = true;
                            }
                            else if (parentName == "Enum")
                            {
                                isEnum = true;
                            }
                            else if (parentName != "object")
                            {
                                extends.Add(parentName);
                            }
                        }
                        //implementedInterfaces
                        if (typeDef.interfaces_count > 0)
                        {
                            for (int i = 0; i < typeDef.interfaces_count; i++)
                            {
                                var @interface = il2cpp.types[metadata.interfaceIndices[typeDef.interfacesStart + i]];
                                extends.Add(GetTypeName(@interface));
                            }
                        }
                        dumpType.Namespace = metadata.GetStringFromIndex(typeDef.namespaceIndex);
                        var dumpTypeAttributes = new List <DumpAttribute>();
                        var typeAttributes     = GetCustomAttributes(imageDef, typeDef.customAttributeIndex, typeDef.token);
                        if (typeAttributes != null)
                        {
                            dumpTypeAttributes.AddRange(typeAttributes);
                        }
                        if (config.DumpAttribute && (typeDef.flags & TYPE_ATTRIBUTE_SERIALIZABLE) != 0)
                        {
                            dumpTypeAttributes.Add(new DumpAttribute {
                                Name = "[Serializable]"
                            });
                        }
                        dumpType.Attributes = dumpTypeAttributes.ToArray();
                        var visibility = typeDef.flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
                        switch (visibility)
                        {
                        case TYPE_ATTRIBUTE_PUBLIC:
                        case TYPE_ATTRIBUTE_NESTED_PUBLIC:
                            dumpType.Modifier += "public ";
                            break;

                        case TYPE_ATTRIBUTE_NOT_PUBLIC:
                        case TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM:
                        case TYPE_ATTRIBUTE_NESTED_ASSEMBLY:
                            dumpType.Modifier += "internal ";
                            break;

                        case TYPE_ATTRIBUTE_NESTED_PRIVATE:
                            dumpType.Modifier += "private ";
                            break;

                        case TYPE_ATTRIBUTE_NESTED_FAMILY:
                            dumpType.Modifier += "protected ";
                            break;

                        case TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM:
                            dumpType.Modifier += "protected internal ";
                            break;
                        }
                        if ((typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0 && (typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0)
                        {
                            dumpType.Modifier += "static ";
                        }
                        else if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) == 0 && (typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0)
                        {
                            dumpType.Modifier += "abstract ";
                        }
                        else if (!isStruct && !isEnum && (typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0)
                        {
                            dumpType.Modifier += "sealed ";
                        }
                        dumpType.Modifier.TrimEnd();
                        if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) != 0)
                        {
                            dumpType.TypeStr = "interface";
                        }
                        else if (isStruct)
                        {
                            dumpType.TypeStr = "struct";
                        }
                        else if (isEnum)
                        {
                            dumpType.TypeStr = "enum";
                        }
                        else
                        {
                            dumpType.TypeStr = "class";
                        }
                        var typeName = GetTypeName(typeDef);
                        dumpType.Name = $"{typeName}";
                        if (extends.Count > 0)
                        {
                            dumpType.Extends = extends.ToArray();
                        }
                        //dump field
                        var dumpFields = new List <DumpField>();
                        if (config.DumpField && typeDef.field_count > 0)
                        {
                            var fieldEnd = typeDef.fieldStart + typeDef.field_count;
                            for (var i = typeDef.fieldStart; i < fieldEnd; ++i)
                            {
                                //dump_field(i, idx, i - typeDef.fieldStart);
                                var dumpField         = new DumpField();
                                var fieldDef          = metadata.fieldDefs[i];
                                var fieldType         = il2cpp.types[fieldDef.typeIndex];
                                var fieldDefaultValue = metadata.GetFieldDefaultValueFromIndex(i);
                                var fieldAttributes   = GetCustomAttributes(imageDef, fieldDef.customAttributeIndex, fieldDef.token);
                                if (fieldAttributes != null)
                                {
                                    dumpField.Attributes = fieldAttributes;
                                }
                                var access = fieldType.attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
                                switch (access)
                                {
                                case FIELD_ATTRIBUTE_PRIVATE:
                                    dumpField.Modifier += "private ";
                                    break;

                                case FIELD_ATTRIBUTE_PUBLIC:
                                    dumpField.Modifier += "public ";
                                    break;

                                case FIELD_ATTRIBUTE_FAMILY:
                                    dumpField.Modifier += "protected ";
                                    break;

                                case FIELD_ATTRIBUTE_ASSEMBLY:
                                case FIELD_ATTRIBUTE_FAM_AND_ASSEM:
                                    dumpField.Modifier += "internal ";
                                    break;

                                case FIELD_ATTRIBUTE_FAM_OR_ASSEM:
                                    dumpField.Modifier += "protected internal ";
                                    break;
                                }
                                if ((fieldType.attrs & FIELD_ATTRIBUTE_LITERAL) != 0)
                                {
                                    dumpField.Modifier += "const ";
                                }
                                else
                                {
                                    if ((fieldType.attrs & FIELD_ATTRIBUTE_STATIC) != 0)
                                    {
                                        dumpField.Modifier += "static ";
                                    }
                                    if ((fieldType.attrs & FIELD_ATTRIBUTE_INIT_ONLY) != 0)
                                    {
                                        dumpField.Modifier += "readonly ";
                                    }
                                }
                                dumpField.TypeStr = GetTypeName(fieldType);
                                dumpField.Name    = metadata.GetStringFromIndex(fieldDef.nameIndex);
                                if (fieldDefaultValue != null && fieldDefaultValue.dataIndex != -1)
                                {
                                    var pointer = metadata.GetDefaultValueFromIndex(fieldDefaultValue.dataIndex);
                                    if (pointer > 0)
                                    {
                                        var fieldDefaultValueType = il2cpp.types[fieldDefaultValue.typeIndex];
                                        metadata.Position = pointer;
                                        object val = null;
                                        switch (fieldDefaultValueType.type)
                                        {
                                        case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN:
                                            val = metadata.ReadBoolean();
                                            break;

                                        case Il2CppTypeEnum.IL2CPP_TYPE_U1:
                                            val = metadata.ReadByte();
                                            break;

                                        case Il2CppTypeEnum.IL2CPP_TYPE_I1:
                                            val = metadata.ReadSByte();
                                            break;

                                        case Il2CppTypeEnum.IL2CPP_TYPE_CHAR:
                                            val = BitConverter.ToChar(metadata.ReadBytes(2), 0);
                                            break;

                                        case Il2CppTypeEnum.IL2CPP_TYPE_U2:
                                            val = metadata.ReadUInt16();
                                            break;

                                        case Il2CppTypeEnum.IL2CPP_TYPE_I2:
                                            val = metadata.ReadInt16();
                                            break;

                                        case Il2CppTypeEnum.IL2CPP_TYPE_U4:
                                            val = metadata.ReadUInt32();
                                            break;

                                        case Il2CppTypeEnum.IL2CPP_TYPE_I4:
                                            val = metadata.ReadInt32();
                                            break;

                                        case Il2CppTypeEnum.IL2CPP_TYPE_U8:
                                            val = metadata.ReadUInt64();
                                            break;

                                        case Il2CppTypeEnum.IL2CPP_TYPE_I8:
                                            val = metadata.ReadInt64();
                                            break;

                                        case Il2CppTypeEnum.IL2CPP_TYPE_R4:
                                            val = metadata.ReadSingle();
                                            break;

                                        case Il2CppTypeEnum.IL2CPP_TYPE_R8:
                                            val = metadata.ReadDouble();
                                            break;

                                        case Il2CppTypeEnum.IL2CPP_TYPE_STRING:
                                            var len = metadata.ReadInt32();
                                            val = Encoding.UTF8.GetString(metadata.ReadBytes(len));
                                            break;
                                        }
                                        if (val is string str)
                                        {
                                            dumpField.ValueStr = $"\"{ToEscapedString(str)}\"";
                                        }
                                        else if (val is char c)
                                        {
                                            var v = (int)c;
                                            dumpField.ValueStr = $"'\\x{v:x}'";
                                        }
                                        else if (val != null)
                                        {
                                            dumpField.ValueStr = $"{val}";
                                        }
                                    }
                                }
                                dumpFields.Add(dumpField);
                            }
                        }
                        dumpType.Fields = dumpFields.ToArray();
                        //dump property
                        var dumpProperties = new List <DumpProperty>();
                        if (config.DumpProperty && typeDef.property_count > 0)
                        {
                            var propertyEnd = typeDef.propertyStart + typeDef.property_count;
                            for (var i = typeDef.propertyStart; i < propertyEnd; ++i)
                            {
                                var dumpProperty       = new DumpProperty();
                                var propertyDef        = metadata.propertyDefs[i];
                                var propertyAttributes = GetCustomAttributes(imageDef, propertyDef.customAttributeIndex, propertyDef.token);
                                if (propertyAttributes != null)
                                {
                                    dumpProperty.Attributes = propertyAttributes;
                                }
                                if (propertyDef.get >= 0)
                                {
                                    var methodDef = metadata.methodDefs[typeDef.methodStart + propertyDef.get];
                                    dumpProperty.Modifier = GetModifiers(methodDef);
                                    var propertyType = il2cpp.types[methodDef.returnType];
                                    dumpProperty.TypeStr = GetTypeName(propertyType);
                                    dumpProperty.Name    = metadata.GetStringFromIndex(propertyDef.nameIndex);
                                }
                                else if (propertyDef.set > 0)
                                {
                                    var methodDef = metadata.methodDefs[typeDef.methodStart + propertyDef.set];
                                    dumpProperty.Modifier = GetModifiers(methodDef);
                                    var parameterDef = metadata.parameterDefs[methodDef.parameterStart];
                                    var propertyType = il2cpp.types[parameterDef.typeIndex];
                                    dumpProperty.TypeStr = GetTypeName(propertyType);
                                    dumpProperty.Name    = metadata.GetStringFromIndex(propertyDef.nameIndex);
                                }
                                dumpProperty.Access += "{ ";
                                if (propertyDef.get >= 0)
                                {
                                    dumpProperty.Access += "get; ";
                                }
                                if (propertyDef.set >= 0)
                                {
                                    dumpProperty.Access += "set; ";
                                }
                                dumpProperty.Access += "}";
                                dumpProperties.Add(dumpProperty);
                            }
                        }
                        dumpType.Properties = dumpProperties.ToArray();
                        //dump method
                        var dumpMethods = new List <DumpMethod>();
                        if (config.DumpMethod && typeDef.method_count > 0)
                        {
                            var methodEnd = typeDef.methodStart + typeDef.method_count;
                            for (var i = typeDef.methodStart; i < methodEnd; ++i)
                            {
                                var dumpMethod       = new DumpMethod();
                                var methodDef        = metadata.methodDefs[i];
                                var methodAttributes = GetCustomAttributes(imageDef, methodDef.customAttributeIndex, methodDef.token);
                                if (methodAttributes != null)
                                {
                                    dumpMethod.Attributes = methodAttributes;
                                }
                                dumpMethod.Modifier = GetModifiers(methodDef);
                                var methodReturnType = il2cpp.types[methodDef.returnType];
                                var methodName       = metadata.GetStringFromIndex(methodDef.nameIndex);
                                dumpMethod.TypeStr = GetTypeName(methodReturnType);
                                dumpMethod.Name    = methodName;
                                for (var j = 0; j < methodDef.parameterCount; ++j)
                                {
                                    var parameterStr      = "";
                                    var parameterDef      = metadata.parameterDefs[methodDef.parameterStart + j];
                                    var parameterName     = metadata.GetStringFromIndex(parameterDef.nameIndex);
                                    var parameterType     = il2cpp.types[parameterDef.typeIndex];
                                    var parameterTypeName = GetTypeName(parameterType);
                                    if ((parameterType.attrs & PARAM_ATTRIBUTE_OPTIONAL) != 0)
                                    {
                                        parameterStr += "optional ";
                                    }
                                    if ((parameterType.attrs & PARAM_ATTRIBUTE_OUT) != 0)
                                    {
                                        parameterStr += "out ";
                                    }
                                    parameterStr         += $"{parameterTypeName} {parameterName}";
                                    dumpMethod.Parameters = new string[] { parameterStr };
                                }
                                if (config.DumpMethodOffset)
                                {
                                    var methodPointer = il2cpp.GetMethodPointer(methodDef.methodIndex, i, imageIndex, methodDef.token);
                                    if (methodPointer > 0)
                                    {
                                        dumpMethod.Address = il2cpp.MapVATR(methodPointer);
                                    }
                                }
                                dumpMethods.Add(dumpMethod);
                            }
                        }
                        dumpType.Methods = dumpMethods.ToArray();
                        dumpTypes.Add(dumpType);
                    }
                }
                catch
                {
                    throw new Exception("ERROR: Some errors in dumping.");
                }
            }

            return(dumpTypes.ToArray());
        }