From e6488615ded12cabc3ed071a0faee3a8262a4fc3 Mon Sep 17 00:00:00 2001 From: Katy Coe Date: Fri, 10 Nov 2017 12:05:07 +0100 Subject: [PATCH] Implement and output field modifiers correctly --- Il2CppDumper/Il2CppDumper.cs | 18 +++++++++- Il2CppInspector/Reflection/FieldInfo.cs | 47 +++++++++++++++++++------ 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/Il2CppDumper/Il2CppDumper.cs b/Il2CppDumper/Il2CppDumper.cs index 4247f23..724a2ce 100644 --- a/Il2CppDumper/Il2CppDumper.cs +++ b/Il2CppDumper/Il2CppDumper.cs @@ -52,14 +52,30 @@ namespace Il2CppInspector foreach (var field in type.DeclaredFields) { writer.Write("\t"); + if (field.IsNotSerialized) + writer.Write("[NonSerialized]\t"); + if (field.IsPrivate) writer.Write("private "); if (field.IsPublic) writer.Write("public "); - if (field.IsStatic) + if (field.IsFamily) + writer.Write("protected "); + if (field.IsAssembly) + writer.Write("internal "); + if (field.IsFamilyOrAssembly) + writer.Write("protected internal "); + if (field.IsFamilyAndAssembly) + writer.Write("[family and assembly] "); + if (field.IsLiteral) + writer.Write("const "); + // All const fields are also static by implication + else if (field.IsStatic) writer.Write("static "); if (field.IsInitOnly) writer.Write("readonly "); + if (field.IsPinvokeImpl) + writer.Write("extern "); writer.Write($"{field.FieldType.CSharpName} {field.Name}"); if (field.HasDefaultValue) writer.Write($" = {field.DefaultValueString}"); diff --git a/Il2CppInspector/Reflection/FieldInfo.cs b/Il2CppInspector/Reflection/FieldInfo.cs index e8621df..46e312a 100644 --- a/Il2CppInspector/Reflection/FieldInfo.cs +++ b/Il2CppInspector/Reflection/FieldInfo.cs @@ -30,25 +30,37 @@ namespace Il2CppInspector.Reflection { // https://docs.microsoft.com/en-us/dotnet/api/system.reflection.fieldinfo.isfamilyandassembly?view=netframework-4.7.1#System_Reflection_FieldInfo_IsFamilyAndAssembly // True if the field is declared as internal - public bool IsAssembly => throw new NotImplementedException(); + public bool IsAssembly => (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Assembly; // True if the field is declared as protected - public bool IsFamily => throw new NotImplementedException(); + public bool IsFamily => (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Family; // True if the field is declared as 'protected private' (always false) - public bool IsFamilyAndAssembly => false; + public bool IsFamilyAndAssembly => (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamANDAssem; // True if the field is declared as protected public - public bool IsFamilyOrAssembly => throw new NotImplementedException(); + public bool IsFamilyOrAssembly => (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamORAssem; // True if the field is declared as readonly public bool IsInitOnly => (Attributes & FieldAttributes.InitOnly) == FieldAttributes.InitOnly; + // True if the field is const + public bool IsLiteral => (Attributes & FieldAttributes.Literal) == FieldAttributes.Literal; + + // True if the field has the NonSerialized attribute + public bool IsNotSerialized => (Attributes & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized; + + // True if the field is extern + public bool IsPinvokeImpl => (Attributes & FieldAttributes.PinvokeImpl) == FieldAttributes.PinvokeImpl; + // True if the field is declared a private - public bool IsPrivate => (Attributes & FieldAttributes.Private) == FieldAttributes.Private; + public bool IsPrivate => (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Private; // True if the field is declared as public - public bool IsPublic => (Attributes & FieldAttributes.Public) == FieldAttributes.Public; + public bool IsPublic => (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public; + + // True if the field has a special name + public bool IsSpecialName => (Attributes & FieldAttributes.SpecialName) == FieldAttributes.SpecialName; // True if the field is declared as static public bool IsStatic => (Attributes & FieldAttributes.Static) == FieldAttributes.Static; @@ -63,15 +75,30 @@ namespace Il2CppInspector.Reflection { Name = pkg.Strings[Definition.nameIndex]; fieldType = pkg.TypeUsages[Definition.typeIndex]; - if ((fieldType.attrs & Il2CppConstants.FIELD_ATTRIBUTE_PRIVATE) == Il2CppConstants.FIELD_ATTRIBUTE_PRIVATE) + if ((fieldType.attrs & Il2CppConstants.FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == Il2CppConstants.FIELD_ATTRIBUTE_PRIVATE) Attributes |= FieldAttributes.Private; - if ((fieldType.attrs & Il2CppConstants.FIELD_ATTRIBUTE_PUBLIC) == Il2CppConstants.FIELD_ATTRIBUTE_PUBLIC) + if ((fieldType.attrs & Il2CppConstants.FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == Il2CppConstants.FIELD_ATTRIBUTE_PUBLIC) Attributes |= FieldAttributes.Public; + if ((fieldType.attrs & Il2CppConstants.FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == Il2CppConstants.FIELD_ATTRIBUTE_FAM_AND_ASSEM) + Attributes |= FieldAttributes.FamANDAssem; + if ((fieldType.attrs & Il2CppConstants.FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == Il2CppConstants.FIELD_ATTRIBUTE_ASSEMBLY) + Attributes |= FieldAttributes.Assembly; + if ((fieldType.attrs & Il2CppConstants.FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == Il2CppConstants.FIELD_ATTRIBUTE_FAMILY) + Attributes |= FieldAttributes.Family; + if ((fieldType.attrs & Il2CppConstants.FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == Il2CppConstants.FIELD_ATTRIBUTE_FAM_OR_ASSEM) + Attributes |= FieldAttributes.FamORAssem; if ((fieldType.attrs & Il2CppConstants.FIELD_ATTRIBUTE_STATIC) == Il2CppConstants.FIELD_ATTRIBUTE_STATIC) Attributes |= FieldAttributes.Static; - if ((fieldType.attrs & Il2CppConstants.FIELD_ATTRIBUTE_INIT_ONLY) == - Il2CppConstants.FIELD_ATTRIBUTE_INIT_ONLY) + if ((fieldType.attrs & Il2CppConstants.FIELD_ATTRIBUTE_INIT_ONLY) == Il2CppConstants.FIELD_ATTRIBUTE_INIT_ONLY) Attributes |= FieldAttributes.InitOnly; + if ((fieldType.attrs & Il2CppConstants.FIELD_ATTRIBUTE_LITERAL) == Il2CppConstants.FIELD_ATTRIBUTE_LITERAL) + Attributes |= FieldAttributes.Literal; + if ((fieldType.attrs & Il2CppConstants.FIELD_ATTRIBUTE_NOT_SERIALIZED) == Il2CppConstants.FIELD_ATTRIBUTE_NOT_SERIALIZED) + Attributes |= FieldAttributes.NotSerialized; + if ((fieldType.attrs & Il2CppConstants.FIELD_ATTRIBUTE_SPECIAL_NAME) == Il2CppConstants.FIELD_ATTRIBUTE_SPECIAL_NAME) + Attributes |= FieldAttributes.SpecialName; + if ((fieldType.attrs & Il2CppConstants.FIELD_ATTRIBUTE_PINVOKE_IMPL) == Il2CppConstants.FIELD_ATTRIBUTE_PINVOKE_IMPL) + Attributes |= FieldAttributes.PinvokeImpl; // Default initialization value if present if (pkg.FieldDefaultValue.TryGetValue(fieldIndex, out object variant)) {