Skip to content

Commit

Permalink
Export FieldInfo/FIeldRva contents into script metadata and import as…
Browse files Browse the repository at this point in the history
… comments
  • Loading branch information
LukeFZ committed Dec 2, 2023
1 parent c2cb88a commit f1cb0d1
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 17 deletions.
27 changes: 19 additions & 8 deletions Il2CppInspector.Common/Model/AppModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ public class AppModel : IEnumerable<CppType>
// 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<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;

Expand Down Expand Up @@ -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;
}
}
Expand Down
25 changes: 18 additions & 7 deletions Il2CppInspector.Common/Outputs/JSONMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
}

Expand Down
14 changes: 12 additions & 2 deletions Il2CppInspector.Common/Outputs/ScriptResources/shared-main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):

Expand Down Expand Up @@ -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')
Expand Down

0 comments on commit f1cb0d1

Please sign in to comment.