Beispiel #1
0
        public static void Dumpv23(byte[] il2cppfile, byte[] metadatafile)
        {
            //判断il2cpp的magic
            var il2cppmagic = BitConverter.ToUInt32(il2cppfile, 0);
            var isElf       = false;

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

            case 0x464c457f:
                isElf = true;
                goto case 0xFEEDFACE;

            case 0xCAFEBABE:
            case 0xBEBAFECA:
                Console.Write("WARNING: fat macho will only dump the first object file.");
                var fat = new MachoFat(new MemoryStream(il2cppfile));
                il2cppfile = fat.GetFirstMacho();
                var magic = fat.GetFirstMachoMagic();
                if (magic == 0xFEEDFACF)     // 64-bit mach object file
                {
                    goto case 0xFEEDFACF;
                }
                else
                {
                    goto case 0xFEEDFACE;
                }

            case 0xFEEDFACF:     // 64-bit mach object file
                _64bit.Dump.Dump64bit(il2cppfile, metadatafile);
                break;

            case 0xFEEDFACE:     // 32-bit mach object file
                Console.WriteLine("Select Mode: 1. Manual 2.Auto");
                var key = Console.ReadKey(true);
                if (key.KeyChar == '2')
                {
                    metadata = new Metadata(new MemoryStream(metadatafile));
                    if (isElf)
                    {
                        il2cpp = new Elf(new MemoryStream(il2cppfile));
                    }
                    else
                    {
                        il2cpp = new Macho(new MemoryStream(il2cppfile));
                    }
                    if (!il2cpp.Auto())
                    {
                        throw new Exception(
                                  "ERROR: Unable to process file automatically, try to use manual mode.");
                    }
                }
                else if (key.KeyChar == '1')
                {
                    Console.Write("Input CodeRegistration(R0): ");
                    var codeRegistration = Convert.ToUInt32(Console.ReadLine(), 16);
                    Console.Write("Input MetadataRegistration(R1): ");
                    var metadataRegistration = Convert.ToUInt32(Console.ReadLine(), 16);
                    metadata = new Metadata(new MemoryStream(metadatafile));
                    if (isElf)
                    {
                        il2cpp = new Elf(new MemoryStream(il2cppfile), codeRegistration,
                                         metadataRegistration);
                    }
                    else
                    {
                        il2cpp = new Macho(new MemoryStream(il2cppfile), codeRegistration,
                                           metadataRegistration);
                    }
                }
                else
                {
                    return;
                }
                var writer = new StreamWriter(new FileStream("dump.cs", FileMode.Create));
                Console.WriteLine("Dumping...");
                //dump_image();
                for (var imageIndex = 0; imageIndex < metadata.uiImageCount; imageIndex++)
                {
                    var imageDef = metadata.imageDefs[imageIndex];
                    writer.Write(
                        $"// Image {imageIndex}: {metadata.GetString(imageDef.nameIndex)} - {imageDef.typeStart}\n");
                }
                for (var idx = 0; idx < metadata.uiNumTypes; ++idx)
                {
                    try
                    {
                        //dump_class(i);
                        var typeDef = metadata.typeDefs[idx];
                        writer.Write($"\n// Namespace: {metadata.GetString(typeDef.namespaceIndex)}\n");
                        writer.Write(GetCustomAttribute(typeDef.customAttributeIndex));
                        if ((typeDef.flags & TYPE_ATTRIBUTE_SERIALIZABLE) != 0)
                        {
                            writer.Write("[Serializable]\n");
                        }
                        if ((typeDef.flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_PUBLIC)
                        {
                            writer.Write("public ");
                        }
                        else if ((typeDef.flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) ==
                                 TYPE_ATTRIBUTE_NOT_PUBLIC)
                        {
                            writer.Write("internal ");
                        }
                        if ((typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0)
                        {
                            writer.Write("abstract ");
                        }
                        if ((typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0)
                        {
                            writer.Write("sealed ");
                        }
                        if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) != 0)
                        {
                            writer.Write("interface ");
                        }
                        else
                        {
                            writer.Write("class ");
                        }
                        writer.Write($"{metadata.GetString(typeDef.nameIndex)}");
                        if (typeDef.parentIndex >= 0)
                        {
                            var parent     = il2cpp.types[typeDef.parentIndex];
                            var parentname = get_type_name(parent);
                            if (parentname != "object")
                            {
                                writer.Write($" : {parentname}");
                            }
                        }
                        writer.Write($" // TypeDefIndex: {idx}\n{{\n");
                        if (typeDef.field_count > 0)
                        {
                            writer.Write("\t// Fields\n");
                            var fieldEnd = typeDef.fieldStart + typeDef.field_count;
                            for (var i = typeDef.fieldStart; i < fieldEnd; ++i)
                            {
                                //dump_field(i, idx, i - typeDef.fieldStart);
                                var pField   = metadata.fieldDefs[i];
                                var pType    = il2cpp.types[pField.typeIndex];
                                var pDefault = metadata.GetFieldDefaultFromIndex(i);
                                writer.Write(GetCustomAttribute(pField.customAttributeIndex, "\t"));
                                writer.Write("\t");
                                if ((pType.attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) ==
                                    FIELD_ATTRIBUTE_PRIVATE)
                                {
                                    writer.Write("private ");
                                }
                                else if ((pType.attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) ==
                                         FIELD_ATTRIBUTE_PUBLIC)
                                {
                                    writer.Write("public ");
                                }
                                else if ((pType.attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) ==
                                         FIELD_ATTRIBUTE_FAMILY)
                                {
                                    writer.Write("protected ");
                                }
                                if ((pType.attrs & FIELD_ATTRIBUTE_STATIC) != 0)
                                {
                                    writer.Write("static ");
                                }
                                if ((pType.attrs & FIELD_ATTRIBUTE_INIT_ONLY) != 0)
                                {
                                    writer.Write("readonly ");
                                }
                                writer.Write(
                                    $"{get_type_name(pType)} {metadata.GetString(pField.nameIndex)}");
                                if (pDefault != null && pDefault.dataIndex != -1)
                                {
                                    var pointer = metadata.GetDefaultValueFromIndex(pDefault.dataIndex);
                                    if (pointer > 0)
                                    {
                                        var pTypeToUse = il2cpp.types[pDefault.typeIndex];
                                        metadata.Position = pointer;
                                        object multi = null;
                                        switch (pTypeToUse.type)
                                        {
                                        case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN:
                                            multi = metadata.ReadBoolean();
                                            break;

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

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

                                        case Il2CppTypeEnum.IL2CPP_TYPE_CHAR:
                                            multi = metadata.ReadChar();
                                            break;

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

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

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

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

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

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

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

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

                                        case Il2CppTypeEnum.IL2CPP_TYPE_STRING:
                                            var uiLen = metadata.ReadInt32();
                                            multi = Encoding.UTF8.GetString(metadata.ReadBytes(uiLen));
                                            break;
                                        }
                                        if (multi is string)
                                        {
                                            writer.Write($" = \"{multi}\"");
                                        }
                                        else if (multi != null)
                                        {
                                            writer.Write($" = {multi}");
                                        }
                                    }
                                }
                                writer.Write("; // 0x{0:x}\n",
                                             il2cpp.GetFieldOffsetFromIndex(idx, i - typeDef.fieldStart));
                            }
                            writer.Write("\n");
                        }
                        if (typeDef.property_count > 0)
                        {
                            //dump_property(i);
                            writer.Write("\t// Properties\n");
                            var propertyEnd = typeDef.propertyStart + typeDef.property_count;
                            for (var i = typeDef.propertyStart; i < propertyEnd; ++i)
                            {
                                var propertydef = metadata.propertyDefs[i];
                                writer.Write(GetCustomAttribute(propertydef.customAttributeIndex, "\t"));
                                writer.Write("\t");
                                if (propertydef.get >= 0)
                                {
                                    var methodDef =
                                        metadata.methodDefs[typeDef.methodStart + propertydef.get];
                                    var pReturnType = il2cpp.types[methodDef.returnType];
                                    if ((methodDef.flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) ==
                                        METHOD_ATTRIBUTE_PRIVATE)
                                    {
                                        writer.Write("private ");
                                    }
                                    else if ((methodDef.flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) ==
                                             METHOD_ATTRIBUTE_PUBLIC)
                                    {
                                        writer.Write("public ");
                                    }
                                    else if ((methodDef.flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) ==
                                             METHOD_ATTRIBUTE_FAMILY)
                                    {
                                        writer.Write("protected ");
                                    }
                                    if ((methodDef.flags & METHOD_ATTRIBUTE_ABSTRACT) != 0)
                                    {
                                        writer.Write("abstract ");
                                    }
                                    else if ((methodDef.flags & METHOD_ATTRIBUTE_VIRTUAL) != 0)
                                    {
                                        writer.Write("virtual ");
                                    }
                                    if ((methodDef.flags & METHOD_ATTRIBUTE_STATIC) != 0)
                                    {
                                        writer.Write("static ");
                                    }
                                    writer.Write(
                                        $"{get_type_name(pReturnType)} {metadata.GetString(propertydef.nameIndex)} {{ ");
                                }
                                else if (propertydef.set > 0)
                                {
                                    var methodDef =
                                        metadata.methodDefs[typeDef.methodStart + propertydef.set];
                                    if ((methodDef.flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) ==
                                        METHOD_ATTRIBUTE_PRIVATE)
                                    {
                                        writer.Write("private ");
                                    }
                                    else if ((methodDef.flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) ==
                                             METHOD_ATTRIBUTE_PUBLIC)
                                    {
                                        writer.Write("public ");
                                    }
                                    else if ((methodDef.flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) ==
                                             METHOD_ATTRIBUTE_FAMILY)
                                    {
                                        writer.Write("protected ");
                                    }
                                    if ((methodDef.flags & METHOD_ATTRIBUTE_ABSTRACT) != 0)
                                    {
                                        writer.Write("abstract ");
                                    }
                                    else if ((methodDef.flags & METHOD_ATTRIBUTE_VIRTUAL) != 0)
                                    {
                                        writer.Write("virtual ");
                                    }
                                    if ((methodDef.flags & METHOD_ATTRIBUTE_STATIC) != 0)
                                    {
                                        writer.Write("static ");
                                    }
                                    var pParam = metadata.parameterDefs[methodDef.parameterStart];
                                    var pType  = il2cpp.types[pParam.typeIndex];
                                    writer.Write(
                                        $"{get_type_name(pType)} {metadata.GetString(propertydef.nameIndex)} {{ ");
                                }
                                if (propertydef.get >= 0)
                                {
                                    writer.Write("get; ");
                                }
                                if (propertydef.set >= 0)
                                {
                                    writer.Write("set; ");
                                }
                                writer.Write("}");
                                writer.Write("\n");
                            }
                            writer.Write("\n");
                        }
                        if (typeDef.method_count > 0)
                        {
                            writer.Write("\t// Methods\n");
                            var methodEnd = typeDef.methodStart + typeDef.method_count;
                            for (var i = typeDef.methodStart; i < methodEnd; ++i)
                            {
                                //dump_method(i);
                                var methodDef = metadata.methodDefs[i];
                                writer.Write(GetCustomAttribute(methodDef.customAttributeIndex, "\t"));
                                writer.Write("\t");
                                var pReturnType = il2cpp.types[methodDef.returnType];
                                if ((methodDef.flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) ==
                                    METHOD_ATTRIBUTE_PRIVATE)
                                {
                                    writer.Write("private ");
                                }
                                else if ((methodDef.flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) ==
                                         METHOD_ATTRIBUTE_PUBLIC)
                                {
                                    writer.Write("public ");
                                }
                                else if ((methodDef.flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) ==
                                         METHOD_ATTRIBUTE_FAMILY)
                                {
                                    writer.Write("protected ");
                                }
                                if ((methodDef.flags & METHOD_ATTRIBUTE_ABSTRACT) != 0)
                                {
                                    writer.Write("abstract ");
                                }
                                else if ((methodDef.flags & METHOD_ATTRIBUTE_VIRTUAL) != 0)
                                {
                                    writer.Write("virtual ");
                                }
                                if ((methodDef.flags & METHOD_ATTRIBUTE_STATIC) != 0)
                                {
                                    writer.Write("static ");
                                }
                                writer.Write(
                                    $"{get_type_name(pReturnType)} {metadata.GetString(methodDef.nameIndex)}(");
                                for (var j = 0; j < methodDef.parameterCount; ++j)
                                {
                                    var pParam      = metadata.parameterDefs[methodDef.parameterStart + j];
                                    var szParamName = metadata.GetString(pParam.nameIndex);
                                    var pType       = il2cpp.types[pParam.typeIndex];
                                    var szTypeName  = get_type_name(pType);
                                    if ((pType.attrs & PARAM_ATTRIBUTE_OPTIONAL) != 0)
                                    {
                                        writer.Write("optional ");
                                    }
                                    if ((pType.attrs & PARAM_ATTRIBUTE_OUT) != 0)
                                    {
                                        writer.Write("out ");
                                    }
                                    if (j != methodDef.parameterCount - 1)
                                    {
                                        writer.Write($"{szTypeName} {szParamName}, ");
                                    }
                                    else
                                    {
                                        writer.Write($"{szTypeName} {szParamName}");
                                    }
                                }
                                if (methodDef.methodIndex >= 0)
                                {
                                    writer.Write("); // {0:x}\n",
                                                 il2cpp.methodPointers[methodDef.methodIndex]);
                                }
                                else
                                {
                                    writer.Write("); // 0\n");
                                }
                            }
                        }
                        writer.Write("}\n");
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("ERROR: Some errors in dumping");
                        writer.Write("/*");
                        writer.Write($"{e.Message}\n{e.StackTrace}\n");
                        writer.Write("*/\n}\n");
                    }
                }
                writer.Close();
                Console.WriteLine("Done !");
                break;
            }
        }
Beispiel #2
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);
        }