private static int Run(Options options) { // Banner var asmInfo = FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetEntryAssembly().Location); Console.WriteLine(asmInfo.ProductName); Console.WriteLine("Version " + asmInfo.ProductVersion); Console.WriteLine(asmInfo.LegalCopyright); Console.WriteLine(""); // Check excluded namespaces if (options.ExcludedNamespaces.Count() == 1 && options.ExcludedNamespaces.First().ToLower() == "none") { options.ExcludedNamespaces = new List <string>(); } // Check files if (!File.Exists(options.BinaryFile)) { Console.Error.WriteLine($"File {options.BinaryFile} does not exist"); return(1); } if (!File.Exists(options.MetadataFile)) { Console.Error.WriteLine($"File {options.MetadataFile} does not exist"); return(1); } // Creating a Visual Studio solution requires Unity assembly references var unityPath = string.Empty; var unityAssembliesPath = string.Empty; if (options.CreateSolution) { unityPath = Utils.FindPath(options.UnityPath); unityAssembliesPath = Utils.FindPath(options.UnityAssembliesPath); if (!Directory.Exists(unityPath)) { Console.Error.WriteLine($"Unity path {unityPath} does not exist"); return(1); } if (!File.Exists(unityPath + @"\Editor\Data\Managed\UnityEditor.dll")) { Console.Error.WriteLine($"No Unity installation found at {unityPath}"); return(1); } if (!Directory.Exists(unityAssembliesPath)) { Console.Error.WriteLine($"Unity assemblies path {unityAssembliesPath} does not exist"); return(1); } if (!File.Exists(unityAssembliesPath + @"\UnityEngine.UI.dll")) { Console.Error.WriteLine($"No Unity assemblies found at {unityAssembliesPath}"); return(1); } Console.WriteLine("Using Unity editor at " + unityPath); Console.WriteLine("Using Unity assemblies at " + unityAssembliesPath); } // Analyze data List <Il2CppInspector> il2cppInspectors; using (var il2cppTimer = new Benchmark("Analyze IL2CPP data")) il2cppInspectors = Il2CppInspector.LoadFromFile(options.BinaryFile, options.MetadataFile); if (il2cppInspectors == null) { Environment.Exit(1); } // Write output file int i = 0; foreach (var il2cpp in il2cppInspectors) { // Create model Il2CppModel model; using (var modelTimer = new Benchmark("Create type model")) model = new Il2CppModel(il2cpp); // C# signatures output using (var signaturesDumperTimer = new Benchmark("Generate C# code")) { var writer = new CSharpCodeStubs(model) { ExcludedNamespaces = options.ExcludedNamespaces.ToList(), SuppressMetadata = options.SuppressMetadata, MustCompile = options.MustCompile }; var imageSuffix = i++ > 0 ? "-" + (i - 1) : ""; var csOut = options.CSharpOutPath; if (csOut.ToLower().EndsWith(".cs")) { csOut = csOut.Insert(csOut.Length - 3, imageSuffix); } else { csOut += imageSuffix; } if (options.CreateSolution) { writer.WriteSolution(csOut, unityPath, unityAssembliesPath); } else { switch (options.LayoutSchema.ToLower(), options.SortOrder.ToLower()) {
private static int Run(Options options) { // Banner var asmInfo = FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetEntryAssembly().Location); Console.WriteLine(asmInfo.ProductName); Console.WriteLine("Version " + asmInfo.ProductVersion); Console.WriteLine(asmInfo.LegalCopyright); Console.WriteLine(""); // Check excluded namespaces if (options.ExcludedNamespaces.Count() == 1 && options.ExcludedNamespaces.First().ToLower() == "none") { options.ExcludedNamespaces = new List <string>(); } // Creating a Visual Studio solution requires Unity assembly references var unityPath = string.Empty; var unityAssembliesPath = string.Empty; if (options.CreateSolution) { unityPath = Utils.FindPath(options.UnityPath); unityAssembliesPath = Utils.FindPath(options.UnityAssembliesPath); if (!Directory.Exists(unityPath)) { Console.Error.WriteLine($"Unity path {unityPath} does not exist"); return(1); } string editorPathSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? @"/Contents/Managed/UnityEditor.dll" : @"\Editor\Data\Managed\UnityEditor.dll"; if (!File.Exists(unityPath + editorPathSuffix)) { Console.Error.WriteLine($"No Unity installation found at {unityPath}"); return(1); } if (!Directory.Exists(unityAssembliesPath)) { Console.Error.WriteLine($"Unity assemblies path {unityAssembliesPath} does not exist"); return(1); } string uiDllPath = Path.Combine(unityAssembliesPath, "UnityEngine.UI.dll"); if (!File.Exists(uiDllPath)) { Console.Error.WriteLine($"No UnityEngine.UI.dll assemblies found at {uiDllPath}"); return(1); } Console.WriteLine("Using Unity editor at " + unityPath); Console.WriteLine("Using Unity assemblies at " + unityAssembliesPath); } // Check files exist and determine whether they're archives or not List <Il2CppInspector> il2cppInspectors; using (new Benchmark("Analyze IL2CPP data")) { if (!File.Exists(options.BinaryFile)) { Console.Error.WriteLine($"File {options.BinaryFile} does not exist"); return(1); } try { il2cppInspectors = Il2CppInspector.LoadFromPackage(options.BinaryFile); } catch (Exception ex) { Console.Error.WriteLine(ex.Message); return(1); } if (il2cppInspectors == null) { if (!File.Exists(options.MetadataFile)) { Console.Error.WriteLine($"File {options.MetadataFile} does not exist"); return(1); } il2cppInspectors = Il2CppInspector.LoadFromFile(options.BinaryFile, options.MetadataFile); } } if (il2cppInspectors == null) { Environment.Exit(1); } // Write output file int i = 0; foreach (var il2cpp in il2cppInspectors) { // Create model TypeModel model; using (new Benchmark("Create .NET type model")) model = new TypeModel(il2cpp); AppModel appModel; using (new Benchmark("Create C++ application model")) { appModel = new AppModel(model).Build(options.UnityVersion, options.CppCompiler); } // C# signatures output using (new Benchmark("Generate C# code")) { var writer = new CSharpCodeStubs(model) { ExcludedNamespaces = options.ExcludedNamespaces.ToList(), SuppressMetadata = options.SuppressMetadata, MustCompile = options.MustCompile }; var imageSuffix = i++ > 0 ? "-" + (i - 1) : ""; var csOut = options.CSharpOutPath; if (csOut.ToLower().EndsWith(".cs")) { csOut = csOut.Insert(csOut.Length - 3, imageSuffix); } else { csOut += imageSuffix; } if (options.CreateSolution) { writer.WriteSolution(csOut, unityPath, unityAssembliesPath); } else { switch (options.LayoutSchema.ToLower(), options.SortOrder.ToLower()) {
private static int Run(Options options) { // Banner var asmInfo = FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetEntryAssembly().Location); Console.WriteLine(asmInfo.ProductName); Console.WriteLine("Version " + asmInfo.ProductVersion); Console.WriteLine(asmInfo.LegalCopyright); Console.WriteLine(""); // Check script target is valid if (!PythonScript.GetAvailableTargets().Contains(options.ScriptTarget)) { Console.Error.WriteLine($"Script target {options.ScriptTarget} is invalid."); Console.Error.WriteLine("Valid targets are: " + string.Join(", ", PythonScript.GetAvailableTargets())); return(1); } // Check excluded namespaces if (options.ExcludedNamespaces.Count() == 1 && options.ExcludedNamespaces.First().ToLower() == "none") { options.ExcludedNamespaces = new List <string>(); } // Creating a Visual Studio solution requires Unity assembly references var unityPath = string.Empty; var unityAssembliesPath = string.Empty; if (options.CreateSolution) { unityPath = Utils.FindPath(options.UnityPath); unityAssembliesPath = Utils.FindPath(options.UnityAssembliesPath); if (!Directory.Exists(unityPath)) { Console.Error.WriteLine($"Unity path {unityPath} does not exist"); return(1); } string editorPathSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? @"/Contents/Managed/UnityEditor.dll" : @"\Editor\Data\Managed\UnityEditor.dll"; if (!File.Exists(unityPath + editorPathSuffix)) { Console.Error.WriteLine($"No Unity installation found at {unityPath}"); return(1); } if (!Directory.Exists(unityAssembliesPath)) { Console.Error.WriteLine($"Unity assemblies path {unityAssembliesPath} does not exist"); return(1); } string uiDllPath = Path.Combine(unityAssembliesPath, "UnityEngine.UI.dll"); if (!File.Exists(uiDllPath)) { Console.Error.WriteLine($"No UnityEngine.UI.dll assemblies found at {uiDllPath}"); return(1); } Console.WriteLine("Using Unity editor at " + unityPath); Console.WriteLine("Using Unity assemblies at " + unityAssembliesPath); } // Check that specified binary files exist foreach (var file in options.BinaryFiles) { if (!File.Exists(file)) { Console.Error.WriteLine($"File {file} does not exist"); return(1); } } // Check files exist and determine whether they're archives or not List <Il2CppInspector> il2cppInspectors; using (new Benchmark("Analyze IL2CPP data")) { try { il2cppInspectors = Il2CppInspector.LoadFromPackage(options.BinaryFiles); } catch (Exception ex) { Console.Error.WriteLine(ex.Message); return(1); } if (il2cppInspectors == null) { if (!File.Exists(options.MetadataFile)) { Console.Error.WriteLine($"File {options.MetadataFile} does not exist"); return(1); } try { il2cppInspectors = Il2CppInspector.LoadFromFile(options.BinaryFiles.First(), options.MetadataFile); } catch (Exception ex) { Console.Error.WriteLine(ex.Message); return(1); } } } if (il2cppInspectors == null) { Environment.Exit(1); } // Write output files for each binary int imageIndex = 0; foreach (var il2cpp in il2cppInspectors) { Console.WriteLine($"Processing image {imageIndex} - {il2cpp.BinaryImage.Arch} / {il2cpp.BinaryImage.Bits}-bit"); // Create model TypeModel model; using (new Benchmark("Create .NET type model")) model = new TypeModel(il2cpp); AppModel appModel; using (new Benchmark("Create C++ application model")) { appModel = new AppModel(model, makeDefaultBuild: false).Build(options.UnityVersion, options.CppCompiler); } // C# signatures output using (new Benchmark("Generate C# code")) { var writer = new CSharpCodeStubs(model) { ExcludedNamespaces = options.ExcludedNamespaces.ToList(), SuppressMetadata = options.SuppressMetadata, MustCompile = options.MustCompile }; var csOut = getOutputPath(options.CSharpOutPath, "cs", imageIndex); if (options.CreateSolution) { writer.WriteSolution(csOut, unityPath, unityAssembliesPath); } else { switch (options.LayoutSchema.ToLower(), options.SortOrder.ToLower()) {
/// <summary> /// Perform export /// </summary> private async void BtnExport_OnClick(object sender, RoutedEventArgs e) { var model = (AppModel)lstImages.SelectedItem; var unityPath = txtUnityPath.Text; var unityAssembliesPath = txtUnityScriptPath.Text; var sortOrder = rdoSortIndex.IsChecked == true ? "index" : rdoSortName.IsChecked == true ? "name" : "unknown"; var layout = rdoLayoutSingle.IsChecked == true? "single" : rdoLayoutAssembly.IsChecked == true? "assembly" : rdoLayoutNamespace.IsChecked == true? "namespace" : rdoLayoutClass.IsChecked == true? "class" : rdoLayoutTree.IsChecked == true? "tree" : "unknown"; switch (this) { // C# prototypes and Visual Studio solution case { rdoOutputCSharp: var r, rdoOutputSolution : var s } when r.IsChecked == true || s.IsChecked == true : var createSolution = rdoOutputSolution.IsChecked == true; if (createSolution) { if (!ValidateUnityPath(unityPath)) { return; } if (!ValidateUnityAssembliesPath(unityAssembliesPath)) { return; } } // Get options var excludedNamespaces = constructExcludedNamespaces((IEnumerable <CheckboxNode>)trvNamespaces.ItemsSource); var writer = new CSharpCodeStubs(model.ILModel) { ExcludedNamespaces = excludedNamespaces.ToList(), SuppressMetadata = cbSuppressMetadata.IsChecked == true, MustCompile = cbMustCompile.IsChecked == true }; var flattenHierarchy = cbFlattenHierarchy.IsChecked == true; var separateAssemblyAttributesFiles = cbSeparateAttributes.IsChecked == true; // Determine if we need a filename or a folder - file for single file, folder for everything else var needsFolder = rdoOutputCSharp.IsChecked == false || rdoLayoutSingle.IsChecked == false; var saveFolderDialog = new VistaFolderBrowserDialog { Description = "Select save location", UseDescriptionForTitle = true }; var saveFileDialog = new SaveFileDialog { Filter = "C# source files (*.cs)|*.cs|All files (*.*)|*.*", FileName = "types.cs", CheckFileExists = false, OverwritePrompt = true }; if (needsFolder && saveFolderDialog.ShowDialog() == false) { return; } if (!needsFolder && saveFileDialog.ShowDialog() == false) { return; } txtBusyStatus.Text = createSolution ? "Creating Visual Studio solution..." : "Exporting C# type definitions..."; areaBusyIndicator.Visibility = Visibility.Visible; var outPath = needsFolder ? saveFolderDialog.SelectedPath : saveFileDialog.FileName; await Task.Run(() => { if (createSolution) { writer.WriteSolution(outPath, unityPath, unityAssembliesPath); } else { switch (layout, sortOrder) {
private static int Run(Options options) { // Banner var asmInfo = FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetEntryAssembly().Location); Console.WriteLine(asmInfo.ProductName); Console.WriteLine("Version " + asmInfo.ProductVersion); Console.WriteLine(asmInfo.LegalCopyright); Console.WriteLine(""); // Safe plugin manager load try { PluginManager.EnsureInit(); } catch (Exception ex) when(ex is InvalidOperationException || ex is DirectoryNotFoundException) { Console.Error.WriteLine(ex.Message); Environment.Exit(1); } // Check plugin options are valid if (!PluginOptions.ParsePluginOptions(options.PluginOptions, PluginOptions.GetPluginOptionTypes())) { return(1); } // Check script target is valid if (!PythonScript.GetAvailableTargets().Contains(options.ScriptTarget)) { Console.Error.WriteLine($"Script target {options.ScriptTarget} is invalid."); Console.Error.WriteLine("Valid targets are: " + string.Join(", ", PythonScript.GetAvailableTargets())); return(1); } // Set load options var loadOptions = new LoadOptions { BinaryFilePath = options.BinaryFiles.First() }; // Check image base if (!string.IsNullOrEmpty(options.ElfImageBaseString)) { try { loadOptions.ImageBase = Convert.ToUInt64(options.ElfImageBaseString, 16); } catch (Exception ex) when(ex is ArgumentException || ex is FormatException || ex is OverflowException) { Console.Error.WriteLine("Image base must be a 32 or 64-bit hex value (optionally starting with '0x')"); return(1); } } // Check Unity asset if (options.UnityVersionAsset != null) { try { options.UnityVersion = UnityVersion.FromAssetFile(options.UnityVersionAsset); Console.WriteLine("Unity asset file has version " + options.UnityVersion); } catch (FileNotFoundException) { Console.Error.WriteLine($"Unity asset file {options.UnityVersionAsset} does not exist"); return(1); } catch (ArgumentException) { Console.Error.WriteLine("Could not determine Unity version from asset file - ignoring"); } } // Check excluded namespaces if (options.ExcludedNamespaces.Count() == 1 && options.ExcludedNamespaces.First().ToLower() == "none") { options.ExcludedNamespaces = new List <string>(); } // Creating a Visual Studio solution requires Unity assembly references var unityPath = string.Empty; var unityAssembliesPath = string.Empty; if (options.CreateSolution) { unityPath = Utils.FindPath(options.UnityPath); unityAssembliesPath = Utils.FindPath(options.UnityAssembliesPath); if (!Directory.Exists(unityPath)) { Console.Error.WriteLine($"Unity path {unityPath} does not exist"); return(1); } string editorPathSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? @"/Contents/Managed/UnityEditor.dll" : @"\Editor\Data\Managed\UnityEditor.dll"; if (!File.Exists(unityPath + editorPathSuffix)) { Console.Error.WriteLine($"No Unity installation found at {unityPath}"); return(1); } if (!Directory.Exists(unityAssembliesPath)) { Console.Error.WriteLine($"Unity assemblies path {unityAssembliesPath} does not exist"); return(1); } string uiDllPath = Path.Combine(unityAssembliesPath, "UnityEngine.UI.dll"); if (!File.Exists(uiDllPath)) { Console.Error.WriteLine($"No UnityEngine.UI.dll assemblies found at {uiDllPath}"); return(1); } Console.WriteLine("Using Unity editor at " + unityPath); Console.WriteLine("Using Unity assemblies at " + unityAssembliesPath); } // Set plugin handlers PluginManager.ErrorHandler += (s, e) => { Console.Error.WriteLine($"The plugin {e.Error.Plugin.Name} encountered an error while executing {e.Error.Operation}: {e.Error.Exception.Message}." + " Plugin has been disabled."); }; PluginManager.StatusHandler += (s, e) => { Console.WriteLine("Plugin " + e.Plugin.Name + ": " + e.Text); }; // Check that specified binary files exist foreach (var file in options.BinaryFiles) { if (!File.Exists(file)) { Console.Error.WriteLine($"File {file} does not exist"); return(1); } } // Check files exist and determine whether they're archives or not bool isExtractedFromPackage = false; List <Il2CppInspector> il2cppInspectors; using (new Benchmark("Analyze IL2CPP data")) { try { il2cppInspectors = Il2CppInspector.LoadFromPackage(options.BinaryFiles, loadOptions); isExtractedFromPackage = true; } catch (Exception ex) { Console.Error.WriteLine(ex.Message); return(1); } if (il2cppInspectors == null) { isExtractedFromPackage = false; if (!File.Exists(options.MetadataFile)) { Console.Error.WriteLine($"File {options.MetadataFile} does not exist"); return(1); } try { il2cppInspectors = Il2CppInspector.LoadFromFile(options.BinaryFiles.First(), options.MetadataFile, loadOptions); } catch (Exception ex) { Console.Error.WriteLine(ex.Message); return(1); } } } if (il2cppInspectors == null) { Environment.Exit(1); } // Save metadata and binary if extracted or modified and save requested if (!string.IsNullOrEmpty(options.MetadataFileOut)) { if (isExtractedFromPackage || il2cppInspectors[0].Metadata.IsModified) { Console.WriteLine($"Saving metadata file to {options.MetadataFileOut}"); il2cppInspectors[0].SaveMetadataToFile(options.MetadataFileOut); } else { Console.WriteLine("Metadata file was not modified - skipping save"); } } if (!string.IsNullOrEmpty(options.BinaryFileOut)) { var outputIndex = 0; foreach (var il2cpp in il2cppInspectors) { // If there's an extension, strip the leading period var ext = Path.GetExtension(options.BinaryFileOut); if (ext.Length > 0) { ext = ext.Substring(1); } var outPath = getOutputPath(options.BinaryFileOut, ext, outputIndex); if (isExtractedFromPackage || il2cpp.Binary.IsModified) { Console.WriteLine($"Saving binary file to {outPath}"); il2cpp.SaveBinaryToFile(outPath); } else { Console.WriteLine("Binary file was not modified - skipping save"); } outputIndex++; } } // Write output files for each binary int imageIndex = 0; foreach (var il2cpp in il2cppInspectors) { Console.WriteLine($"Processing image {imageIndex} - {il2cpp.BinaryImage.Arch} / {il2cpp.BinaryImage.Bits}-bit"); // Create model TypeModel model; using (new Benchmark("Create .NET type model")) model = new TypeModel(il2cpp); AppModel appModel; using (new Benchmark("Create C++ application model")) { appModel = new AppModel(model, makeDefaultBuild: false).Build(options.UnityVersion, options.CppCompiler); } // C# signatures output using (new Benchmark("Generate C# code")) { var writer = new CSharpCodeStubs(model) { ExcludedNamespaces = options.ExcludedNamespaces.ToList(), SuppressMetadata = options.SuppressMetadata, MustCompile = options.MustCompile }; var csOut = getOutputPath(options.CSharpOutPath, "cs", imageIndex); if (options.CreateSolution) { writer.WriteSolution(csOut, unityPath, unityAssembliesPath); } else { switch (options.LayoutSchema.ToLower(), options.SortOrder.ToLower()) {