示例#1
0
 public StructJsonGenerator(Il2CppExecutor il2CppExecutor, Config config)
 {
     executor = il2CppExecutor;
     metadata = il2CppExecutor.metadata;
     il2Cpp   = il2CppExecutor.il2Cpp;
     index    = new Il2CppIndex(il2CppExecutor, config);
 }
示例#2
0
        private static void Dump(Metadata metadata, Il2Cpp il2Cpp)
        {
            Console.WriteLine("Dumping...");
            var writer     = new StreamWriter(new FileStream("dump.cs", FileMode.Create), new UTF8Encoding(false));
            var decompiler = new Il2CppDecompiler(metadata, il2Cpp);

            decompiler.Decompile(writer, config);
            Console.WriteLine("Done!");
            Console.WriteLine("Generate script...");
            var scriptwriter    = new StreamWriter(new FileStream("script.py", FileMode.Create), new UTF8Encoding(false));
            var scriptGenerator = new ScriptGenerator(decompiler);

            scriptGenerator.WriteScript(scriptwriter, config);
            Console.WriteLine("Done!");
            if (config.DummyDll)
            {
                Console.WriteLine("Generate dummy dll...");
                if (Directory.Exists("DummyDll"))
                {
                    Directory.Delete("DummyDll", true);
                }
                Directory.CreateDirectory("DummyDll");
                Directory.SetCurrentDirectory("DummyDll");
                var dummy = new DummyAssemblyGenerator(metadata, il2Cpp);
                foreach (var assembly in dummy.Assemblies)
                {
                    using (var stream = new MemoryStream())
                    {
                        assembly.Write(stream);
                        File.WriteAllBytes(assembly.MainModule.Name, stream.ToArray());
                    }
                }
                Console.WriteLine("Done!");
            }
        }
示例#3
0
        private void Dump(Metadata metadata, Il2Cpp il2Cpp, string outputDir)
        {
            Log("Dumping...");
            var executor   = new Il2CppExecutor(metadata, il2Cpp);
            var decompiler = new Il2CppDecompiler(executor);

            decompiler.Decompile(config, outputDir);
            Log("Done!");
            if (config.GenerateStruct)
            {
                Log("Generate struct...");
                try
                {
                    var scriptGenerator = new StructGenerator(executor);
                    scriptGenerator.WriteScript(outputDir);
                    Log("Done!");
                }
                catch
                {
                    Log("There was an error trying to generate struct. Skipped", Color.Orange);
                }
            }
            if (config.GenerateDummyDll)
            {
                Log("Generate dummy dll...");
                DummyAssemblyExporter.Export(executor, outputDir, config.DummyDllAddToken);
                Log("Done!");
                Directory.SetCurrentDirectory(realPath); //Fix read-only directory permission
            }
        }
示例#4
0
 public PlusSearch(Il2Cpp il2Cpp, int methodCount, int typeDefinitionsCount, long maxMetadataUsages)
 {
     this.il2Cpp               = il2Cpp;
     this.methodCount          = methodCount;
     this.typeDefinitionsCount = typeDefinitionsCount;
     this.maxMetadataUsages    = maxMetadataUsages;
 }
示例#5
0
        public Il2CppExecutor(Metadata metadata, Il2Cpp il2Cpp)
        {
            this.metadata      = metadata;
            this.il2Cpp        = il2Cpp;
            this.TypeDefToName = new UniqueTypeDefNameMap(new WeakReference <Il2CppExecutor>(this));

            if (il2Cpp.Version >= 27)
            {
                customAttributeGenerators = new ulong[metadata.imageDefs.Sum(x => x.customAttributeCount)];
                foreach (var imageDef in metadata.imageDefs)
                {
                    var imageDefName  = metadata.GetStringFromIndex(imageDef.nameIndex);
                    var codeGenModule = il2Cpp.codeGenModules[imageDefName];
                    var pointers      = il2Cpp.ReadClassArray <ulong>(il2Cpp.MapVATR(codeGenModule.customAttributeCacheGenerator), imageDef.customAttributeCount);
                    pointers.CopyTo(customAttributeGenerators, imageDef.customAttributeStart);
                }
            }
            else
            {
                customAttributeGenerators = il2Cpp.customAttributeGenerators;
            }

            for (int index = 0; index < metadata.typeDefs.Length; ++index)
            {
                TypeDefToIndex[metadata.typeDefs[index]] = index;
            }
            for (long index = 0; index < il2Cpp.types.Length; ++index)
            {
                TypeToIndex[il2Cpp.types[index]] = index;
            }
        }
示例#6
0
        private static void Dump(Metadata metadata, Il2Cpp il2Cpp, string outputDir)
        {
            Console.WriteLine("Dumping...");
            var executor   = new Il2CppExecutor(metadata, il2Cpp);
            var structJson = new StructJsonGenerator(executor, config);

            structJson.WriteJson(outputDir);
        }
示例#7
0
 public Il2CppIndex(Il2CppExecutor il2CppExecutor, Config config)
 {
     this.config = config;
     executor    = il2CppExecutor;
     metadata    = il2CppExecutor.metadata;
     il2Cpp      = il2CppExecutor.il2Cpp;
     BuildIndex();
 }
示例#8
0
 public SectionHelper(Il2Cpp il2Cpp, int methodCount, int typeDefinitionsCount, long maxMetadataUsages, int imageCount)
 {
     this.il2Cpp               = il2Cpp;
     this.methodCount          = methodCount;
     this.typeDefinitionsCount = typeDefinitionsCount;
     this.maxMetadataUsages    = maxMetadataUsages;
     this.imageCount           = imageCount;
 }
示例#9
0
        private static void Dump(Metadata metadata, Il2Cpp il2Cpp, string outputDir)
        {
            Console.WriteLine("Dumping...");
            var executor   = new Il2CppExecutor(metadata, il2Cpp);
            var decompiler = new Il2CppDecompiler(executor);

            decompiler.Decompile(config, outputDir);
            Console.WriteLine("Done!");
        }
 public CustomAttributeDataReader(Il2CppExecutor executor, byte[] buff) : base(new MemoryStream(buff))
 {
     this.executor = executor;
     metadata      = executor.metadata;
     il2Cpp        = executor.il2Cpp;
     Count         = this.ReadCompressedUInt32();
     ctorBuffer    = BaseStream.Position;
     dataBuffer    = BaseStream.Position + Count * 4;
 }
示例#11
0
        private static void Dump(Metadata metadata, Il2Cpp il2Cpp)
        {
            Console.WriteLine("Dumping...");
            var writer     = new StreamWriter(new FileStream("dump.cs", FileMode.Create), new UTF8Encoding(false));
            var decompiler = new Il2CppDecompiler(metadata, il2Cpp);

            decompiler.Decompile(writer, config);
            Console.WriteLine("Done!");
            Console.WriteLine("Generate script...");
            var scriptwriter    = new StreamWriter(new FileStream("script.py", FileMode.Create), new UTF8Encoding(false));
            var scriptGenerator = new ScriptGenerator(metadata, il2Cpp);

            scriptGenerator.WriteScript(scriptwriter, config);
            Console.WriteLine("Done!");
            if (config.DummyDll)
            {
                Console.WriteLine("Generate dummy dll...");
                Console.WriteLine("Select style: 1.Original 2.Original+NET_SDK");
                string netSDKPath = "";
                switch (int.Parse(Console.ReadKey(true).KeyChar.ToString()))
                {
                case 2:
                    Console.WriteLine("Enter path to NET_SDK.dll: ");
                    netSDKPath = Console.ReadLine().Trim();
                    break;
                }
                if (Directory.Exists("DummyDll"))
                {
                    Directory.Delete("DummyDll", true);
                }
                Directory.CreateDirectory("DummyDll");
                Directory.SetCurrentDirectory("DummyDll");
                var dummy = new DummyAssemblyGenerator(metadata, il2Cpp, netSDKPath);
                foreach (var assembly in dummy.Assemblies)
                {
                    using (var stream = new MemoryStream())
                    {
                        assembly.Write(stream);
                        File.WriteAllBytes(assembly.MainModule.Name, stream.ToArray());
                    }
                }
                Console.WriteLine("Done!");
            }
        }
        public static void Export(Metadata metadata, Il2Cpp il2Cpp)
        {
            if (Directory.Exists("DummyDll"))
            {
                Directory.Delete("DummyDll", true);
            }
            Directory.CreateDirectory("DummyDll");
            Directory.SetCurrentDirectory("DummyDll");
            var dummy = new DummyAssemblyGenerator(metadata, il2Cpp);

            foreach (var assembly in dummy.Assemblies)
            {
                using (var stream = new MemoryStream())
                {
                    assembly.Write(stream);
                    File.WriteAllBytes(assembly.MainModule.Name, stream.ToArray());
                }
            }
        }
示例#13
0
        private static void Dump(Metadata metadata, Il2Cpp il2Cpp)
        {
            Console.WriteLine("Dumping...");
            var decompiler = new Il2CppDecompiler(metadata, il2Cpp);

            decompiler.Decompile(config);
            Console.WriteLine("Done!");
            Console.WriteLine("Generate script...");
            var scriptGenerator = new ScriptGenerator(metadata, il2Cpp);

            scriptGenerator.WriteScript(config);
            Console.WriteLine("Done!");
            if (config.DummyDll)
            {
                Console.WriteLine("Generate dummy dll...");
                DummyAssemblyExporter.Export(metadata, il2Cpp);
                Console.WriteLine("Done!");
            }
        }
示例#14
0
        public Il2CppExecutor(Metadata metadata, Il2Cpp il2Cpp)
        {
            this.metadata = metadata;
            this.il2Cpp   = il2Cpp;

            if (il2Cpp.Version >= 27)
            {
                customAttributeGenerators = new ulong[metadata.imageDefs.Sum(x => x.customAttributeCount)];
                foreach (var imageDef in metadata.imageDefs)
                {
                    var imageDefName  = metadata.GetStringFromIndex(imageDef.nameIndex);
                    var codeGenModule = il2Cpp.codeGenModules[imageDefName];
                    var pointers      = il2Cpp.ReadClassArray <ulong>(il2Cpp.MapVATR(codeGenModule.customAttributeCacheGenerator), imageDef.customAttributeCount);
                    pointers.CopyTo(customAttributeGenerators, imageDef.customAttributeStart);
                }
            }
            else
            {
                customAttributeGenerators = il2Cpp.customAttributeGenerators;
            }
        }
示例#15
0
        private static void Dump(Metadata metadata, Il2Cpp il2Cpp, string outputDir)
        {
            Console.WriteLine("Dumping...");
            var executor   = new Il2CppExecutor(metadata, il2Cpp);
            var decompiler = new Il2CppDecompiler(executor);

            decompiler.Decompile(config, outputDir);
            Console.WriteLine("Done!");
            if (config.GenerateStruct)
            {
                Console.WriteLine("Generate struct...");
                var scriptGenerator = new StructGenerator(executor);
                scriptGenerator.WriteScript(outputDir);
                Console.WriteLine("Done!");
            }
            if (config.GenerateDummyDll)
            {
                Console.WriteLine("Generate dummy dll...");
                DummyAssemblyExporter.Export(executor, outputDir, config.DummyDllAddToken);
                Console.WriteLine("Done!");
            }
        }
示例#16
0
        private void Dump(Metadata metadata, Il2Cpp il2Cpp, string outputDir)
        {
            WriteLine("Dumping...");
            var executor   = new Il2CppExecutor(metadata, il2Cpp);
            var decompiler = new Il2CppDecompiler(executor);

            decompiler.Decompile(config, outputDir);
            WriteLine("Done!");
            if (config.GenerateStruct)
            {
                WriteLine("Generate struct...");
                var scriptGenerator = new StructGenerator(executor);
                scriptGenerator.WriteScript(outputDir);
                WriteLine("Done!");
            }
            if (config.GenerateDummyDll)
            {
                WriteLine("Generate dummy dll...");
                DummyAssemblyExporter.Export(executor, outputDir, config.DummyDllAddToken);
                WriteLine("Done!");
                Directory.SetCurrentDirectory(RealPath); //Fix read-only directory permission
            }
        }
示例#17
0
        private static bool Init(byte[] il2cppBytes, byte[] metadataBytes, string stringVersion, int mode, out Metadata metadata, out Il2Cpp il2Cpp)
        {
            var sanity = BitConverter.ToUInt32(metadataBytes, 0);

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

            if (metadataVersion == 24)
            {
                if (stringVersion == null)
                {
                    Console.WriteLine("Input Unity version: ");
                    stringVersion = Console.ReadLine();
                }
                try
                {
                    var versionSplit = Array.ConvertAll(Regex.Replace(stringVersion, @"\D", ".").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries), int.Parse);
                    var unityVersion = new Version(versionSplit[0], versionSplit[1]);
                    if (unityVersion >= Unity20201)
                    {
                        fixedVersion = 24.3f;
                    }
                    else if (unityVersion >= Unity20191)
                    {
                        fixedVersion = 24.2f;
                    }
                    else if (unityVersion >= Unity20183)
                    {
                        fixedVersion = 24.1f;
                    }
                    else
                    {
                        fixedVersion = metadataVersion;
                    }
                }
                catch
                {
                    throw new InvalidDataException("You must enter the correct Unity version number");
                }
            }
            else
            {
                fixedVersion = metadataVersion;
            }
            Console.WriteLine("Initializing metadata...");
            metadata = new Metadata(new MemoryStream(metadataBytes), fixedVersion);
            //判断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 NotSupportedException("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:
                var machofat = new MachoFat(new MemoryStream(il2cppBytes));
                Console.Write("Select Platform: ");
                for (var i = 0; i < machofat.fats.Length; i++)
                {
                    var fat = machofat.fats[i];
                    Console.Write(fat.magic == 0xFEEDFACF ? $"{i + 1}.64bit " : $"{i + 1}.32bit ");
                }
                Console.WriteLine();
                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);
                if (magic == 0xFEEDFACF)
                {
                    goto case 0xFEEDFACF;
                }
                else
                {
                    goto case 0xFEEDFACE;
                }

            case 0xFEEDFACF:     // 64bit Mach-O
                is64bit = true;
                break;

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

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

            Console.WriteLine("Initializing il2cpp file...");
            var il2CppMemory = new MemoryStream(il2cppBytes);

            if (isNSO)
            {
                var nso = new NSO(il2CppMemory, version, metadata.maxMetadataUsages);
                il2Cpp = nso.UnCompress();
            }
            else if (isPE)
            {
                il2Cpp = new PE(il2CppMemory, version, metadata.maxMetadataUsages);
            }
            else if (isElf)
            {
                if (is64bit)
                {
                    il2Cpp = new Elf64(il2CppMemory, version, metadata.maxMetadataUsages);
                }
                else
                {
                    il2Cpp = new Elf(il2CppMemory, version, metadata.maxMetadataUsages);
                }
            }
            else if (is64bit)
            {
                il2Cpp = new Macho64(il2CppMemory, version, metadata.maxMetadataUsages);
            }
            else
            {
                il2Cpp = new Macho(il2CppMemory, version, metadata.maxMetadataUsages);
            }

            if (mode == 0)
            {
                Console.WriteLine("Select Mode: 1.Manual 2.Auto");
                var modeKey = Console.ReadKey(true);
                mode = int.Parse(modeKey.KeyChar.ToString());
            }
            try
            {
                if (mode == 1)
                {
                    Console.Write("Input CodeRegistration: ");
                    var codeRegistration = Convert.ToUInt64(Console.ReadLine(), 16);
                    Console.Write("Input MetadataRegistration: ");
                    var metadataRegistration = Convert.ToUInt64(Console.ReadLine(), 16);
                    il2Cpp.Init(codeRegistration, metadataRegistration);
                    return(true);
                }
                else if (mode == 2)
                {
                    Console.WriteLine("Searching...");
                    var flag = il2Cpp.PlusSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length);
                    if (!flag)
                    {
                        flag = il2Cpp.Search();
                    }
                    if (!flag)
                    {
                        flag = il2Cpp.SymbolSearch();
                    }
                    if (!flag)
                    {
                        Console.WriteLine("ERROR: Can't use auto mode to process file, try manual mode.");
                        return(false);
                    }
                }
                else
                {
                    Console.WriteLine("ERROR: You have to choose a mode.");
                    return(false);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                Console.WriteLine("ERROR: An error occurred while processing.");
                return(false);
            }
            return(true);
        }
        public DummyAssemblyGenerator(Metadata metadata, Il2Cpp il2Cpp)
        {
            this.metadata = metadata;
            this.il2Cpp   = il2Cpp;

            //Il2CppDummyDll
            var il2CppDummyDll = Il2CppDummyDll.Create();

            Assemblies.Add(il2CppDummyDll);
            var addressAttribute     = il2CppDummyDll.MainModule.Types.First(x => x.Name == "AddressAttribute").Methods[0];
            var fieldOffsetAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "FieldOffsetAttribute").Methods[0];

            attributeAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "AttributeAttribute").Methods[0];
            var metadataOffsetAttribute = il2CppDummyDll.MainModule.Types.First(x => x.Name == "MetadataOffsetAttribute").Methods[0];

            stringType = il2CppDummyDll.MainModule.TypeSystem.String;

            var resolver         = new MyAssemblyResolver();
            var moduleParameters = new ModuleParameters
            {
                Kind             = ModuleKind.Dll,
                AssemblyResolver = resolver
            };

            resolver.Register(il2CppDummyDll);

            var fieldDefinitionDic     = new Dictionary <int, FieldDefinition>();
            var methodDefinitionDic    = new Dictionary <int, MethodDefinition>();
            var parameterDefinitionDic = new Dictionary <int, ParameterDefinition>();
            var propertyDefinitionDic  = new Dictionary <int, PropertyDefinition>();
            var eventDefinitionDic     = new Dictionary <int, EventDefinition>();

            //创建程序集,同时创建所有类
            foreach (var imageDef in metadata.imageDefs)
            {
                var imageName          = metadata.GetStringFromIndex(imageDef.nameIndex);
                var assemblyName       = new AssemblyNameDefinition(imageName.Replace(".dll", ""), new Version("3.7.1.6"));
                var assemblyDefinition = AssemblyDefinition.CreateAssembly(assemblyName, imageName, moduleParameters);
                resolver.Register(assemblyDefinition);
                Assemblies.Add(assemblyDefinition);
                var moduleDefinition = assemblyDefinition.MainModule;
                moduleDefinition.Types.Clear();//清除自动创建的<Module>类
                var typeEnd = imageDef.typeStart + imageDef.typeCount;
                for (var index = imageDef.typeStart; index < typeEnd; ++index)
                {
                    var            typeDef       = metadata.typeDefs[index];
                    var            namespaceName = metadata.GetStringFromIndex(typeDef.namespaceIndex);
                    var            typeName      = metadata.GetStringFromIndex(typeDef.nameIndex);
                    TypeDefinition typeDefinition;
                    if (typeDef.declaringTypeIndex != -1)//nested types
                    {
                        typeDefinition = typeDefinitionDic[index];
                    }
                    else
                    {
                        typeDefinition = new TypeDefinition(namespaceName, typeName, (TypeAttributes)typeDef.flags);
                        moduleDefinition.Types.Add(typeDefinition);
                        typeDefinitionDic.Add(index, typeDefinition);
                    }
                    //nestedtype
                    for (int i = 0; i < typeDef.nested_type_count; i++)
                    {
                        var nestedIndex          = metadata.nestedTypeIndices[typeDef.nestedTypesStart + i];
                        var nestedTypeDef        = metadata.typeDefs[nestedIndex];
                        var nestedTypeDefinition = new TypeDefinition(metadata.GetStringFromIndex(nestedTypeDef.namespaceIndex), metadata.GetStringFromIndex(nestedTypeDef.nameIndex), (TypeAttributes)nestedTypeDef.flags);
                        typeDefinition.NestedTypes.Add(nestedTypeDefinition);
                        typeDefinitionDic.Add(nestedIndex, nestedTypeDefinition);
                    }
                }
            }
            //先单独处理,因为不知道会不会有问题
            for (var index = 0; index < metadata.typeDefs.Length; ++index)
            {
                var typeDef        = metadata.typeDefs[index];
                var typeDefinition = typeDefinitionDic[index];
                //parent
                if (typeDef.parentIndex >= 0)
                {
                    var parentType    = il2Cpp.types[typeDef.parentIndex];
                    var parentTypeRef = GetTypeReference(typeDefinition, parentType);
                    typeDefinition.BaseType = parentTypeRef;
                }
                //interfaces
                for (int i = 0; i < typeDef.interfaces_count; i++)
                {
                    var interfaceType    = il2Cpp.types[metadata.interfaceIndices[typeDef.interfacesStart + i]];
                    var interfaceTypeRef = GetTypeReference(typeDefinition, interfaceType);
                    typeDefinition.Interfaces.Add(new InterfaceImplementation(interfaceTypeRef));
                }
            }
            //处理field, method, property等等
            for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++)
            {
                var imageDef = metadata.imageDefs[imageIndex];
                var typeEnd  = imageDef.typeStart + imageDef.typeCount;
                for (int index = imageDef.typeStart; index < typeEnd; index++)
                {
                    var typeDef        = metadata.typeDefs[index];
                    var typeDefinition = typeDefinitionDic[index];

                    //field
                    var fieldEnd = typeDef.fieldStart + typeDef.field_count;
                    for (var i = typeDef.fieldStart; i < fieldEnd; ++i)
                    {
                        var fieldDef        = metadata.fieldDefs[i];
                        var fieldType       = il2Cpp.types[fieldDef.typeIndex];
                        var fieldName       = metadata.GetStringFromIndex(fieldDef.nameIndex);
                        var fieldTypeRef    = GetTypeReference(typeDefinition, fieldType);
                        var fieldDefinition = new FieldDefinition(fieldName, (FieldAttributes)fieldType.attrs, fieldTypeRef);
                        typeDefinition.Fields.Add(fieldDefinition);
                        fieldDefinitionDic.Add(i, fieldDefinition);
                        //fieldDefault
                        if (metadata.GetFieldDefaultValueFromIndex(i, out var fieldDefault) && fieldDefault.dataIndex != -1)
                        {
                            if (TryGetDefaultValue(fieldDefault.typeIndex, fieldDefault.dataIndex, out var value))
                            {
                                fieldDefinition.Constant = value;
                            }
                            else
                            {
                                var customAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(metadataOffsetAttribute));
                                var offset          = new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{value:X}"));
                                customAttribute.Fields.Add(offset);
                                fieldDefinition.CustomAttributes.Add(customAttribute);
                            }
                        }
                        //fieldOffset
                        if (!fieldDefinition.IsLiteral)
                        {
                            var fieldOffset = il2Cpp.GetFieldOffsetFromIndex(index, i - typeDef.fieldStart, i, typeDefinition.IsValueType, fieldDefinition.IsStatic);
                            if (fieldOffset >= 0)
                            {
                                var customAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(fieldOffsetAttribute));
                                var offset          = new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{fieldOffset:X}"));
                                customAttribute.Fields.Add(offset);
                                fieldDefinition.CustomAttributes.Add(customAttribute);
                            }
                        }
                    }
                    //method
                    var methodEnd = typeDef.methodStart + typeDef.method_count;
                    for (var i = typeDef.methodStart; i < methodEnd; ++i)
                    {
                        var methodDef        = metadata.methodDefs[i];
                        var methodName       = metadata.GetStringFromIndex(methodDef.nameIndex);
                        var methodDefinition = new MethodDefinition(methodName, (MethodAttributes)methodDef.flags, typeDefinition.Module.ImportReference(typeof(void)));
                        methodDefinition.ImplAttributes = (MethodImplAttributes)methodDef.iflags;
                        typeDefinition.Methods.Add(methodDefinition);
                        var methodReturnType = il2Cpp.types[methodDef.returnType];
                        var returnType       = GetTypeReferenceWithByRef(methodDefinition, methodReturnType);
                        methodDefinition.ReturnType = returnType;
                        if (methodDefinition.HasBody && typeDefinition.BaseType?.FullName != "System.MulticastDelegate")
                        {
                            var ilprocessor = methodDefinition.Body.GetILProcessor();
                            if (returnType.FullName == "System.Void")
                            {
                                ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
                            }
                            else if (returnType.IsValueType)
                            {
                                var variable = new VariableDefinition(returnType);
                                methodDefinition.Body.Variables.Add(variable);
                                ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloca_S, variable));
                                ilprocessor.Append(ilprocessor.Create(OpCodes.Initobj, returnType));
                                ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
                                ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
                            }
                            else
                            {
                                ilprocessor.Append(ilprocessor.Create(OpCodes.Ldnull));
                                ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
                            }
                        }
                        methodDefinitionDic.Add(i, methodDefinition);
                        //method parameter
                        for (var j = 0; j < methodDef.parameterCount; ++j)
                        {
                            var parameterDef        = metadata.parameterDefs[methodDef.parameterStart + j];
                            var parameterName       = metadata.GetStringFromIndex(parameterDef.nameIndex);
                            var parameterType       = il2Cpp.types[parameterDef.typeIndex];
                            var parameterTypeRef    = GetTypeReferenceWithByRef(methodDefinition, parameterType);
                            var parameterDefinition = new ParameterDefinition(parameterName, (ParameterAttributes)parameterType.attrs, parameterTypeRef);
                            methodDefinition.Parameters.Add(parameterDefinition);
                            parameterDefinitionDic.Add(methodDef.parameterStart + j, parameterDefinition);
                            //ParameterDefault
                            if (metadata.GetParameterDefaultValueFromIndex(methodDef.parameterStart + j, out var parameterDefault) && parameterDefault.dataIndex != -1)
                            {
                                if (TryGetDefaultValue(parameterDefault.typeIndex, parameterDefault.dataIndex, out var value))
                                {
                                    parameterDefinition.Constant = value;
                                }
                                else
                                {
                                    var customAttribute = new CustomAttribute(typeDefinition.Module.ImportReference(metadataOffsetAttribute));
                                    var offset          = new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{value:X}"));
                                    customAttribute.Fields.Add(offset);
                                    parameterDefinition.CustomAttributes.Add(customAttribute);
                                }
                            }
                        }
                        //补充泛型参数
                        if (methodDef.genericContainerIndex >= 0)
                        {
                            var genericContainer = metadata.genericContainers[methodDef.genericContainerIndex];
                            if (genericContainer.type_argc > methodDefinition.GenericParameters.Count)
                            {
                                for (int j = 0; j < genericContainer.type_argc; j++)
                                {
                                    var genericParameterIndex = genericContainer.genericParameterStart + j;
                                    if (!genericParameterDic.TryGetValue(genericParameterIndex, out var genericParameter))
                                    {
                                        CreateGenericParameter(genericParameterIndex, methodDefinition);
                                    }
                                    else
                                    {
                                        if (!methodDefinition.GenericParameters.Contains(genericParameter))
                                        {
                                            methodDefinition.GenericParameters.Add(genericParameter);
                                        }
                                    }
                                }
                            }
                        }
                        //methodAddress
                        var methodPointer = il2Cpp.GetMethodPointer(methodDef, imageIndex);
                        if (methodPointer > 0)
                        {
                            var customAttribute    = new CustomAttribute(typeDefinition.Module.ImportReference(addressAttribute));
                            var fixedMethodPointer = il2Cpp.GetRVA(methodPointer);
                            var rva    = new CustomAttributeNamedArgument("RVA", new CustomAttributeArgument(stringType, $"0x{fixedMethodPointer:X}"));
                            var offset = new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{il2Cpp.MapVATR(methodPointer):X}"));
                            var va     = new CustomAttributeNamedArgument("VA", new CustomAttributeArgument(stringType, $"0x{methodPointer:X}"));
                            customAttribute.Fields.Add(rva);
                            customAttribute.Fields.Add(offset);
                            customAttribute.Fields.Add(va);
                            if (methodDef.slot != ushort.MaxValue)
                            {
                                var slot = new CustomAttributeNamedArgument("Slot", new CustomAttributeArgument(stringType, methodDef.slot.ToString()));
                                customAttribute.Fields.Add(slot);
                            }
                            methodDefinition.CustomAttributes.Add(customAttribute);
                        }
                    }
                    //property
                    var propertyEnd = typeDef.propertyStart + typeDef.property_count;
                    for (var i = typeDef.propertyStart; i < propertyEnd; ++i)
                    {
                        var              propertyDef  = metadata.propertyDefs[i];
                        var              propertyName = metadata.GetStringFromIndex(propertyDef.nameIndex);
                        TypeReference    propertyType = null;
                        MethodDefinition GetMethod    = null;
                        MethodDefinition SetMethod    = null;
                        if (propertyDef.get >= 0)
                        {
                            GetMethod    = methodDefinitionDic[typeDef.methodStart + propertyDef.get];
                            propertyType = GetMethod.ReturnType;
                        }
                        if (propertyDef.set >= 0)
                        {
                            SetMethod = methodDefinitionDic[typeDef.methodStart + propertyDef.set];
                            if (propertyType == null)
                            {
                                propertyType = SetMethod.Parameters[0].ParameterType;
                            }
                        }
                        var propertyDefinition = new PropertyDefinition(propertyName, (PropertyAttributes)propertyDef.attrs, propertyType)
                        {
                            GetMethod = GetMethod,
                            SetMethod = SetMethod
                        };
                        typeDefinition.Properties.Add(propertyDefinition);
                        propertyDefinitionDic.Add(i, propertyDefinition);
                    }
                    //event
                    var eventEnd = typeDef.eventStart + typeDef.event_count;
                    for (var i = typeDef.eventStart; i < eventEnd; ++i)
                    {
                        var eventDef        = metadata.eventDefs[i];
                        var eventName       = metadata.GetStringFromIndex(eventDef.nameIndex);
                        var eventType       = il2Cpp.types[eventDef.typeIndex];
                        var eventTypeRef    = GetTypeReference(typeDefinition, eventType);
                        var eventDefinition = new EventDefinition(eventName, (EventAttributes)eventType.attrs, eventTypeRef);
                        if (eventDef.add >= 0)
                        {
                            eventDefinition.AddMethod = methodDefinitionDic[typeDef.methodStart + eventDef.add];
                        }
                        if (eventDef.remove >= 0)
                        {
                            eventDefinition.RemoveMethod = methodDefinitionDic[typeDef.methodStart + eventDef.remove];
                        }
                        if (eventDef.raise >= 0)
                        {
                            eventDefinition.InvokeMethod = methodDefinitionDic[typeDef.methodStart + eventDef.raise];
                        }
                        typeDefinition.Events.Add(eventDefinition);
                        eventDefinitionDic.Add(i, eventDefinition);
                    }
                    //补充泛型参数
                    if (typeDef.genericContainerIndex >= 0)
                    {
                        var genericContainer = metadata.genericContainers[typeDef.genericContainerIndex];
                        if (genericContainer.type_argc > typeDefinition.GenericParameters.Count)
                        {
                            for (int i = 0; i < genericContainer.type_argc; i++)
                            {
                                var genericParameterIndex = genericContainer.genericParameterStart + i;
                                if (!genericParameterDic.TryGetValue(genericParameterIndex, out var genericParameter))
                                {
                                    CreateGenericParameter(genericParameterIndex, typeDefinition);
                                }
                                else
                                {
                                    if (!typeDefinition.GenericParameters.Contains(genericParameter))
                                    {
                                        typeDefinition.GenericParameters.Add(genericParameter);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            //第三遍,添加CustomAttribute
            if (il2Cpp.Version > 20)
            {
                PrepareCustomAttribute();
                foreach (var imageDef in metadata.imageDefs)
                {
                    var typeEnd = imageDef.typeStart + imageDef.typeCount;
                    for (int index = imageDef.typeStart; index < typeEnd; index++)
                    {
                        var typeDef        = metadata.typeDefs[index];
                        var typeDefinition = typeDefinitionDic[index];
                        //typeAttribute
                        CreateCustomAttribute(imageDef, typeDef.customAttributeIndex, typeDef.token, typeDefinition.Module, typeDefinition.CustomAttributes);

                        //field
                        var fieldEnd = typeDef.fieldStart + typeDef.field_count;
                        for (var i = typeDef.fieldStart; i < fieldEnd; ++i)
                        {
                            var fieldDef        = metadata.fieldDefs[i];
                            var fieldDefinition = fieldDefinitionDic[i];
                            //fieldAttribute
                            CreateCustomAttribute(imageDef, fieldDef.customAttributeIndex, fieldDef.token, typeDefinition.Module, fieldDefinition.CustomAttributes);
                        }

                        //method
                        var methodEnd = typeDef.methodStart + typeDef.method_count;
                        for (var i = typeDef.methodStart; i < methodEnd; ++i)
                        {
                            var methodDef        = metadata.methodDefs[i];
                            var methodDefinition = methodDefinitionDic[i];
                            //methodAttribute
                            CreateCustomAttribute(imageDef, methodDef.customAttributeIndex, methodDef.token, typeDefinition.Module, methodDefinition.CustomAttributes);

                            //method parameter
                            for (var j = 0; j < methodDef.parameterCount; ++j)
                            {
                                var parameterDef        = metadata.parameterDefs[methodDef.parameterStart + j];
                                var parameterDefinition = parameterDefinitionDic[methodDef.parameterStart + j];
                                //parameterAttribute
                                CreateCustomAttribute(imageDef, parameterDef.customAttributeIndex, parameterDef.token, typeDefinition.Module, parameterDefinition.CustomAttributes);
                            }
                        }

                        //property
                        var propertyEnd = typeDef.propertyStart + typeDef.property_count;
                        for (var i = typeDef.propertyStart; i < propertyEnd; ++i)
                        {
                            var propertyDef        = metadata.propertyDefs[i];
                            var propertyDefinition = propertyDefinitionDic[i];
                            //propertyAttribute
                            CreateCustomAttribute(imageDef, propertyDef.customAttributeIndex, propertyDef.token, typeDefinition.Module, propertyDefinition.CustomAttributes);
                        }

                        //event
                        var eventEnd = typeDef.eventStart + typeDef.event_count;
                        for (var i = typeDef.eventStart; i < eventEnd; ++i)
                        {
                            var eventDef        = metadata.eventDefs[i];
                            var eventDefinition = eventDefinitionDic[i];
                            //eventAttribute
                            CreateCustomAttribute(imageDef, eventDef.customAttributeIndex, eventDef.token, typeDefinition.Module, eventDefinition.CustomAttributes);
                        }
                    }
                }
            }
        }
示例#19
0
        static void Main(string[] args)
        {
            config = File.Exists("config.json") ? new JavaScriptSerializer().Deserialize <Config>(File.ReadAllText("config.json")) : new Config();
            var ofd = new OpenFileDialog();

            ofd.Filter = "Il2Cpp binary file|*.*";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                var il2cppfile = File.ReadAllBytes(ofd.FileName);
                ofd.Filter = "global-metadata|global-metadata.dat";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        Console.WriteLine("Initializing metadata...");
                        metadata = new Metadata(new MemoryStream(File.ReadAllBytes(ofd.FileName)));
                        Console.Clear();
                        //判断il2cpp的magic
                        var il2cppMagic = BitConverter.ToUInt32(il2cppfile, 0);
                        var isElf       = false;
                        var isPE        = false;
                        var is64bit     = false;
                        switch (il2cppMagic)
                        {
                        default:
                            throw new Exception("ERROR: il2cpp file not supported.");

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

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

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

                        case 0xFEEDFACF:     // 64-bit mach object file
                            is64bit = true;
                            break;

                        case 0xFEEDFACE:     // 32-bit mach object file
                            break;
                        }

                        Console.WriteLine("Select Mode: 1.Manual 2.Auto 3.Auto(Advanced) 4.Auto(Plus) 5.Auto(Symbol)");
                        var modeKey = Console.ReadKey(true);
                        var version = config.ForceIl2CppVersion ? config.ForceVersion : metadata.version;
                        Console.WriteLine("Initializing il2cpp file...");
                        if (isPE)
                        {
                            il2cpp = new PE(new MemoryStream(il2cppfile), version, metadata.maxMetadataUsages);
                        }
                        else if (isElf)
                        {
                            if (is64bit)
                            {
                                il2cpp = new Elf64(new MemoryStream(il2cppfile), version, metadata.maxMetadataUsages);
                            }
                            else
                            {
                                il2cpp = new Elf(new MemoryStream(il2cppfile), version, metadata.maxMetadataUsages);
                            }
                        }
                        else if (is64bit)
                        {
                            il2cpp = new Macho64(new MemoryStream(il2cppfile), version, metadata.maxMetadataUsages);
                        }
                        else
                        {
                            il2cpp = new Macho(new MemoryStream(il2cppfile), version, metadata.maxMetadataUsages);
                        }

                        try
                        {
                            bool flag;
                            switch (modeKey.KeyChar)
                            {
                            case '1':     //Manual
                                Console.Write("Input CodeRegistration: ");
                                var codeRegistration = Convert.ToUInt64(Console.ReadLine(), 16);
                                Console.Write("Input MetadataRegistration: ");
                                var metadataRegistration = Convert.ToUInt64(Console.ReadLine(), 16);
                                il2cpp.Init(codeRegistration, metadataRegistration);
                                flag = true;
                                break;

                            case '2':     //Auto
                                flag = il2cpp.Search();
                                break;

                            case '3':     //Auto(Advanced)
                                flag = il2cpp.AdvancedSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0));
                                break;

                            case '4':     //Auto(Plus)
                                flag = il2cpp.PlusSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length);
                                break;

                            case '5':     //Auto(Symbol)
                                flag = il2cpp.SymbolSearch();
                                break;

                            default:
                                return;
                            }
                            if (!flag)
                            {
                                throw new Exception();
                            }
                        }
                        catch
                        {
                            throw new Exception("ERROR: Can't use this mode to process file, try another mode.");
                        }
                        var writer = new StreamWriter(new FileStream("dump.cs", FileMode.Create), new UTF8Encoding(false));
                        Console.WriteLine("Dumping...");
                        //Script
                        var scriptwriter = new StreamWriter(new FileStream("script.py", FileMode.Create), new UTF8Encoding(false));
                        scriptwriter.WriteLine(Resource1.ida);
                        //dump image;
                        for (var imageIndex = 0; imageIndex < metadata.uiImageCount; imageIndex++)
                        {
                            var imageDef = metadata.imageDefs[imageIndex];
                            writer.Write($"// Image {imageIndex}: {metadata.GetStringFromIndex(imageDef.nameIndex)} - {imageDef.typeStart}\n");
                        }
                        //dump type;
                        for (var idx = 0; idx < metadata.uiNumTypes; ++idx)
                        {
                            try
                            {
                                var typeDef  = metadata.typeDefs[idx];
                                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));
                                    }
                                }
                                writer.Write($"\n// Namespace: {metadata.GetStringFromIndex(typeDef.namespaceIndex)}\n");
                                writer.Write(GetCustomAttribute(typeDef.customAttributeIndex));
                                if (config.DumpAttribute && (typeDef.flags & TYPE_ATTRIBUTE_SERIALIZABLE) != 0)
                                {
                                    writer.Write("[Serializable]\n");
                                }
                                var visibility = typeDef.flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
                                switch (visibility)
                                {
                                case TYPE_ATTRIBUTE_PUBLIC:
                                case TYPE_ATTRIBUTE_NESTED_PUBLIC:
                                    writer.Write("public ");
                                    break;

                                case TYPE_ATTRIBUTE_NOT_PUBLIC:
                                case TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM:
                                case TYPE_ATTRIBUTE_NESTED_ASSEMBLY:
                                    writer.Write("internal ");
                                    break;

                                case TYPE_ATTRIBUTE_NESTED_PRIVATE:
                                    writer.Write("private ");
                                    break;

                                case TYPE_ATTRIBUTE_NESTED_FAMILY:
                                    writer.Write("protected ");
                                    break;

                                case TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM:
                                    writer.Write("protected internal ");
                                    break;
                                }
                                if ((typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0 && (typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0)
                                {
                                    writer.Write("static ");
                                }
                                else if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) == 0 && (typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0)
                                {
                                    writer.Write("abstract ");
                                }
                                else if (!isStruct && !isEnum && (typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0)
                                {
                                    writer.Write("sealed ");
                                }
                                if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) != 0)
                                {
                                    writer.Write("interface ");
                                }
                                else if (isStruct)
                                {
                                    writer.Write("struct ");
                                }
                                else if (isEnum)
                                {
                                    writer.Write("enum ");
                                }
                                else
                                {
                                    writer.Write("class ");
                                }
                                var typeName = metadata.GetStringFromIndex(typeDef.nameIndex);
                                writer.Write($"{typeName}");
                                if (extends.Count > 0)
                                {
                                    writer.Write($" : {string.Join(", ", extends)}");
                                }
                                if (config.DumpTypeDefIndex)
                                {
                                    writer.Write($" // TypeDefIndex: {idx}\n{{\n");
                                }
                                else
                                {
                                    writer.Write("\n{\n");
                                }
                                //dump field
                                if (config.DumpField && 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 fieldDef     = metadata.fieldDefs[i];
                                        var fieldType    = il2cpp.types[fieldDef.typeIndex];
                                        var fieldDefault = metadata.GetFieldDefaultValueFromIndex(i);
                                        writer.Write(GetCustomAttribute(fieldDef.customAttributeIndex, "\t"));
                                        writer.Write("\t");
                                        var access = fieldType.attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
                                        switch (access)
                                        {
                                        case FIELD_ATTRIBUTE_PRIVATE:
                                            writer.Write("private ");
                                            break;

                                        case FIELD_ATTRIBUTE_PUBLIC:
                                            writer.Write("public ");
                                            break;

                                        case FIELD_ATTRIBUTE_FAMILY:
                                            writer.Write("protected ");
                                            break;

                                        case FIELD_ATTRIBUTE_ASSEMBLY:
                                        case FIELD_ATTRIBUTE_FAM_AND_ASSEM:
                                            writer.Write("internal ");
                                            break;

                                        case FIELD_ATTRIBUTE_FAM_OR_ASSEM:
                                            writer.Write("protected internal ");
                                            break;
                                        }
                                        if ((fieldType.attrs & FIELD_ATTRIBUTE_LITERAL) != 0)
                                        {
                                            writer.Write("const ");
                                        }
                                        else
                                        {
                                            if ((fieldType.attrs & FIELD_ATTRIBUTE_STATIC) != 0)
                                            {
                                                writer.Write("static ");
                                            }
                                            if ((fieldType.attrs & FIELD_ATTRIBUTE_INIT_ONLY) != 0)
                                            {
                                                writer.Write("readonly ");
                                            }
                                        }
                                        writer.Write($"{GetTypeName(fieldType)} {metadata.GetStringFromIndex(fieldDef.nameIndex)}");
                                        if (fieldDefault != null && fieldDefault.dataIndex != -1)
                                        {
                                            var pointer = metadata.GetDefaultValueFromIndex(fieldDefault.dataIndex);
                                            if (pointer > 0)
                                            {
                                                var pTypeToUse = il2cpp.types[fieldDefault.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 = BitConverter.ToChar(metadata.ReadBytes(2), 0);
                                                    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 str)
                                                {
                                                    writer.Write($" = \"{ToEscapedString(str)}\"");
                                                }
                                                else if (multi is char c)
                                                {
                                                    var v = (int)c;
                                                    writer.Write($" = '\\x{v:x}'");
                                                }
                                                else if (multi != null)
                                                {
                                                    writer.Write($" = {multi}");
                                                }
                                            }
                                        }
                                        if (config.DumpFieldOffset)
                                        {
                                            writer.Write("; // 0x{0:X}\n", il2cpp.GetFieldOffsetFromIndex(idx, i - typeDef.fieldStart, i));
                                        }
                                        else
                                        {
                                            writer.Write(";\n");
                                        }
                                    }
                                    writer.Write("\n");
                                }
                                //dump property
                                if (config.DumpProperty && typeDef.property_count > 0)
                                {
                                    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];
                                            writer.Write(GetModifiers(methodDef));
                                            var propertyType = il2cpp.types[methodDef.returnType];
                                            writer.Write($"{GetTypeName(propertyType)} {metadata.GetStringFromIndex(propertyDef.nameIndex)} {{ ");
                                        }
                                        else if (propertyDef.set > 0)
                                        {
                                            var methodDef = metadata.methodDefs[typeDef.methodStart + propertyDef.set];
                                            writer.Write(GetModifiers(methodDef));
                                            var parameterDef = metadata.parameterDefs[methodDef.parameterStart];
                                            var propertyType = il2cpp.types[parameterDef.typeIndex];
                                            writer.Write($"{GetTypeName(propertyType)} {metadata.GetStringFromIndex(propertyDef.nameIndex)} {{ ");
                                        }
                                        if (propertyDef.get >= 0)
                                        {
                                            writer.Write("get; ");
                                        }
                                        if (propertyDef.set >= 0)
                                        {
                                            writer.Write("set; ");
                                        }
                                        writer.Write("}");
                                        writer.Write("\n");
                                    }
                                    writer.Write("\n");
                                }
                                //dump method
                                if (config.DumpMethod && typeDef.method_count > 0)
                                {
                                    writer.Write("\t// Methods\n");
                                    var methodEnd = typeDef.methodStart + typeDef.method_count;
                                    for (var i = typeDef.methodStart; i < methodEnd; ++i)
                                    {
                                        var methodDef = metadata.methodDefs[i];
                                        writer.Write(GetCustomAttribute(methodDef.customAttributeIndex, "\t"));
                                        writer.Write("\t");
                                        writer.Write(GetModifiers(methodDef));
                                        var methodReturnType = il2cpp.types[methodDef.returnType];
                                        var methodName       = metadata.GetStringFromIndex(methodDef.nameIndex);
                                        writer.Write($"{GetTypeName(methodReturnType)} {methodName}(");
                                        var parameterStrs = new List <string>();
                                        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}";
                                            parameterStrs.Add(parameterStr);
                                        }
                                        writer.Write(string.Join(", ", parameterStrs));
                                        if (config.DumpMethodOffset)
                                        {
                                            ulong methodPointer;
                                            if (methodDef.methodIndex >= 0)
                                            {
                                                methodPointer = il2cpp.methodPointers[methodDef.methodIndex];
                                            }
                                            else
                                            {
                                                il2cpp.genericMethoddDictionary.TryGetValue(i, out methodPointer);
                                            }
                                            if (methodPointer > 0)
                                            {
                                                writer.Write("); // RVA: 0x{0:X} Offset: 0x{1:X}\n", methodPointer, il2cpp.MapVATR(methodPointer));
                                                //Script - method
                                                var name = ToEscapedString(HandleSpecialCharacters(typeName + "$$" + methodName));
                                                scriptwriter.WriteLine($"SetMethod(0x{methodPointer:X}, '{name}')");
                                            }
                                            else
                                            {
                                                writer.Write("); // -1\n");
                                            }
                                        }
                                        else
                                        {
                                            writer.Write("); \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");
                            }
                        }
                        //Script - stringLiteral
                        scriptwriter.WriteLine("print('Make method name done')");
                        scriptwriter.WriteLine("print('Setting String...')");
                        if (il2cpp.version > 16)
                        {
                            foreach (var i in metadata.stringLiteralsdic)
                            {
                                scriptwriter.WriteLine($"SetString(0x{il2cpp.metadataUsages[i.Key]:X}, r'{ToEscapedString(i.Value)}')");
                            }
                        }
                        scriptwriter.WriteLine("print('Set string done')");
                        //Script - MakeFunction
                        if (config.MakeFunction)
                        {
                            var orderedPointers = il2cpp.methodPointers.ToList();
                            orderedPointers.AddRange(il2cpp.genericMethodPointers.Where(x => x > 0));
                            orderedPointers.AddRange(il2cpp.invokerPointers);
                            orderedPointers.AddRange(il2cpp.customAttributeGenerators);
                            orderedPointers = orderedPointers.OrderBy(x => x).ToList();
                            scriptwriter.WriteLine("print('Making function...')");
                            for (int i = 0; i < orderedPointers.Count - 1; i++)
                            {
                                scriptwriter.WriteLine($"MakeFunction(0x{orderedPointers[i]:X}, 0x{orderedPointers[i + 1]:X})");
                            }
                            scriptwriter.WriteLine("print('Make function done, please wait for IDA to complete the analysis')");
                        }
                        scriptwriter.WriteLine("print('Script finish !')");
                        //writer close
                        writer.Close();
                        scriptwriter.Close();
                        Console.WriteLine("Done !");
                        //DummyDll
                        if (config.DummyDll)
                        {
                            Console.WriteLine("Create DummyDll...");
                            if (Directory.Exists("DummyDll"))
                            {
                                Directory.Delete("DummyDll", true);
                            }
                            Directory.CreateDirectory("DummyDll");
                            Directory.SetCurrentDirectory("DummyDll");
                            File.WriteAllBytes("Il2CppDummyDll.dll", Resource1.Il2CppDummyDll);
                            var dummy = new DummyAssemblyCreator(metadata, il2cpp);
                            foreach (var assembly in dummy.Assemblies)
                            {
                                var stream = new MemoryStream();
                                assembly.Write(stream);
                                File.WriteAllBytes(assembly.MainModule.Name, stream.ToArray());
                            }
                            Console.WriteLine("Done !");
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                    }
                    Console.WriteLine("Press any key to exit...");
                    Console.ReadKey(true);
                }
            }
        }
示例#20
0
        private static bool Init(byte[] il2cppBytes, byte[] metadataBytes, out Metadata metadata, out Il2Cpp il2Cpp)
        {
            var sanity = BitConverter.ToUInt32(metadataBytes, 0);

            if (sanity != 0xFAB11BAF)
            {
                throw new InvalidDataException("ERROR: Metadata file supplied is not valid metadata file.");
            }
            Console.WriteLine("Initializing metadata...");
            metadata = new Metadata(new MemoryStream(metadataBytes));
            Console.WriteLine($"Metadata Version: {metadata.Version}");
            //判断il2cpp的magic
            var il2cppMagic = BitConverter.ToUInt32(il2cppBytes, 0);
            var isElf       = false;
            var isPE        = false;
            var is64bit     = false;
            var isNSO       = false;
            var isRaw       = false;
            var baseAddr    = 0UL;

            switch (il2cppMagic)
            {
            default:
                //throw new NotSupportedException("ERROR: il2cpp file not supported.");
                Console.Write("Failed to recognize the format of il2cpp, processing it as raw memory file!");
                isRaw = true;
                Console.Write("Enter base address (in hex, like 23c000): ");
                baseAddr = Convert.ToUInt64(Console.ReadLine(), 16);
                Console.WriteLine("Select the bit width:");
                Console.WriteLine("1.32bit 2.64bit");
                var k      = Console.ReadKey();
                var choice = int.Parse(k.KeyChar.ToString()) - 1;
                if (choice > 2 || choice < 0)
                {
                    throw new InvalidDataException("ERROR: wrong bit width choice");
                }
                is64bit = choice == 1;
                break;

            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:
                var machofat = new MachoFat(new MemoryStream(il2cppBytes));
                Console.Write("Select Platform: ");
                for (var i = 0; i < machofat.fats.Length; i++)
                {
                    var fat = machofat.fats[i];
                    Console.Write(fat.magic == 0xFEEDFACF ? $"{i + 1}.64bit " : $"{i + 1}.32bit ");
                }
                Console.WriteLine();
                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);
                if (magic == 0xFEEDFACF)
                {
                    goto case 0xFEEDFACF;
                }
                else
                {
                    goto case 0xFEEDFACE;
                }

            case 0xFEEDFACF:     // 64bit Mach-O
                is64bit = true;
                break;

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

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

            Console.WriteLine("Initializing il2cpp file...");
            var il2CppMemory = new MemoryStream(il2cppBytes);

            if (isRaw)
            {
                il2Cpp = new Raw(il2CppMemory, baseAddr, is64bit, version, metadata.maxMetadataUsages);
            }
            else if (isNSO)
            {
                var nso = new NSO(il2CppMemory, version, metadata.maxMetadataUsages);
                il2Cpp = nso.UnCompress();
            }
            else if (isPE)
            {
                il2Cpp = new PE(il2CppMemory, version, metadata.maxMetadataUsages);
            }
            else if (isElf)
            {
                if (is64bit)
                {
                    il2Cpp = new Elf64(il2CppMemory, version, metadata.maxMetadataUsages);
                }
                else
                {
                    il2Cpp = new Elf(il2CppMemory, version, metadata.maxMetadataUsages);
                }
            }
            else if (is64bit)
            {
                il2Cpp = new Macho64(il2CppMemory, version, metadata.maxMetadataUsages);
            }
            else
            {
                il2Cpp = new Macho(il2CppMemory, version, metadata.maxMetadataUsages);
            }
            Console.WriteLine($"Il2Cpp Version: {il2Cpp.Version}");

            Console.WriteLine("Searching...");
            try
            {
                var flag = il2Cpp.PlusSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length);
                if (!flag)
                {
                    flag = il2Cpp.Search();
                }
                if (!flag)
                {
                    flag = il2Cpp.SymbolSearch();
                }
                if (!flag)
                {
                    Console.WriteLine("ERROR: Can't use auto mode to process file, try manual mode.");
                    Console.Write("Input CodeRegistration: ");
                    var codeRegistration = Convert.ToUInt64(Console.ReadLine(), 16);
                    Console.Write("Input MetadataRegistration: ");
                    var metadataRegistration = Convert.ToUInt64(Console.ReadLine(), 16);
                    il2Cpp.Init(codeRegistration, metadataRegistration);
                    return(true);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                Console.WriteLine("ERROR: An error occurred while processing.");
                return(false);
            }
            return(true);
        }
示例#21
0
        private static void Init(byte[] il2cppBytes, byte[] metadataBytes)
        {
            var sanity = BitConverter.ToUInt32(metadataBytes, 0);

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

            if (metadataVersion == 24)
            {
                Console.WriteLine("Is the Unity version greater than or equal to 2018.3?");
                Console.WriteLine("1.Yes 2.No");
                var key = Console.ReadKey(true);
                if (key.KeyChar == '1')
                {
                    metadataVersion = 24.1f;
                }
            }
            Console.WriteLine("Initializing metadata...");
            metadata = new Metadata(new MemoryStream(metadataBytes), metadataVersion);
            //判断il2cpp的magic
            var il2cppMagic = BitConverter.ToUInt32(il2cppBytes, 0);
            var isElf       = false;
            var isPE        = false;
            var is64bit     = false;

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

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

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

            case 0xCAFEBABE:     //FAT header
            case 0xBEBAFECA:
                var machofat = new MachoFat(new MemoryStream(il2cppBytes));
                Console.Write("Select Platform: ");
                for (var i = 0; i < machofat.fats.Length; i++)
                {
                    var fat = machofat.fats[i];
                    Console.Write(fat.magic == 0xFEEDFACF ? $"{i + 1}.64bit " : $"{i + 1}.32bit ");
                }
                Console.WriteLine();
                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);
                if (magic == 0xFEEDFACF)     // 64-bit mach object file
                {
                    goto case 0xFEEDFACF;
                }
                else
                {
                    goto case 0xFEEDFACE;
                }

            case 0xFEEDFACF:     // 64-bit mach object file
                is64bit = true;
                break;

            case 0xFEEDFACE:     // 32-bit mach object file
                break;
            }

            Console.WriteLine("Select Mode: 1.Manual 2.Auto 3.Auto(Advanced) 4.Auto(Plus) 5.Auto(Symbol)");
            var modeKey = Console.ReadKey(true);
            var version = config.ForceIl2CppVersion ? config.ForceVersion : metadata.version;

            Console.WriteLine("Initializing il2cpp file...");
            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);
            }
            if (modeKey.KeyChar != '1')
            {
                Console.WriteLine("Searching...");
            }
            try
            {
                bool flag;
                switch (modeKey.KeyChar)
                {
                case '1':     //Manual
                    Console.Write("Input CodeRegistration: ");
                    var codeRegistration = Convert.ToUInt64(Console.ReadLine(), 16);
                    Console.Write("Input MetadataRegistration: ");
                    var metadataRegistration = Convert.ToUInt64(Console.ReadLine(), 16);
                    il2cpp.Init(codeRegistration, metadataRegistration);
                    flag = true;
                    break;

                case '2':     //Auto
                    flag = il2cpp.Search();
                    break;

                case '3':     //Auto(Advanced)
                    flag = il2cpp.AdvancedSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0));
                    break;

                case '4':     //Auto(Plus)
                    flag = il2cpp.PlusSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length);
                    break;

                case '5':     //Auto(Symbol)
                    flag = il2cpp.SymbolSearch();
                    break;

                default:
                    return;
                }
                if (!flag)
                {
                    throw new Exception();
                }
            }
            catch
            {
                throw new Exception("ERROR: Can't use this mode to process file, try another mode.");
            }
        }
示例#22
0
        static void Main(string[] args)
        {
            config = File.Exists("config.json") ? new JavaScriptSerializer().Deserialize <Config>(File.ReadAllText("config.json")) : new Config();
            var ofd = new OpenFileDialog();

            ofd.Filter = "ELF file or Mach-O file|*.*";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                var il2cppfile = File.ReadAllBytes(ofd.FileName);
                ofd.Filter = "global-metadata|global-metadata.dat";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        metadata = new Metadata(new MemoryStream(File.ReadAllBytes(ofd.FileName)));
                        //判断il2cpp的magic
                        var il2cppmagic = BitConverter.ToUInt32(il2cppfile, 0);
                        var isElf       = false;
                        var is64bit     = false;
                        switch (il2cppmagic)
                        {
                        default:
                            throw new Exception("ERROR: il2cpp file not supported.");

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

                        case 0xCAFEBABE:    //FAT header
                        case 0xBEBAFECA:
                            var machofat = new MachoFat(new MemoryStream(il2cppfile));
                            Console.Write("Select Platform: ");
                            for (var i = 0; i < machofat.fats.Length; i++)
                            {
                                var fat = machofat.fats[i];
                                if (fat.magic == 0xFEEDFACF)    //64-bit mach object file
                                {
                                    Console.Write($"{i + 1}.64bit ");
                                }
                                else
                                {
                                    Console.Write($"{i + 1}.32bit ");
                                }
                            }
                            Console.WriteLine();
                            var key   = Console.ReadKey(true);
                            var index = int.Parse(key.KeyChar.ToString()) - 1;
                            var magic = machofat.fats[index].magic;
                            il2cppfile = machofat.GetMacho(index);
                            if (magic == 0xFEEDFACF)    // 64-bit mach object file
                            {
                                goto case 0xFEEDFACF;
                            }
                            else
                            {
                                goto case 0xFEEDFACE;
                            }

                        case 0xFEEDFACF:    // 64-bit mach object file
                            is64bit = true;
                            goto case 0xFEEDFACE;

                        case 0xFEEDFACE:    // 32-bit mach object file
                            Console.WriteLine("Select Mode: 1.Manual 2.Auto 3.Auto(Advanced)");
                            key = Console.ReadKey(true);
                            var version = config.forceil2cppversion ? config.forceversion : metadata.version;
                            switch (key.KeyChar)
                            {
                            case '2':
                            case '3':
                                if (isElf)
                                {
                                    il2cpp = new Elf(new MemoryStream(il2cppfile), version, metadata.maxmetadataUsages);
                                }
                                else if (is64bit)
                                {
                                    il2cpp = new Macho64(new MemoryStream(il2cppfile), version, metadata.maxmetadataUsages);
                                }
                                else
                                {
                                    il2cpp = new Macho(new MemoryStream(il2cppfile), version, metadata.maxmetadataUsages);
                                }
                                try
                                {
                                    if (key.KeyChar == '2' ?
                                        !il2cpp.Search() :
                                        !il2cpp.AdvancedSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0)))
                                    {
                                        throw new Exception();
                                    }
                                }
                                catch
                                {
                                    throw new Exception("ERROR: Unable to process file automatically, try to use other mode.");
                                }
                                break;

                            case '1':
                            {
                                Console.Write("Input CodeRegistration(Parameter 0): ");
                                var codeRegistration = Convert.ToUInt64(Console.ReadLine(), 16);
                                Console.Write("Input MetadataRegistration(Parameter 1): ");
                                var metadataRegistration = Convert.ToUInt64(Console.ReadLine(), 16);
                                if (isElf)
                                {
                                    il2cpp = new Elf(new MemoryStream(il2cppfile), codeRegistration, metadataRegistration, version, metadata.maxmetadataUsages);
                                }
                                else if (is64bit)
                                {
                                    il2cpp = new Macho64(new MemoryStream(il2cppfile), codeRegistration, metadataRegistration, version, metadata.maxmetadataUsages);
                                }
                                else
                                {
                                    il2cpp = new Macho(new MemoryStream(il2cppfile), codeRegistration, metadataRegistration, version, metadata.maxmetadataUsages);
                                }
                                break;
                            }

                            default:
                                return;
                            }
                            var writer = new StreamWriter(new FileStream("dump.cs", FileMode.Create), Encoding.UTF8);
                            Console.WriteLine("Dumping...");
                            //Script
                            var scriptwriter = new StreamWriter(new FileStream("script.py", FileMode.Create), Encoding.UTF8);
                            scriptwriter.WriteLine(Resource1.ida);
                            //
                            //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");
                            }
                            //dump type;
                            for (var idx = 0; idx < metadata.uiNumTypes; ++idx)
                            {
                                try
                                {
                                    var typeDef  = metadata.typeDefs[idx];
                                    var isStruct = 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 != "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));
                                        }
                                    }
                                    writer.Write($"\n// Namespace: {metadata.GetString(typeDef.namespaceIndex)}\n");
                                    writer.Write(GetCustomAttribute(typeDef.customAttributeIndex));
                                    if (config.dumpattribute && (typeDef.flags & TYPE_ATTRIBUTE_SERIALIZABLE) != 0)
                                    {
                                        writer.Write("[Serializable]\n");
                                    }
                                    var visibility = typeDef.flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
                                    if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
                                    {
                                        writer.Write("public ");
                                    }
                                    else if (visibility == TYPE_ATTRIBUTE_NOT_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM || visibility == TYPE_ATTRIBUTE_NESTED_ASSEMBLY)
                                    {
                                        writer.Write("internal ");
                                    }
                                    else if (visibility == TYPE_ATTRIBUTE_NESTED_PRIVATE)
                                    {
                                        writer.Write("private ");
                                    }
                                    else if (visibility == TYPE_ATTRIBUTE_NESTED_FAMILY)
                                    {
                                        writer.Write("protected ");
                                    }
                                    else if (visibility == TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM)
                                    {
                                        writer.Write("protected internal ");
                                    }
                                    if ((typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0 && (typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0)
                                    {
                                        writer.Write("static ");
                                    }
                                    else if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) == 0 && (typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0)
                                    {
                                        writer.Write("abstract ");
                                    }
                                    else if (!isStruct && (typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0)
                                    {
                                        writer.Write("sealed ");
                                    }
                                    if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) != 0)
                                    {
                                        writer.Write("interface ");
                                    }
                                    else if (isStruct)
                                    {
                                        writer.Write("struct ");
                                    }
                                    else
                                    {
                                        writer.Write("class ");
                                    }
                                    writer.Write($"{metadata.GetString(typeDef.nameIndex)}");
                                    if (extends.Count > 0)
                                    {
                                        writer.Write($" : {string.Join(", ", extends)}");
                                    }
                                    writer.Write($" // TypeDefIndex: {idx}\n{{\n");
                                    //dump field
                                    if (config.dumpfield && 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");
                                            var access = pType.attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
                                            if (access == FIELD_ATTRIBUTE_PRIVATE)
                                            {
                                                writer.Write("private ");
                                            }
                                            else if (access == FIELD_ATTRIBUTE_PUBLIC)
                                            {
                                                writer.Write("public ");
                                            }
                                            else if (access == FIELD_ATTRIBUTE_FAMILY)
                                            {
                                                writer.Write("protected ");
                                            }
                                            else if (access == FIELD_ATTRIBUTE_ASSEMBLY || access == FIELD_ATTRIBUTE_FAM_AND_ASSEM)
                                            {
                                                writer.Write("internal ");
                                            }
                                            else if (access == FIELD_ATTRIBUTE_FAM_OR_ASSEM)
                                            {
                                                writer.Write("protected internal ");
                                            }
                                            if ((pType.attrs & FIELD_ATTRIBUTE_LITERAL) != 0)
                                            {
                                                writer.Write("const ");
                                            }
                                            else
                                            {
                                                if ((pType.attrs & FIELD_ATTRIBUTE_STATIC) != 0)
                                                {
                                                    writer.Write("static ");
                                                }
                                                if ((pType.attrs & FIELD_ATTRIBUTE_INIT_ONLY) != 0)
                                                {
                                                    writer.Write("readonly ");
                                                }
                                            }
                                            writer.Write($"{GetTypeName(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();
                                                        multi = BitConverter.ToChar(metadata.ReadBytes(2), 0);
                                                        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}");
                                                    }
                                                }
                                            }
                                            if (config.dumpfieldoffset)
                                            {
                                                writer.Write("; // 0x{0:X}\n", il2cpp.GetFieldOffsetFromIndex(idx, i - typeDef.fieldStart, i));
                                            }
                                            else
                                            {
                                                writer.Write(";\n");
                                            }
                                        }
                                        writer.Write("\n");
                                    }
                                    //dump property
                                    if (config.dumpproperty && typeDef.property_count > 0)
                                    {
                                        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];
                                                writer.Write(GetModifiers(methodDef));
                                                var pReturnType = il2cpp.types[methodDef.returnType];
                                                writer.Write($"{GetTypeName(pReturnType)} {metadata.GetString(propertydef.nameIndex)} {{ ");
                                            }
                                            else if (propertydef.set > 0)
                                            {
                                                var methodDef = metadata.methodDefs[typeDef.methodStart + propertydef.set];
                                                writer.Write(GetModifiers(methodDef));
                                                var pParam = metadata.parameterDefs[methodDef.parameterStart];
                                                var pType  = il2cpp.types[pParam.typeIndex];
                                                writer.Write($"{GetTypeName(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");
                                    }
                                    //dump method
                                    if (config.dumpmethod && typeDef.method_count > 0)
                                    {
                                        writer.Write("\t// Methods\n");
                                        var methodEnd = typeDef.methodStart + typeDef.method_count;
                                        for (var i = typeDef.methodStart; i < methodEnd; ++i)
                                        {
                                            var methodDef = metadata.methodDefs[i];
                                            writer.Write(GetCustomAttribute(methodDef.customAttributeIndex, "\t"));
                                            writer.Write("\t");
                                            writer.Write(GetModifiers(methodDef));
                                            var pReturnType = il2cpp.types[methodDef.returnType];
                                            writer.Write($"{GetTypeName(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  = GetTypeName(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("); // 0x{0:X}\n", il2cpp.methodPointers[methodDef.methodIndex]);
                                                //Script
                                                var name = ToUnicodeString(metadata.GetString(typeDef.nameIndex) + "$$" + metadata.GetString(methodDef.nameIndex));
                                                scriptwriter.WriteLine($"SetMethod(0x{il2cpp.methodPointers[methodDef.methodIndex]:x}, '{name}')");
                                                //
                                            }
                                            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");
                                }
                            }
                            //Script
                            if (il2cpp.version > 16)
                            {
                                foreach (var i in metadata.stringLiteralsdic)
                                {
                                    scriptwriter.WriteLine($"SetString(0x{il2cpp.metadataUsages[i.Key]:x}, '{ToUnicodeString(i.Value)}')");
                                }
                            }
                            //
                            writer.Close();
                            scriptwriter.Close();
                            Console.WriteLine("Done !");
                            break;
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine($"{e.Message}\r\n{e.StackTrace}");
                    }
                    Console.WriteLine("Press any key to exit...");
                    Console.ReadKey(true);
                }
            }
        }
示例#23
0
 public Il2CppDecompiler(Metadata metadata, Il2Cpp il2Cpp)
 {
     writer        = new StreamWriter(new FileStream("dump.cs", FileMode.Create), new UTF8Encoding(false));
     this.metadata = metadata;
     this.il2Cpp   = il2Cpp;
 }
示例#24
0
        private static bool Init(string il2cppPath, string metadataPath, out Metadata metadata, out Il2Cpp il2Cpp)
        {
            Console.WriteLine("Initializing metadata...");
            var metadataBytes = File.ReadAllBytes(metadataPath);

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

            Console.WriteLine("Initializing il2cpp file...");
            var il2cppBytes  = File.ReadAllBytes(il2cppPath);
            var il2cppMagic  = BitConverter.ToUInt32(il2cppBytes, 0);
            var il2CppMemory = new MemoryStream(il2cppBytes);

            switch (il2cppMagic)
            {
            default:
                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
                {
                    il2Cpp = new Elf64(il2CppMemory);
                }
                else
                {
                    il2Cpp = new Elf(il2CppMemory);
                }
                break;

            case 0xCAFEBABE:     //FAT Mach-O
            case 0xBEBAFECA:
                var machofat = new MachoFat(new MemoryStream(il2cppBytes));
                Console.Write("Select Platform: ");
                for (var i = 0; i < machofat.fats.Length; i++)
                {
                    var fat = machofat.fats[i];
                    Console.Write(fat.magic == 0xFEEDFACF ? $"{i + 1}.64bit " : $"{i + 1}.32bit ");
                }
                Console.WriteLine();
                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);
            Console.WriteLine($"Il2Cpp Version: {il2Cpp.Version}");
            if (il2Cpp.Version >= 27 && il2Cpp is ElfBase elf && elf.IsDumped)
            {
                Console.WriteLine("Input global-metadata.dat dump address:");
                metadata.Address = Convert.ToUInt64(Console.ReadLine(), 16);
            }


            Console.WriteLine("Searching...");
            try
            {
                var flag = il2Cpp.PlusSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length, metadata.imageDefs.Length);
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    if (!flag && il2Cpp is PE)
                    {
                        Console.WriteLine("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)
                {
                    Console.WriteLine("ERROR: Can't use auto mode to process file, try manual mode.");
                    Console.Write("Input CodeRegistration: ");
                    var codeRegistration = Convert.ToUInt64(Console.ReadLine(), 16);
                    Console.Write("Input MetadataRegistration: ");
                    var metadataRegistration = Convert.ToUInt64(Console.ReadLine(), 16);
                    il2Cpp.Init(codeRegistration, metadataRegistration);
                    return(true);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                Console.WriteLine("ERROR: An error occurred while processing.");
                return(false);
            }
            return(true);
        }
示例#25
0
        static void Main(string[] args)
        {
            Console.WriteLine("Select Mode: 1. Manual 2.Auto");
            var key = Console.ReadKey(true);

            try
            {
                if (key.KeyChar == '2')
                {
                    metadata = new Metadata(new MemoryStream(File.ReadAllBytes("global-metadata.dat")));
                    il2cpp   = new Il2Cpp(new MemoryStream(File.ReadAllBytes("libil2cpp.so")));
                }
                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(File.ReadAllBytes("global-metadata.dat")));
                    il2cpp   = new Il2Cpp(new MemoryStream(File.ReadAllBytes("libil2cpp.so")), codeRegistration, metadataRegistration);
                }
                else
                {
                    return;
                }
                var writer = new StreamWriter(new FileStream("dump.cs", FileMode.Create));
                Console.WriteLine("Dumping...");
                //dump_image();
                for (int imageIndex = 0; imageIndex < metadata.uiImageCount; imageIndex++)
                {
                    var imageDef = metadata.imageDefs[imageIndex];
                    writer.Write($"// Image {imageIndex}: {metadata.GetString(imageDef.nameIndex)} - {imageDef.typeStart}\n");
                }
                for (int idx = 0; idx < metadata.uiNumTypes; ++idx)
                {
                    //dump_class(i);
                    var typeDef = metadata.typeDefs[idx];
                    writer.Write($"// Namespace: {metadata.GetString(typeDef.namespaceIndex)}\n");
                    if ((typeDef.flags & DefineConstants.TYPE_ATTRIBUTE_SERIALIZABLE) != 0)
                    {
                        writer.Write("[Serializable]\n");
                    }
                    if ((typeDef.flags & DefineConstants.TYPE_ATTRIBUTE_VISIBILITY_MASK) == DefineConstants.TYPE_ATTRIBUTE_PUBLIC)
                    {
                        writer.Write("public ");
                    }
                    if ((typeDef.flags & DefineConstants.TYPE_ATTRIBUTE_ABSTRACT) != 0)
                    {
                        writer.Write("abstract ");
                    }
                    if ((typeDef.flags & DefineConstants.TYPE_ATTRIBUTE_SEALED) != 0)
                    {
                        writer.Write("sealed ");
                    }
                    if ((typeDef.flags & DefineConstants.TYPE_ATTRIBUTE_INTERFACE) != 0)
                    {
                        writer.Write("interface ");
                    }
                    else
                    {
                        writer.Write("class ");
                    }
                    writer.Write($"{metadata.GetString(typeDef.nameIndex)} // TypeDefIndex: {idx}\n{{\n");
                    writer.Write("\t// Fields\n");
                    var fieldEnd = typeDef.fieldStart + typeDef.field_count;
                    for (int i = typeDef.fieldStart; i < fieldEnd; ++i)
                    {
                        //dump_field(i, idx, i - typeDef.fieldStart);
                        var pField   = metadata.fieldDefs[i];
                        var pType    = il2cpp.GetTypeFromTypeIndex(pField.typeIndex);
                        var pDefault = metadata.GetFieldDefaultFromIndex(i);
                        writer.Write("\t");
                        if ((pType.attrs & DefineConstants.FIELD_ATTRIBUTE_PRIVATE) == DefineConstants.FIELD_ATTRIBUTE_PRIVATE)
                        {
                            writer.Write("private ");
                        }
                        if ((pType.attrs & DefineConstants.FIELD_ATTRIBUTE_PUBLIC) == DefineConstants.FIELD_ATTRIBUTE_PUBLIC)
                        {
                            writer.Write("public ");
                        }
                        if ((pType.attrs & DefineConstants.FIELD_ATTRIBUTE_STATIC) != 0)
                        {
                            writer.Write("static ");
                        }
                        if ((pType.attrs & DefineConstants.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);
                            Il2CppType pTypeToUse = il2cpp.GetTypeFromTypeIndex(pDefault.typeIndex);
                            if (pointer > 0)
                            {
                                metadata.Position = pointer;
                                object multi = null;
                                switch (pTypeToUse.type)
                                {
                                case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN:
                                    multi = metadata.ReadBoolean();
                                    break;

                                case Il2CppTypeEnum.IL2CPP_TYPE_U1:
                                case Il2CppTypeEnum.IL2CPP_TYPE_I1:
                                    multi = metadata.ReadByte();
                                    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("\t// Methods\n");
                    var methodEnd = typeDef.methodStart + typeDef.method_count;
                    for (int i = typeDef.methodStart; i < methodEnd; ++i)
                    {
                        //dump_method(i);
                        var methodDef = metadata.methodDefs[i];
                        writer.Write("\t");
                        Il2CppType pReturnType = il2cpp.GetTypeFromTypeIndex(methodDef.returnType);
                        if ((methodDef.flags & DefineConstants.METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == DefineConstants.METHOD_ATTRIBUTE_PRIVATE)
                        {
                            writer.Write("private ");
                        }
                        if ((methodDef.flags & DefineConstants.METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == DefineConstants.METHOD_ATTRIBUTE_PUBLIC)
                        {
                            writer.Write("public ");
                        }
                        if ((methodDef.flags & DefineConstants.METHOD_ATTRIBUTE_VIRTUAL) != 0)
                        {
                            writer.Write("virtual ");
                        }
                        if ((methodDef.flags & DefineConstants.METHOD_ATTRIBUTE_STATIC) != 0)
                        {
                            writer.Write("static ");
                        }

                        writer.Write($"{get_type_name(pReturnType)} {metadata.GetString(methodDef.nameIndex)}(");
                        for (int j = 0; j < methodDef.parameterCount; ++j)
                        {
                            Il2CppParameterDefinition pParam = metadata.parameterDefs[methodDef.parameterStart + j];
                            string     szParamName           = metadata.GetString(pParam.nameIndex);
                            Il2CppType pType      = il2cpp.GetTypeFromTypeIndex(pParam.typeIndex);
                            string     szTypeName = get_type_name(pType);
                            if ((pType.attrs & DefineConstants.PARAM_ATTRIBUTE_OPTIONAL) != 0)
                            {
                                writer.Write("optional ");
                            }
                            if ((pType.attrs & DefineConstants.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} - {1}\n", il2cpp.pCodeRegistration.methodPointers[methodDef.methodIndex], methodDef.methodIndex);
                        }
                        else
                        {
                            writer.Write("); // 0 - -1\n");
                        }
                    }
                    writer.Write("}\n");
                }
                writer.Close();
                Console.WriteLine("Done !");
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey(true);
        }
示例#26
0
 public Il2CppDecompiler(Il2CppExecutor il2CppExecutor)
 {
     executor = il2CppExecutor;
     metadata = il2CppExecutor.metadata;
     il2Cpp   = il2CppExecutor.il2Cpp;
 }
示例#27
0
 public ScriptGenerator(Il2CppExecutor il2CppExecutor)
 {
     executor = il2CppExecutor;
     metadata = il2CppExecutor.metadata;
     il2Cpp   = il2CppExecutor.il2Cpp;
 }
        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);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
示例#29
0
 public DummyAssemblyCreator(Metadata metadata, Il2Cpp il2cpp)
 {
     this.metadata = metadata;
     this.il2cpp   = il2cpp;
     //创建程序集,同时创建所有类
     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), ModuleKind.Dll);
         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);
                 }
             }
         }
         //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 pParam              = metadata.parameterDefs[methodDef.parameterStart + j];
                 var parameterName       = metadata.GetStringFromIndex(pParam.nameIndex);
                 var parameterType       = il2cpp.types[pParam.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);
                     }
                 }
             }
         }
         //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);
                 }
             }
         }
     }
 }
示例#30
0
 public ScriptGenerator(Metadata metadata, Il2Cpp il2Cpp)
 {
     this.metadata = metadata;
     this.il2Cpp   = il2Cpp;
 }