diff --git a/Il2CppDumper/Il2CppIDAScriptDumper.cs b/Il2CppDumper/Il2CppIDAScriptDumper.cs index cf948b9..4867bb1 100644 --- a/Il2CppDumper/Il2CppIDAScriptDumper.cs +++ b/Il2CppDumper/Il2CppIDAScriptDumper.cs @@ -13,6 +13,15 @@ namespace Il2CppInspector { public class Il2CppIDAScriptDumper { + private readonly Dictionary usagePrefixes = new Dictionary { + [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)}'"); } } diff --git a/Il2CppInspector/IL2CPP/Il2CppModel.cs b/Il2CppInspector/IL2CPP/Il2CppModel.cs index 31c5c2e..829a9ab 100644 --- a/Il2CppInspector/IL2CPP/Il2CppModel.cs +++ b/Il2CppInspector/IL2CPP/Il2CppModel.cs @@ -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. */ @@ -19,7 +19,7 @@ namespace Il2CppInspector.Reflection // List of all types ordered by their TypeDefinitionIndex public TypeInfo[] TypesByDefinitionIndex { get; } - + // List of all type definitions by fully qualified name public Dictionary TypesByFullName { get; } = new Dictionary(); @@ -30,7 +30,7 @@ namespace Il2CppInspector.Reflection public ConcurrentDictionary TypesByVirtualAddress { get; } = new ConcurrentDictionary(); // Every type - public IEnumerable Types => new IEnumerable[] { TypesByDefinitionIndex, TypesByUsageIndex, TypesByVirtualAddress.Values }.SelectMany(t => t); + public IEnumerable Types => new IEnumerable[] {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); + } } } \ No newline at end of file diff --git a/Il2CppInspector/IL2CPP/MetadataUsage.cs b/Il2CppInspector/IL2CPP/MetadataUsage.cs index 477216b..2966111 100644 --- a/Il2CppInspector/IL2CPP/MetadataUsage.cs +++ b/Il2CppInspector/IL2CPP/MetadataUsage.cs @@ -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. */