Esempio n. 1
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))}";
            }
        }
Esempio n. 2
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);
             }
         }
     }
 }
Esempio n. 3
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;
                         }
                     }
                 }
             }
         }
     }
 }
Esempio n. 4
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);
        }
Esempio n. 5
0
        private void AddGenericClassStruct(ulong pointer)
        {
            var genericClass = il2Cpp.MapVATR <Il2CppGenericClass>(pointer);
            var typeDef      = metadata.typeDefs[genericClass.typeDefinitionIndex];
            var structInfo   = new StructInfo();

            structInfoList.Add(structInfo);
            structInfo.TypeName    = genericClassStructNameDic[pointer];
            structInfo.IsValueType = typeDef.IsValueType;
            AddFields(typeDef, structInfo.Fields, structInfo.StaticFields, genericClass.context, false);
            AddVTableMethod(structInfo, typeDef);
        }
Esempio n. 6
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);
        }
Esempio n. 7
0
        private string RecursionStructInfo(StructInfo info)
        {
            if (!structCache.Add(info))
            {
                return(string.Empty);
            }

            var sb  = new StringBuilder();
            var pre = new StringBuilder();

            sb.Append($"struct {info.TypeName}_o {{\n");
            foreach (var field in info.Fields)
            {
                if (field.IsValueType)
                {
                    var fieldInfo = structInfoWithStructName[field.FieldTypeName];
                    pre.Append(RecursionStructInfo(fieldInfo));
                }
                sb.Append($"\t{field.FieldTypeName} {field.FieldName};\n");
            }
            sb.Append("};\n");

            sb.Append($"struct {info.TypeName}_StaticFields {{\n");
            foreach (var field in info.StaticFields)
            {
                if (field.IsValueType)
                {
                    var fieldInfo = structInfoWithStructName[field.FieldTypeName];
                    pre.Append(RecursionStructInfo(fieldInfo));
                }
                sb.Append($"\t{field.FieldTypeName} {field.FieldName};\n");
            }
            sb.Append("};\n");

            sb.Append($"struct {info.TypeName}_VTable {{\n");
            foreach (var method in info.VTableMethod)
            {
                sb.Append($"\tVirtualInvokeData {method.MethodName};\n");
            }
            sb.Append("};\n");

            sb.Append($"struct {info.TypeName}_c {{\n" +
                      $"\tIl2CppClass_1 _1;\n" +
                      $"\t{info.TypeName}_StaticFields* static_fields;\n" +
                      $"\tIl2CppClass_2 _2;\n" +
                      $"\t{info.TypeName}_VTable vtable;\n" +
                      $"}};\n");

            return(pre.Append(sb).ToString());
        }
Esempio n. 8
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;
                    }
                    }
                }
            }
        }
Esempio n. 9
0
        private string RecursionStructInfo(StructInfo info)
        {
            if (!structCache.Add(info))
            {
                return(string.Empty);
            }

            var sb  = new StringBuilder();
            var pre = new StringBuilder();

            sb.Append($"struct {info.TypeName}_Fields {{\n");
            foreach (var field in info.Fields)
            {
                if (field.IsValueType)
                {
                    var fieldInfo = structInfoWithStructName[field.FieldTypeName];
                    pre.Append(RecursionStructInfo(fieldInfo));
                }
                sb.Append($"\t{field.FieldTypeName} {field.FieldName};\n");
            }
            sb.Append("};\n");

            sb.Append($"struct {info.TypeName}_RGCTXs {{\n");
            for (int i = 0; i < info.RGCTXs.Count; i++)
            {
                var rgctx = info.RGCTXs[i];
                switch (rgctx.Type)
                {
                case Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_TYPE:
                    sb.Append($"\tIl2CppType* _{i}_{rgctx.TypeName};\n");
                    break;

                case Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_CLASS:
                    sb.Append($"\tIl2CppClass* _{i}_{rgctx.ClassName};\n");
                    break;

                case Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_METHOD:
                    sb.Append($"\tMethodInfo* _{i}_{rgctx.MethodName};\n");
                    break;
                }
            }
            sb.Append("};\n");

            sb.Append($"struct {info.TypeName}_VTable {{\n");
            foreach (var method in info.VTableMethod)
            {
                sb.Append($"\tVirtualInvokeData {method.MethodName};\n");
            }
            sb.Append("};\n");

            sb.Append($"struct {info.TypeName}_c {{\n" +
                      $"\tIl2CppClass_1 _1;\n" +
                      $"\tstruct {info.TypeName}_StaticFields* static_fields;\n" +
                      $"\t{info.TypeName}_RGCTXs* rgctx_data;\n" +
                      $"\tIl2CppClass_2 _2;\n" +
                      $"\t{info.TypeName}_VTable vtable;\n" +
                      $"}};\n");

            sb.Append($"struct {info.TypeName}_o {{\n");
            if (!info.IsValueType)
            {
                sb.Append($"\t{info.TypeName}_c *klass;\n");
                sb.Append($"\tvoid *monitor;\n");
            }
            for (int i = 0; i < info.Parents.Count; i++)
            {
                var parent           = info.Parents[i];
                var parentStructName = parent + "_o";
                pre.Append(RecursionStructInfo(structInfoWithStructName[parentStructName]));
                sb.Append($"\t{parent}_Fields parent_fields_{i};\n");
            }
            sb.Append($"\t{info.TypeName}_Fields fields;\n");
            sb.Append("};\n");

            sb.Append($"struct {info.TypeName}_StaticFields {{\n");
            foreach (var field in info.StaticFields)
            {
                if (field.IsValueType)
                {
                    var fieldInfo = structInfoWithStructName[field.FieldTypeName];
                    pre.Append(RecursionStructInfo(fieldInfo));
                }
                sb.Append($"\t{field.FieldTypeName} {field.FieldName};\n");
            }
            sb.Append("};\n");

            return(pre.Append(sb).ToString());
        }