diff --git a/Il2CppInspector.CLI/Program.cs b/Il2CppInspector.CLI/Program.cs index c55eab5..9f4b2b4 100644 --- a/Il2CppInspector.CLI/Program.cs +++ b/Il2CppInspector.CLI/Program.cs @@ -109,6 +109,9 @@ namespace Il2CppInspector.CLI [Option("unity-version", Required = false, HelpText = "Version of Unity used to create the input files, if known. Used to enhance Python, C++ and JSON output. If not specified, a close match will be inferred automatically.", Default = null)] public UnityVersion UnityVersion { get; set; } + [Option("unity-version-from-asset", Required = false, HelpText = "A Unity asset file used to determine the exact Unity version. Overrides --unity-version.", Default = null)] + public string UnityVersionAsset { get; set; } + [Option("plugins", Required = false, HelpText = "Specify options for plugins. Enclose each plugin's configuration in quotes as follows: --plugins \"pluginone --option1 value1 --option2 value2\" \"plugintwo --option...\". Use --plugins to get help on a specific plugin")] public IEnumerable PluginOptions { get; set; } } @@ -192,6 +195,21 @@ namespace Il2CppInspector.CLI } } + // 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(); diff --git a/Il2CppInspector.Common/Cpp/UnityHeaders/UnityVersion.cs b/Il2CppInspector.Common/Cpp/UnityHeaders/UnityVersion.cs index 07afd9c..0b3714d 100644 --- a/Il2CppInspector.Common/Cpp/UnityHeaders/UnityVersion.cs +++ b/Il2CppInspector.Common/Cpp/UnityHeaders/UnityVersion.cs @@ -6,8 +6,11 @@ */ using System; +using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text.RegularExpressions; +using NoisyCowStudios.Bin2Object; namespace Il2CppInspector.Cpp.UnityHeaders { @@ -65,6 +68,26 @@ namespace Il2CppInspector.Cpp.UnityHeaders BuildNumber = match.Groups[5].Success ? int.Parse(match.Groups[5].Value) : 0; } + // Get a Unity version from a Unity asset file + public static UnityVersion FromAssetFile(string filePath) { + // Don't use BinaryObjectStream because we'd have to read the entire file into memory + using var file = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); + using var reader = new BinaryReader(file, System.Text.Encoding.UTF8); + + // Position of Unity version string in asset files + file.Position = 0x14; + + // Read null-terminated string + var bytes = new List(); + var maxLength = 15; + byte b; + while ((b = reader.ReadByte()) != 0 && bytes.Count < maxLength) + bytes.Add(b); + + var unityString = System.Text.Encoding.UTF8.GetString(bytes.ToArray()); + return new UnityVersion(unityString); + } + public static implicit operator UnityVersion(string versionString) => new UnityVersion(versionString); public override string ToString() { diff --git a/Il2CppInspector.GUI/MainWindow.xaml b/Il2CppInspector.GUI/MainWindow.xaml index 3930acb..8640534 100644 --- a/Il2CppInspector.GUI/MainWindow.xaml +++ b/Il2CppInspector.GUI/MainWindow.xaml @@ -112,6 +112,9 @@ + + +