diff --git a/Il2CppInspector.Common/Model/AppModel.cs b/Il2CppInspector.Common/Model/AppModel.cs index c32609c1..8ddd9c01 100644 --- a/Il2CppInspector.Common/Model/AppModel.cs +++ b/Il2CppInspector.Common/Model/AppModel.cs @@ -49,9 +49,10 @@ public class AppModel : IEnumerable // Note: Does not include string literals from global-metadata.dat // Note: The virtual addresses are of String* (VAs of the pointer to String*) objects, not the strings themselves // For il2cpp < 19, the key is the string literal ordinal instead of the address - public Dictionary Strings { get; } = new Dictionary(); + public Dictionary Strings { get; } = []; - public Dictionary Fields { get; } = new Dictionary(); + public Dictionary Fields { get; } = []; + public Dictionary FieldRvas { get; } = []; public bool StringIndexesAreOrdinals => Package.Version < 19; @@ -246,18 +247,28 @@ public AppModel Build(UnityVersion unityVersion = null, CppCompilerType compiler Methods[method].MethodInfoPtrAddress = address; break; + // FieldInfo is used for array initializers. + // FieldRva is used for span initializers. case MetadataUsageType.FieldInfo or MetadataUsageType.FieldRva: var fieldRef = TypeModel.Package.FieldRefs[usage.SourceIndex]; var fieldType = TypeModel.GetMetadataUsageType(usage); var field = fieldType.DeclaredFields.First(f => f.Index == fieldType.Definition.fieldStart + fieldRef.fieldIndex); - + + var name = usage.Type == MetadataUsageType.FieldInfo + ? $"{fieldType.Name}.{field.Name}".ToCIdentifier() + : $"{fieldType.Name}.{field.Name}_FieldRva".ToCIdentifier(); + + var value = field.HasFieldRVA + ? Convert.ToHexString(Package.Metadata.ReadBytes( + (long) field.DefaultValueMetadataAddress, field.FieldType.Sizes.nativeSize)) + : ""; + + if (usage.Type == MetadataUsageType.FieldInfo) - Fields.Add(usage.VirtualAddress, $"{fieldType.Name}.{field.Name}".ToCIdentifier()); + Fields[usage.VirtualAddress] = (name, value); else - { - var defaultValue = Package.FieldDefaultValue[field.Index]; - // TODO: Unsure what it could be used for here. Maybe PID array initializers? - } + FieldRvas[usage.VirtualAddress] = (name, value); + break; } } diff --git a/Il2CppInspector.Common/Outputs/JSONMetadata.cs b/Il2CppInspector.Common/Outputs/JSONMetadata.cs index bc3de842..24856e7e 100644 --- a/Il2CppInspector.Common/Outputs/JSONMetadata.cs +++ b/Il2CppInspector.Common/Outputs/JSONMetadata.cs @@ -220,13 +220,24 @@ private void writeFields() { writeArray("fields", () => { - foreach (var field in model.Fields) - { - writeObject(() => - { - writeName(field.Key, field.Value); - }); - } + foreach (var (addr, field) in model.Fields) + writeFieldObject(addr, field.Name, field.Value); + }); + + writeArray("fieldRvas", () => + { + foreach (var (addr, rva) in model.FieldRvas) + writeFieldObject(addr, rva.Name, rva.Value); + }); + } + + private void writeFieldObject(ulong addr, string name, string value) + { + writeObject(() => + { + writer.WriteString("virtualAddress", addr.ToAddressString()); + writer.WriteString("name", name); + writer.WriteString("value", value); }); } diff --git a/Il2CppInspector.Common/Outputs/ScriptResources/shared-main.py b/Il2CppInspector.Common/Outputs/ScriptResources/shared-main.py index 54d098f8..893bdceb 100644 --- a/Il2CppInspector.Common/Outputs/ScriptResources/shared-main.py +++ b/Il2CppInspector.Common/Outputs/ScriptResources/shared-main.py @@ -43,6 +43,11 @@ def DefineArray(jsonDef): MakeArray(addr, int(jsonDef['count']), AsUTF8(jsonDef['type'])) SetName(addr, AsUTF8(jsonDef['name'])) +def DefineFieldWithValue(jsonDef): + addr = ParseAddress(jsonDef) + SetName(addr, AsUTF8(jsonDef['name'])) + SetComment(addr, AsUTF8(jsonDef['value'])) + # Process JSON def ProcessJSON(jsonData): @@ -95,10 +100,15 @@ def ProcessJSON(jsonData): for d in jsonData['methodInfoPointers']: DefineILMethodInfo(d) - # FieldInfo + # FieldInfo pointers, add the contents as a comment print('Processing FieldInfo pointers') for d in jsonData['fields']: - DefineField(d['virtualAddress'], d['name'], r"uint64_t") + DefineFieldWithValue(d) + + # FieldRva pointers, add the contents as a comment + print('Processing FieldRva pointers') + for d in jsonData['fieldRvas']: + DefineFieldWithValue(d) # Function boundaries print('Processing function boundaries')