From f750000c9055a1af53304dc9b1db1bb1b1a8c144 Mon Sep 17 00:00:00 2001 From: Katy Coe Date: Tue, 11 Aug 2020 07:36:41 +0200 Subject: [PATCH] Model: Preliminary attempt at populating AddressMap --- Il2CppInspector.Common/Model/AddressMap.cs | 90 +++++++++++++++++++++- 1 file changed, 88 insertions(+), 2 deletions(-) diff --git a/Il2CppInspector.Common/Model/AddressMap.cs b/Il2CppInspector.Common/Model/AddressMap.cs index bb017e3..df98511 100644 --- a/Il2CppInspector.Common/Model/AddressMap.cs +++ b/Il2CppInspector.Common/Model/AddressMap.cs @@ -7,7 +7,10 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Linq; using System.Text; +using Il2CppInspector.Cpp; +using Il2CppInspector.Reflection; namespace Il2CppInspector.Model { @@ -19,7 +22,7 @@ namespace Il2CppInspector.Model public AppModel Model { get; } // Underlying collection - public Dictionary Items { get; } = new Dictionary(); + public SortedDictionary Items { get; } = new SortedDictionary(); #region Surrogate implementation of IDictionary @@ -50,7 +53,90 @@ namespace Il2CppInspector.Model } private void build() { - // TODO: Build address map + // Get handle to C++ types + var cppTypes = Model.CppTypeCollection; + + // Start by adding all of the .NET methods from all groups + var methodInfoPtrType = cppTypes.GetType("MethodInfo *"); + + foreach (var method in Model.Methods.Values) { + // Method function body + // Shared generic methods may share the same address! + if (method.HasCompiledCode) + TryAdd(method.MethodCodeAddress, method); + + // Method reference (MethodInfo *) + if (method.HasMethodInfo) + Add(method.MethodInfoPtrAddress, new CppField($"{method.CppFnPtrType.Name}__MethodInfo", methodInfoPtrType)); + } + + // Add all custom attributes generators + // The compiler might perform ICF which will cause duplicates with the above + foreach (var cag in Model.ILModel.CustomAttributeGeneratorsByAddress) + TryAdd(cag.Key, cag.Value); + + // Add all method invokers. Multiple invoker indices may reference the same function address + foreach (var mi in Model.ILModel.MethodInvokers.Where(m => m != null)) + TryAdd(mi.VirtualAddress.Start, mi); + + // String literals (metadata >= 19) + if (!Model.StringIndexesAreOrdinals) + foreach (var str in Model.Strings) + Add(str.Key, str.Value); + + // Type definitions and references + var classPtrType = cppTypes.GetType("Il2CppClass *"); + var classRefPtrType = cppTypes.GetType("Il2CppType *"); + foreach (var type in Model.Types.Values) { + if (type.TypeClassAddress != 0xffffffff_ffffffff) + Add(type.TypeClassAddress, new CppField($"{type.Name}__TypeInfo", classPtrType)); + + if (type.TypeRefPtrAddress != 0xffffffff_ffffffff) + Add(type.TypeRefPtrAddress, new CppField($"{type.Name}__TypeRef", classRefPtrType)); + } + + // Internal metadata + var binary = Model.Package.Binary; + Add(binary.CodeRegistrationPointer, binary.CodeRegistration); + Add(binary.MetadataRegistrationPointer, binary.MetadataRegistration); + + if (Model.Package.Version >= 24.2) { + Add(binary.CodeRegistration.pcodeGenModules, binary.CodeGenModulePointers); + + foreach (var ptr in binary.CodeGenModulePointers) + Add(ptr.Value, binary.Modules[ptr.Key]); + } + + if (binary.RegistrationFunctionPointer != 0) + if (Model.UnityVersion.CompareTo("5.3.5") >= 0) + Add(binary.RegistrationFunctionPointer, CppFnPtrType.FromSignature(cppTypes, + "void (*il2cpp_codegen_register)(const Il2CppCodeRegistration* const codeRegistration, const Il2CppMetadataRegistration* const metadataRegistration, const Il2CppCodeGenOptions* const codeGenOptions)")); + else + Add(binary.RegistrationFunctionPointer, CppFnPtrType.FromSignature(cppTypes, + "void (*il2cpp_codegen_register)(const Il2CppCodeRegistration* const codeRegistration, const Il2CppMetadataRegistration* const metadataRegistration)")); + + // IL2CPP API exports + // Alternative names like il2cpp_class_from_type and il2cpp_class_from_il2cpp_type may point to the same address + foreach (var api in Model.AvailableAPIs) { + var address = Model.AvailableAPIs.primaryToSubkeyMapping[api.Key]; + TryAdd(address, api.Value); + } + + // Unknown functions + // We'll skip over all the functions already added via the method iterators above, + // leaving just the ones we haven't done any processing on + foreach (var func in Model.Package.FunctionAddresses.Keys) + TryAdd(func, CppFnPtrType.FromSignature(cppTypes, $"void (*unk_{func.ToAddressString()})()")); + + // Remaining exports + var voidPtrType = cppTypes.GetType("void *"); + foreach (var export in Model.Exports) + TryAdd(export.VirtualAddress, export); + + // Symbols + // The symbols may also include the exports + foreach (var symbol in Model.Symbols.Values) + TryAdd(symbol.VirtualAddress, symbol); } } }