IL2CPP: Refactor metadata usage name discovery

This commit is contained in:
Katy Coe
2020-01-26 23:00:56 +01:00
parent 274f61d605
commit d9cedeca15
3 changed files with 52 additions and 32 deletions

View File

@@ -13,6 +13,15 @@ namespace Il2CppInspector
{
public class Il2CppIDAScriptDumper
{
private readonly Dictionary<MetadataUsageType, string> usagePrefixes = new Dictionary<MetadataUsageType, string> {
[MetadataUsageType.TypeInfo] = "Class",
[MetadataUsageType.Type] = "Class",
[MetadataUsageType.MethodDef] = "Method",
[MetadataUsageType.FieldInfo] = "Field",
[MetadataUsageType.StringLiteral] = "String",
[MetadataUsageType.MethodRef] = "Method"
};
private readonly Il2CppModel model;
private StreamWriter writer;
@@ -69,32 +78,12 @@ index = 1
private void writeUsages() {
foreach (var usage in model.Package.MetadataUsages) {
switch (usage.Type) {
case MetadataUsageType.TypeInfo:
case MetadataUsageType.Type:
var type = model.GetTypeFromUsage(usage.SourceIndex);
writeLines($"SetName({model.Package.BinaryMetadataUsages[usage.DestinationIndex].ToAddressString()}, 'Class${type.Name}')");
break;
case MetadataUsageType.MethodDef:
var method = model.MethodsByDefinitionIndex[usage.SourceIndex];
writeLines($"SetName({model.Package.BinaryMetadataUsages[usage.DestinationIndex].ToAddressString()}, 'Method${method.DeclaringType.Name}.{method.Name}')");
break;
case MetadataUsageType.FieldInfo:
var field = model.Package.Fields[usage.SourceIndex];
type = model.GetTypeFromUsage(field.typeIndex);
var fieldName = model.Package.Strings[field.nameIndex];
writeLines($"SetName({model.Package.BinaryMetadataUsages[usage.DestinationIndex].ToAddressString()}, 'Field${type.Name}.{fieldName}')");
break;
case MetadataUsageType.StringLiteral:
// TODO: String literals
break;
case MetadataUsageType.MethodRef:
var methodSpec = model.Package.MethodSpecs[usage.SourceIndex];
method = model.MethodsByDefinitionIndex[methodSpec.methodDefinitionIndex];
type = method.DeclaringType;
writeLines($"SetName({model.Package.BinaryMetadataUsages[usage.DestinationIndex].ToAddressString()}, 'Method${type.Name}.{method.Name}')");
break;
}
// TODO: String literals
if (usage.Type == MetadataUsageType.StringLiteral)
continue;
var address = model.Package.BinaryMetadataUsages[usage.DestinationIndex];
writeLines($"SetName({address.ToAddressString()}, '{usagePrefixes[usage.Type]}${model.GetMetadataUsageName(usage)}'");
}
}

View File

@@ -1,5 +1,5 @@
/*
Copyright 2017-2019 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
Copyright 2017-2020 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
All rights reserved.
*/
@@ -30,7 +30,7 @@ namespace Il2CppInspector.Reflection
public ConcurrentDictionary<ulong, TypeInfo> TypesByVirtualAddress { get; } = new ConcurrentDictionary<ulong, TypeInfo>();
// Every type
public IEnumerable<TypeInfo> Types => new IEnumerable<TypeInfo>[] { TypesByDefinitionIndex, TypesByUsageIndex, TypesByVirtualAddress.Values }.SelectMany(t => t);
public IEnumerable<TypeInfo> Types => new IEnumerable<TypeInfo>[] {TypesByDefinitionIndex, TypesByUsageIndex, TypesByVirtualAddress.Values}.SelectMany(t => t);
// List of all methods ordered by their MethodDefinitionIndex
public MethodBase[] MethodsByDefinitionIndex { get; }
@@ -79,7 +79,7 @@ namespace Il2CppInspector.Reflection
}
// Create a reference type if necessary
return usage.byref? underlyingType.MakeByRefType() : underlyingType;
return usage.byref ? underlyingType.MakeByRefType() : underlyingType;
}
// Get or generate a type from its IL2CPP binary type usage reference
@@ -99,7 +99,7 @@ namespace Il2CppInspector.Reflection
// Basic primitive types
public TypeInfo GetTypeFromTypeEnum(Il2CppTypeEnum t) {
if ((int)t >= Il2CppConstants.FullNameTypeString.Count)
if ((int) t >= Il2CppConstants.FullNameTypeString.Count)
return null;
var fqn = Il2CppConstants.FullNameTypeString[(int) t];
@@ -130,5 +130,36 @@ namespace Il2CppInspector.Reflection
return -1;
return index;
}
// Get the name of a metadata usage
public string GetMetadataUsageName(MetadataUsage usage) {
switch (usage.Type) {
case MetadataUsageType.TypeInfo:
case MetadataUsageType.Type:
var type = GetTypeFromUsage(usage.SourceIndex);
return type.Name;
case MetadataUsageType.MethodDef:
var method = MethodsByDefinitionIndex[usage.SourceIndex];
return $"{method.DeclaringType.Name}.{method.Name}";
case MetadataUsageType.FieldInfo:
var field = Package.Fields[usage.SourceIndex];
type = GetTypeFromUsage(field.typeIndex);
var fieldName = Package.Strings[field.nameIndex];
return $"{type.Name}.{fieldName}";
case MetadataUsageType.StringLiteral:
// TODO: String literals
return string.Empty;
case MetadataUsageType.MethodRef:
var methodSpec = Package.MethodSpecs[usage.SourceIndex];
method = MethodsByDefinitionIndex[methodSpec.methodDefinitionIndex];
type = method.DeclaringType;
return $"{type.Name}.{method.Name}";
}
throw new NotImplementedException("Unknown metadata usage type: " + usage.Type);
}
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright (c) 2019-2020 Carter Bush - https://github.com/carterbush
Copyright 2020 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
Copyright (c) 2020 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
All rights reserved.
*/