Export FieldInfo/FIeldRva contents into script metadata and import as comments
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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')
|
||||||
|
|||||||
Reference in New Issue
Block a user