Export FieldInfo/FIeldRva contents into script metadata and import as comments

This commit is contained in:
LukeFZ
2023-12-02 08:27:12 +01:00
parent c2cb88ad81
commit f1cb0d14a2
3 changed files with 49 additions and 17 deletions

View File

@@ -49,9 +49,10 @@ namespace Il2CppInspector.Model
// Note: Does not include string literals from global-metadata.dat // 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 // 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 // For il2cpp < 19, the key is the string literal ordinal instead of the address
public Dictionary<ulong, string> Strings { get; } = new Dictionary<ulong, string>(); public Dictionary<ulong, string> Strings { get; } = [];
public Dictionary<ulong, string> Fields { get; } = new Dictionary<ulong, string>(); public Dictionary<ulong, (string Name, string Value)> Fields { get; } = [];
public Dictionary<ulong, (string Name, string Value)> FieldRvas { get; } = [];
public bool StringIndexesAreOrdinals => Package.Version < 19; public bool StringIndexesAreOrdinals => Package.Version < 19;
@@ -246,18 +247,28 @@ namespace Il2CppInspector.Model
Methods[method].MethodInfoPtrAddress = address; Methods[method].MethodInfoPtrAddress = address;
break; break;
// FieldInfo is used for array initializers.
// FieldRva is used for span initializers.
case MetadataUsageType.FieldInfo or MetadataUsageType.FieldRva: case MetadataUsageType.FieldInfo or MetadataUsageType.FieldRva:
var fieldRef = TypeModel.Package.FieldRefs[usage.SourceIndex]; var fieldRef = TypeModel.Package.FieldRefs[usage.SourceIndex];
var fieldType = TypeModel.GetMetadataUsageType(usage); var fieldType = TypeModel.GetMetadataUsageType(usage);
var field = fieldType.DeclaredFields.First(f => f.Index == fieldType.Definition.fieldStart + fieldRef.fieldIndex); 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) if (usage.Type == MetadataUsageType.FieldInfo)
Fields.Add(usage.VirtualAddress, $"{fieldType.Name}.{field.Name}".ToCIdentifier()); Fields[usage.VirtualAddress] = (name, value);
else else
{ FieldRvas[usage.VirtualAddress] = (name, value);
var defaultValue = Package.FieldDefaultValue[field.Index];
// TODO: Unsure what it could be used for here. Maybe PID array initializers?
}
break; break;
} }
} }

View File

@@ -220,13 +220,24 @@ namespace Il2CppInspector.Outputs
{ {
writeArray("fields", () => writeArray("fields", () =>
{ {
foreach (var field in model.Fields) foreach (var (addr, field) in model.Fields)
{ writeFieldObject(addr, field.Name, field.Value);
writeObject(() => });
{
writeName(field.Key, 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);
}); });
} }

View File

@@ -43,6 +43,11 @@ def DefineArray(jsonDef):
MakeArray(addr, int(jsonDef['count']), AsUTF8(jsonDef['type'])) MakeArray(addr, int(jsonDef['count']), AsUTF8(jsonDef['type']))
SetName(addr, AsUTF8(jsonDef['name'])) SetName(addr, AsUTF8(jsonDef['name']))
def DefineFieldWithValue(jsonDef):
addr = ParseAddress(jsonDef)
SetName(addr, AsUTF8(jsonDef['name']))
SetComment(addr, AsUTF8(jsonDef['value']))
# Process JSON # Process JSON
def ProcessJSON(jsonData): def ProcessJSON(jsonData):
@@ -95,10 +100,15 @@ def ProcessJSON(jsonData):
for d in jsonData['methodInfoPointers']: for d in jsonData['methodInfoPointers']:
DefineILMethodInfo(d) DefineILMethodInfo(d)
# FieldInfo # FieldInfo pointers, add the contents as a comment
print('Processing FieldInfo pointers') print('Processing FieldInfo pointers')
for d in jsonData['fields']: 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 # Function boundaries
print('Processing function boundaries') print('Processing function boundaries')