From 35587452b4fd2d4c6af2982ed11fcf674eecaa04 Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 10 Sep 2020 09:42:43 +0100 Subject: [PATCH] Fix folder creation conditions + make libil2cpp provide methods by address --- Cpp2IL/Program.cs | 32 ++++++++++++++++---------------- LibCpp2IL/LibCpp2IlMain.cs | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/Cpp2IL/Program.cs b/Cpp2IL/Program.cs index 25564f82..7fd4af6e 100644 --- a/Cpp2IL/Program.cs +++ b/Cpp2IL/Program.cs @@ -160,8 +160,6 @@ public static void Main(string[] args) //Dump DLLs #region Assembly Generation - - LibCpp2IlMain.GetMethodDefinitionByGlobalAddress(0x180623548); var resolver = new RegistryAssemblyResolver(); var moduleParams = new ModuleParameters @@ -173,7 +171,7 @@ public static void Main(string[] args) Console.WriteLine("Building assemblies..."); - Console.WriteLine("\tPass 1: Creating types..."); + Console.WriteLine("\tPass 1: Creating empty types..."); Assemblies = AssemblyBuilder.CreateAssemblies(LibCpp2IlMain.TheMetadata!, resolver, moduleParams); @@ -182,20 +180,30 @@ public static void Main(string[] args) //Stateful method, no return value AssemblyBuilder.ConfigureHierarchy(LibCpp2IlMain.TheMetadata, LibCpp2IlMain.ThePe!); - Console.WriteLine("\tPass 3: Handling Fields, methods, and properties (THIS MAY TAKE A WHILE)..."); + Console.WriteLine("\tPass 3: Populating types..."); var methods = new List<(TypeDefinition type, List methods)>(); + + //Create out dirs if needed + var outputPath = Path.GetFullPath("cpp2il_out"); + if (!Directory.Exists(outputPath)) + Directory.CreateDirectory(outputPath); + + var methodOutputDir = Path.Combine(outputPath, "types"); + if (!(CommandLineOptions.SkipAnalysis && CommandLineOptions.SkipMetadataTextFiles) && !Directory.Exists(methodOutputDir)) + Directory.CreateDirectory(methodOutputDir); for (var imageIndex = 0; imageIndex < LibCpp2IlMain.TheMetadata.assemblyDefinitions.Length; imageIndex++) { var imageDef = LibCpp2IlMain.TheMetadata.assemblyDefinitions[imageIndex]; - var firstTypeDefinition = SharedState.TypeDefsByIndex[imageDef.firstTypeIndex]; - var currentAssembly = firstTypeDefinition.Module.Assembly; - Console.WriteLine($"\t\tProcessing DLL {imageIndex + 1} of {LibCpp2IlMain.TheMetadata.assemblyDefinitions.Length}: {currentAssembly.Name}..."); + Console.WriteLine($"\t\tPopulating {imageDef.typeCount} types in assembly {imageIndex + 1} of {LibCpp2IlMain.TheMetadata.assemblyDefinitions.Length}: {imageDef.Name}..."); + var assemblySpecificPath = Path.Combine(methodOutputDir, imageDef.Name.Replace(".dll", "")); + if (!(CommandLineOptions.SkipMetadataTextFiles && CommandLineOptions.SkipAnalysis) && !Directory.Exists(assemblySpecificPath)) + Directory.CreateDirectory(assemblySpecificPath); - methods.AddRange(AssemblyBuilder.ProcessAssemblyTypes(LibCpp2IlMain.TheMetadata, LibCpp2IlMain.ThePe, LibCpp2IlMain.TheMetadata.assemblyDefinitions[imageIndex])); + methods.AddRange(AssemblyBuilder.ProcessAssemblyTypes(LibCpp2IlMain.TheMetadata, LibCpp2IlMain.ThePe, imageDef)); } //Invert dict for CppToMono @@ -281,14 +289,6 @@ public static void Main(string[] args) Utils.BuildPrimitiveMappings(); - var outputPath = Path.GetFullPath("cpp2il_out"); - if (!Directory.Exists(outputPath)) - Directory.CreateDirectory(outputPath); - - var methodOutputDir = Path.Combine(outputPath, "types"); - if (!CommandLineOptions.SkipAnalysis && !Directory.Exists(methodOutputDir)) - Directory.CreateDirectory(methodOutputDir); - Console.WriteLine("Saving Header DLLs to " + outputPath + "..."); GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency; diff --git a/LibCpp2IL/LibCpp2IlMain.cs b/LibCpp2IL/LibCpp2IlMain.cs index 8e5739ea..8654fc6c 100644 --- a/LibCpp2IL/LibCpp2IlMain.cs +++ b/LibCpp2IL/LibCpp2IlMain.cs @@ -1,3 +1,5 @@ +using System; +using System.Collections.Generic; using System.IO; using System.Linq; using LibCpp2IL.Metadata; @@ -13,11 +15,20 @@ public class LibCpp2IlSettings } public static readonly LibCpp2IlSettings Settings = new LibCpp2IlSettings(); - + public static float MetadataVersion = 24f; public static PE.PE? ThePe; public static Il2CppMetadata? TheMetadata; + + private static readonly Dictionary> MethodsByPtr = new Dictionary>(); + public static List? GetListOfMethodImplementationsAtAddress(ulong addr) + { + MethodsByPtr.TryGetValue(addr, out var ret); + + return ret; + } + public static string? GetLiteralByAddress(ulong address) { var literal = LibCpp2IlGlobalMapper.Literals.FirstOrDefault(lit => lit.Offset == address); @@ -78,13 +89,31 @@ public static bool Initialize(byte[] peBytes, byte[] metadataBytes, int[] unityV if (TheMetadata == null) return false; + + Console.WriteLine("Read Metadata ok."); ThePe = new PE.PE(new MemoryStream(peBytes, 0, peBytes.Length, false, true), TheMetadata.maxMetadataUsages); if (!ThePe.PlusSearch(TheMetadata.methodDefs.Count(x => x.methodIndex >= 0), TheMetadata.typeDefs.Length)) return false; - LibCpp2IlGlobalMapper.MapGlobalIdentifiers(TheMetadata, ThePe); + Console.WriteLine("Read PE Data ok."); + var start = DateTime.Now; + Console.Write("Mapping Globals..."); + LibCpp2IlGlobalMapper.MapGlobalIdentifiers(TheMetadata, ThePe); + Console.WriteLine($"OK ({(DateTime.Now - start).TotalMilliseconds}ms)"); + + start = DateTime.Now; + Console.Write("Mapping pointers to Il2CppMethodDefinitions..."); + foreach (var (method, ptr) in TheMetadata.methodDefs.AsParallel().Select(method => (method, ptr: method.MethodPointer))) + { + if(!MethodsByPtr.ContainsKey(ptr)) + MethodsByPtr[ptr] = new List(); + + MethodsByPtr[ptr].Add(method); + } + Console.WriteLine($"OK ({(DateTime.Now - start).TotalMilliseconds}ms)"); + return true; }