예제 #1
0
 private void AddParents(Il2CppTypeDefinition typeDef, StructInfo structInfo)
 {
     if (!typeDef.IsValueType && !typeDef.IsEnum)
     {
         if (typeDef.parentIndex >= 0)
         {
             var parent    = il2Cpp.types[typeDef.parentIndex];
             var parentDef = GetTypeDefinition(parent);
             if (parentDef != null)
             {
                 AddParents(parentDef, structInfo);
                 if (parentDef.field_count > 0)
                 {
                     var fieldEnd = parentDef.fieldStart + parentDef.field_count;
                     for (var i = parentDef.fieldStart; i < fieldEnd; ++i)
                     {
                         var fieldDef  = metadata.fieldDefs[i];
                         var fieldType = il2Cpp.types[fieldDef.typeIndex];
                         if ((fieldType.attrs & FIELD_ATTRIBUTE_LITERAL) == 0 && (fieldType.attrs & FIELD_ATTRIBUTE_STATIC) == 0)
                         {
                             structInfo.Parents.Add(GetIl2CppStructName(parent));
                             break;
                         }
                     }
                 }
             }
         }
     }
 }
예제 #2
0
        private string GetTypeDefName(Il2CppTypeDefinition typeDef, bool generic = true)
        {
            var prefix = string.Empty;

            if (typeDef.declaringTypeIndex != -1)
            {
                prefix = GetTypeName(il2Cpp.types[typeDef.declaringTypeIndex]) + ".";
            }
            var typeName = metadata.GetStringFromIndex(typeDef.nameIndex);

            if (typeDef.genericContainerIndex >= 0)
            {
                var genericContainer = metadata.genericContainers[typeDef.genericContainerIndex];
                typeName = typeName.Replace($"`{genericContainer.type_argc}", "");
                if (generic)
                {
                    var genericParameterNames = new List <string>();
                    for (int i = 0; i < genericContainer.type_argc; i++)
                    {
                        var genericParameterIndex = genericContainer.genericParameterStart + i;
                        var param = metadata.genericParameters[genericParameterIndex];
                        genericParameterNames.Add(metadata.GetStringFromIndex(param.nameIndex));
                    }
                    typeName += $"<{string.Join(", ", genericParameterNames)}>";
                }
            }
            return(prefix + typeName);
        }
예제 #3
0
        public string GetTypeDefName(Il2CppTypeDefinition typeDef, bool addNamespace, bool genericParameter)
        {
            var prefix = string.Empty;

            if (typeDef.declaringTypeIndex != -1)
            {
                prefix = GetTypeName(il2Cpp.types[typeDef.declaringTypeIndex], addNamespace, true) + ".";
            }
            else if (addNamespace)
            {
                var @namespace = metadata.GetStringFromIndex(typeDef.namespaceIndex);
                if (@namespace != "")
                {
                    prefix = @namespace + ".";
                }
            }
            var typeName = metadata.GetStringFromIndex(typeDef.nameIndex);

            if (typeDef.genericContainerIndex >= 0)
            {
                var index = typeName.IndexOf("`");
                if (index != -1)
                {
                    typeName = typeName.Substring(0, index);
                }
                if (genericParameter)
                {
                    var genericContainer = metadata.genericContainers[typeDef.genericContainerIndex];
                    typeName += GetGenericContainerParams(genericContainer);
                }
            }
            return(prefix + typeName);
        }
예제 #4
0
        private void AddVTableMethod(StructInfo structInfo, Il2CppTypeDefinition typeDef)
        {
            var dic = new SortedDictionary <int, Il2CppMethodDefinition>();

            for (int i = 0; i < typeDef.vtable_count; i++)
            {
                var vTableIndex        = typeDef.vtableStart + i;
                var encodedMethodIndex = metadata.vtableMethods[vTableIndex];
                var usage = metadata.GetEncodedIndexType(encodedMethodIndex);
                var index = metadata.GetDecodedMethodIndex(encodedMethodIndex);
                Il2CppMethodDefinition methodDef;
                if (usage == 6) //kIl2CppMetadataUsageMethodRef
                {
                    var methodSpec = il2Cpp.methodSpecs[index];
                    methodDef = metadata.methodDefs[methodSpec.methodDefinitionIndex];
                }
                else
                {
                    methodDef = metadata.methodDefs[index];
                }
                dic[methodDef.slot] = methodDef;
            }
            foreach (var i in dic)
            {
                var methodInfo = new StructVTableMethodInfo();
                structInfo.VTableMethod.Add(methodInfo);
                var methodDef = i.Value;
                methodInfo.MethodName = $"_{methodDef.slot}_{FixName(metadata.GetStringFromIndex(methodDef.nameIndex))}";
            }
        }
예제 #5
0
        public string GetTypeName(Il2CppTypeDefinition typeDef)
        {
            var ret = string.Empty;

            if (typeDef.declaringTypeIndex != -1)
            {
                ret += GetTypeName(il2Cpp.types[typeDef.declaringTypeIndex]) + ".";
            }
            ret += metadata.GetStringFromIndex(typeDef.nameIndex);
            var names = new List <string>();

            if (typeDef.genericContainerIndex >= 0)
            {
                var genericContainer = metadata.genericContainers[typeDef.genericContainerIndex];
                for (int i = 0; i < genericContainer.type_argc; i++)
                {
                    var genericParameterIndex = genericContainer.genericParameterStart + i;
                    var param = metadata.genericParameters[genericParameterIndex];
                    names.Add(metadata.GetStringFromIndex(param.nameIndex));
                }
                ret  = ret.Replace($"`{genericContainer.type_argc}", "");
                ret += $"<{string.Join(", ", names)}>";
            }
            return(ret);
        }
예제 #6
0
 private void AddFields(Il2CppTypeDefinition typeDef, StructInfo structInfo, Il2CppGenericContext context)
 {
     if (typeDef.field_count > 0)
     {
         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];
             if ((fieldType.attrs & FIELD_ATTRIBUTE_LITERAL) != 0)
             {
                 continue;
             }
             var structFieldInfo = new StructFieldInfo();
             structFieldInfo.FieldTypeName = ParseType(fieldType, context);
             var fieldName = FixName(metadata.GetStringFromIndex(fieldDef.nameIndex));
             structFieldInfo.FieldName   = fieldName;
             structFieldInfo.IsValueType = IsValueType(fieldType, context);
             if ((fieldType.attrs & FIELD_ATTRIBUTE_STATIC) != 0)
             {
                 structInfo.StaticFields.Add(structFieldInfo);
             }
             else
             {
                 structInfo.Fields.Add(structFieldInfo);
             }
         }
     }
 }
예제 #7
0
        private void CreateStructNameDic(Il2CppTypeDefinition typeDef)
        {
            var typeName       = executor.GetTypeDefName(typeDef, true, true);
            var typeStructName = FixName(typeName);
            var uniqueName     = GetUniqueName(typeStructName);

            structNameDic.Add(typeDef, uniqueName);
        }
예제 #8
0
        private void DumpMethod(StreamWriter writer, StreamWriter scriptwriter, Il2CppTypeDefinition typeDef, string typeName)
        {
            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));
                ulong methodPointer;
                if (methodDef.methodIndex >= 0)
                {
                    methodPointer = il2cpp.methodPointers[methodDef.methodIndex];
                }
                else
                {
                    il2cpp.genericMethoddDictionary.TryGetValue(i, out methodPointer);
                }
                if (methodPointer > 0)
                {
                    writer.Write("); // 0x{0:X}\n", methodPointer);
                    if (scriptwriter != null)
                    {
                        var name = ToEscapedString(Regex.Replace(typeName, @"`\d", "") + "$$" + methodName);
                        scriptwriter.WriteLine($"SetMethod(0x{methodPointer:X}, '{name}')");
                    }
                }
                else
                {
                    writer.Write("); // -1\n");
                }
            }
        }
예제 #9
0
 private void AddFields(Il2CppTypeDefinition typeDef, List <StructFieldInfo> fields, List <StructFieldInfo> staticFields, Il2CppGenericContext context, bool isParent)
 {
     if (!typeDef.IsValueType && !typeDef.IsEnum)
     {
         if (typeDef.parentIndex >= 0)
         {
             var parent = il2Cpp.types[typeDef.parentIndex];
             ParseParent(parent, out var parentDef, out var parentContext);
             if (parentDef != null)
             {
                 AddFields(parentDef, fields, staticFields, parentContext, true);
             }
         }
     }
     if (typeDef.field_count > 0)
     {
         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];
             if ((fieldType.attrs & FIELD_ATTRIBUTE_LITERAL) != 0)
             {
                 continue;
             }
             var structFieldInfo = new StructFieldInfo();
             structFieldInfo.FieldTypeName = ParseType(fieldType, context);
             var fieldName = FixName(metadata.GetStringFromIndex(fieldDef.nameIndex));
             structFieldInfo.FieldName   = fieldName;
             structFieldInfo.IsValueType = IsValueType(fieldType, context);
             if ((fieldType.attrs & FIELD_ATTRIBUTE_STATIC) != 0)
             {
                 if (!isParent)
                 {
                     staticFields.Add(structFieldInfo);
                 }
             }
             else
             {
                 if (isParent)
                 {
                     var access = fieldType.attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
                     if (access == FIELD_ATTRIBUTE_PRIVATE)
                     {
                         structFieldInfo.FieldName = $"{FixName(metadata.GetStringFromIndex(typeDef.nameIndex))}_{fieldName}";
                     }
                 }
                 if (fields.Any(x => x.FieldName == structFieldInfo.FieldName))
                 {
                     structFieldInfo.FieldName = $"{FixName(metadata.GetStringFromIndex(typeDef.nameIndex))}_{structFieldInfo.FieldName}";
                 }
                 fields.Add(structFieldInfo);
             }
         }
     }
 }
예제 #10
0
        private void AddStruct(Il2CppTypeDefinition typeDef)
        {
            var structInfo = new StructInfo();

            structInfoList.Add(structInfo);
            structInfo.TypeName    = structNameDic[typeDef];
            structInfo.IsValueType = typeDef.IsValueType;
            AddFields(typeDef, structInfo.Fields, structInfo.StaticFields, null, false);
            AddVTableMethod(structInfo, typeDef);
        }
        private static string GetTypeName(Il2CppTypeDefinition typeDef)
        {
            var ret = string.Empty;

            if (typeDef.declaringTypeIndex != -1)
            {
                ret += GetTypeName(il2cpp.types[typeDef.declaringTypeIndex]) + ".";
            }
            ret += metadata.GetStringFromIndex(typeDef.nameIndex);
            return(ret);
        }
예제 #12
0
        private Il2CppTypeDefinitionInfo AddStruct(Il2CppTypeDefinition typeDef, TypeDefinitionMetadata metadata, Il2CppGenericClass genericClass = null)
        {
            var typeInfo = executor.GetTypeDefInfo(typeDef, genericClass);

            typeInfo.ImageName = metadata.ImageName;
            if (typeDefToAddress.ContainsKey(typeDef))
            {
                typeInfo.Type.Address = typeDefToAddress[typeDef];
            }
            TypeInfoList.Add(typeInfo);
            return(typeInfo);
        }
예제 #13
0
        public string GetName(Il2CppTypeDefinition typeDef, string originalName)
        {
            Il2CppExecutor executor;

            if (!_executor.TryGetTarget(out executor))
            {
                throw new InvalidOperationException("Cannot be used with disposed executor!");
            }
            var il2CppType = executor.GetIl2CppTypeFromTypeDefinition(typeDef);

            return(GetName(executor, typeDef, il2CppType, originalName));
        }
예제 #14
0
        private void AddStruct(Il2CppTypeDefinition typeDef)
        {
            var structInfo = new StructInfo();

            structInfoList.Add(structInfo);
            structInfo.TypeName    = structNameDic[typeDef];
            structInfo.IsValueType = typeDef.IsValueType;
            AddParents(typeDef, structInfo);
            AddFields(typeDef, structInfo, null);
            AddVTableMethod(structInfo, typeDef);
            AddRGCTX(structInfo, typeDef);
        }
예제 #15
0
        private static string get_type_name(Il2CppType pType)
        {
            string ret;

            if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_CLASS || pType.type == Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE)
            {
                Il2CppTypeDefinition klass = metadata.typeDefs[pType.data.klassIndex];
                ret = metadata.GetString(klass.nameIndex);
            }
            else if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST)
            {
                Il2CppGenericClass   generic_class = il2cpp.MapVATR <Il2CppGenericClass>(pType.data.generic_class);
                Il2CppTypeDefinition pMainDef      = metadata.typeDefs[generic_class.typeDefinitionIndex];
                ret = metadata.GetString(pMainDef.nameIndex);
                var typeNames           = new List <string>();
                Il2CppGenericInst pInst = il2cpp.MapVATR <Il2CppGenericInst>(generic_class.context.class_inst);
                var pointers            = il2cpp.MapVATR <uint>(pInst.type_argv, (int)pInst.type_argc);
                for (int i = 0; i < pInst.type_argc; ++i)
                {
                    var pOriType = il2cpp.MapVATR <Il2CppType>(pointers[i]);
                    pOriType.Init();
                    typeNames.Add(get_type_name(pOriType));
                }
                ret += $"<{string.Join(", ", typeNames)}>";
            }
            else if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_ARRAY)
            {
                Il2CppArrayType arrayType = il2cpp.MapVATR <Il2CppArrayType>(pType.data.array);
                var             type      = il2cpp.MapVATR <Il2CppType>(arrayType.etype);
                type.Init();
                ret = $"{get_type_name(type)}[]";
            }
            else if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY)
            {
                var type = il2cpp.MapVATR <Il2CppType>(pType.data.type);
                type.Init();
                ret = $"{get_type_name(type)}[]";
            }
            else
            {
                if ((int)pType.type >= szTypeString.Length)
                {
                    ret = "unknow";
                }
                else
                {
                    ret = szTypeString[(int)pType.type];
                }
            }
            return(ret);
        }
예제 #16
0
        public string GetTypeDefName(Il2CppTypeDefinition typeDef, bool addNamespace, bool genericParameter, bool generic_decl = false)
        {
            var prefix = string.Empty;

            if (typeDef.declaringTypeIndex != -1)
            {
                prefix = GetTypeName(il2Cpp.types[typeDef.declaringTypeIndex], addNamespace, true) + "_";
            }
            else if (addNamespace)
            {
                var @namespace = metadata.GetStringFromIndex(typeDef.namespaceIndex);
                @namespace = @namespace.Replace(".", "::");
                if (@namespace != "")
                {
                    prefix = @namespace + "::";
                }
            }
            var typeName = metadata.GetStringFromIndex(typeDef.nameIndex);

            if (typeDef.genericContainerIndex >= 0)
            {
                var index = typeName.IndexOf("`");
                if (index != -1)
                {
                    typeName = typeName.Substring(0, index);
                    typeName = typeName.Replace("<", "_");
                    typeName = typeName.Replace(">", "_");
                }
                if (genericParameter)
                {
                    var genericContainer = metadata.genericContainers[typeDef.genericContainerIndex];
                    typeName += GetGenericContainerParams(genericContainer, generic_decl);
                    if (generic_decl)
                    {
                        return("template " + GetGenericContainerParams(genericContainer, generic_decl));
                    }
                }
            }
            else
            {
                typeName = typeName.Replace("<", "_");
                typeName = typeName.Replace(">", "_");
            }

            //typeName = Il2CppDecompiler.deobfu(typeName);

            return(Il2CppDecompiler.deobfu(prefix + typeName));
        }
예제 #17
0
 private void IndexTypeMetadata()
 {
     // build type -> image reverse lookup
     for (int imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++)
     {
         Il2CppImageDefinition imageDef = metadata.imageDefs[imageIndex];
         string imageName = metadata.GetStringFromIndex(imageDef.nameIndex);
         long   typeEnd   = imageDef.typeStart + imageDef.typeCount;
         foreach (int typeIndex in imageDef.TypeRange)
         {
             Il2CppTypeDefinition typeDef = metadata.typeDefs[typeIndex];
             string typeName = executor.GetTypeDefName(typeDef, true, true);
             TypeMetadata.Add(typeDef, new TypeDefinitionMetadata(imageIndex, typeIndex, imageName, null, typeName));
         }
     }
 }
예제 #18
0
 public Il2CppRGCTXDefinition[] GetRGCTXDefinition(string imageName, Il2CppTypeDefinition typeDef)
 {
     Il2CppRGCTXDefinition[] collection = null;
     if (il2Cpp.Version >= 24.2)
     {
         il2Cpp.rgctxsDictionary[imageName].TryGetValue(typeDef.token, out collection);
     }
     else
     {
         if (typeDef.rgctxCount > 0)
         {
             collection = new Il2CppRGCTXDefinition[typeDef.rgctxCount];
             Array.Copy(metadata.rgctxEntries, typeDef.rgctxStartIndex, collection, 0, typeDef.rgctxCount);
         }
     }
     return(collection);
 }
예제 #19
0
        private string GetName(Il2CppExecutor executor, Il2CppTypeDefinition typeDef, Il2CppType il2CppType, string originalName)
        {
            if (_typeDefToName.ContainsKey(il2CppType))
            {
                return(_typeDefToName[il2CppType].Split('|')[1]);
            }

            var uniqueTypeNamePair = $"{typeDef.namespaceIndex}|{originalName}";
            int n = 0;

            while (_uniqueNames.Contains(uniqueTypeNamePair))
            {
                uniqueTypeNamePair = $"{typeDef.namespaceIndex}|_{++n}_{originalName}";
            }
            _uniqueNames.Add(uniqueTypeNamePair);
            _typeDefToName[il2CppType] = uniqueTypeNamePair;
            return(uniqueTypeNamePair.Split('|')[1]);
        }
예제 #20
0
        public string GetTypeDefName(Il2CppTypeDefinition typeDef, bool addNamespace, bool genericParameter)
        {
            var prefix = string.Empty;

            if (typeDef.declaringTypeIndex != -1)
            {
                prefix = GetTypeName(il2Cpp.types[typeDef.declaringTypeIndex], addNamespace, true) + ".";
            }
            else if (addNamespace)
            {
                var @namespace = metadata.GetStringFromIndex(typeDef.namespaceIndex);
                if (@namespace != "")
                {
                    prefix = @namespace + ".";
                }
            }
            var typeName = metadata.GetStringFromIndex(typeDef.nameIndex);

            if (typeDef.genericContainerIndex >= 0)
            {
                var index = typeName.IndexOf("`");
                if (index != -1)
                {
                    typeName = typeName.Substring(0, index);
                }
                if (genericParameter)
                {
                    var genericContainer      = metadata.genericContainers[typeDef.genericContainerIndex];
                    var genericParameterNames = new List <string>();
                    for (int i = 0; i < genericContainer.type_argc; i++)
                    {
                        var genericParameterIndex = genericContainer.genericParameterStart + i;
                        var param = metadata.genericParameters[genericParameterIndex];
                        genericParameterNames.Add(metadata.GetStringFromIndex(param.nameIndex));
                    }
                    typeName += $"<{string.Join(", ", genericParameterNames)}>";
                }
            }
            return(prefix + typeName);
        }
예제 #21
0
        private void AddRGCTX(StructInfo structInfo, Il2CppTypeDefinition typeDef)
        {
            var imageIndex = typeDefImageIndices[typeDef];
            var collection = executor.GetTypeRGCTXDefinition(typeDef, imageIndex);

            if (collection != null)
            {
                foreach (var definitionData in collection)
                {
                    var structRGCTXInfo = new StructRGCTXInfo();
                    structInfo.RGCTXs.Add(structRGCTXInfo);
                    structRGCTXInfo.Type = definitionData.type;
                    switch (definitionData.type)
                    {
                    case Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_TYPE:
                    {
                        var il2CppType = il2Cpp.types[definitionData.data.typeIndex];
                        structRGCTXInfo.TypeName = FixName(executor.GetTypeName(il2CppType, true, false));
                        break;
                    }

                    case Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_CLASS:
                    {
                        var il2CppType = il2Cpp.types[definitionData.data.typeIndex];
                        structRGCTXInfo.ClassName = FixName(executor.GetTypeName(il2CppType, true, false));
                        break;
                    }

                    case Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_METHOD:
                    {
                        var methodSpec = il2Cpp.methodSpecs[definitionData.data.methodIndex];
                        (var methodSpecTypeName, var methodSpecMethodName) = executor.GetMethodSpecName(methodSpec, true);
                        structRGCTXInfo.MethodName = FixName(methodSpecTypeName + "." + methodSpecMethodName);
                        break;
                    }
                    }
                }
            }
        }
예제 #22
0
        private void DumpProperty(StreamWriter writer, Il2CppTypeDefinition typeDef)
        {
            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");
        }
예제 #23
0
        private void ParseParent(Il2CppType il2CppType, out Il2CppTypeDefinition typeDef, out Il2CppGenericContext context)
        {
            context = null;
            switch (il2CppType.type)
            {
            case Il2CppTypeEnum.IL2CPP_TYPE_CLASS:
            case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE:
                typeDef = metadata.typeDefs[il2CppType.data.klassIndex];
                break;

            case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST:
                var genericClass = il2Cpp.MapVATR <Il2CppGenericClass>(il2CppType.data.generic_class);
                context = genericClass.context;
                typeDef = metadata.typeDefs[genericClass.typeDefinitionIndex];
                break;

            case Il2CppTypeEnum.IL2CPP_TYPE_OBJECT:
                typeDef = null;
                break;

            default:
                throw new NotSupportedException();
            }
        }
        private (Il2CppTypeDefinition, int) ReadCustomAttributeNamedArgumentClassAndIndex(Il2CppTypeDefinition typeDef)
        {
            var memberIndex = this.ReadCompressedInt32();

            if (memberIndex >= 0)
            {
                return(typeDef, memberIndex);
            }
            memberIndex = -(memberIndex + 1);

            var typeIndex      = this.ReadCompressedUInt32();
            var declaringClass = metadata.typeDefs[typeIndex];

            return(declaringClass, memberIndex);
        }
예제 #25
0
        private void DumpField(StreamWriter writer, Il2CppTypeDefinition typeDef, int idx)
        {
            writer.Write("\t// Fields\n");
            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 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");
        }